Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions fastcore/docments.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,8 @@ def _get_comment(line, arg, comments, parms):

def _get_full(p, docs, eval_str=False):
anno = p.annotation
if anno==empty:
if p.default!=empty: anno = type(p.default)
if anno is empty:
if p.default is not empty: anno = type(p.default)
elif eval_str: anno = None
return AttrDict(docment=docs.get(p.name), anno=anno, default=p.default, kind=p.kind)

Expand Down Expand Up @@ -255,7 +255,7 @@ def extract_docstrings(code):
def _bold(s): return f'**{s}**' if s.strip() else s

def _maybe_nm(o):
if (o == inspect._empty): return ''
if (o is inspect._empty): return ''
else: return o.__name__ if hasattr(o, '__name__') else str(o)

# %% ../nbs/04_docments.ipynb #ac070254
Expand Down Expand Up @@ -291,13 +291,13 @@ def __init__(self, obj, verbose=True, returns=True):
def _columns(self):
"Fields with at least one non-empty value"
candidates = self._map if self.verbose else {'docment': 'Details'}
return {k:v for k,v in candidates.items() if any(d[k] != empty for d in self.dm.values())}
return {k:v for k,v in candidates.items() if any(d[k] is not empty for d in self.dm.values())}

@property
def has_docment(self): return 'docment' in self._columns and bool(self.params)

@property
def has_return(self): return self.returns and any(v != empty for v in self.dm.get('return', {}).values())
def has_return(self): return self.returns and any(v is not empty for v in self.dm.get('return', {}).values())

@property
def hdr_str(self):
Expand Down Expand Up @@ -330,7 +330,7 @@ def __eq__(self,other): return self.__str__() == str(other).strip()
class DocmentList(_DocmentBase):
def _fmt(self, nm, p):
anno,default,doc = _maybe_nm(p.get('anno','')), p.get('default',empty), p.get('docment','')
s = f'`{nm}{":" + anno if anno else ""}{"=" + _maybe_nm(default) if default != empty else ""}`'
s = f'`{nm}{":" + anno if anno else ""}{"=" + _maybe_nm(default) if default is not empty else ""}`'
br = '\xa0'*3
return f'- {s}' + (f'{br}*{doc}*' if doc else '')

Expand Down Expand Up @@ -374,8 +374,8 @@ def __init__(self, obj, maxline=110, docstring=True):
def _fmt_param(self, nm, p):
anno,default,kind = p.get('anno',empty), p.get('default',empty), p.get('kind')
pre = '*' if kind==Parameter.VAR_POSITIONAL else '**' if kind==Parameter.VAR_KEYWORD else ''
anno = f':{_type_str(anno)}' if anno != empty else ''
default = f'={_fmt_default(default)}' if default != empty else ''
anno = f':{_type_str(anno)}' if anno is not empty else ''
default = f'={_fmt_default(default)}' if default is not empty else ''
return pre + nm + anno + default

def _repr_markdown_(self): return f"```python\n{self}\n```"
Expand Down Expand Up @@ -406,7 +406,7 @@ def _clean_text_sig(obj):
@patch(as_prop=True)
def _ret_str(self:DocmentText):
ret = self.dm.get('return', {})
anno = f"->{_type_str(ret['anno'])}" if ret.get('anno',empty) != empty else ''
anno = f"->{_type_str(ret['anno'])}" if ret.get('anno',empty) is not empty else ''
doc = f" # {ret['docment']}" if ret.get('docment') else ''
return f"){anno}:{doc}"

