Skip to content

Commit eb7dc1b

Browse files
committed
Migrate cryptocurrency.py to use pydantic models
1 parent e36fd90 commit eb7dc1b

19 files changed

+388
-581
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,4 @@ config.json
6565
.vagrant/
6666
.mypy_cache/
6767
.DS_Store
68+
*.bak

.pre-commit-config.yaml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ ci:
55
exclude: ^\.vscode/.*$
66
repos:
77
- repo: https://github.com/pre-commit/pre-commit-hooks
8-
rev: c4a0b883114b00d8d76b479c820ce7950211c99b # frozen: v4.5.0
8+
rev: 2c9f875913ee60ca25ce70243dc24d5b6415598c # frozen: v4.6.0
99
hooks:
1010
- id: trailing-whitespace
1111
args: ['--markdown-linebreak-ext=md,markdown']
@@ -36,7 +36,7 @@ repos:
3636
args:
3737
- --remove
3838
- repo: https://github.com/psf/black
39-
rev: 6fdf8a4af28071ed1d079c01122b34c5d587207a # frozen: 24.2.0
39+
rev: 8fe627072f15ff2e3d380887b92f7868efaf6d05 # frozen: 24.4.0
4040
hooks:
4141
- id: black
4242
- repo: https://github.com/pycqa/isort
@@ -49,12 +49,18 @@ repos:
4949
- id: python-no-eval
5050
- id: python-no-log-warn
5151
- repo: https://github.com/asottile/pyupgrade
52-
rev: df17dfa3911b81b4a27190b0eea5b1debc7ffa0a # frozen: v3.15.1
52+
rev: 12af25eb252deaaecb6b259df40d01f42e716dc3 # frozen: v3.15.2
5353
hooks:
5454
- id: pyupgrade
5555
args:
5656
- "--py38-plus"
5757

58+
- repo: https://github.com/PyCQA/autoflake
59+
rev: 0544741e2b4a22b472d9d93e37d4ea9153820bb1 # frozen: v2.3.1
60+
hooks:
61+
- id: autoflake
62+
63+
5864
- repo: local
5965
hooks:
6066
- id: mypy

.vscode/settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,6 @@
1010
"editor.formatOnType": true,
1111
"editor.wordBasedSuggestions": "off",
1212
"editor.defaultFormatter": "ms-python.black-formatter"
13-
}
13+
},
14+
"python.analysis.diagnosticMode": "workspace"
1415
}

cloudbot/config.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import time
55
from collections import OrderedDict
66
from pathlib import Path
7+
from typing import Dict, Optional, cast
78

89
logger = logging.getLogger("cloudbot")
910

@@ -15,19 +16,21 @@ def __init__(self, bot, *, filename="config.json"):
1516
self.path = Path(self.filename).resolve()
1617
self.bot = bot
1718

18-
self._api_keys = {}
19+
self._api_keys: Dict[str, Optional[str]] = {}
1920

2021
# populate self with config data
2122
self.load_config()
2223

23-
def get_api_key(self, name, default=None):
24+
def get_api_key(
25+
self, name: str, default: Optional[str] = None
26+
) -> Optional[str]:
2427
try:
2528
return self._api_keys[name]
2629
except LookupError:
2730
self._api_keys[name] = value = self.get("api_keys", {}).get(
2831
name, default
2932
)
30-
return value
33+
return cast(Optional[str], value)
3134

3235
def load_config(self):
3336
"""(re)loads the bot config from the config file"""

cloudbot/event.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import enum
33
import logging
44
from functools import partial
5-
from typing import Any, Iterator, Mapping
5+
from typing import Any, Iterator, Mapping, Optional
66

77
from irclib.parser import Message
88

@@ -245,7 +245,7 @@ def admin_log(self, message, broadcast=False):
245245
if conn and conn.connected:
246246
conn.admin_log(message, console=not broadcast)
247247

248-
def reply(self, *messages, target=None):
248+
def reply(self, *messages: str, target: Optional[str] = None) -> None:
249249
"""sends a message to the current channel/user with a prefix"""
250250
reply_ping = self.conn.config.get("reply_ping", True)
251251
if target is None:

cloudbot/hook.py

Lines changed: 61 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,18 @@
44
import re
55
import warnings
66
from enum import Enum, IntEnum, unique
7+
from typing import (
8+
Any,
9+
Callable,
10+
List,
11+
Optional,
12+
Sequence,
13+
TypeVar,
14+
Union,
15+
overload,
16+
)
17+
18+
from typing_extensions import ParamSpec
719

