Skip to content

Commit e09d1a3

Browse files
author
Rens Dimmendaal
committed
add repr
1 parent 3f1b07e commit e09d1a3

File tree

4 files changed

+168
-184
lines changed

4 files changed

+168
-184
lines changed

Diff for: fasttransform/_modidx.py

+3
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,17 @@
2626
'fasttransform.core.Transform.__init_subclass__': ( 'core.html#transform.__init_subclass__',
2727
'fasttransform/core.py'),
2828
'fasttransform.core.Transform.__new__': ('core.html#transform.__new__', 'fasttransform/core.py'),
29+
'fasttransform.core.Transform.__repr__': ('core.html#transform.__repr__', 'fasttransform/core.py'),
2930
'fasttransform.core.Transform._call': ('core.html#transform._call', 'fasttransform/core.py'),
3031
'fasttransform.core.Transform._do_call': ('core.html#transform._do_call', 'fasttransform/core.py'),
3132
'fasttransform.core.Transform.decode': ('core.html#transform.decode', 'fasttransform/core.py'),
33+
'fasttransform.core.Transform.name': ('core.html#transform.name', 'fasttransform/core.py'),
3234
'fasttransform.core.Transform.setup': ('core.html#transform.setup', 'fasttransform/core.py'),
3335
'fasttransform.core._TfmDict': ('core.html#_tfmdict', 'fasttransform/core.py'),
3436
'fasttransform.core._TfmDict.__setitem__': ('core.html#_tfmdict.__setitem__', 'fasttransform/core.py'),
3537
'fasttransform.core._TfmMeta': ('core.html#_tfmmeta', 'fasttransform/core.py'),
3638
'fasttransform.core._TfmMeta.__prepare__': ('core.html#_tfmmeta.__prepare__', 'fasttransform/core.py'),
39+
'fasttransform.core._get_name': ('core.html#_get_name', 'fasttransform/core.py'),
3740
'fasttransform.core._has_self_arg': ('core.html#_has_self_arg', 'fasttransform/core.py'),
3841
'fasttransform.core._is_tfm_method': ('core.html#_is_tfm_method', 'fasttransform/core.py'),
3942
'fasttransform.core._is_tuple': ('core.html#_is_tuple', 'fasttransform/core.py'),

Diff for: fasttransform/core.py

+27-30
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,15 @@
1818
from fastcore.dispatch import retain_type
1919

2020
# %% ../nbs/00_core.ipynb 6
21-
def _is_tuple(o): return isinstance(o, tuple) and not hasattr(o, '_fields')
21+
def _get_name(o):
22+
if hasattr(o,'__qualname__'): return o.__qualname__
23+
if hasattr(o,'__name__'): return o.__name__
24+
return o.__class__.__name__
2225

2326
# %% ../nbs/00_core.ipynb 7
27+
def _is_tuple(o): return isinstance(o, tuple) and not hasattr(o, '_fields')
28+
29+
# %% ../nbs/00_core.ipynb 8
2430
def retain_type(new, old, ret_type,as_copy=False):
2531
if new is None: return new
2632
if ret_type is NoneType: return new
@@ -34,7 +40,7 @@ def retain_type(new, old, ret_type,as_copy=False):
3440
return retain_meta(old, cast(new, ret_type), as_copy=as_copy)
3541

3642

37-
# %% ../nbs/00_core.ipynb 14
43+
# %% ../nbs/00_core.ipynb 15
3844
_tfm_methods = 'encodes','decodes','setups'
3945

4046
def _is_tfm_method(n, f): return n in _tfm_methods and callable(f)
@@ -46,91 +52,78 @@ def __setitem__(self, k, v):
4652
self[k].dispatch(v)
4753

4854

49-
# %% ../nbs/00_core.ipynb 15
55+
# %% ../nbs/00_core.ipynb 16
5056
class _TfmMeta(type):
5157
@classmethod
5258
def __prepare__(cls, name, bases):
5359
return _TfmDict()
5460

55-
# %% ../nbs/00_core.ipynb 18
61+
# %% ../nbs/00_core.ipynb 20
5662
def _has_self_arg(f) -> bool:
5763
"Check if function `f` has 'self' as first parameter"
5864
try: return f.__code__.co_varnames[0] == 'self'
5965
# Attribute error if not callable
6066
# IndexError if no (kw)args
6167
except (AttributeError, IndexError): return False
6268

63-
# %% ../nbs/00_core.ipynb 19
69+
# %% ../nbs/00_core.ipynb 21
6470
def _subclass_decorator(cls, f):
6571
nm = f.__name__
66-
# needed for plum to register dispatch correctly
67-
# f.__qualname__ = f"{cls.__name__}.{nm}"
6872
if not hasattr(cls, nm): setattr(cls, nm, Function(f).dispatch(f))
6973
else: getattr(cls,nm).dispatch(f)
7074
return cls
7175

72-
# %% ../nbs/00_core.ipynb 20
76+
# %% ../nbs/00_core.ipynb 22
7377
class Transform(metaclass=_TfmMeta):
7478
"Delegates (`__call__`,`decode`,`setup`) to (<code>encodes</code>,<code>decodes</code>,<code>setups</code>) if `split_idx` matches"
7579
split_idx,init_enc,order,train_setup = None,None,0,None
76-
80+
7781
def __init_subclass__(cls):
7882
orig_init = cls.__init__ if hasattr(cls,'__init__') else lambda o: None
79-
8083
def __init__(self,*args,**kwargs):
8184
orig_init(self, *args, **kwargs)
8285
for nm in _tfm_methods:
8386
if hasattr(self.__class__, nm):
8487
setattr(self, nm, MethodType(getattr(self.__class__, nm), self))
85-
8688
cls.__init__ = __init__
8789

