Skip to content

Commit

Permalink
fixes #179
Browse files Browse the repository at this point in the history
  • Loading branch information
jph00 committed Nov 9, 2020
1 parent fc9c177 commit 497d205
Show file tree
Hide file tree
Showing 7 changed files with 262 additions and 190 deletions.
6 changes: 4 additions & 2 deletions fastcore/_nbdev.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@
"otherwise": "01_basics.ipynb",
"custom_dir": "01_basics.ipynb",
"AttrDict": "01_basics.ipynb",
"type_hints": "01_basics.ipynb",
"annotations": "01_basics.ipynb",
"anno_ret": "01_basics.ipynb",
"argnames": "01_basics.ipynb",
"with_cast": "01_basics.ipynb",
"store_attr": "01_basics.ipynb",
"attrdict": "01_basics.ipynb",
Expand Down Expand Up @@ -165,8 +169,6 @@
"run_procs": "03_xtras.ipynb",
"parallel_gen": "03_xtras.ipynb",
"threaded": "03_xtras.ipynb",
"type_hints": "04_dispatch.ipynb",
"anno_ret": "04_dispatch.ipynb",
"lenient_issubclass": "04_dispatch.ipynb",
"sorted_topologically": "04_dispatch.ipynb",
"TypeDispatch": "04_dispatch.ipynb",
Expand Down
61 changes: 45 additions & 16 deletions fastcore/basics.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,18 @@
__all__ = ['defaults', 'ifnone', 'maybe_attr', 'basic_repr', 'is_array', 'listify', 'true', 'NullType', 'null',
'tonull', 'get_class', 'mk_class', 'wrap_class', 'ignore_exceptions', 'exec_local', 'risinstance', 'Inf',
'in_', 'lt', 'gt', 'le', 'ge', 'eq', 'ne', 'add', 'sub', 'mul', 'truediv', 'is_', 'is_not', 'in_', 'true',
'stop', 'gen', 'chunked', 'otherwise', 'custom_dir', 'AttrDict', 'with_cast', 'store_attr', 'attrdict',
'properties', 'camel2snake', 'snake2camel', 'class2attr', 'getattrs', 'hasattrs', 'setattrs', 'try_attrs',
'ShowPrint', 'Int', 'Str', 'Float', 'detuplify', 'replicate', 'setify', 'merge', 'range_of', 'groupby',
'last_index', 'filter_dict', 'filter_keys', 'filter_values', 'cycle', 'zip_cycle', 'sorted_ex',
'negate_func', 'argwhere', 'filter_ex', 'range_of', 'renumerate', 'first', 'nested_attr', 'nested_idx',
'num_methods', 'rnum_methods', 'inum_methods', 'fastuple', 'arg0', 'arg1', 'arg2', 'arg3', 'arg4', 'bind',
'map_ex', 'compose', 'maps', 'partialler', 'instantiate', 'using_attr', 'Self', 'Self', 'PrettyString',
'even_mults', 'num_cpus', 'add_props', 'typed']
'stop', 'gen', 'chunked', 'otherwise', 'custom_dir', 'AttrDict', 'type_hints', 'annotations', 'anno_ret',
'argnames', 'with_cast', 'store_attr', 'attrdict', 'properties', 'camel2snake', 'snake2camel', 'class2attr',
'getattrs', 'hasattrs', 'setattrs', 'try_attrs', 'ShowPrint', 'Int', 'Str', 'Float', 'detuplify',
'replicate', 'setify', 'merge', 'range_of', 'groupby', 'last_index', 'filter_dict', 'filter_keys',
'filter_values', 'cycle', 'zip_cycle', 'sorted_ex', 'negate_func', 'argwhere', 'filter_ex', 'range_of',
'renumerate', 'first', 'nested_attr', 'nested_idx', 'num_methods', 'rnum_methods', 'inum_methods',
'fastuple', 'arg0', 'arg1', 'arg2', 'arg3', 'arg4', 'bind', 'map_ex', 'compose', 'maps', 'partialler',
'instantiate', 'using_attr', 'Self', 'Self', 'PrettyString', 'even_mults', 'num_cpus', 'add_props', 'typed']

# Cell
from .imports import *
import weakref