820
from cloudbot.event import EventType
921
from cloudbot.util import HOOK_ATTR
@@ -186,10 +198,36 @@ def _hook_warn():
186198
)
187199

188200

189-
def command(*args, **kwargs):
201+
_T = TypeVar("_T")
202+
_P = ParamSpec("_P")
203+
_Func = Callable[_P, _T]
204+
205+
206+
@overload
207+
def command(arg: Callable[_P, _T], /) -> Callable[_P, _T]: ...
208+
209+
210+
@overload
211+
def command(
212+
arg: Optional[Union[str, Sequence[str]]] = None,
213+
/,
214+
*args: Union[str, Sequence[str]],
215+
**kwargs: Any,
216+
) -> Callable[[Callable[_P, _T]], Callable[_P, _T]]: ...
217+
218+
219+
def command(
220+
arg: Optional[Union[Callable[_P, _T], str, Sequence[str]]] = None,
221+
/,
222+
*args: Union[str, Sequence[str]],
223+
**kwargs: Any,
224+
) -> Union[Callable[_P, _T], Callable[[Callable[_P, _T]], Callable[_P, _T]]]:
190225
"""External command decorator. Can be used directly as a decorator, or with args to return a decorator."""
191226

192-
def _command_hook(func, alias_param=None):
227+
def _command_hook(
228+
func: Callable[_P, _T],
229+
alias_param: Optional[Sequence[Union[Sequence[str], str]]] = None,
230+
) -> Callable[_P, _T]:
193231
hook = _get_hook(func, "command")
194232
if hook is None:
195233
hook = _CommandHook(func)
@@ -198,13 +236,17 @@ def _command_hook(func, alias_param=None):
198236
hook.add_hook(alias_param, kwargs)
199237
return func
200238

201-
if len(args) == 1 and callable(args[0]):
239+
if arg is not None and not isinstance(arg, (str, collections.abc.Sequence)):
202240
# this decorator is being used directly
203241
_hook_warn()
204-
return _command_hook(args[0])
242+
return _command_hook(arg)
243+
244+
arg_list: List[Union[str, Sequence[str]]] = list(args)
245+
if arg:
246+
arg_list.insert(0, arg)
205247

206248
# this decorator is being used indirectly, so return a decorator function
207-
return lambda func: _command_hook(func, alias_param=args)
249+
return lambda func: _command_hook(func, alias_param=arg_list)
208250

209251

210252
def irc_raw(triggers_param, **kwargs):
@@ -332,10 +374,22 @@ def _config_hook(func):
332374
return _config_hook
333375

334376

335-
def on_start(param=None, **kwargs):
377+
@overload
378+
def on_start(
379+
**kwargs: Any,
380+
) -> Callable[[Callable[_P, _T]], Callable[_P, _T]]: ...
381+
382+
383+
@overload
384+
def on_start(param: Callable[_P, _T], /) -> Callable[_P, _T]: ...
385+
386+
387+
def on_start(
388+
param: Optional[Callable[_P, _T]] = None, /, **kwargs: Any
389+
) -> Union[Callable[_P, _T], Callable[[Callable[_P, _T]], Callable[_P, _T]]]:
336390
"""External on_start decorator. Can be used directly as a decorator, or with args to return a decorator"""
337391

338-
def _on_start_hook(func):
392+
def _on_start_hook(func: Callable[_P, _T]) -> Callable[_P, _T]:
339393
hook = _get_hook(func, "on_start")
340394
if hook is None:
341395
hook = _Hook(func, "on_start")

cloudbot/util/colors.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ def get_available_colours():
154154
return ret[:-2]
155155

156156

157-
def parse(string):
157+
def parse(string: str) -> str:
158158
"""
159159
parse: Formats a string, replacing words wrapped in $( ) with actual colours or formatting.
160160
example:

cloudbot/util/func_utils.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import inspect
2+
from typing import Any, Callable, Mapping, TypeVar
23

34

45
class ParameterError(Exception):
@@ -12,7 +13,14 @@ def __init__(self, name, valid_args):
1213
self.valid_args = list(valid_args)
1314

1415

15-
def call_with_args(func, arg_data):
16+
_T = TypeVar("_T")
17+
18+
19+
def call_with_args(func: Callable[..., _T], arg_data: Mapping[str, Any]) -> _T:
20+
"""
21+
>>> call_with_args(lambda a: a, {'a':1, 'b':2})
22+
1
23+
"""
1624
sig = inspect.signature(func, follow_wrapped=False)
1725
try:
1826
args = [

0 commit comments

Comments
 (0)