8890
def __new__(cls, enc=None, dec=None):
89-
# subclass of Transform decorator usage
91+
"Catch use of subclasses of Transform as decorator."
9092
if (
9193
issubclass(cls,Transform) and
9294
_has_self_arg(enc) and
9395
enc.__name__ in _tfm_methods and
9496
dec is None
9597
): return _subclass_decorator(cls, enc)
96-
# default usecase
9798
return super().__new__(cls)
9899

99100
def __init__(self,enc=None,dec=None, split_idx=None, order=None):
100101
self.split_idx = ifnone(split_idx, self.split_idx)
101-
if order is not None: self.order=order
102-
102+
if order is not None: self.order=order
103103
enc = L(enc)
104104
if enc: self.encodes = Function(enc[0])
105105
for e in enc: self.encodes.dispatch(e)
106-
107106
dec = L(dec)
108107
if dec: self.decodes = Function(dec[0])
109108
for d in dec: self.decodes.dispatch(d)
110109

111-
def __call__(self,*args,split_idx=None, **kwargs):
112-
return self._call('encodes', split_idx, *args,**kwargs)
113-
114-
def decode(self, *args,split_idx=None, **kwargs):
115-
return self._call('decodes', split_idx, *args, **kwargs)
116-
110+
def __call__(self,*args,split_idx=None, **kwargs): return self._call('encodes', split_idx, *args,**kwargs)
111+
def decode(self, *args,split_idx=None, **kwargs): return self._call('decodes', split_idx, *args, **kwargs)
117112
def setup(self, items=None, train_setup=False):
118113
train_setup = train_setup if self.train_setup is None else self.train_setup
119-
# fastcore could initalize a TypeDispatch without implementation, always returning input
120114
setups = self.setups if hasattr(self,'setups') else lambda o:o
121115
return setups(getattr(items, 'train', items) if train_setup else items)
122116

123117
def _call(self, nm, split_idx=None, *args, **kwargs):
124118
if split_idx!=self.split_idx and self.split_idx is not None: return args[0]
125119
return self._do_call(nm, *args, **kwargs)
126-
120+
127121
def _do_call(self, nm, *args, **kwargs):
128122
x = args[0]
129123
if not hasattr(self, nm): return x
130124
if _is_tuple(x):
131125
res = tuple(self._do_call(nm, x_, *args[1:], **kwargs) for x_ in x)
132126
return retain_type(res, x, Any)
133-
134127
f_args = args if type(self) is Transform else (self,)+args
135128
try:
136129
method, ret_type = getattr(self,nm)._resolve_method_with_cache(f_args)
@@ -139,9 +132,13 @@ def _do_call(self, nm, *args, **kwargs):
139132
res = method(*f_args,**kwargs)
140133
return retain_type(res, x, ret_type)
141134

135+
@property
136+
def name(self): return getattr(self, '_name', _get_name(self))
137+
def __repr__(self): return f'{self.name}:\nencodes: {self.encodes}decodes: {self.decodes}'
138+
142139
add_docs(Transform, decode="Delegate to decodes to undo transform", setup="Delegate to setups to set up transform")
143140

144-
# %% ../nbs/00_core.ipynb 116
141+
# %% ../nbs/00_core.ipynb 117
145142
def compose_tfms(x, tfms, is_enc=True, reverse=False, **kwargs):
146143
"Apply all `func_nm` attribute of `tfms` on `x`, maybe in `reverse` order"
147144
if reverse: tfms = reversed(tfms)
@@ -151,13 +148,13 @@ def compose_tfms(x, tfms, is_enc=True, reverse=False, **kwargs):
151148
return x
152149

153150

154-
# %% ../nbs/00_core.ipynb 121
151+
# %% ../nbs/00_core.ipynb 122
155152
def mk_transform(f):
156153
"Convert function `f` to `Transform` if it isn't already one"
157154
f = instantiate(f)
158155
return f if isinstance(f,(Transform,Pipeline)) else Transform(f)
159156

160-
# %% ../nbs/00_core.ipynb 122
157+
# %% ../nbs/00_core.ipynb 123
161158
def gather_attrs(o, k, nm):
162159
"Used in __getattr__ to collect all attrs `k` from `self.{nm}`"
163160
if k.startswith('_') or k==nm: raise AttributeError(k)
@@ -166,12 +163,12 @@ def gather_attrs(o, k, nm):
166163
if not res: raise AttributeError(k)
167164
return res[0] if len(res)==1 else L(res)
168165

169-
# %% ../nbs/00_core.ipynb 123
166+
# %% ../nbs/00_core.ipynb 124
170167
def gather_attr_names(o, nm):
171168
"Used in __dir__ to collect all attrs `k` from `self.{nm}`"
172169
return L(getattr(o,nm)).map(dir).concat().unique()
173170

174-
# %% ../nbs/00_core.ipynb 124
171+
# %% ../nbs/00_core.ipynb 125
175172
class Pipeline:
176173
"A pipeline of composed (for encode/decode) transforms, setup with types"
177174
def __init__(self, funcs=None, split_idx=None):

0 commit comments

Comments
 (0)