Skip to content

Commit 1b96df6

Browse files
committed
fixes #125
1 parent c0c419a commit 1b96df6

File tree

7 files changed

+79
-17
lines changed

7 files changed

+79
-17
lines changed

fastcore/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "1.1.1"
1+
__version__ = "1.1.2"

fastcore/_nbdev.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@
131131
"defaults.cpus": "02_utils.ipynb",
132132
"add_props": "02_utils.ipynb",
133133
"ContextManagers": "02_utils.ipynb",
134+
"typed": "02_utils.ipynb",
134135
"set_num_threads": "02_utils.ipynb",
135136
"ProcessPoolExecutor": "02_utils.ipynb",
136137
"ThreadPoolExecutor": "02_utils.ipynb",

fastcore/foundation.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -422,15 +422,15 @@ def setattrs(self, attr, val): [setattr(o,attr,val) for o in self]
422422
Sequence.register(L);
423423

424424
# Cell
425-
def save_config_file(file, d):
425+
def save_config_file(file, d, **kwargs):
426426
"Write settings dict to a new config file, or overwrite the existing one."
427-
config = ConfigParser()
427+
config = ConfigParser(**kwargs)
428428
config['DEFAULT'] = d
429429
config.write(open(file, 'w'))
430430

431431
# Cell
432-
def read_config_file(file):
433-
config = ConfigParser()
432+
def read_config_file(file, **kwargs):
433+
config = ConfigParser(**kwargs)
434434
config.read(file)
435435
return config
436436

fastcore/utils.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
'inum_methods', 'fastuple', 'trace', 'compose', 'maps', 'partialler', 'mapped', 'instantiate', 'using_attr',
1010
'Self', 'Self', 'save_pickle', 'load_pickle', 'bunzip', 'join_path_file', 'urlread', 'urljson', 'run',
1111
'do_request', 'sort_by_run', 'PrettyString', 'round_multiple', 'even_mults', 'num_cpus', 'add_props',
12-
'ContextManagers', 'set_num_threads', 'ProcessPoolExecutor', 'ThreadPoolExecutor', 'parallel', 'run_procs',
13-
'parallel_gen', 'threaded']
12+
'ContextManagers', 'typed', 'set_num_threads', 'ProcessPoolExecutor', 'ThreadPoolExecutor', 'parallel',
13+
'run_procs', 'parallel_gen', 'threaded']
1414

1515
# Cell
1616
from .imports import *
@@ -675,6 +675,23 @@ def __init__(self, mgrs): self.default,self.stack = L(mgrs),ExitStack()
675675
def __enter__(self): self.default.map(self.stack.enter_context)
676676
def __exit__(self, *args, **kwargs): self.stack.__exit__(*args, **kwargs)
677677

678+
# Cell
679+
def typed(f):
680+
"Decorator to check param and return types at runtime"
681+
names = f.__code__.co_varnames
682+
anno = f.__annotations__
683+
ret = anno.pop('return',None)
684+
def _f(*args,**kwargs):
685+
kw = {**kwargs}
686+
if len(anno) > 0:
687+
for i,arg in enumerate(args): kw[names[i]] = arg
688+
for k,v in kw.items():
689+
if not isinstance(v,anno[k]): raise TypeError(f"{k}=={v} not {anno[k]}")
690+
res = f(*args,**kwargs)
691+
if ret is not None and not isinstance(res,ret): raise TypeError(f"return=={res} not {ret}")
692+
return res
693+
return functools.update_wrapper(_f, f)
694+
678695
# Cell
679696
from multiprocessing import Process, Queue
680697
import concurrent.futures

