|
122 | 122 | "text/markdown": [
|
123 | 123 | "---\n",
|
124 | 124 | "\n",
|
| 125 | + "[source](https://github.com/AnswerDotAI/fastcore/blob/master/fastcore/meta.py#L28){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n", |
| 126 | + "\n", |
125 | 127 | "### FixSigMeta\n",
|
126 | 128 | "\n",
|
127 | 129 | "> FixSigMeta (name, bases, dict)\n",
|
128 | 130 | "\n",
|
129 |
| - "A metaclass that fixes the signature on classes that override `__new__`" |
| 131 | + "*A metaclass that fixes the signature on classes that override `__new__`*" |
130 | 132 | ],
|
131 | 133 | "text/plain": [
|
132 | 134 | "---\n",
|
133 | 135 | "\n",
|
| 136 | + "[source](https://github.com/AnswerDotAI/fastcore/blob/master/fastcore/meta.py#L28){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n", |
| 137 | + "\n", |
134 | 138 | "### FixSigMeta\n",
|
135 | 139 | "\n",
|
136 | 140 | "> FixSigMeta (name, bases, dict)\n",
|
137 | 141 | "\n",
|
138 |
| - "A metaclass that fixes the signature on classes that override `__new__`" |
| 142 | + "*A metaclass that fixes the signature on classes that override `__new__`*" |
139 | 143 | ]
|
140 | 144 | },
|
141 | 145 | "execution_count": null,
|
|
343 | 347 | "text/markdown": [
|
344 | 348 | "---\n",
|
345 | 349 | "\n",
|
| 350 | + "[source](https://github.com/AnswerDotAI/fastcore/blob/master/fastcore/meta.py#L36){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n", |
| 351 | + "\n", |
346 | 352 | "### PrePostInitMeta\n",
|
347 | 353 | "\n",
|
348 | 354 | "> PrePostInitMeta (name, bases, dict)\n",
|
349 | 355 | "\n",
|
350 |
| - "A metaclass that calls optional `__pre_init__` and `__post_init__` methods" |
| 356 | + "*A metaclass that calls optional `__pre_init__` and `__post_init__` methods*" |
351 | 357 | ],
|
352 | 358 | "text/plain": [
|
353 | 359 | "---\n",
|
354 | 360 | "\n",
|
| 361 | + "[source](https://github.com/AnswerDotAI/fastcore/blob/master/fastcore/meta.py#L36){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n", |
| 362 | + "\n", |
355 | 363 | "### PrePostInitMeta\n",
|
356 | 364 | "\n",
|
357 | 365 | "> PrePostInitMeta (name, bases, dict)\n",
|
358 | 366 | "\n",
|
359 |
| - "A metaclass that calls optional `__pre_init__` and `__post_init__` methods" |
| 367 | + "*A metaclass that calls optional `__pre_init__` and `__post_init__` methods*" |
360 | 368 | ]
|
361 | 369 | },
|
362 | 370 | "execution_count": null,
|
|
460 | 468 | "text/markdown": [
|
461 | 469 | "---\n",
|
462 | 470 | "\n",
|
| 471 | + "[source](https://github.com/AnswerDotAI/fastcore/blob/master/fastcore/meta.py#L52){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n", |
| 472 | + "\n", |
463 | 473 | "### NewChkMeta\n",
|
464 | 474 | "\n",
|
465 | 475 | "> NewChkMeta (name, bases, dict)\n",
|
466 | 476 | "\n",
|
467 |
| - "Metaclass to avoid recreating object passed to constructor" |
| 477 | + "*Metaclass to avoid recreating object passed to constructor*" |
468 | 478 | ],
|
469 | 479 | "text/plain": [
|
470 | 480 | "---\n",
|
471 | 481 | "\n",
|
| 482 | + "[source](https://github.com/AnswerDotAI/fastcore/blob/master/fastcore/meta.py#L52){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n", |
| 483 | + "\n", |
472 | 484 | "### NewChkMeta\n",
|
473 | 485 | "\n",
|
474 | 486 | "> NewChkMeta (name, bases, dict)\n",
|
475 | 487 | "\n",
|
476 |
| - "Metaclass to avoid recreating object passed to constructor" |
| 488 | + "*Metaclass to avoid recreating object passed to constructor*" |
477 | 489 | ]
|
478 | 490 | },
|
479 | 491 | "execution_count": null,
|
|
630 | 642 | "text/markdown": [
|
631 | 643 | "---\n",
|
632 | 644 | "\n",
|
| 645 | + "[source](https://github.com/AnswerDotAI/fastcore/blob/master/fastcore/meta.py#L60){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n", |
| 646 | + "\n", |
633 | 647 | "### BypassNewMeta\n",
|
634 | 648 | "\n",
|
635 | 649 | "> BypassNewMeta (name, bases, dict)\n",
|
636 | 650 | "\n",
|
637 |
| - "Metaclass: casts `x` to this class if it's of type `cls._bypass_type`" |
| 651 | + "*Metaclass: casts `x` to this class if it's of type `cls._bypass_type`*" |
638 | 652 | ],
|
639 | 653 | "text/plain": [
|
640 | 654 | "---\n",
|
641 | 655 | "\n",
|
| 656 | + "[source](https://github.com/AnswerDotAI/fastcore/blob/master/fastcore/meta.py#L60){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n", |
| 657 | + "\n", |
642 | 658 | "### BypassNewMeta\n",
|
643 | 659 | "\n",
|
644 | 660 | "> BypassNewMeta (name, bases, dict)\n",
|
645 | 661 | "\n",
|
646 |
| - "Metaclass: casts `x` to this class if it's of type `cls._bypass_type`" |
| 662 | + "*Metaclass: casts `x` to this class if it's of type `cls._bypass_type`*" |
647 | 663 | ]
|
648 | 664 | },
|
649 | 665 | "execution_count": null,
|
|
904 | 920 | "#|export\n",
|
905 | 921 | "def delegates(to:FunctionType=None, # Delegatee\n",
|
906 | 922 | " keep=False, # Keep `kwargs` in decorated function?\n",
|
907 |
| - " but:list=None): # Exclude these parameters from signature\n", |
| 923 | + " but:list=None, # Exclude these parameters from signature\n", |
| 924 | + " sort_args=False): # Sort arguments alphabetically, doesn't work with call_parse\n", |
908 | 925 | " \"Decorator: replace `**kwargs` in signature with params from `to`\"\n",
|
909 | 926 | " if but is None: but = []\n",
|
910 | 927 | " def _f(f):\n",
|
|
918 | 935 | " k = sigd.pop('kwargs')\n",
|
919 | 936 | " s2 = {k:v.replace(kind=inspect.Parameter.KEYWORD_ONLY) for k,v in inspect.signature(to_f).parameters.items()\n",
|
920 | 937 | " if v.default != inspect.Parameter.empty and k not in sigd and k not in but}\n",
|
| 938 | + " if sort_args: s2 = dict(sorted(s2.items()))\n", |
921 | 939 | " anno = {k:v for k,v in getattr(to_f, \"__annotations__\", {}).items() if k not in sigd and k not in but}\n",
|
922 | 940 | " sigd.update(s2)\n",
|
923 | 941 | " if keep: sigd['kwargs'] = k\n",
|
|
1216 | 1234 | "assert type(a).__name__ == 'method'"
|
1217 | 1235 | ]
|
1218 | 1236 | },
|
| 1237 | + { |
| 1238 | + "cell_type": "markdown", |
| 1239 | + "metadata": {}, |
| 1240 | + "source": [ |
| 1241 | + "You can also sort the arguments by setting the `sort_args` parameter to `True`. Here's a function with arguments not in alphabetical order." |
| 1242 | + ] |
| 1243 | + }, |
| 1244 | + { |
| 1245 | + "cell_type": "code", |
| 1246 | + "execution_count": null, |
| 1247 | + "metadata": {}, |
| 1248 | + "outputs": [ |
| 1249 | + { |
| 1250 | + "data": { |
| 1251 | + "text/plain": [ |
| 1252 | + "<function __main__.unsortedfunc(c=3, a=1, b=2)>" |
| 1253 | + ] |
| 1254 | + }, |
| 1255 | + "execution_count": null, |
| 1256 | + "metadata": {}, |
| 1257 | + "output_type": "execute_result" |
| 1258 | + } |
| 1259 | + ], |
| 1260 | + "source": [ |
| 1261 | + "def unsortedfunc(c=3,a=1,b=2): pass\n", |
| 1262 | + "unsortedfunc" |
| 1263 | + ] |
| 1264 | + }, |
| 1265 | + { |
| 1266 | + "cell_type": "markdown", |
| 1267 | + "metadata": {}, |
| 1268 | + "source": [ |
| 1269 | + "We can sort them using the `sort_args` parameter:" |
| 1270 | + ] |
| 1271 | + }, |
| 1272 | + { |
| 1273 | + "cell_type": "code", |
| 1274 | + "execution_count": null, |
| 1275 | + "metadata": {}, |
| 1276 | + "outputs": [ |
| 1277 | + { |
| 1278 | + "data": { |
| 1279 | + "text/plain": [ |
| 1280 | + "<function __main__.sortedfunc(*, a=1, b=2, c=3)>" |
| 1281 | + ] |
| 1282 | + }, |
| 1283 | + "execution_count": null, |
| 1284 | + "metadata": {}, |
| 1285 | + "output_type": "execute_result" |
| 1286 | + } |
| 1287 | + ], |
| 1288 | + "source": [ |
| 1289 | + "@delegates(unsortedfunc, sort_args=True)\n", |
| 1290 | + "def sortedfunc(**kwargs): pass\n", |
| 1291 | + "test_sig(sortedfunc, '(*, a=1, b=2, c=3)')\n", |
| 1292 | + "sortedfunc" |
| 1293 | + ] |
| 1294 | + }, |
1219 | 1295 | {
|
1220 | 1296 | "cell_type": "code",
|
1221 | 1297 | "execution_count": null,
|
|
0 commit comments