diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml
index eb57105af..467777382 100644
--- a/.github/workflows/test.yaml
+++ b/.github/workflows/test.yaml
@@ -11,7 +11,7 @@ jobs:
fail-fast: true
matrix:
os: [ubuntu, macos]
- version: ["3.7", "3.8", "3.9", "3.10"]
+ version: ["3.7", "3.8", "3.9", "3.10", "3.11"]
runs-on: ${{ matrix.os }}-latest
steps:
- uses: fastai/workflows/nbdev-ci@master
diff --git a/nbdev/showdoc.py b/nbdev/showdoc.py
index a57393d98..5c8eee64b 100644
--- a/nbdev/showdoc.py
+++ b/nbdev/showdoc.py
@@ -29,7 +29,7 @@ def _escape_markdown(s):
return s.replace('\n', '
')
# %% ../nbs/api/08_showdoc.ipynb 9
-def _maybe_nm(o):
+def _maybe_nm(o):
if (o == inspect._empty): return ''
else: return o.__name__ if hasattr(o, '__name__') else _escape_markdown(str(o))
@@ -40,7 +40,7 @@ def _list2row(l:list): return '| '+' | '.join([_maybe_nm(o) for o in l]) + ' |'
class DocmentTbl:
# this is the column order we want these items to appear
_map = OrderedDict({'anno':'Type', 'default':'Default', 'docment':'Details'})
-
+
def __init__(self, obj, verbose=True, returns=True):
"Compute the docment table string"
self.verbose = verbose
@@ -52,30 +52,30 @@ def __init__(self, obj, verbose=True, returns=True):
if 'self' in _dm: del _dm['self']
for d in _dm.values(): d['docment'] = ifnone(d['docment'], inspect._empty)
self.dm = _dm
-
+
@property
def _columns(self):
"Compute the set of fields that have at least one non-empty value so we don't show tables empty columns"
cols = set(flatten(L(self.dm.values()).filter().map(_non_empty_keys)))
candidates = self._map if self.verbose else {'docment': 'Details'}
return OrderedDict({k:v for k,v in candidates.items() if k in cols})
-
+
@property
- def has_docment(self): return 'docment' in self._columns and self._row_list
+ def has_docment(self): return 'docment' in self._columns and self._row_list
@property
def has_return(self): return self.returns and bool(_non_empty_keys(self.dm.get('return', {})))
-
- def _row(self, nm, props):
+
+ def _row(self, nm, props):
"unpack data for single row to correspond with column names."
return [nm] + [props[c] for c in self._columns]
-
+
@property
def _row_list(self):
"unpack data for all rows."
ordered_params = [(p, self.dm[p]) for p in self.params if p != 'self' and p in self.dm]
return L([self._row(nm, props) for nm,props in ordered_params])
-
+
@property
def _hdr_list(self): return [' '] + [_bold(l) for l in L(self._columns.values())]
@@ -84,23 +84,23 @@ def hdr_str(self):
"The markdown string for the header portion of the table"
md = _list2row(self._hdr_list)
return md + '\n' + _list2row(['-' * len(l) for l in self._hdr_list])
-
+
@property
- def params_str(self):
+ def params_str(self):
"The markdown string for the parameters portion of the table."
return '\n'.join(self._row_list.map(_list2row))
-
+
@property
def return_str(self):
"The markdown string for the returns portion of the table."
return _list2row(['**Returns**']+[_bold(_maybe_nm(self.dm['return'][c])) for c in self._columns])
-
+
def _repr_markdown_(self):
if not self.has_docment: return ''
_tbl = [self.hdr_str, self.params_str]
if self.has_return: _tbl.append(self.return_str)
return '\n'.join(_tbl)
-
+
def __eq__(self,other): return self.__str__() == str(other).strip()
__str__ = _repr_markdown_
diff --git a/nbs/api/08_showdoc.ipynb b/nbs/api/08_showdoc.ipynb
index 51d33289d..31069b61e 100644
--- a/nbs/api/08_showdoc.ipynb
+++ b/nbs/api/08_showdoc.ipynb
@@ -120,7 +120,7 @@
"outputs": [],
"source": [
"#|export\n",
- "def _maybe_nm(o): \n",
+ "def _maybe_nm(o):\n",
" if (o == inspect._empty): return ''\n",
" else: return o.__name__ if hasattr(o, '__name__') else _escape_markdown(str(o))"
]
@@ -171,7 +171,7 @@
"class DocmentTbl:\n",
" # this is the column order we want these items to appear\n",
" _map = OrderedDict({'anno':'Type', 'default':'Default', 'docment':'Details'})\n",
- " \n",
+ "\n",
" def __init__(self, obj, verbose=True, returns=True):\n",
" \"Compute the docment table string\"\n",
" self.verbose = verbose\n",
@@ -183,30 +183,30 @@
" if 'self' in _dm: del _dm['self']\n",
" for d in _dm.values(): d['docment'] = ifnone(d['docment'], inspect._empty)\n",
" self.dm = _dm\n",
- " \n",
+ "\n",
" @property\n",
" def _columns(self):\n",
" \"Compute the set of fields that have at least one non-empty value so we don't show tables empty columns\"\n",
" cols = set(flatten(L(self.dm.values()).filter().map(_non_empty_keys)))\n",
" candidates = self._map if self.verbose else {'docment': 'Details'}\n",
" return OrderedDict({k:v for k,v in candidates.items() if k in cols})\n",
- " \n",
+ "\n",
" @property\n",
- " def has_docment(self): return 'docment' in self._columns and self._row_list \n",
+ " def has_docment(self): return 'docment' in self._columns and self._row_list\n",
"\n",
" @property\n",
" def has_return(self): return self.returns and bool(_non_empty_keys(self.dm.get('return', {})))\n",
- " \n",
- " def _row(self, nm, props): \n",
+ "\n",
+ " def _row(self, nm, props):\n",
" \"unpack data for single row to correspond with column names.\"\n",
" return [nm] + [props[c] for c in self._columns]\n",
- " \n",
+ "\n",
" @property\n",
" def _row_list(self):\n",
" \"unpack data for all rows.\"\n",
" ordered_params = [(p, self.dm[p]) for p in self.params if p != 'self' and p in self.dm]\n",
" return L([self._row(nm, props) for nm,props in ordered_params])\n",
- " \n",
+ "\n",
" @property\n",
" def _hdr_list(self): return [' '] + [_bold(l) for l in L(self._columns.values())]\n",
"\n",
@@ -215,23 +215,23 @@
" \"The markdown string for the header portion of the table\"\n",
" md = _list2row(self._hdr_list)\n",
" return md + '\\n' + _list2row(['-' * len(l) for l in self._hdr_list])\n",
- " \n",
+ "\n",
" @property\n",
- " def params_str(self): \n",
+ " def params_str(self):\n",
" \"The markdown string for the parameters portion of the table.\"\n",
" return '\\n'.join(self._row_list.map(_list2row))\n",
- " \n",
+ "\n",
" @property\n",
" def return_str(self):\n",
" \"The markdown string for the returns portion of the table.\"\n",
" return _list2row(['**Returns**']+[_bold(_maybe_nm(self.dm['return'][c])) for c in self._columns])\n",
- " \n",
+ "\n",
" def _repr_markdown_(self):\n",
" if not self.has_docment: return ''\n",
" _tbl = [self.hdr_str, self.params_str]\n",
" if self.has_return: _tbl.append(self.return_str)\n",
" return '\\n'.join(_tbl)\n",
- " \n",
+ "\n",
" def __eq__(self,other): return self.__str__() == str(other).strip()\n",
"\n",
" __str__ = _repr_markdown_\n",
@@ -272,7 +272,7 @@
}
],
"source": [
- "def _f(a, # description of param a \n",
+ "def _f(a, # description of param a\n",
" b=True, # description of param b\n",
" c:str=None\n",
" ) -> int: ...\n",
@@ -334,7 +334,7 @@
}
],
"source": [
- "def _f(a, \n",
+ "def _f(a,\n",
" b, #param b\n",
" c #param c\n",
" ): ...\n",
@@ -378,13 +378,13 @@
"outputs": [],
"source": [
"class _Test:\n",
- " def __init__(self, \n",
- " a, # description of param a \n",
+ " def __init__(self,\n",
+ " a, # description of param a\n",
" b=True, # description of param b\n",
" c:str=None):\n",
" ...\n",
- " \n",
- " def foo(self, \n",
+ "\n",
+ " def foo(self,\n",
" c:int, # description of param c\n",
" d=True, # description of param d\n",
" ):\n",
@@ -598,7 +598,7 @@
"def _long_f(a_param, b_param=True, c_param:str='Some quite long value', d:int=2, e:bool=False):\n",
" \"A docstring\"\n",
" ...\n",
- " \n",
+ "\n",
"_res = \"> (a_param, b_param=True, c_param:str='Some quite long value', d:int=2,\\n> e:bool=False)\"\n",
"_sig = _fmt_sig(signature_ex(_long_f, eval_str=True))\n",
"test_eq(_wrap_sig(_sig), _res)"
@@ -727,14 +727,14 @@
"def f(x=1):\n",
" \"\"\"\n",
" func docstring in the numpy style.\n",
- " \n",
+ "\n",
" This is another line of the docstring.\n",
- " \n",
+ "\n",
" Parameters\n",
" ----------\n",
" x : int\n",
" the parameter x\n",
- " \n",
+ "\n",
" Returns\n",
" -------\n",
" None\n",
@@ -811,7 +811,7 @@
" \"This is the docstring for the `__init__` method\"\n",
" ...\n",
" @property\n",
- " def some_prop(self): \n",
+ " def some_prop(self):\n",
" \"This is a class property.\"\n",
" return 'foo property'\n",
"\n",
@@ -873,7 +873,7 @@
"source": [
"#|hide\n",
"@patch\n",
- "def a_method(self:Foo, \n",
+ "def a_method(self:Foo,\n",
" a:list, # param a\n",
" b:dict,c):\n",
" \"This is a method\"\n",
@@ -1009,7 +1009,7 @@
"text/html": [
"
show_doc(sym, renderer=None, name:Optional[str]=None, title_level:int=3)
Show signature and docstring for `sym`
\n", + "show_doc(sym, renderer=None, name:str|None=None, title_level:int=3)
Show signature and docstring for `sym`
\n", "" ], "text/plain": [ @@ -1054,12 +1054,12 @@ " def __init__(self, x:int=1): ...\n", "\n", " @classmethod\n", - " def class_method(cls, \n", + " def class_method(cls,\n", " foo:str, # docment for parameter foo\n", " bar:int):\n", " \"This is a class method.\"\n", " pass\n", - " \n", + "\n", " def regular_method(self,\n", " baz:bool=True): # docment for parameter baz\n", " \"This is a regular method\"\n", @@ -1285,18 +1285,6 @@ "## Test Edgecases -" ] }, - { - "cell_type": "code", - "execution_count": null, - "id": "66569922", - "metadata": {}, - "outputs": [], - "source": [ - "#|hide\n", - "e = enum.Enum('e', 'a b')\n", - "test_eq(str(show_doc(e)), '---\\n\\n### e\\n\\n> e (value, names=None, module=None, qualname=None, type=None, start=1)\\n\\nAn enumeration.')" - ] - }, { "cell_type": "code", "execution_count": null, @@ -1353,14 +1341,6 @@ "#|hide\n", "import nbdev; nbdev. nbdev_export()" ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b508e79a", - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { diff --git a/setup.py b/setup.py index d405e2a07..a5aa9996e 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,9 @@ -from pkg_resources import parse_version +import shlex from configparser import ConfigParser -import setuptools,shlex + +import setuptools +from pkg_resources import parse_version + assert parse_version(setuptools.__version__)>=parse_version('36.2') # note: all settings are in settings.ini; edit there, not here @@ -23,7 +26,7 @@ } statuses = [ '0 - Pre-Planning', '1 - Planning', '2 - Pre-Alpha', '3 - Alpha', '4 - Beta', '5 - Production/Stable', '6 - Mature', '7 - Inactive' ] -py_versions = '3.7 3.8 3.9 3.10'.split() +py_versions = '3.7 3.8 3.9 3.10 3.11'.split() requirements = shlex.split(cfg.get('requirements', '')) if cfg.get('pip_requirements'): requirements += shlex.split(cfg.get('pip_requirements', ''))