Skip to content

Commit bbcc9a1

Browse files
committed
cell_number
1 parent 53d93e8 commit bbcc9a1

File tree

17 files changed

+407
-406
lines changed

17 files changed

+407
-406
lines changed

fastcore/basics.py

Lines changed: 134 additions & 134 deletions
Large diffs are not rendered by default.

fastcore/dispatch.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@
1212
__all__ = ['typedispatch', 'lenient_issubclass', 'sorted_topologically', 'TypeDispatch', 'DispatchReg', 'retain_meta',
1313
'default_set_meta', 'cast', 'retain_type', 'retain_types', 'explode_types']
1414

15-
# %% ../nbs/04_dispatch.ipynb 5
15+
# %% ../nbs/04_dispatch.ipynb
1616
def lenient_issubclass(cls, types):
1717
"If possible return whether `cls` is a subclass of `types`, otherwise return False."
1818
if cls is object and types is not object: return False # treat `object` as highest level
1919
try: return isinstance(cls, types) or issubclass(cls, types)
2020
except: return False
2121

22-
# %% ../nbs/04_dispatch.ipynb 7
22+
# %% ../nbs/04_dispatch.ipynb
2323
def sorted_topologically(iterable, *, cmp=operator.lt, reverse=False):
2424
"Return a new list containing all items from the iterable sorted topologically"
2525
l,res = L(list(iterable)),[]
@@ -28,7 +28,7 @@ def sorted_topologically(iterable, *, cmp=operator.lt, reverse=False):
2828
res.append(t), l.remove(t)
2929
return res[::-1] if reverse else res
3030

31-
# %% ../nbs/04_dispatch.ipynb 11
31+
# %% ../nbs/04_dispatch.ipynb
3232
def _chk_defaults(f, ann):
3333
pass
3434
# Implementation removed until we can figure out how to do this without `inspect` module
@@ -38,7 +38,7 @@ def _chk_defaults(f, ann):
3838
# warn(f"{f.__name__} has default params. These will be ignored.")
3939
# except ValueError: pass
4040

41-
# %% ../nbs/04_dispatch.ipynb 12
41+
# %% ../nbs/04_dispatch.ipynb
4242
def _p2_anno(f):
4343
"Get the 1st 2 annotations of `f`, defaulting to `object`"
4444
hints = type_hints(f)
@@ -47,7 +47,7 @@ def _p2_anno(f):
4747
while len(ann)<2: ann.append(object)
4848
return ann[:2]
4949

50-
# %% ../nbs/04_dispatch.ipynb 17
50+
# %% ../nbs/04_dispatch.ipynb
5151
class _TypeDict:
5252
def __init__(self): self.d,self.cache = {},{}
5353

@@ -76,7 +76,7 @@ def __getitem__(self, k):
7676
def __repr__(self): return self.d.__repr__()
7777
def first(self): return first(self.d.values())
7878

79-
# %% ../nbs/04_dispatch.ipynb 18
79+
# %% ../nbs/04_dispatch.ipynb
8080
class TypeDispatch:
8181
"Dictionary-like object; `__getitem__` matches keys of types using `issubclass`"
8282
def __init__(self, funcs=(), bases=()):
@@ -137,7 +137,7 @@ def __getitem__(self, k):
137137
if res is not None: return res
138138
return None
139139

140-
# %% ../nbs/04_dispatch.ipynb 77
140+
# %% ../nbs/04_dispatch.ipynb
141141
class DispatchReg:
142142
"A global registry for `TypeDispatch` objects keyed by function name"
143143
def __init__(self): self.d = defaultdict(TypeDispatch)
@@ -150,16 +150,16 @@ def __call__(self, f):
150150

151151
typedispatch = DispatchReg()
152152

153-
# %% ../nbs/04_dispatch.ipynb 84
153+
# %% ../nbs/04_dispatch.ipynb
154154
_all_=['cast']
155155