nbs/01_foundation.ipynb

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1964,7 +1964,7 @@
19641964
{
19651965
"data": {
19661966
"text/plain": [
1967-
"['k', 4, 'j']"
1967+
"[0, 9, 1]"
19681968
]
19691969
},
19701970
"execution_count": null,
@@ -2143,7 +2143,7 @@
21432143
"cell_type": "markdown",
21442144
"metadata": {},
21452145
"source": [
2146-
"### Class L Methods"
2146+
"### `L` Methods"
21472147
]
21482148
},
21492149
{
@@ -3036,9 +3036,9 @@
30363036
"outputs": [],
30373037
"source": [
30383038
"#export\n",
3039-
"def save_config_file(file, d):\n",
3039+
"def save_config_file(file, d, **kwargs):\n",
30403040
" \"Write settings dict to a new config file, or overwrite the existing one.\"\n",
3041-
" config = ConfigParser()\n",
3041+
" config = ConfigParser(**kwargs)\n",
30423042
" config['DEFAULT'] = d\n",
30433043
" config.write(open(file, 'w'))"
30443044
]
@@ -3050,8 +3050,8 @@
30503050
"outputs": [],
30513051
"source": [
30523052
"#export\n",
3053-
"def read_config_file(file):\n",
3054-
" config = ConfigParser()\n",
3053+
"def read_config_file(file, **kwargs):\n",
3054+
" config = ConfigParser(**kwargs)\n",
30553055
" config.read(file)\n",
30563056
" return config"
30573057
]

nbs/02_utils.ipynb

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@
296296
{
297297
"data": {
298298
"text/plain": [
299-
"<__main__._t at 0x7ff9a9c3deb0>"
299+
"<__main__._t at 0x7f945b39e070>"
300300
]
301301
},
302302
"execution_count": null,
@@ -2171,7 +2171,7 @@
21712171
{
21722172
"data": {
21732173
"text/plain": [
2174-
"['g', 'd', 'h', 'a', 'f', 'c', 'b', 'e']"
2174+
"['h', 'g', 'f', 'b', 'd', 'e', 'a', 'c']"
21752175
]
21762176
},
21772177
"execution_count": null,
@@ -3513,7 +3513,7 @@
35133513
{
35143514
"data": {
35153515
"text/plain": [
3516-
"64"
3516+
"8"
35173517
]
35183518
},
35193519
"execution_count": null,
@@ -3621,6 +3621,50 @@
36213621
"show_doc(ContextManagers, title_level=4)"
36223622
]
36233623
},
3624+
{
3625+
"cell_type": "code",
3626+
"execution_count": null,
3627+
"metadata": {},
3628+
"outputs": [],
3629+
"source": [
3630+
"#export\n",
3631+
"def typed(f):\n",
3632+
" \"Decorator to check param and return types at runtime\"\n",
3633+
" names = f.__code__.co_varnames\n",
3634+
" anno = f.__annotations__\n",
3635+
" ret = anno.pop('return',None)\n",
3636+
" def _f(*args,**kwargs):\n",
3637+
" kw = {**kwargs}\n",
3638+
" if len(anno) > 0:\n",
3639+
" for i,arg in enumerate(args): kw[names[i]] = arg\n",
3640+
" for k,v in kw.items():\n",
3641+
" if not isinstance(v,anno[k]): raise TypeError(f\"{k}=={v} not {anno[k]}\")\n",
3642+
" res = f(*args,**kwargs)\n",
3643+
" if ret is not None and not isinstance(res,ret): raise TypeError(f\"return=={res} not {ret}\")\n",
3644+
" return res\n",
3645+
" return functools.update_wrapper(_f, f)"
3646+
]
3647+
},
3648+
{
3649+
"cell_type": "code",
3650+
"execution_count": null,
3651+
"metadata": {},
3652+
"outputs": [],
3653+
"source": [
3654+
"@typed\n",
3655+
"def foo(a:int, b:str='a'): return a\n",
3656+
"test_eq(foo(1, '2'), 1)\n",
3657+
"test_fail(partial(foo, 1, 2))\n",
3658+
"\n",
3659+
"@typed\n",
3660+
"def foo()->str: return 1\n",
3661+
"test_fail(partial(foo))\n",
3662+
"\n",
3663+
"@typed\n",
3664+
"def foo()->str: return '1'\n",
3665+
"assert foo()"
3666+
]
3667+
},
36243668
{
36253669
"cell_type": "markdown",
36263670
"metadata": {},

settings.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ author = Jeremy Howard and Sylvain Gugger
77
author_email = infos@fast.ai
88
copyright = fast.ai
99
branch = master
10-
version = 1.1.1
10+
version = 1.1.2
1111
min_python = 3.6
1212
audience = Developers
1313
language = English

0 commit comments

Comments
 (0)