Last active
September 6, 2018 23:41
-
-
Save kne42/93f8a9d09aa8c5ea1160f1b18a51f2d9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"# Type Definitions" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 1, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"import typing as typ\n", | |
"from typing import Union, _tp_cache, TypeVar\n", | |
"from enum import Enum\n", | |
"import collections as coll\n", | |
"import functools as ft\n", | |
"\n", | |
"import numpy as np\n", | |
"\n", | |
"\n", | |
"__all__ = ['Union', 'Optional', 'Maybe',\n", | |
" 'Array', 'Scalar',\n", | |
" 'Real', 'Float', 'Complex',\n", | |
" 'Integer', 'SignedInteger', 'UnsignedInteger',\n", | |
" 'Number', 'Boolean']\n", | |
"\n", | |
"DType = TypeVar('DType')\n", | |
"\n", | |
"\n", | |
"class Optional(typ.Generic[DType]):\n", | |
" \n", | |
" __slots__ = ()\n", | |
" \n", | |
"\n", | |
"Maybe = typ.Optional\n", | |
"\n", | |
"\n", | |
"def _to_typevar(name, subtypes):\n", | |
" s = set()\n", | |
" \n", | |
" if not isinstance(subtypes, coll.Iterable):\n", | |
" subtypes = (subtypes,)\n", | |
" \n", | |
" for subtype in subtypes:\n", | |
" if isinstance(subtype, typ.TypeVar):\n", | |
" s = s.union(subtype.__constraints__)\n", | |
" else:\n", | |
" s.add(subtype)\n", | |
" \n", | |
" return typ.TypeVar(name, *s)\n", | |
"\n", | |
"\n", | |
"def _import_np_types():\n", | |
" np_dtype_table = np.typeDict\n", | |
" np_dtype_groupings = np.typecodes\n", | |
" \n", | |
" for name in np_dtype_table:\n", | |
" if isinstance(name, str) and len(name) > 2 and name[0].isupper():\n", | |
" globals()[name] = np_dtype_table[name]\n", | |
" \n", | |
" np_dtype_name_map = {\n", | |
" 'NumPyDType' : 'All',\n", | |
" 'NumPyInteger' : 'AllInteger',\n", | |
" 'NumPySignedInteger' : 'Integer',\n", | |
" 'NumPyUnsignedInteger' : 'UnsignedInteger',\n", | |
" 'NumPyReal' : 'Float',\n", | |
" 'NumPyFloat' : 'AllFloat',\n", | |
" 'NumPyComplex' : 'Complex'\n", | |
" }\n", | |
" \n", | |
" for group_name in np_dtype_name_map:\n", | |
" np_group_name = np_dtype_name_map[group_name]\n", | |
" dtype_codes = np_dtype_groupings[np_group_name]\n", | |
"\n", | |
" typevar = _to_typevar(group_name, (np_dtype_table[code]\n", | |
" for code in dtype_codes))\n", | |
" \n", | |
" globals()[group_name] = typevar\n", | |
" \n", | |
" \n", | |
"_import_np_types()\n", | |
"\n", | |
"NumPyBoolean = _to_typevar('NumPyBoolean',\n", | |
" (np.bool, np.bool_, np.bool8))\n", | |
"NumPyString = _to_typevar('NumPyString',\n", | |
" (np.str, np.str0, np.str_))\n", | |
" \n", | |
"SignedInteger = _to_typevar('SignedInteger',\n", | |
" (int, NumPySignedInteger))\n", | |
"UnsignedInteger = _to_typevar('UnsignedInteger',\n", | |
" NumPyUnsignedInteger)\n", | |
"Integer = _to_typevar('Integer',\n", | |
" (SignedInteger, UnsignedInteger))\n", | |
"\n", | |
"Real = _to_typevar('Real',\n", | |
" (float, NumPyReal))\n", | |
"Complex = _to_typevar('Complex',\n", | |
" (complex, NumPyComplex))\n", | |
"Float = _to_typevar('Float',\n", | |
" (Real, Complex))\n", | |
"\n", | |
"Number = _to_typevar('Number',\n", | |
" (Real, Integer))\n", | |
"Scalar = _to_typevar('Scalar', Number)\n", | |
"\n", | |
"Boolean = _to_typevar('Boolean',\n", | |
" (bool, NumPyBoolean))\n", | |
"String = _to_typevar('String',\n", | |
" (str, NumPyString))\n", | |
"\n", | |
"\n", | |
"class Array(np.ndarray, typ.MutableSequence[DType], extra=np.ndarray):\n", | |
" \n", | |
" __slots__ = ()\n", | |
" \n", | |
" def __new__(cls, *args, **kwds):\n", | |
" if cls._gorg is Array:\n", | |
" raise TypeError(\"Type Array cannot be instantiated; \"\n", | |
" \"use np.array() instead.\")\n", | |
" return typ._generic_new(np.ndarray, cls, *args, *kwds)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"# Autotyping" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 2, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"import numpy as np" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 3, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"from numpydoc.docscrape import FunctionDoc, ClassDoc" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 4, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"import typing as typ" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 5, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"import re" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 6, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"pattern_optional = r',\\s+optional.*$'" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 7, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"pattern_comma = r',(?![^(]*\\)|[^[]*]|[^{]*})'" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 8, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"from collections import OrderedDict" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 9, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"matchedtypedict = OrderedDict()\n", | |
"\n", | |
"def register_matchedtype(pattern, front=True):\n", | |
" def inner(func):\n", | |
" matchedtypedict[pattern] = func\n", | |
" if front:\n", | |
" matchedtypedict.move_to_end(pattern, last=False)\n", | |
" return func\n", | |
" return inner" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 10, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"simpletypedict = OrderedDict({\n", | |
" 'int' : Integer,\n", | |
" 'float' : Real,\n", | |
" 'double' : Real,\n", | |
" 'scalar' : Scalar,\n", | |
" 'complex' : Complex,\n", | |
" 'bool' : Boolean,\n", | |
" 'str' : String,\n", | |
" 'any' : typ.Any\n", | |
"})" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 11, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"def str_to_type(string, name=''):\n", | |
" string = string.strip()\n", | |
" \n", | |
" type = str_to_matchedtype(string, name)\n", | |
" if type:\n", | |
" return type\n", | |
" \n", | |
" type = str_to_simpletype(string)\n", | |
" if type:\n", | |
" return type\n", | |
" \n", | |
" raise ValueError(\"str_to_type: no type found for '%s'\" % string)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 12, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"def str_to_matchedtype(string, name):\n", | |
" for st in matchedtypedict:\n", | |
" match = re.search(st, string, re.IGNORECASE)\n", | |
" if match:\n", | |
" func = matchedtypedict[st]\n", | |
" return func(name, match.groups(), match.groupdict())" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 13, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"def str_to_simpletype(string):\n", | |
" for bt in simpletypedict:\n", | |
" if re.search(bt, string, re.IGNORECASE):\n", | |
" return simpletypedict[bt]" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 14, | |
"metadata": { | |
"scrolled": true | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"~Integer" | |
] | |
}, | |
"execution_count": 14, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"str_to_type('int')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 15, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"~Real" | |
] | |
}, | |
"execution_count": 15, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"str_to_type('float')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 16, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"@register_matchedtype(r'^(.*?),?\\s+or\\s+(.*)$')\n", | |
"def match_union(name, groups, groupdict):\n", | |
" typestr = ','.join((groups[0], groups[1]))\n", | |
" \n", | |
" split_typestr = re.split(pattern_comma, typestr)\n", | |
" \n", | |
" union_types = tuple(str_to_type(t) for t in split_typestr)\n", | |
" return Union[union_types]" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 17, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"typing.Union[~Integer, ~Real]" | |
] | |
}, | |
"execution_count": 17, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"str_to_type('int or float')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 18, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"typing.Union[~Integer, ~Real, ~Complex]" | |
] | |
}, | |
"execution_count": 18, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"str_to_type('int, float, or complex')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 19, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"def snake_to_camel(name):\n", | |
" # https://stackoverflow.com/a/42450252\n", | |
" return ''.join(list(map(str.title, name.split('_'))))" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 20, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"'Trivial'" | |
] | |
}, | |
"execution_count": 20, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"snake_to_camel('trivial')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 21, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"'NonTrivial'" | |
] | |
}, | |
"execution_count": 21, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"snake_to_camel('non_trivial')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 22, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"@register_matchedtype(r'^\\{(.*),(.*)\\}$')\n", | |
"def match_enum(name, groups, groupdict):\n", | |
" valstr = ','.join((groups[0], groups[1]))\n", | |
" \n", | |
" split_valstr = re.split(pattern_comma, valstr)\n", | |
" \n", | |
" lower_valstr = [val.strip()[1:-1] for val in split_valstr]\n", | |
" caps_valstr = [val.upper() for val in lower_valstr]\n", | |
" \n", | |
" enum = Enum(snake_to_camel(name), dict(zip(caps_valstr, lower_valstr)))\n", | |
" \n", | |
" return enum" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 23, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"<Test.FOO: 'foo'>" | |
] | |
}, | |
"execution_count": 23, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"str_to_type(\"{'foo', 'bar', 'baz'}\", 'test').FOO" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 24, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"<Mode.CONSTANT: 'constant'>" | |
] | |
}, | |
"execution_count": 24, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"str_to_type(\"{'reflect', 'constant', 'nearest', 'mirror', 'wrap'}\", 'mode').CONSTANT" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 25, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"array_base_re = r'(?:array(?:-|_)like|(?:(?:np|numpy)\\.)?(?:nd)?array)'\n", | |
"ndim_re = r'^(?:(?:(?P<shape>\\(.*,.*\\))|(?P<ndim>.)-?D)\\s+)?'\n", | |
"@register_matchedtype(ndim_re\n", | |
" + r'(?:(?P<subtype>.+)\\s+)?'\n", | |
" + array_base_re + '$',\n", | |
" front=True)\n", | |
"@register_matchedtype(ndim_re\n", | |
" + array_base_re\n", | |
" + r'(?:\\s+of\\s+(?P<subtype>.+))?$',\n", | |
" front=True)\n", | |
"def match_array(name, groups, groupdict):\n", | |
" shape = groupdict.get('shape')\n", | |
" ndim = groupdict.get('ndim')\n", | |
" subtype = groupdict.get('subtype')\n", | |
" \n", | |
" structtype = Array[Number]\n", | |
" \n", | |
" if subtype:\n", | |
" structtype = Array[str_to_type(subtype)]\n", | |
" \n", | |
" if ndim:\n", | |
" print('ndim:', ndim)\n", | |
" \n", | |
" if shape:\n", | |
" print('shape:', shape)\n", | |
" \n", | |
" return structtype" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 26, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"__main__.Array[~Integer]" | |
] | |
}, | |
"execution_count": 26, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"str_to_type('int ndarray')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 27, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"__main__.Array[typing.Union[~Real, ~Integer]]" | |
] | |
}, | |
"execution_count": 27, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"str_to_type('float or int array')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 28, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"shape: (M, N)\n" | |
] | |
}, | |
{ | |
"data": { | |
"text/plain": [ | |
"__main__.Array[~Number]" | |
] | |
}, | |
"execution_count": 28, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"str_to_type('(M, N) array')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 29, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"shape: (M, N)\n" | |
] | |
}, | |
{ | |
"data": { | |
"text/plain": [ | |
"__main__.Array[typing.Union[~Real, ~Integer]]" | |
] | |
}, | |
"execution_count": 29, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"str_to_type('(M, N) int or float array')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 30, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"ndim: n\n" | |
] | |
}, | |
{ | |
"data": { | |
"text/plain": [ | |
"__main__.Array[~Number]" | |
] | |
}, | |
"execution_count": 30, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"str_to_type('nD array')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 31, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"ndim: 2\n" | |
] | |
}, | |
{ | |
"data": { | |
"text/plain": [ | |
"__main__.Array[~Real]" | |
] | |
}, | |
"execution_count": 31, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"str_to_type('2-D float array')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 32, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"typing.Union[~Real, __main__.Array[~Real]]" | |
] | |
}, | |
"execution_count": 32, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"str_to_type('float or array of float')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 33, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"@register_matchedtype(r'^(?:(?P<size>\\w+)-)?tuple'\n", | |
" r'(?:\\s+of\\s+(?P<subtype>.*))?$')\n", | |
"def match_tuple(name, group, groupdict):\n", | |
" size = groupdict.get('size')\n", | |
" subtype = groupdict.get('subtype')\n", | |
" \n", | |
" if size:\n", | |
" size = int(size)\n", | |
" else:\n", | |
" size = 1\n", | |
" \n", | |
" if subtype:\n", | |
" subtype = str_to_type(subtype)\n", | |
" else:\n", | |
" subtype = typ.Any\n", | |
" \n", | |
" return typ.Tuple[(subtype,) * size]" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 34, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"typing.Tuple[typing.Any]" | |
] | |
}, | |
"execution_count": 34, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"str_to_type('tuple')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 35, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"typing.Tuple[~Integer]" | |
] | |
}, | |
"execution_count": 35, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"str_to_type('tuple of ints')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 36, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"typing.Tuple[typing.Any, typing.Any]" | |
] | |
}, | |
"execution_count": 36, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"str_to_type('2-tuple')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 37, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"typing.Tuple[~Real, ~Real]" | |
] | |
}, | |
"execution_count": 37, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"str_to_type('2-tuple of float')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 38, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"typing.Union[~Boolean, typing.Tuple[~Boolean]]" | |
] | |
}, | |
"execution_count": 38, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"str_to_type('bool or tuple of bool')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 39, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"@register_matchedtype(r'^dict(?:\\s+of\\s+(?P<keytype>[^:]*)'\n", | |
" '(?::\\s*(?P<valtype>.*))?)?$')\n", | |
"def match_dict(name, group, groupdict):\n", | |
" keytype = groupdict.get('keytype')\n", | |
" valtype = groupdict.get('valtype')\n", | |
" \n", | |
" if keytype:\n", | |
" keytype = str_to_type(keytype)\n", | |
" else:\n", | |
" keytype = typ.Any\n", | |
" \n", | |
" if valtype:\n", | |
" valtype = str_to_type(valtype)\n", | |
" else:\n", | |
" valtype = typ.Any\n", | |
" \n", | |
" return typ.Dict[keytype, valtype]" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 40, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"typing.Dict[typing.Any, typing.Any]" | |
] | |
}, | |
"execution_count": 40, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"str_to_type('dict')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 41, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"typing.Dict[~Integer, typing.Any]" | |
] | |
}, | |
"execution_count": 41, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"str_to_type('dict of int')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 42, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"typing.Dict[~Integer, ~String]" | |
] | |
}, | |
"execution_count": 42, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"str_to_type('dict of int:str')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 43, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"typing.Union[~Integer, typing.Dict[~Integer, ~String]]" | |
] | |
}, | |
"execution_count": 43, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"str_to_type('int or dict of int:str')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 44, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"@register_matchedtype(r'^(?P<struct>(?:list)|(?:set)|(?:sequence))'\n", | |
" r'(?:\\s+of\\s+(?P<subtype>.*))?$')\n", | |
"def match_list_set_sequence(name, group, groupdict):\n", | |
" struct = groupdict.get('struct')\n", | |
" subtype = groupdict.get('subtype')\n", | |
" \n", | |
" if subtype:\n", | |
" subtype = str_to_type(subtype)\n", | |
" else:\n", | |
" subtype = typ.Any\n", | |
" \n", | |
" if struct == 'list':\n", | |
" struct = typ.List\n", | |
" elif struct == 'set':\n", | |
" struct = typ.Set\n", | |
" elif struct == 'sequence':\n", | |
" struct = typ.Sequence\n", | |
" \n", | |
" return struct[subtype]" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 45, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"typing.List[~Real]" | |
] | |
}, | |
"execution_count": 45, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"str_to_type('list of floats')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 46, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"typing.Set[typing.Any]" | |
] | |
}, | |
"execution_count": 46, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"str_to_type('set')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 47, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"typing.Sequence[~Scalar]" | |
] | |
}, | |
"execution_count": 47, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"str_to_type('sequence of scalars')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 48, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"typing.Union[~Integer, typing.Sequence[~Integer]]" | |
] | |
}, | |
"execution_count": 48, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"str_to_type('int or sequence of int')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 49, | |
"metadata": { | |
"scrolled": true | |
}, | |
"outputs": [], | |
"source": [ | |
"def determine_if_optional(typestr):\n", | |
" stripped = re.sub(pattern_optional, '', typestr)\n", | |
" \n", | |
" return stripped != typestr, stripped" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 50, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"(False, 'int')" | |
] | |
}, | |
"execution_count": 50, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"determine_if_optional('int')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 51, | |
"metadata": { | |
"scrolled": true | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"(True, 'int')" | |
] | |
}, | |
"execution_count": 51, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"determine_if_optional('int, optional')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 52, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"def parse_typestring(typestr, name):\n", | |
" optional, typestr = determine_if_optional(typestr)\n", | |
" typestr = str_to_type(typestr, name)\n", | |
" \n", | |
" if optional:\n", | |
" return Optional[typestr]\n", | |
" return typestr" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 53, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"def autotype_func(func):\n", | |
" print(\"Function: \", func.__name__)\n", | |
" \n", | |
" doc = FunctionDoc(func)\n", | |
" params = doc['Parameters']\n", | |
" \n", | |
" for name, typestr, description in params:\n", | |
" print()\n", | |
" print('Name:', name)\n", | |
" print('Original:', typestr)\n", | |
" print('Parsed:', parse_typestring(typestr, name))" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 54, | |
"metadata": { | |
"scrolled": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"Function: gaussian\n", | |
"\n", | |
"Name: image\n", | |
"Original: array-like\n", | |
"Parsed: __main__.Array[~Number]\n", | |
"\n", | |
"Name: sigma\n", | |
"Original: scalar or sequence of scalars, optional\n", | |
"Parsed: __main__.Optional[typing.Union[~Scalar, typing.Sequence[~Scalar]]]\n", | |
"\n", | |
"Name: output\n", | |
"Original: array, optional\n", | |
"Parsed: __main__.Optional[__main__.Array[~Number]]\n", | |
"\n", | |
"Name: mode\n", | |
"Original: {'reflect', 'constant', 'nearest', 'mirror', 'wrap'}, optional\n", | |
"Parsed: __main__.Optional[__main__.Mode]\n", | |
"\n", | |
"Name: cval\n", | |
"Original: scalar, optional\n", | |
"Parsed: __main__.Optional[~Scalar]\n", | |
"\n", | |
"Name: multichannel\n", | |
"Original: bool, optional (default: None)\n", | |
"Parsed: __main__.Optional[~Boolean]\n", | |
"\n", | |
"Name: preserve_range\n", | |
"Original: bool, optional\n", | |
"Parsed: __main__.Optional[~Boolean]\n", | |
"\n", | |
"Name: truncate\n", | |
"Original: float, optional\n", | |
"Parsed: __main__.Optional[~Real]\n" | |
] | |
} | |
], | |
"source": [ | |
"from skimage.filters import gaussian\n", | |
"autotype_func(gaussian)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "Python 3", | |
"language": "python", | |
"name": "python3" | |
}, | |
"language_info": { | |
"codemirror_mode": { | |
"name": "ipython", | |
"version": 3 | |
}, | |
"file_extension": ".py", | |
"mimetype": "text/x-python", | |
"name": "python", | |
"nbconvert_exporter": "python", | |
"pygments_lexer": "ipython3", | |
"version": "3.6.5" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 2 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment