fastai / nbdev

Create delightful software with Jupyter Notebooks
https://nbdev.fast.ai/
Apache License 2.0
4.9k stars 487 forks source link

`show_docs` requires `@delegates` types to be imported #1116

Open filipj8 opened 2 years ago

filipj8 commented 2 years ago
from fastcore.meta import delegates
from nbdev import show_doc

@delegates(pd.DataFrame.to_sql)
def _b(df, **kwargs): return df.to_sql(**kwargs)

show_doc(_b)
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In [15], line 7
      4 @delegates(pd.DataFrame.to_sql)
      5 def _b(df, **kwargs): return df.to_sql(**kwargs)
----> 7 show_doc(_b)

File /opt/conda/lib/python3.9/site-packages/nbdev/showdoc.py:191, in show_doc(sym, renderer, name, title_level)
    189     renderer = getattr(import_module(p), m)
    190 if isinstance(sym, TypeDispatch): pass
--> 191 else:return renderer(sym or show_doc, name=name, title_level=title_level)

File /opt/conda/lib/python3.9/site-packages/nbdev/showdoc.py:127, in ShowDocRenderer.__init__(self, sym, name, title_level)
    125 self.nm = name or qual_name(sym)
    126 self.isfunc = inspect.isfunction(sym)
--> 127 try: self.sig = signature_ex(sym, eval_str=True)
    128 except (ValueError,TypeError): self.sig = None
    129 self.docs = _docstring(sym)

File /opt/conda/lib/python3.9/site-packages/fastcore/basics.py:350, in signature_ex(obj, eval_str)
    348 sig = signature(obj)
    349 if sig is None: return None
--> 350 ann = type_hints(obj)
    351 params = [_eval_param(ann,k,v) for k,v in sig.parameters.items()]
    352 return Signature(params, return_annotation=sig.return_annotation)

File /opt/conda/lib/python3.9/site-packages/fastcore/basics.py:318, in type_hints(f)
    316 if not isinstance(f, typing._allowed_types): return {}
    317 ann,glb,loc = get_annotations_ex(f)
--> 318 return {k:_eval_type(v,glb,loc) for k,v in ann.items()}

File /opt/conda/lib/python3.9/site-packages/fastcore/basics.py:318, in <dictcomp>(.0)
    316 if not isinstance(f, typing._allowed_types): return {}
    317 ann,glb,loc = get_annotations_ex(f)
--> 318 return {k:_eval_type(v,glb,loc) for k,v in ann.items()}

File /opt/conda/lib/python3.9/site-packages/fastcore/basics.py:311, in _eval_type(t, glb, loc)
    310 def _eval_type(t, glb, loc):
--> 311     res = eval_type(t, glb, loc)
    312     return NoneType if res is None else res

File /opt/conda/lib/python3.9/site-packages/fastcore/basics.py:305, in eval_type(t, glb, loc)
    303 if isinstance(t,str):
    304     if '|' in t: return Union[eval_type(tuple(t.split('|')), glb, loc)]
--> 305     return eval(t, glb, loc)
    306 if isinstance(t,(tuple,list)): return type(t)([eval_type(c, glb, loc) for c in t])
    307 return t

File <string>:1

NameError: name 'bool_t' is not defined

Here are the types for the delegate fn:

pd.DataFrame.to_sql(
    self,
    name: 'str',
    con,
    schema=None,
    if_exists: 'str' = 'fail',
    index: 'bool_t' = True,
    index_label=None,
    chunksize=None,
    dtype: 'DtypeArg | None' = None,
    method=None,
) -> 'int | None'

Show doc works after adding the missing types.

from pandas._typing import DtypeArg

bool_t = bool

show_doc(_b)
seeM commented 1 year ago

Thanks for raising this. I can see how this is unintuitive behaviour. Perhaps we don't need to evaluate any annotations for the signature in show_doc..