|
1 | 1 | # AUTOGENERATED! DO NOT EDIT! File to edit: nbs/02_utils.ipynb (unless otherwise specified). |
2 | 2 |
|
3 | | -__all__ = ['ifnone', 'maybe_attr', 'basic_repr', 'get_class', 'mk_class', 'wrap_class', 'ignore_exceptions', 'dict2obj', |
4 | | - 'store_attr', 'attrdict', 'properties', 'camel2snake', 'snake2camel', 'class2attr', 'hasattrs', 'setattrs', |
5 | | - 'ShowPrint', 'Int', 'Str', 'Float', 'tuplify', 'detuplify', 'replicate', 'uniqueify', 'setify', 'merge', |
6 | | - 'is_listy', 'range_of', 'groupby', 'last_index', 'shufflish', 'IterLen', 'ReindexCollection', 'num_methods', |
7 | | - 'rnum_methods', 'inum_methods', 'fastuple', 'Inf', 'in_', 'lt', 'gt', 'le', 'ge', 'eq', 'ne', 'add', 'sub', |
8 | | - 'mul', 'truediv', 'is_', 'is_not', 'in_', 'true', 'stop', 'gen', 'chunked', 'trace', 'compose', 'maps', |
9 | | - 'partialler', 'mapped', 'instantiate', 'using_attr', 'Self', 'Self', 'remove_patches_path', 'bunzip', |
10 | | - 'join_path_file', 'urlread', 'urljson', 'run', 'do_request', 'sort_by_run', 'PrettyString', 'round_multiple', |
11 | | - 'even_mults', 'num_cpus', 'add_props', 'ContextManagers', 'set_num_threads', 'ProcessPoolExecutor', |
12 | | - 'ThreadPoolExecutor', 'parallel', 'run_procs', 'parallel_gen'] |
| 3 | +__all__ = ['ifnone', 'maybe_attr', 'basic_repr', 'get_class', 'mk_class', 'wrap_class', 'ignore_exceptions', 'stop', |
| 4 | + 'AttrDict', 'dict2obj', 'store_attr', 'attrdict', 'properties', 'camel2snake', 'snake2camel', 'class2attr', |
| 5 | + 'hasattrs', 'setattrs', 'ShowPrint', 'Int', 'Str', 'Float', 'tuplify', 'detuplify', 'replicate', 'uniqueify', |
| 6 | + 'setify', 'merge', 'is_listy', 'range_of', 'groupby', 'last_index', 'shufflish', 'IterLen', |
| 7 | + 'ReindexCollection', 'num_methods', 'rnum_methods', 'inum_methods', 'fastuple', 'Inf', 'in_', 'lt', 'gt', |
| 8 | + 'le', 'ge', 'eq', 'ne', 'add', 'sub', 'mul', 'truediv', 'is_', 'is_not', 'in_', 'true', 'gen', 'chunked', |
| 9 | + 'trace', 'compose', 'maps', 'partialler', 'mapped', 'instantiate', 'using_attr', 'Self', 'Self', |
| 10 | + 'remove_patches_path', 'bunzip', 'join_path_file', 'urlread', 'urljson', 'run', 'do_request', 'sort_by_run', |
| 11 | + 'PrettyString', 'round_multiple', 'even_mults', 'num_cpus', 'add_props', 'ContextManagers', |
| 12 | + 'set_num_threads', 'ProcessPoolExecutor', 'ThreadPoolExecutor', 'parallel', 'run_procs', 'parallel_gen'] |
13 | 13 |
|
14 | 14 | # Cell |
15 | 15 | from .imports import * |
@@ -87,12 +87,27 @@ class ignore_exceptions: |
87 | 87 | def __enter__(self): pass |
88 | 88 | def __exit__(self, *args): return True |
89 | 89 |
|
| 90 | +# Cell |
| 91 | +def stop(e=StopIteration): |
| 92 | + "Raises exception `e` (by default `StopException`)" |
| 93 | + raise e |
| 94 | + |
| 95 | +# Cell |
| 96 | +class AttrDict(GetAttr, dict): |
| 97 | + "`dict` subclass that also provides access to keys as attrs" |
| 98 | + def _dir(self): return list(self.keys()) |
| 99 | + def __getattr__(self,k): return self[k] if k in self else stop(AttributeError(k)) |
| 100 | + def __setattr__(self, k, v): |
| 101 | + if k.startswith('_'): super().__setattr__(k,v) |
| 102 | + self[k] = v |
| 103 | + def __dir__(self): return custom_dir(self,self._dir()) |
| 104 | + |
90 | 105 | # Cell |
91 | 106 | def dict2obj(d): |
92 | | - "Convert (possibly nested) dicts (or lists of dicts) to `SimpleNamespace`" |
| 107 | + "Convert (possibly nested) dicts (or lists of dicts) to `AttrDict`" |
93 | 108 | if isinstance(d, (L,list)): return L(d).map(dict2obj) |
94 | 109 | if not isinstance(d, dict): return d |
95 | | - return SimpleNamespace(**{k:dict2obj(v) for k,v in d.items()}) |
| 110 | + return AttrDict(**{k:dict2obj(v) for k,v in d.items()}) |
96 | 111 |
|
97 | 112 | # Cell |
98 | 113 | def _store_attr(self, **attrs): |
@@ -361,11 +376,6 @@ def true(*args, **kwargs): |
361 | 376 | "Predicate: always `True`" |
362 | 377 | return True |
363 | 378 |
|
364 | | -# Cell |
365 | | -def stop(e=StopIteration): |
366 | | - "Raises exception `e` (by default `StopException`) even if in an expression" |
367 | | - raise e |
368 | | - |
369 | 379 | # Cell |
370 | 380 | def gen(func, seq, cond=true): |
371 | 381 | "Like `(func(o) for o in seq if cond(func(o)))` but handles `StopIteration`" |
@@ -569,13 +579,16 @@ def urljson(url): |
569 | 579 | return json.loads(urlread(url)) |
570 | 580 |
|
571 | 581 | # Cell |
572 | | -def run(cmd, *rest): |
| 582 | +def run(cmd, *rest, ignore_ex=False, as_bytes=False): |
573 | 583 | "Pass `cmd` (splitting with `shlex` if string) to `subprocess.run`, returning `stdout`, or raise `IOError` on failure" |
574 | 584 | if rest: cmd = (cmd,)+rest |
575 | 585 | elif isinstance(cmd,str): cmd = shlex.split(cmd) |
576 | 586 | res = subprocess.run(cmd, capture_output=True) |
| 587 | + stdout = res.stdout |
| 588 | + if not as_bytes: stdout = stdout.decode() |
| 589 | + if ignore_ex: return (res.returncode, stdout) |
577 | 590 | if res.returncode: raise IOError("{} ;; {}".format(res.stdout, res.stderr)) |
578 | | - return res.stdout |
| 591 | + return stdout |
579 | 592 |
|
580 | 593 | # Cell |
581 | 594 | def do_request(url, post=False, headers=None, **data): |
|
0 commit comments