# Cell
defaults = SimpleNamespace()
Expand Down Expand Up @@ -216,12 +217,37 @@ def __getattr__(self,k): return self[k] if k in self else stop(AttributeError(k)
def __setattr__(self, k, v): (self.__setitem__,super().__setattr__)[k[0]=='_'](k,v)
def __dir__(self): return custom_dir(self, list(self.keys()))

# Cell
def type_hints(f):
"Same as `typing.get_type_hints` but returns `{}` if not allowed type"
return typing.get_type_hints(f) if isinstance(f, typing._allowed_types) else {}

# Cell
def annotations(o):
"Annotations for `o`, or `type(o)`"
res = {}
if not o: return res
res = type_hints(o)
if not res: res = type_hints(getattr(o,'__init__',None))
if not res: res = type_hints(type(o))
return res

# Cell
def anno_ret(func):
"Get the return annotation of `func`"
return annotations(func).get('return', None) if func else None

# Cell
def argnames(f):
"Names of arguments to function `f`"
code = f.__code__
return code.co_varnames[:code.co_argcount]

# Cell
def with_cast(f):
"Decorator which uses any parameter annotations as preprocessing functions"
anno = f.__annotations__
params = f.__code__.co_varnames[:f.__code__.co_argcount]
defaults = dict(zip(reversed(params), reversed(f.__defaults__))) if f.__defaults__ else {}
anno,params = annotations(f),argnames(f)
defaults = dict(zip(reversed(params), reversed(f.__defaults__ or {})))
@functools.wraps(f)
def _inner(*args, **kwargs):
args = list(args)
Expand All @@ -236,10 +262,13 @@ def _inner(*args, **kwargs):

# Cell
def _store_attr(self, anno, **attrs):
stored = self.__stored_args__
for n,v in attrs.items():
if n in anno: v = anno[n](v)
setattr(self, n, v)
self.__stored_args__[n] = v
try: v = weakref.proxy(v)
except TypeError: pass
stored[n] = v

# Cell
def store_attr(names=None, self=None, but='', cast=False, **attrs):
Expand All @@ -249,7 +278,7 @@ def store_attr(names=None, self=None, but='', cast=False, **attrs):
if self: args = ('self', *args)
else: self = fr.f_locals[args[0]]
if not hasattr(self, '__stored_args__'): self.__stored_args__ = {}
anno = self.__class__.__init__.__annotations__ if cast else {}
anno = annotations(self) if cast else {}
if not attrs:
ns = re.split(', *', names) if names else args[1:]
attrs = {n:fr.f_locals[n] for n in ns}
Expand All @@ -258,9 +287,9 @@ def store_attr(names=None, self=None, but='', cast=False, **attrs):
return _store_attr(self, anno, **attrs)

# Cell
def attrdict(o, *ks):
def attrdict(o, *ks, default=None):
"Dict from each `k` in `ks` to `getattr(o,k)`"
return {k:getattr(o,k) for k in ks}
return {k:getattr(o, k, default) for k in ks}

# Cell
def properties(cls, *ps):
Expand Down Expand Up @@ -668,7 +697,7 @@ def _typeerr(arg, val, typ): return TypeError(f"{arg}=={val} not {typ}")
def typed(f):
"Decorator to check param and return types at runtime"
names = f.__code__.co_varnames
anno = f.__annotations__
anno = annotations(f)
ret = anno.pop('return',None)
def _f(*args,**kwargs):
kw = {**kwargs}
Expand Down
20 changes: 4 additions & 16 deletions fastcore/dispatch.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,14 @@
# AUTOGENERATED! DO NOT EDIT! File to edit: nbs/04_dispatch.ipynb (unless otherwise specified).

__all__ = ['type_hints', 'anno_ret', 'lenient_issubclass', 'sorted_topologically', 'TypeDispatch', 'DispatchReg',
'typedispatch', 'cast', 'retain_meta', 'default_set_meta', 'retain_type', 'retain_types', 'explode_types']
__all__ = ['lenient_issubclass', 'sorted_topologically', 'TypeDispatch', 'DispatchReg', 'typedispatch', 'cast',
'retain_meta', 'default_set_meta', 'retain_type', 'retain_types', 'explode_types']

# Cell
from .imports import *
from .foundation import *
from .utils import *
from collections import defaultdict

# Cell
def type_hints(f):
"Same as `typing.get_type_hints` but returns `{}` if not allowed type"
return typing.get_type_hints(f) if isinstance(f, typing._allowed_types) else {}

# Cell
def anno_ret(func):
"Get the return annotation of `func`"
if not func: return None
ann = type_hints(func)
if not ann: return None
return ann.get('return')
from collections import defaultdict

# Cell
def lenient_issubclass(cls, types):
Expand Down Expand Up @@ -114,7 +102,7 @@ def returns_none(self, x):

def _attname(self,k): return getattr(k,'__name__',str(k))
def __repr__(self):
r = [f'({self._attname(k)},{self._attname(l)}) -> {getattr(v, "__name__", v.__class__.__name__)}'
r = [f'({self._attname(k)},{self._attname(l)}) -> {getattr(v, "__name__", type(v).__name__)}'
for k in self.funcs.d for l,v in self.funcs[k].d.items()]
r = r + [o.__repr__() for o in self.bases]
return '\n'.join(r)
Expand Down
2 changes: 1 addition & 1 deletion fastcore/imports.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import sys,os,re,shutil,typing,itertools,operator,functools,math,warnings,functools,io
import sys,os,re,typing,itertools,operator,functools,math,warnings,functools,io

from operator import itemgetter,attrgetter
from warnings import warn
Expand Down
2 changes: 1 addition & 1 deletion fastcore/nb_imports.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import numpy as np
import matplotlib.pyplot as plt
import numbers,tempfile,pickle,random,inspect
import numbers,tempfile,pickle,random,inspect,shutil

from PIL import Image
from numpy import array,ndarray
Expand Down
Loading

0 comments on commit 497d205

Please sign in to comment.