Expand Down
41 changes: 32 additions & 9 deletions nbs/04_docments.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -600,8 +600,8 @@
"\n",
"def _get_full(p, docs, eval_str=False):\n",
" anno = p.annotation\n",
" if anno==empty:\n",
" if p.default!=empty: anno = type(p.default)\n",
" if anno is empty:\n",
" if p.default is not empty: anno = type(p.default)\n",
" elif eval_str: anno = None\n",
" return AttrDict(docment=docs.get(p.name), anno=anno, default=p.default, kind=p.kind)"
]
Expand Down Expand Up @@ -1874,7 +1874,7 @@
"def _bold(s): return f'**{s}**' if s.strip() else s\n",
"\n",
"def _maybe_nm(o):\n",
" if (o == inspect._empty): return ''\n",
" if (o is inspect._empty): return ''\n",
" else: return o.__name__ if hasattr(o, '__name__') else str(o)"
]
},
Expand Down Expand Up @@ -1966,13 +1966,13 @@
" def _columns(self):\n",
" \"Fields with at least one non-empty value\"\n",
" candidates = self._map if self.verbose else {'docment': 'Details'}\n",
" return {k:v for k,v in candidates.items() if any(d[k] != empty for d in self.dm.values())}\n",
" return {k:v for k,v in candidates.items() if any(d[k] is not empty for d in self.dm.values())}\n",
"\n",
" @property\n",
" def has_docment(self): return 'docment' in self._columns and bool(self.params)\n",
"\n",
" @property\n",
" def has_return(self): return self.returns and any(v != empty for v in self.dm.get('return', {}).values())\n",
" def has_return(self): return self.returns and any(v is not empty for v in self.dm.get('return', {}).values())\n",
"\n",
" @property\n",
" def hdr_str(self):\n",
Expand Down Expand Up @@ -2001,6 +2001,29 @@
" __repr__ = basic_repr()\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9b1e7c3a",
"metadata": {},
"outputs": [],
"source": [
"class _NoBoolEq:\n",
" \"A default like a numpy array, whose `==`/`!=` can't be used as a bool\"\n",
" def __eq__(self, o): raise ValueError(\"ambiguous truth value\")\n",
" __ne__ = __eq__\n",
" __hash__ = object.__hash__\n",
" def __repr__(self): return 'NoBoolEq()'\n",
"\n",
"def _f(a:int, # first\n",
" b=_NoBoolEq()): # second\n",
" \"A function whose default can't be compared with `==`\"\n",
" ...\n",
"\n",
"test_eq(docments(_f, full=True)['b']['anno'], _NoBoolEq)\n",
"assert 'NoBoolEq()' in str(DocmentTbl(_f))"
]
},
{
"cell_type": "markdown",
"id": "80fb1215",
Expand Down Expand Up @@ -2254,7 +2277,7 @@
"class DocmentList(_DocmentBase):\n",
" def _fmt(self, nm, p):\n",
" anno,default,doc = _maybe_nm(p.get('anno','')), p.get('default',empty), p.get('docment','')\n",
" s = f'`{nm}{\":\" + anno if anno else \"\"}{\"=\" + _maybe_nm(default) if default != empty else \"\"}`'\n",
" s = f'`{nm}{\":\" + anno if anno else \"\"}{\"=\" + _maybe_nm(default) if default is not empty else \"\"}`'\n",
" br = '\\xa0'*3\n",
" return f'- {s}' + (f'{br}*{doc}*' if doc else '')\n",
"\n",
Expand Down Expand Up @@ -2405,8 +2428,8 @@
" def _fmt_param(self, nm, p):\n",
" anno,default,kind = p.get('anno',empty), p.get('default',empty), p.get('kind')\n",
" pre = '*' if kind==Parameter.VAR_POSITIONAL else '**' if kind==Parameter.VAR_KEYWORD else ''\n",
" anno = f':{_type_str(anno)}' if anno != empty else ''\n",
" default = f'={_fmt_default(default)}' if default != empty else ''\n",
" anno = f':{_type_str(anno)}' if anno is not empty else ''\n",
" default = f'={_fmt_default(default)}' if default is not empty else ''\n",
" return pre + nm + anno + default\n",
"\n",
" def _repr_markdown_(self): return f\"```python\\n{self}\\n```\""
Expand Down Expand Up @@ -2484,7 +2507,7 @@
"@patch(as_prop=True)\n",
"def _ret_str(self:DocmentText):\n",
" ret = self.dm.get('return', {})\n",
" anno = f\"->{_type_str(ret['anno'])}\" if ret.get('anno',empty) != empty else ''\n",
" anno = f\"->{_type_str(ret['anno'])}\" if ret.get('anno',empty) is not empty else ''\n",
" doc = f\" # {ret['docment']}\" if ret.get('docment') else ''\n",
" return f\"){anno}:{doc}\""
]
Expand Down