Skip to content

Commit e662075

Browse files
committed
fixes #90
1 parent 707f60b commit e662075

File tree

5 files changed

+88
-20
lines changed

5 files changed

+88
-20
lines changed

fastcore/__init__.py

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

fastcore/_nbdev.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
"mk_class": "02_utils.ipynb",
5252
"wrap_class": "02_utils.ipynb",
5353
"ignore_exceptions": "02_utils.ipynb",
54+
"dict2obj": "02_utils.ipynb",
5455
"store_attr": "02_utils.ipynb",
5556
"attrdict": "02_utils.ipynb",
5657
"properties": "02_utils.ipynb",

fastcore/utils.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# AUTOGENERATED! DO NOT EDIT! File to edit: nbs/02_utils.ipynb (unless otherwise specified).
22

3-
__all__ = ['ifnone', 'maybe_attr', 'basic_repr', 'get_class', 'mk_class', 'wrap_class', 'ignore_exceptions',
3+
__all__ = ['ifnone', 'maybe_attr', 'basic_repr', 'get_class', 'mk_class', 'wrap_class', 'ignore_exceptions', 'dict2obj',
44
'store_attr', 'attrdict', 'properties', 'camel2snake', 'snake2camel', 'class2attr', 'hasattrs', 'ShowPrint',
55
'Int', 'Str', 'Float', 'tuplify', 'detuplify', 'replicate', 'uniqueify', 'setify', 'merge', 'is_listy',
66
'range_of', 'groupby', 'first', 'last_index', 'shufflish', 'IterLen', 'ReindexCollection', 'num_methods',
@@ -87,6 +87,12 @@ class ignore_exceptions:
8787
def __enter__(self): pass
8888
def __exit__(self, *args): return True
8989

90+
# Cell
91+
def dict2obj(d):
92+
if isinstance(d, (L,list)): return L(d).map(dict2obj)
93+
if not isinstance(d, dict): return d
94+
return SimpleNamespace(**{k:dict2obj(v) for k,v in d.items()})
95+
9096
# Cell
9197
def _store_attr(self, **attrs):
9298
for n,v in attrs.items():
@@ -678,12 +684,13 @@ def _call(lock, pause, n, g, item):
678684
# Cell
679685
class ProcessPoolExecutor(concurrent.futures.ProcessPoolExecutor):
680686
"Same as Python's ProcessPoolExecutor, except can pass `max_workers==0` for serial execution"
681-
def __init__(self, max_workers=defaults.cpus, on_exc=print, pause=0, **kwargs):
687+
def __init__(self, max_workers=defaults.cpus, on_exc=print, pause=0,
688+
mp_context=None, initializer=None, initargs=(),):
682689
if max_workers is None: max_workers=defaults.cpus
683690
store_attr()
684691
self.not_parallel = max_workers==0
685692
if self.not_parallel: max_workers=1
686-
super().__init__(max_workers, **kwargs)
693+
super().__init__(max_workers, mp_context=mp_context, initializer=initializer, initargs=initargs)
687694

688695
def map(self, f, items, timeout=None, chunksize=1, *args, **kwargs):
689696
self.lock = Manager().Lock()

nbs/02_utils.ipynb

Lines changed: 75 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@
294294
{
295295
"data": {
296296
"text/plain": [
297-
"<__main__._t at 0x7fd2eaf8cf50>"
297+
"<__main__._t at 0x7efe2eb5ef90>"
298298
]
299299
},
300300
"execution_count": null,
@@ -478,11 +478,77 @@
478478
"cell_type": "markdown",
479479
"metadata": {},
480480
"source": [
481-
"## Attribute Helpers\n",
482-
"\n",
481+
"## Attribute Helpers"
482+
]
483+
},
484+
{
485+
"cell_type": "markdown",
486+
"metadata": {},
487+
"source": [
483488
"These functions reduce boilerplate when setting or manipulating attributes or properties of objects."
484489
]
485490
},
491+
{
492+
"cell_type": "code",
493+
"execution_count": null,
494+
"metadata": {},
495+
"outputs": [],
496+
"source": [
497+
"#export\n",
498+
"def dict2obj(d):\n",
499+
" \"Convert (possibly nested) dicts (or lists of dicts) to `SimpleNamespace`\"\n",
500+
" if isinstance(d, (L,list)): return L(d).map(dict2obj)\n",
501+
" if not isinstance(d, dict): return d\n",
502+
" return SimpleNamespace(**{k:dict2obj(v) for k,v in d.items()})"
503+
]
504+
},
505+
{
506+
"cell_type": "markdown",
507+
"metadata": {},
508+
"source": [
509+
"This is a convenience to give you \"dotted\" access to (possibly nested) dictionaries, e.g:"
510+
]
511+
},
512+
{
513+
"cell_type": "code",
514+
"execution_count": null,
515+
"metadata": {},
516+
"outputs": [
517+
{
518+
"data": {
519+
"text/plain": [
520+
"namespace(a=1, b=namespace(c=2, d=3))"
521+
]
522+
},
523+
"execution_count": null,
524+
"metadata": {},
525+
"output_type": "execute_result"
526+
}
527+
],
528+
"source": [
529+
"d1 = dict(a=1, b=dict(c=2,d=3))\n",
530+
"d2 = dict2obj(d1)\n",
531+
"test_eq(d2.b.c, 2)\n",
532+
"d2"
533+
]
534+
},
535+
{
536+
"cell_type": "markdown",
537+
"metadata": {},
538+
"source": [
539+
"It can also be used on lists of dicts."
540+
]
541+
},
542+
{
543+
"cell_type": "code",
544+
"execution_count": null,
545+
"metadata": {},
546+
"outputs": [],
547+
"source": [
548+
"ds = L(d1, d1)\n",
549+
"test_eq(dict2obj(ds[0]).b.c, 2)"
550+
]
551+
},
486552
{
487553
"cell_type": "code",
488554
"execution_count": null,
@@ -519,7 +585,7 @@
519585
"cell_type": "markdown",
520586
"metadata": {},
521587
"source": [
522-
"In it's most basic form, you can use this to shorten code like this:"
588+
"In it's most basic form, you can use `store_attr` to shorten code like this:"
523589
]
524590
},
525591
{
@@ -1625,7 +1691,7 @@
16251691
{
16261692
"data": {
16271693
"text/plain": [
1628-
"['g', 'e', 'f', 'a', 'h', 'c', 'd', 'b']"
1694+
"['a', 'e', 'b', 'h', 'c', 'd', 'g', 'f']"
16291695
]
16301696
},
16311697
"execution_count": null,
@@ -3511,12 +3577,13 @@
35113577
"#export\n",
35123578
"class ProcessPoolExecutor(concurrent.futures.ProcessPoolExecutor):\n",
35133579
" \"Same as Python's ProcessPoolExecutor, except can pass `max_workers==0` for serial execution\"\n",
3514-
" def __init__(self, max_workers=defaults.cpus, on_exc=print, pause=0, **kwargs):\n",
3580+
" def __init__(self, max_workers=defaults.cpus, on_exc=print, pause=0,\n",
3581+
" mp_context=None, initializer=None, initargs=(),):\n",
35153582
" if max_workers is None: max_workers=defaults.cpus\n",
35163583
" store_attr()\n",
35173584
" self.not_parallel = max_workers==0\n",
35183585
" if self.not_parallel: max_workers=1\n",
3519-
" super().__init__(max_workers, **kwargs)\n",
3586+
" super().__init__(max_workers, mp_context=mp_context, initializer=initializer, initargs=initargs)\n",
35203587
"\n",
35213588
" def map(self, f, items, timeout=None, chunksize=1, *args, **kwargs):\n",
35223589
" self.lock = Manager().Lock()\n",
@@ -3537,7 +3604,7 @@
35373604
"text/markdown": [
35383605
"<h4 id=\"ProcessPoolExecutor\" class=\"doc_header\"><code>class</code> <code>ProcessPoolExecutor</code><a href=\"\" class=\"source_link\" style=\"float:right\">[source]</a></h4>\n",
35393606
"\n",
3540-
"> <code>ProcessPoolExecutor</code>(**`max_workers`**=*`64`*, **`on_exc`**=*`print`*, **`pause`**=*`0`*, **\\*\\*`kwargs`**) :: [`ProcessPoolExecutor`](/utils.html#ProcessPoolExecutor)\n",
3607+
"> <code>ProcessPoolExecutor</code>(**`max_workers`**=*`64`*, **`on_exc`**=*`print`*, **`pause`**=*`0`*, **`mp_context`**=*`None`*, **`initializer`**=*`None`*, **`initargs`**=*`()`*) :: [`ProcessPoolExecutor`](/utils.html#ProcessPoolExecutor)\n",
35413608
"\n",
35423609
"Same as Python's ProcessPoolExecutor, except can pass `max_workers==0` for serial execution"
35433610
],
@@ -3553,13 +3620,6 @@
35533620
"show_doc(ProcessPoolExecutor, title_level=4)"
35543621
]
35553622
},
3556-
{
3557-
"cell_type": "markdown",
3558-
"metadata": {},
3559-
"source": [
3560-
"`kwargs` are passed to Python's [`concurrent.futures.ProcessPoolExecutor`](https://python.readthedocs.io/en/latest/library/concurrent.futures.html#processpoolexecutor), so depend on your python version. From Python 3.7, they are: `mp_context=None`, `initializer=None`, `initargs=()`."
3561-
]
3562-
},
35633623
{
35643624
"cell_type": "code",
35653625
"execution_count": null,

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 = [email protected]
88
copyright = fast.ai
99
branch = master
10-
version = 1.0.12
10+
version = 1.0.13
1111
min_python = 3.6
1212
audience = Developers
1313
language = English

0 commit comments

Comments
 (0)