156-
# %% ../nbs/04_dispatch.ipynb 85
156+
# %% ../nbs/04_dispatch.ipynb
157157
def retain_meta(x, res, as_copy=False):
158158
"Call `res.set_meta(x)`, if it exists"
159159
if hasattr(res,'set_meta'): res.set_meta(x, as_copy=as_copy)
160160
return res
161161

162-
# %% ../nbs/04_dispatch.ipynb 86
162+
# %% ../nbs/04_dispatch.ipynb
163163
def default_set_meta(self, x, as_copy=False):
164164
"Copy over `_meta` from `x` to `res`, if it's missing"
165165
if hasattr(x, '_meta') and not hasattr(self, '_meta'):
@@ -168,7 +168,7 @@ def default_set_meta(self, x, as_copy=False):
168168
self._meta = meta
169169
return self
170170

171-
# %% ../nbs/04_dispatch.ipynb 87
171+
# %% ../nbs/04_dispatch.ipynb
172172
@typedispatch
173173
def cast(x, typ):
174174
"cast `x` to type `typ` (may also change `x` inplace)"
@@ -180,7 +180,7 @@ def cast(x, typ):
180180
except: res = typ(res)
181181
return retain_meta(x, res)
182182

183-
# %% ../nbs/04_dispatch.ipynb 93
183+
# %% ../nbs/04_dispatch.ipynb
184184
def retain_type(new, old=None, typ=None, as_copy=False):
185185
"Cast `new` to type of `old` or `typ` if it's a superclass"
186186
# e.g. old is TensorImage, new is Tensor - if not subclass then do nothing
@@ -193,7 +193,7 @@ def retain_type(new, old=None, typ=None, as_copy=False):
193193
if typ==NoneType or isinstance(new, typ): return new
194194
return retain_meta(old, cast(new, typ), as_copy=as_copy)
195195

196-
# %% ../nbs/04_dispatch.ipynb 97
196+
# %% ../nbs/04_dispatch.ipynb
197197
def retain_types(new, old=None, typs=None):
198198
"Cast each item of `new` to type of matching item in `old` if it's a superclass"
199199
if not is_listy(new): return retain_type(new, old, typs)
@@ -205,7 +205,7 @@ def retain_types(new, old=None, typs=None):
205205
else: t = type(old) if old is not None and isinstance(old,type(new)) else type(new)
206206
return t(L(new, old, typs).map_zip(retain_types, cycled=True))
207207

208-
# %% ../nbs/04_dispatch.ipynb 99
208+
# %% ../nbs/04_dispatch.ipynb
209209
def explode_types(o):
210210
"Return the type of `o`, potentially in nested dictionaries for thing that are listy"
211211
if not is_listy(o): return type(o)

fastcore/docments.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,36 +20,36 @@
2020
__all__ = ['empty', 'docstring', 'parse_docstring', 'isdataclass', 'get_dataclass_source', 'get_source', 'get_name', 'qual_name',
2121
'docments']
2222

23-
# %% ../nbs/06_docments.ipynb 12
23+
# %% ../nbs/06_docments.ipynb
2424
def docstring(sym):
2525
"Get docstring for `sym` for functions ad classes"
2626
if isinstance(sym, str): return sym
2727
res = getdoc(sym)
2828
if not res and isclass(sym): res = getdoc(sym.__init__)
2929
return res or ""
3030

31-
# %% ../nbs/06_docments.ipynb 14
31+
# %% ../nbs/06_docments.ipynb
3232
def parse_docstring(sym):
3333
"Parse a numpy-style docstring in `sym`"
3434
docs = docstring(sym)
3535
return AttrDict(**docscrape.NumpyDocString(docstring(sym)))
3636

37-
# %% ../nbs/06_docments.ipynb 16
37+
# %% ../nbs/06_docments.ipynb
3838
def isdataclass(s):
3939
"Check if `s` is a dataclass but not a dataclass' instance"
4040
return is_dataclass(s) and isclass(s)
4141

