AnswerDotAI / AnswerDotAI/fastcore

explode_types() feeds retain_type() with surprising arguments.

Open
#539 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Jupyter Notebook
Stars
1.1k
Forks
295
Avg merge
1d 6h
Merged PRs (30d)
7

Description

```
data_block = DataBlock(
blocks=(ImageBlock, CategoryBlock),
get_x=existing(ColReader('thumbnail_path')),
get_y=ColReader('label'),
splitter=RandomSplitter(),
item_tfms=Resize(224),
batch_tfms=aug_transforms()
)
train = data_block.dataloaders(train_df, bs=4)

train.show_batch(4)
```

Gets

```
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[20], line 11
1 data_block = DataBlock(
2 blocks=(ImageBlock, CategoryBlock),
3 get_x=existing(ColReader('thumbnail_path')),
(...)
7 batch_tfms=aug_transforms()
8 )
9 train = data_block.dataloaders(train_df, bs=4)
---> 11 train.show_batch(4)

File /opt/conda/lib/python3.10/site-packages/fastai/data/core.py:151, in TfmdDL.show_batch(self, b, max_n, ctxs, show, unique, **kwargs)
149 if b is None: b = self.one_batch()
150 if not show: return self._pre_show_batch(b, max_n=max_n)
--> 151 show_batch(*self._pre_show_batch(b, max_n=max_n), ctxs=ctxs, max_n=max_n, **kwargs)
152 if unique: self.get_idxs = old_get_idxs

File /opt/conda/lib/python3.10/site-packages/fastai/data/core.py:131, in TfmdDL._pre_show_batch(self, b, max_n)
129 def _pre_show_batch(self, b, max_n=9):
130 "Decode `b` to be ready for `show_batch`"
--> 131 b = self.decode(b)
132 if hasattr(b, 'show'): return b,None,None
133 its = self._decode_batch(b, max_n, full=False)

File /opt/conda/lib/python3.10/site-packages/fastai/data/core.py:115, in TfmdDL.decode(self, b)
112 def decode(self,
113 b # Batch to decode
114 ):
--> 115 return to_cpu(self.after_batch.decode(self._retain_dl(b)))

File /opt/conda/lib/python3.10/site-packages/fastai/data/core.py:86, in TfmdDL._retain_dl(self, b)
84 def _retain_dl(self,b):
85 if not getattr(self, '_types', None): self._one_pass()
---> 86 return retain_types(b, typs=self._types)

File /opt/conda/lib/python3.10/site-packages/fastcore/dispatch.py:199, in retain_types(new, old, typs)
197 def retain_types(new, old=None, typs=None):
198 "Cast each item of `new` to type of matching item in `old` if it's a superclass"
--> 199 if not is_listy(new): return retain_type(new, old, typs)
200 if typs is not None:
201 if isinstance(typs, dict):

File /opt/conda/lib/python3.10/site-packages/fastcore/dispatch.py:193, in retain_type(new, old, typ, as_copy)
191 typ = old if isinstance(old,type) else type(old)
192 # Do nothing the new type is already an instance of requested type (i.e. same type)
--> 193 if typ==NoneType or isinstance(new, typ): return new
194 return retain_meta(old, cast(new, typ), as_copy=as_copy)

TypeError: isinstance() arg 2 must be a type, a tuple of types, or a union
```

The problem seems to be that [explode_types()](https://github.com/fastai/fastcore/blob/1cb38a0d8d97091cd3365e669e39db64be40aaa2/fastcore/dispatch.py#L212) sometimes returns a dictionary which surprises [retain_type()](https://github.com/fastai/fastcore/blob/1cb38a0d8d97091cd3365e669e39db64be40aaa2/fastcore/dispatch.py#L193) with a non-listy type.

```
ipdb> p typ
{: [, ]}
```

I am new to fastai and struggling to understand how to fix this without breaking anything else. Any advice?

Contributor guide

Open the contributing guide

Research direction

Start in fastcore/dispatch.py by tracing explode_types() into retain_type() and inspect how the dictionary shown in the report reaches the isinstance call. Reproduce the supplied DataBlock example and verify that train.show_batch(4) completes without the TypeError while preserving the existing type-retention behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.