42-
# %% ../nbs/06_docments.ipynb 17
42+
# %% ../nbs/06_docments.ipynb
4343
def get_dataclass_source(s):
4444
"Get source code for dataclass `s`"
4545
return getsource(s) if not getattr(s, "__module__") == '__main__' else ""
4646

47-
# %% ../nbs/06_docments.ipynb 18
47+
# %% ../nbs/06_docments.ipynb
4848
def get_source(s):
4949
"Get source code for string, function object or dataclass `s`"
5050
return getsource(s) if isfunction(s) or ismethod(s) else get_dataclass_source(s) if isdataclass(s) else s
5151

52-
# %% ../nbs/06_docments.ipynb 19
52+
# %% ../nbs/06_docments.ipynb
5353
def _parses(s):
5454
"Parse Python code in string, function object or dataclass `s`"
5555
return parse(dedent(get_source(s)))
@@ -78,10 +78,10 @@ def _param_locs(s, returns=True):
7878
return res
7979
return None
8080

81-
# %% ../nbs/06_docments.ipynb 20
81+
# %% ../nbs/06_docments.ipynb
8282
empty = Parameter.empty
8383

84-
# %% ../nbs/06_docments.ipynb 21
84+
# %% ../nbs/06_docments.ipynb
8585
def _get_comment(line, arg, comments, parms):
8686
if line in comments: return comments[line].strip()
8787
line -= 1
@@ -95,7 +95,7 @@ def _get_full(anno, name, default, docs):
9595
if anno==empty and default!=empty: anno = type(default)
9696
return AttrDict(docment=docs.get(name), anno=anno, default=default)
9797

98-
# %% ../nbs/06_docments.ipynb 22
98+
# %% ../nbs/06_docments.ipynb
9999
def _merge_doc(dm, npdoc):
100100
if not npdoc: return dm
101101
if not dm.anno or dm.anno==empty: dm.anno = npdoc.type
@@ -108,14 +108,14 @@ def _merge_docs(dms, npdocs):
108108
if 'return' in dms: params['return'] = _merge_doc(dms['return'], npdocs['Returns'])
109109
return params
110110

111-
# %% ../nbs/06_docments.ipynb 23
111+
# %% ../nbs/06_docments.ipynb
112112
def _get_property_name(p):
113113
"Get the name of property `p`"
114114
if hasattr(p, 'fget'):
115115
return p.fget.func.__qualname__ if hasattr(p.fget, 'func') else p.fget.__qualname__
116116
else: return next(iter(re.findall(r'\'(.*)\'', str(p)))).split('.')[-1]
117117

118-
# %% ../nbs/06_docments.ipynb 24
118+
# %% ../nbs/06_docments.ipynb
119119
def get_name(obj):
120120
"Get the name of `obj`"
121121
if hasattr(obj, '__name__'): return obj.__name__
@@ -124,14 +124,14 @@ def get_name(obj):
124124
elif type(obj)==property: return _get_property_name(obj)
125125
else: return str(obj).split('.')[-1]
126126

127-
# %% ../nbs/06_docments.ipynb 26
127+
# %% ../nbs/06_docments.ipynb
128128
def qual_name(obj):
129129
"Get the qualified name of `obj`"
130130
if hasattr(obj,'__qualname__'): return obj.__qualname__
131131
if ismethod(obj): return f"{get_name(obj.__self__)}.{get_name(fn)}"
132132
return get_name(obj)
133133

134-
# %% ../nbs/06_docments.ipynb 29
134+
# %% ../nbs/06_docments.ipynb
135135
def _docments(s, returns=True, eval_str=False):
136136
"`dict` of parameter names to 'docment-style' comments in function or string `s`"
137137
nps = parse_docstring(s)
@@ -151,7 +151,7 @@ def _docments(s, returns=True, eval_str=False):
151151
if k in hints: v['anno'] = hints.get(k)
152152
return res
153153

154-
# %% ../nbs/06_docments.ipynb 30
154+
# %% ../nbs/06_docments.ipynb
155155
@delegates(_docments)
156156
def docments(elt, full=False, **kwargs):
157157
"Generates a `docment`"

fastcore/foundation.py

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
__all__ = ['working_directory', 'add_docs', 'docs', 'coll_repr', 'is_bool', 'mask2idxs', 'cycle', 'zip_cycle', 'is_indexer',
55
'CollBase', 'L', 'save_config_file', 'read_config_file', 'Config']
66

7-
# %% ../nbs/02_foundation.ipynb 1
7+
# %% ../nbs/02_foundation.ipynb
88
from .imports import *
99
from .basics import *
1010
from functools import lru_cache
@@ -13,7 +13,7 @@
1313
from configparser import ConfigParser
1414
import random,pickle,inspect
1515

16-
# %% ../nbs/02_foundation.ipynb 5
16+
# %% ../nbs/02_foundation.ipynb
1717
@contextmanager
1818
def working_directory(path):
1919
"Change working directory to `path` and return to previous on exit."
@@ -22,7 +22,7 @@ def working_directory(path):
2222
try: yield
2323
finally: os.chdir(prev_cwd)
2424

25-
# %% ../nbs/02_foundation.ipynb 6
25+
# %% ../nbs/02_foundation.ipynb
2626
def add_docs(cls, cls_doc=None, **docs):
2727
"Copy values from `docs` to `cls` docstrings, and confirm all public methods are documented"
2828
if cls_doc is not None: cls.__doc__ = cls_doc
@@ -36,24 +36,24 @@ def add_docs(cls, cls_doc=None, **docs):
3636
assert not nodoc, f"Missing docs: {nodoc}"
3737
assert cls.__doc__ is not None, f"Missing class docs: {cls}"
3838

39-
# %% ../nbs/02_foundation.ipynb 16
39+
# %% ../nbs/02_foundation.ipynb
4040
def docs(cls):
4141
"Decorator version of `add_docs`, using `_docs` dict"
4242
add_docs(cls, **cls._docs)
4343
return cls
4444

45-
# %% ../nbs/02_foundation.ipynb 23
45+
# %% ../nbs/02_foundation.ipynb
4646
def coll_repr(c, max_n=10):
4747
"String repr of up to `max_n` items of (possibly lazy) collection `c`"
4848
return f'(#{len(c)}) [' + ','.join(itertools.islice(map(repr,c), max_n)) + (
4949
'...' if len(c)>max_n else '') + ']'
5050

51-
# %% ../nbs/02_foundation.ipynb 28
51+
# %% ../nbs/02_foundation.ipynb
5252
def is_bool(x):
5353
"Check whether `x` is a bool or None"
5454
return isinstance(x,(bool,NoneType)) or risinstance('bool_', x)
5555

56-
# %% ../nbs/02_foundation.ipynb 29
56+
# %% ../nbs/02_foundation.ipynb
5757
def mask2idxs(mask):
5858
"Convert bool mask or index list to index `L`"
5959
if isinstance(mask,slice): return mask
@@ -64,23 +64,23 @@ def mask2idxs(mask):
6464
if is_bool(it): return [i for i,m in enumerate(mask) if m]
6565
return [int(i) for i in mask]
6666

67-
# %% ../nbs/02_foundation.ipynb 31
67+
# %% ../nbs/02_foundation.ipynb
6868
def cycle(o):
6969
"Like `itertools.cycle` except creates list of `None`s if `o` is empty"
7070
o = listify(o)
7171
return itertools.cycle(o) if o is not None and len(o) > 0 else itertools.cycle([None])
7272

73-
# %% ../nbs/02_foundation.ipynb 33
73+
# %% ../nbs/02_foundation.ipynb
7474
def zip_cycle(x, *args):
7575
"Like `itertools.zip_longest` but `cycle`s through elements of all but first argument"
7676
return zip(x, *map(cycle,args))
7777

78-
# %% ../nbs/02_foundation.ipynb 35
78+
# %% ../nbs/02_foundation.ipynb
7979
def is_indexer(idx):
8080
"Test whether `idx` will index a single item in a list"
8181
return isinstance(idx,int) or not getattr(idx,'ndim',1)
8282

83-
# %% ../nbs/02_foundation.ipynb 41
83+
# %% ../nbs/02_foundation.ipynb
8484
class CollBase:
8585
"Base class for composing a list of `items`"
8686
def __init__(self, items): self.items = items
@@ -91,13 +91,13 @@ def __delitem__(self, i): del(self.items[i])
9191
def __repr__(self): return self.items.__repr__()
9292
def __iter__(self): return self.items.__iter__()
9393

94-
# %% ../nbs/02_foundation.ipynb 45
94+
# %% ../nbs/02_foundation.ipynb
9595
class _L_Meta(type):
9696
def __call__(cls, x=None, *args, **kwargs):
9797
if not args and not kwargs and x is not None and isinstance(x,cls): return x
9898
return super().__call__(x, *args, **kwargs)
9999

100-
# %% ../nbs/02_foundation.ipynb 46
100+
# %% ../nbs/02_foundation.ipynb
101101
class L(GetAttr, CollBase, metaclass=_L_Meta):
102102
"Behaves like a list of `items` but can also index with list of indices or masks"
103103
_default='items'
@@ -194,7 +194,7 @@ def sum(self): return self.reduce(operator.add, 0)
194194
def product(self): return self.reduce(operator.mul, 1)
195195
def setattrs(self, attr, val): [setattr(o,attr,val) for o in self]
196196

197-
# %% ../nbs/02_foundation.ipynb 47
197+
# %% ../nbs/02_foundation.ipynb
198198
add_docs(L,
199199
__getitem__="Retrieve `idx` (can be list of indices, or mask, or int) items",
200200
range="Class Method: Same as `range`, but returns `L`. Can pass collection for `a`, to use `len(a)`",
@@ -227,29 +227,29 @@ def setattrs(self, attr, val): [setattr(o,attr,val) for o in self]
227227
setattrs="Call `setattr` on all items"
228228
)
229229

230-
# %% ../nbs/02_foundation.ipynb 48
230+
# %% ../nbs/02_foundation.ipynb
231231
# Here we are fixing the signature of L. What happens is that the __call__ method on the MetaClass of L shadows the __init__
232232
# giving the wrong signature (https://stackoverflow.com/questions/49740290/call-from-metaclass-shadows-signature-of-init).
233233
def _f(items=None, *rest, use_list=False, match=None): ...
234234
L.__signature__ = inspect.signature(_f)
235235

236-
# %% ../nbs/02_foundation.ipynb 49
236+
# %% ../nbs/02_foundation.ipynb
237237
Sequence.register(L);
238238

239-
# %% ../nbs/02_foundation.ipynb 129
239+
# %% ../nbs/02_foundation.ipynb
240240
def save_config_file(file, d, **kwargs):
241241
"Write settings dict to a new config file, or overwrite the existing one."
242242
config = ConfigParser(**kwargs)
243243
config['DEFAULT'] = d
244244
config.write(open(file, 'w'))
245245

246-
# %% ../nbs/02_foundation.ipynb 130
246+
# %% ../nbs/02_foundation.ipynb
247247
def read_config_file(file, **kwargs):
248248
config = ConfigParser(**kwargs)
249249
config.read(file, encoding='utf8')
250250
return config['DEFAULT']
251251

252-
# %% ../nbs/02_foundation.ipynb 133
252+
# %% ../nbs/02_foundation.ipynb
253253
class Config:
254254
"Reading and writing `ConfigParser` ini files"
255255
def __init__(self, cfg_path, cfg_name, create=None, save=True, extra_files=None, types=None):

0 commit comments

Comments
 (0)