diff options
Diffstat (limited to 'doc')
32 files changed, 3137 insertions, 1840 deletions
diff --git a/doc/DISTUTILS.rst.txt b/doc/DISTUTILS.rst.txt index 01527374d..c58a423c0 100644 --- a/doc/DISTUTILS.rst.txt +++ b/doc/DISTUTILS.rst.txt @@ -394,37 +394,37 @@ and ``/**end repeat**/`` lines, which may also be nested using consecutively numbered delimiting lines such as ``/**begin repeat1`` and ``/**end repeat1**/``: -1. "/\**begin repeat "on a line by itself marks the beginning of -a segment that should be repeated. +1. ``/**begin repeat`` on a line by itself marks the beginning of + a segment that should be repeated. 2. Named variable expansions are defined using ``#name=item1, item2, item3, -..., itemN#`` and placed on successive lines. These variables are -replaced in each repeat block with corresponding word. All named -variables in the same repeat block must define the same number of -words. + ..., itemN#`` and placed on successive lines. These variables are + replaced in each repeat block with corresponding word. All named + variables in the same repeat block must define the same number of + words. 3. In specifying the repeat rule for a named variable, ``item*N`` is short- -hand for ``item, item, ..., item`` repeated N times. In addition, -parenthesis in combination with \*N can be used for grouping several -items that should be repeated. Thus, #name=(item1, item2)*4# is -equivalent to #name=item1, item2, item1, item2, item1, item2, item1, -item2# + hand for ``item, item, ..., item`` repeated N times. In addition, + parenthesis in combination with ``*N`` can be used for grouping several + items that should be repeated. Thus, ``#name=(item1, item2)*4#`` is + equivalent to ``#name=item1, item2, item1, item2, item1, item2, item1, + item2#``. -4. "\*/ "on a line by itself marks the end of the variable expansion -naming. The next line is the first line that will be repeated using -the named rules. +4. ``*/`` on a line by itself marks the end of the variable expansion + naming. The next line is the first line that will be repeated using + the named rules. 5. Inside the block to be repeated, the variables that should be expanded -are specified as ``@name@`` + are specified as ``@name@``. -6. "/\**end repeat**/ "on a line by itself marks the previous line -as the last line of the block to be repeated. +6. ``/**end repeat**/`` on a line by itself marks the previous line + as the last line of the block to be repeated. 7. A loop in the NumPy C source code may have a ``@TYPE@`` variable, targeted -for string substitution, which is preprocessed to a number of otherwise -identical loops with several strings such as INT, LONG, UINT, ULONG. The -``@TYPE@`` style syntax thus reduces code duplication and maintenance burden by -mimicking languages that have generic type support. + for string substitution, which is preprocessed to a number of otherwise + identical loops with several strings such as ``INT``, ``LONG``, ``UINT``, + ``ULONG``. The ``@TYPE@`` style syntax thus reduces code duplication and + maintenance burden by mimicking languages that have generic type support. The above rules may be clearer in the following template source example: @@ -464,13 +464,13 @@ The above rules may be clearer in the following template source example: /**end repeat**/ -The preprocessing of generically typed C source files (whether in NumPy +The preprocessing of generically-typed C source files (whether in NumPy proper or in any third party package using NumPy Distutils) is performed by `conv_template.py`_. -The type specific C files generated (extension: .c) +The type-specific C files generated (extension: ``.c``) by these modules during the build process are ready to be compiled. This form of generic typing is also supported for C header files (preprocessed -to produce .h files). +to produce ``.h`` files). .. _conv_template.py: https://github.com/numpy/numpy/blob/master/numpy/distutils/conv_template.py @@ -587,10 +587,6 @@ The header of a typical SciPy ``__init__.py`` is:: test = Tester().test bench = Tester().bench -Note that NumPy submodules still use a file named ``info.py`` in which the -module docstring and ``__all__`` dict are defined. These files will be removed -at some point. - Extra features in NumPy Distutils ''''''''''''''''''''''''''''''''' diff --git a/doc/neps/_static/nep-0041-type-sketch-no-fonts.svg b/doc/neps/_static/nep-0041-type-sketch-no-fonts.svg new file mode 100644 index 000000000..3250396c5 --- /dev/null +++ b/doc/neps/_static/nep-0041-type-sketch-no-fonts.svg @@ -0,0 +1,1110 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + inkscape:version="1.0rc1 (09960d6f05, 2020-04-09)" + sodipodi:docname="nep-0041-type-sketch-no-fonts.svg" + id="svg8" + version="1.1" + viewBox="0 0 390.05549 139.7222" + height="139.7222mm" + width="390.05548mm"> + <defs + id="defs2"> + <rect + x="-108.43283" + y="116.0488" + width="38.824516" + height="5.9122801" + id="rect3054" /> + <marker + inkscape:isstock="true" + style="overflow:visible" + id="marker7096" + refX="0" + refY="0" + orient="auto" + inkscape:stockid="Arrow1Send"> + <path + transform="matrix(-0.2,0,0,-0.2,-1.2,0)" + style="fill:#00b200;fill-opacity:1;fill-rule:evenodd;stroke:#00b200;stroke-width:1pt;stroke-opacity:1" + d="M 0,0 5,-5 -12.5,0 5,5 Z" + id="path7094" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible" + id="marker5628" + refX="0" + refY="0" + orient="auto" + inkscape:stockid="Arrow1Send"> + <path + transform="matrix(-0.2,0,0,-0.2,-1.2,0)" + style="fill:#000081;fill-opacity:1;fill-rule:evenodd;stroke:#000081;stroke-width:1pt;stroke-opacity:1" + d="M 0,0 5,-5 -12.5,0 5,5 Z" + id="path5626" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible" + id="marker5618" + refX="0" + refY="0" + orient="auto" + inkscape:stockid="Arrow1Sstart"> + <path + transform="matrix(0.2,0,0,0.2,1.2,0)" + style="fill:#000081;fill-opacity:1;fill-rule:evenodd;stroke:#000081;stroke-width:1pt;stroke-opacity:1" + d="M 0,0 5,-5 -12.5,0 5,5 Z" + id="path5616" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible" + id="marker4826" + refX="0" + refY="0" + orient="auto" + inkscape:stockid="Arrow1Send"> + <path + transform="matrix(-0.2,0,0,-0.2,-1.2,0)" + style="fill:#206120;fill-opacity:1;fill-rule:evenodd;stroke:#206120;stroke-width:1pt;stroke-opacity:1" + d="M 0,0 5,-5 -12.5,0 5,5 Z" + id="path4824" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:stockid="Arrow1Send" + orient="auto" + refY="0" + refX="0" + id="marker4400" + style="overflow:visible" + inkscape:isstock="true"> + <path + inkscape:connector-curvature="0" + id="path4398" + d="M 0,0 5,-5 -12.5,0 5,5 Z" + style="fill:#00b200;fill-opacity:1;fill-rule:evenodd;stroke:#00b200;stroke-width:1pt;stroke-opacity:1" + transform="matrix(-0.2,0,0,-0.2,-1.2,0)" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible" + id="marker4390" + refX="0" + refY="0" + orient="auto" + inkscape:stockid="Arrow1Send"> + <path + transform="matrix(-0.2,0,0,-0.2,-1.2,0)" + style="fill:#b7943d;fill-opacity:1;fill-rule:evenodd;stroke:#b7943d;stroke-width:1pt;stroke-opacity:1" + d="M 0,0 5,-5 -12.5,0 5,5 Z" + id="path4388" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible" + id="marker2037" + refX="0" + refY="0" + orient="auto" + inkscape:stockid="Arrow1Send"> + <path + transform="matrix(-0.2,0,0,-0.2,-1.2,0)" + style="fill:#f4ae00;fill-opacity:1;fill-rule:evenodd;stroke:#ffc433;stroke-width:1pt;stroke-opacity:1" + d="M 0,0 5,-5 -12.5,0 5,5 Z" + id="path2035" + inkscape:connector-curvature="0" /> + </marker> + <rect + id="rect1296" + height="8.8755655" + width="16.467854" + y="100.87298" + x="-2.9674385" /> + <marker + inkscape:isstock="true" + style="overflow:visible" + id="Arrow1Lend" + refX="0" + refY="0" + orient="auto" + inkscape:stockid="Arrow1Lend"> + <path + transform="matrix(-0.8,0,0,-0.8,-10,0)" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1" + d="M 0,0 5,-5 -12.5,0 5,5 Z" + id="path915" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible" + id="Arrow1Lstart" + refX="0" + refY="0" + orient="auto" + inkscape:stockid="Arrow1Lstart"> + <path + transform="matrix(0.8,0,0,0.8,10,0)" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1" + d="M 0,0 5,-5 -12.5,0 5,5 Z" + id="path912" + inkscape:connector-curvature="0" /> + </marker> + </defs> + <sodipodi:namedview + inkscape:guide-bbox="true" + showguides="true" + inkscape:window-maximized="1" + inkscape:window-y="27" + inkscape:window-x="0" + inkscape:window-height="1376" + inkscape:window-width="2560" + showgrid="false" + inkscape:document-rotation="0" + inkscape:current-layer="layer1" + inkscape:document-units="mm" + inkscape:cy="290.82008" + inkscape:cx="134.87089" + inkscape:zoom="0.98994949" + inkscape:pageshadow="2" + inkscape:pageopacity="0.0" + borderopacity="1.0" + bordercolor="#666666" + pagecolor="#ffffff" + id="base" + lock-margins="true" + fit-margin-top="2" + fit-margin-left="2" + fit-margin-right="2" + fit-margin-bottom="2" + objecttolerance="29.7" + gridtolerance="20.4" + guidetolerance="19.1" + inkscape:snap-perpendicular="true" + inkscape:snap-tangential="true" /> + <metadata + id="metadata5"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + id="layer1" + inkscape:groupmode="layer" + inkscape:label="Layer 1" + transform="translate(143.44857,-67.864137)"> + <path + sodipodi:nodetypes="sssssssss" + inkscape:connector-curvature="0" + id="path1976" + style="opacity:1;fill:#ddb9b9;fill-opacity:0.796078;stroke:none;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.2, 2.4;stroke-dashoffset:0;stroke-opacity:0.497957" + d="m 175.57699,126.11316 h 65.38081 c 1.14406,0 2.06509,0.92103 2.06509,2.06509 v 15.54342 c 0,1.14406 -0.92103,2.06509 -2.06509,2.06509 h -65.38081 c -1.14406,0 -2.06509,-0.92103 -2.06509,-2.06509 v -15.54342 c 0,-1.14406 0.92103,-2.06509 2.06509,-2.06509 z" /> + <path + sodipodi:nodetypes="cc" + inkscape:connector-curvature="0" + id="path3044" + d="M 172.89254,70.114137 V 205.33633" + style="fill:none;stroke:#808080;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <path + d="M 55.143494,98.892926 H 240.95778 c 1.14406,0 2.06509,0.921034 2.06509,2.065094 v 15.54342 c 0,1.14406 -0.92103,2.06509 -2.06509,2.06509 H 55.143494 c -1.14406,0 -2.06509,-0.92103 -2.06509,-2.06509 v -15.54342 c 0,-1.14406 0.92103,-2.065094 2.06509,-2.065094 z" + style="opacity:1;fill:#ddb9b9;fill-opacity:0.796609;stroke:none;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.2, 2.4;stroke-dashoffset:0;stroke-opacity:0.497957" + id="rect5208" + inkscape:connector-curvature="0" + sodipodi:nodetypes="sssssssss" /> + <path + d="M -60.569299,98.727824 H 50.002364 c 1.14406,0 2.06509,0.92103 2.06509,2.065086 v 15.70853 c 0,1.14406 -0.92103,2.06509 -2.06509,2.06509 H -60.569299 c -1.14406,0 -2.06509,-0.92103 -2.06509,-2.06509 v -15.70853 c 0,-1.144056 0.92103,-2.065086 2.06509,-2.065086 z" + style="opacity:0.25;fill:#000080;fill-opacity:0.4;stroke:none;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.2, 2.4;stroke-dashoffset:0;stroke-opacity:0.497957" + id="rect4618" + inkscape:connector-curvature="0" + sodipodi:nodetypes="sssssssss" /> + <g + style="font-size:6.7452px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;stroke-width:0.505891" + id="text4368" /> + <g + style="font-size:3.52778px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;white-space:pre;shape-inside:url(#rect1296)" + id="text1294" /> + <g + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:7.76111px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke-width:0.105503" + id="text1931" + aria-label="Value Storage"> + <path + id="path1309" + style="fill:#000000;stroke-width:0.105503" + d="m 177.73074,82.757808 h 1.46657 l 1.50069,4.176144 1.49689,-4.176144 h 1.46658 l -2.09565,5.65788 h -1.73943 z" /> + <path + id="path1311" + style="fill:#000000;stroke-width:0.105503" + d="m 185.82912,86.505727 q -0.42443,0 -0.64044,0.144005 -0.21222,0.144005 -0.21222,0.424436 0,0.257693 0.17053,0.405487 0.17432,0.144005 0.48128,0.144005 0.38275,0 0.64424,-0.272851 0.26148,-0.276641 0.26148,-0.689708 v -0.155374 z m 2.07292,-0.511597 v 2.421558 h -1.36805 v -0.629075 q -0.27285,0.38654 -0.61392,0.564651 -0.34106,0.174322 -0.82992,0.174322 -0.65939,0 -1.07246,-0.38275 -0.40928,-0.38654 -0.40928,-1.000456 0,-0.746552 0.5116,-1.095195 0.51539,-0.348644 1.61437,-0.348644 h 0.79961 v -0.106109 q 0,-0.322116 -0.25391,-0.469911 -0.2539,-0.151584 -0.79202,-0.151584 -0.43581,0 -0.81098,0.08716 -0.37517,0.08716 -0.69729,0.261483 v -1.034562 q 0.43581,-0.106109 0.8754,-0.159164 0.4396,-0.05684 0.87919,-0.05684 1.14825,0 1.65606,0.454753 0.5116,0.450963 0.5116,1.470366 z" /> + <path + id="path1313" + style="fill:#000000;stroke-width:0.105503" + d="m 189.16397,82.519063 h 1.35668 v 5.896625 h -1.35668 z" /> + <path + id="path1315" + style="fill:#000000;stroke-width:0.105503" + d="m 191.7788,86.76342 v -2.592089 h 1.36426 v 0.424435 q 0,0.344854 -0.004,0.86782 -0.004,0.519176 -0.004,0.693497 0,0.511597 0.0265,0.738973 0.0265,0.223587 0.0909,0.325906 0.0834,0.132636 0.216,0.204639 0.13643,0.072 0.31075,0.072 0.42444,0 0.66697,-0.325906 0.24254,-0.325906 0.24254,-0.905715 v -2.095651 h 1.35667 v 4.244357 h -1.35667 v -0.613916 q -0.30696,0.371381 -0.65182,0.549492 -0.34106,0.174322 -0.75413,0.174322 -0.73518,0 -1.12172,-0.450963 -0.38275,-0.450963 -0.38275,-1.311203 z" /> + <path + id="path1317" + style="fill:#000000;stroke-width:0.105503" + d="m 201.5863,86.28214 v 0.38654 h -3.1719 q 0.0493,0.47749 0.34485,0.716235 0.29559,0.238745 0.82613,0.238745 0.42823,0 0.8754,-0.125057 0.45097,-0.128846 0.92467,-0.386539 v 1.04593 q -0.48128,0.181901 -0.96256,0.272852 -0.48128,0.09474 -0.96256,0.09474 -1.15204,0 -1.79249,-0.583599 -0.63665,-0.587389 -0.63665,-1.644688 0,-1.038352 0.62529,-1.63332 0.62907,-0.594968 1.72806,-0.594968 1.00045,0 1.59921,0.602547 0.60255,0.602548 0.60255,1.610582 z m -1.39458,-0.450963 q 0,-0.386539 -0.22737,-0.621495 -0.22359,-0.238745 -0.58739,-0.238745 -0.39412,0 -0.64045,0.223587 -0.24632,0.219797 -0.30695,0.636653 z" /> + <path + id="path1319" + style="fill:#000000;stroke-width:0.105503" + d="m 209.3133,82.93592 v 1.197515 q -0.46612,-0.208429 -0.9095,-0.314538 -0.44339,-0.106109 -0.83751,-0.106109 -0.52296,0 -0.77308,0.144005 -0.25011,0.144005 -0.25011,0.447174 0,0.227376 0.16674,0.356223 0.17053,0.125057 0.61392,0.216007 l 0.62149,0.125057 q 0.94361,0.18948 1.34152,0.57602 0.39791,0.38654 0.39791,1.098985 0,0.936032 -0.55707,1.394575 -0.55328,0.454752 -1.69395,0.454752 -0.53813,0 -1.08004,-0.102319 -0.54191,-0.10232 -1.08383,-0.303169 v -1.231621 q 0.54192,0.28801 1.04593,0.435804 0.50781,0.144005 0.97772,0.144005 0.47749,0 0.7314,-0.159163 0.2539,-0.159163 0.2539,-0.454752 0,-0.265273 -0.17432,-0.409278 -0.17054,-0.144005 -0.68592,-0.257693 l -0.56465,-0.125057 q -0.84887,-0.181901 -1.24299,-0.579809 -0.39033,-0.397909 -0.39033,-1.072458 0,-0.845082 0.5457,-1.299835 0.5457,-0.454752 1.5689,-0.454752 0.46612,0 0.95877,0.072 0.49265,0.06821 1.0194,0.208429 z" /> + <path + id="path1321" + style="fill:#000000;stroke-width:0.105503" + d="m 212.38667,82.966236 v 1.205095 h 1.39836 v 0.970138 h -1.39836 v 1.800062 q 0,0.29559 0.11748,0.401699 0.11747,0.102319 0.46612,0.102319 h 0.69728 v 0.970139 h -1.1634 q -0.8034,0 -1.14068,-0.333486 -0.33348,-0.337274 -0.33348,-1.140671 v -1.800062 h -0.67455 v -0.970138 h 0.67455 v -1.205095 z" /> + <path + id="path1323" + style="fill:#000000;stroke-width:0.105503" + d="m 216.63482,85.03915 q -0.45097,0 -0.68971,0.325906 -0.23496,0.322116 -0.23496,0.932243 0,0.610126 0.23496,0.936032 0.23874,0.322116 0.68971,0.322116 0.44338,0 0.67834,-0.322116 0.23495,-0.325906 0.23495,-0.936032 0,-0.610127 -0.23495,-0.932243 -0.23496,-0.325906 -0.67834,-0.325906 z m 0,-0.970139 q 1.09519,0 1.70911,0.591179 0.6177,0.591178 0.6177,1.637109 0,1.045931 -0.6177,1.637109 -0.61392,0.591178 -1.70911,0.591178 -1.09899,0 -1.72048,-0.591178 -0.61771,-0.591178 -0.61771,-1.637109 0,-1.045931 0.61771,-1.637109 0.62149,-0.591179 1.72048,-0.591179 z" /> + <path + id="path1325" + style="fill:#000000;stroke-width:0.105503" + d="m 223.09988,85.32716 q -0.17811,-0.08337 -0.35622,-0.121267 -0.17433,-0.04169 -0.35244,-0.04169 -0.52296,0 -0.80718,0.337275 -0.28043,0.333485 -0.28043,0.95877 v 1.955436 h -1.35668 v -4.244357 h 1.35668 v 0.697287 q 0.26148,-0.416857 0.59875,-0.606337 0.34107,-0.19327 0.81477,-0.19327 0.0682,0 0.14779,0.0076 0.0796,0.0038 0.23117,0.02274 z" /> + <path + id="path1327" + style="fill:#000000;stroke-width:0.105503" + d="m 225.67681,86.505727 q -0.42443,0 -0.64044,0.144005 -0.21222,0.144005 -0.21222,0.424436 0,0.257693 0.17053,0.405487 0.17433,0.144005 0.48128,0.144005 0.38275,0 0.64424,-0.272851 0.26148,-0.276641 0.26148,-0.689708 v -0.155374 z m 2.07292,-0.511597 v 2.421558 h -1.36805 v -0.629075 q -0.27285,0.38654 -0.61392,0.564651 -0.34106,0.174322 -0.82992,0.174322 -0.65939,0 -1.07246,-0.38275 -0.40928,-0.38654 -0.40928,-1.000456 0,-0.746552 0.5116,-1.095195 0.51539,-0.348644 1.61437,-0.348644 h 0.79961 v -0.106109 q 0,-0.322116 -0.2539,-0.469911 -0.25391,-0.151584 -0.79203,-0.151584 -0.43581,0 -0.81098,0.08716 -0.37517,0.08716 -0.69728,0.261483 v -1.034562 q 0.4358,-0.106109 0.87539,-0.159164 0.4396,-0.05684 0.87919,-0.05684 1.14825,0 1.65606,0.454753 0.5116,0.450963 0.5116,1.470366 z" /> + <path + id="path1329" + style="fill:#000000;stroke-width:0.105503" + d="m 231.89934,87.695663 q -0.28043,0.371381 -0.6177,0.545703 -0.33728,0.174322 -0.78066,0.174322 -0.77687,0 -1.28468,-0.610127 -0.5078,-0.613916 -0.5078,-1.561317 0,-0.95119 0.5078,-1.557527 0.50781,-0.610126 1.28468,-0.610126 0.44338,0 0.78066,0.174321 0.33727,0.174322 0.6177,0.549493 v -0.629074 h 1.36426 v 3.816131 q 0,1.023193 -0.64802,1.561317 -0.64424,0.541914 -1.87207,0.541914 -0.39791,0 -0.76929,-0.06063 -0.37138,-0.06063 -0.74655,-0.185691 v -1.057299 q 0.35622,0.204638 0.69729,0.303168 0.34106,0.102319 0.68592,0.102319 0.66697,0 0.97771,-0.291799 0.31075,-0.2918 0.31075,-0.913295 z M 231.005,85.054308 q -0.42065,0 -0.65561,0.310748 -0.23495,0.310748 -0.23495,0.879188 0,0.583599 0.22737,0.886768 0.22738,0.299378 0.66319,0.299378 0.42443,0 0.65939,-0.310747 0.23495,-0.310748 0.23495,-0.875399 0,-0.56844 -0.23495,-0.879188 -0.23496,-0.310748 -0.65939,-0.310748 z" /> + <path + id="path1331" + style="fill:#000000;stroke-width:0.105503" + d="m 238.804,86.28214 v 0.38654 h -3.1719 q 0.0493,0.47749 0.34486,0.716235 0.29559,0.238745 0.82613,0.238745 0.42823,0 0.8754,-0.125057 0.45096,-0.128846 0.92466,-0.386539 v 1.04593 q -0.48128,0.181901 -0.96256,0.272852 -0.48128,0.09474 -0.96256,0.09474 -1.15204,0 -1.79248,-0.583599 -0.63665,-0.587389 -0.63665,-1.644688 0,-1.038352 0.62528,-1.63332 0.62908,-0.594968 1.72806,-0.594968 1.00046,0 1.59922,0.602547 0.60254,0.602548 0.60254,1.610582 z m -1.39457,-0.450963 q 0,-0.386539 -0.22738,-0.621495 -0.22358,-0.238745 -0.58739,-0.238745 -0.39412,0 -0.64044,0.223587 -0.24632,0.219797 -0.30696,0.636653 z" /> + </g> + <g + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:7.76111px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke-width:0.105503" + id="text1935" + aria-label="Parameters and +Storage options"> + <path + id="path1254" + style="fill:#000000;stroke-width:0.105503" + d="m 78.339383,73.092678 h 2.421558 q 1.080037,0 1.656057,0.481279 0.579809,0.47749 0.579809,1.364258 0,0.890557 -0.579809,1.371837 -0.57602,0.47749 -1.656057,0.47749 h -0.96256 v 1.963015 h -1.458998 z m 1.458998,1.057299 v 1.580265 h 0.807186 q 0.424436,0 0.655601,-0.204638 0.231166,-0.208429 0.231166,-0.587389 0,-0.378961 -0.231166,-0.583599 -0.231165,-0.204639 -0.655601,-0.204639 z" /> + <path + id="path1256" + style="fill:#000000;stroke-width:0.105503" + d="m 85.660899,76.840596 q -0.424436,0 -0.640443,0.144005 -0.212218,0.144005 -0.212218,0.424436 0,0.257693 0.170532,0.405488 0.174322,0.144005 0.48128,0.144005 0.38275,0 0.644233,-0.272852 0.261482,-0.276641 0.261482,-0.689708 V 76.840596 Z M 87.733813,76.329 v 2.421557 h -1.368048 v -0.629074 q -0.272851,0.386539 -0.613915,0.564651 -0.341065,0.174321 -0.829924,0.174321 -0.659391,0 -1.072458,-0.38275 -0.409277,-0.386539 -0.409277,-1.000455 0,-0.746552 0.511596,-1.095196 0.515387,-0.348643 1.614372,-0.348643 h 0.799606 v -0.106109 q 0,-0.322117 -0.253903,-0.469911 -0.253904,-0.151584 -0.792027,-0.151584 -0.435805,0 -0.810976,0.08716 -0.375171,0.08716 -0.697287,0.261483 v -1.034562 q 0.435805,-0.106109 0.875399,-0.159163 0.439594,-0.05684 0.879188,-0.05684 1.14825,0 1.656057,0.454752 0.511597,0.450963 0.511597,1.470367 z" /> + <path + id="path1258" + style="fill:#000000;stroke-width:0.105503" + d="m 92.148702,75.662029 q -0.178112,-0.08337 -0.356223,-0.121267 -0.174322,-0.04169 -0.352433,-0.04169 -0.522966,0 -0.807186,0.337275 -0.280431,0.333485 -0.280431,0.95877 v 1.955436 H 88.995751 V 74.5062 h 1.356678 v 0.697287 q 0.261483,-0.416856 0.598758,-0.606336 0.341064,-0.19327 0.814765,-0.19327 0.06821,0 0.147794,0.0076 0.07958,0.0038 0.231166,0.02274 z" /> + <path + id="path1260" + style="fill:#000000;stroke-width:0.105503" + d="m 94.725633,76.840596 q -0.424436,0 -0.640444,0.144005 -0.212217,0.144005 -0.212217,0.424436 0,0.257693 0.170532,0.405488 0.174322,0.144005 0.48128,0.144005 0.38275,0 0.644232,-0.272852 0.261483,-0.276641 0.261483,-0.689708 V 76.840596 Z M 96.798546,76.329 v 2.421557 h -1.368047 v -0.629074 q -0.272852,0.386539 -0.613916,0.564651 -0.341064,0.174321 -0.829923,0.174321 -0.659391,0 -1.072458,-0.38275 -0.409278,-0.386539 -0.409278,-1.000455 0,-0.746552 0.511597,-1.095196 0.515386,-0.348643 1.614371,-0.348643 h 0.799607 v -0.106109 q 0,-0.322117 -0.253904,-0.469911 -0.253903,-0.151584 -0.792027,-0.151584 -0.435804,0 -0.810975,0.08716 -0.375171,0.08716 -0.697287,0.261483 v -1.034562 q 0.435804,-0.106109 0.875398,-0.159163 0.439594,-0.05684 0.879188,-0.05684 1.148251,0 1.656058,0.454752 0.511596,0.450963 0.511596,1.470367 z" /> + <path + id="path1262" + style="fill:#000000;stroke-width:0.105503" + d="m 101.99409,75.211066 q 0.2577,-0.394118 0.61013,-0.598757 0.35622,-0.208428 0.78066,-0.208428 0.73139,0 1.11414,0.450963 0.38275,0.450963 0.38275,1.311203 v 2.58451 h -1.36426 v -2.213129 q 0.004,-0.04927 0.004,-0.102319 0.004,-0.05306 0.004,-0.151585 0,-0.450962 -0.13263,-0.651811 -0.13264,-0.204639 -0.42823,-0.204639 -0.38654,0 -0.59876,0.318327 -0.20842,0.318326 -0.216,0.920874 v 2.084282 h -1.36426 v -2.213129 q 0,-0.704866 -0.12127,-0.905715 -0.12126,-0.204639 -0.43201,-0.204639 -0.390332,0 -0.602549,0.322116 -0.212218,0.318327 -0.212218,0.913295 v 2.088072 H 98.052905 V 74.5062 h 1.364258 v 0.621495 q 0.250114,-0.360012 0.57223,-0.541913 0.325907,-0.181901 0.716237,-0.181901 0.43959,0 0.77687,0.212218 0.33727,0.212217 0.51159,0.594967 z" /> + <path + id="path1264" + style="fill:#000000;stroke-width:0.105503" + d="m 110.38428,76.61701 v 0.386539 h -3.1719 q 0.0493,0.47749 0.34485,0.716236 0.29559,0.238745 0.82614,0.238745 0.42822,0 0.8754,-0.125057 0.45096,-0.128847 0.92466,-0.38654 v 1.045931 q -0.48128,0.181901 -0.96256,0.272851 -0.48128,0.09474 -0.96256,0.09474 -1.15204,0 -1.79248,-0.583599 -0.63666,-0.587388 -0.63666,-1.644688 0,-1.038352 0.62529,-1.633319 0.62907,-0.594968 1.72806,-0.594968 1.00045,0 1.59921,0.602547 0.60255,0.602547 0.60255,1.610582 z m -1.39458,-0.450963 q 0,-0.38654 -0.22737,-0.621495 -0.22359,-0.238745 -0.58739,-0.238745 -0.39412,0 -0.64044,0.223586 -0.24633,0.219797 -0.30696,0.636654 z" /> + <path + id="path1266" + style="fill:#000000;stroke-width:0.105503" + d="M 112.893,73.301106 V 74.5062 h 1.39836 v 0.970139 H 112.893 v 1.800062 q 0,0.295589 0.11747,0.401698 0.11748,0.102319 0.46613,0.102319 h 0.69728 v 0.970139 h -1.16341 q -0.80339,0 -1.14067,-0.333485 -0.33348,-0.337275 -0.33348,-1.140671 v -1.800062 h -0.67455 V 74.5062 h 0.67455 v -1.205094 z" /> + <path + id="path1268" + style="fill:#000000;stroke-width:0.105503" + d="m 119.35806,76.61701 v 0.386539 h -3.1719 q 0.0493,0.47749 0.34486,0.716236 0.29558,0.238745 0.82613,0.238745 0.42822,0 0.8754,-0.125057 0.45096,-0.128847 0.92466,-0.38654 v 1.045931 q -0.48128,0.181901 -0.96256,0.272851 -0.48128,0.09474 -0.96256,0.09474 -1.15204,0 -1.79248,-0.583599 -0.63665,-0.587388 -0.63665,-1.644688 0,-1.038352 0.62528,-1.633319 0.62908,-0.594968 1.72806,-0.594968 1.00046,0 1.59921,0.602547 0.60255,0.602547 0.60255,1.610582 z m -1.39457,-0.450963 q 0,-0.38654 -0.22738,-0.621495 -0.22359,-0.238745 -0.58739,-0.238745 -0.39412,0 -0.64044,0.223586 -0.24633,0.219797 -0.30696,0.636654 z" /> + <path + id="path1270" + style="fill:#000000;stroke-width:0.105503" + d="m 123.53799,75.662029 q -0.17811,-0.08337 -0.35622,-0.121267 -0.17432,-0.04169 -0.35243,-0.04169 -0.52297,0 -0.80719,0.337275 -0.28043,0.333485 -0.28043,0.95877 v 1.955436 h -1.35668 V 74.5062 h 1.35668 v 0.697287 q 0.26148,-0.416856 0.59876,-0.606336 0.34106,-0.19327 0.81476,-0.19327 0.0682,0 0.1478,0.0076 0.0796,0.0038 0.23116,0.02274 z" /> + <path + id="path1272" + style="fill:#000000;stroke-width:0.105503" + d="m 127.52845,74.638836 v 1.030773 q -0.4358,-0.181901 -0.84129,-0.272852 -0.40549,-0.09095 -0.7655,-0.09095 -0.38654,0 -0.57602,0.09853 -0.18569,0.09474 -0.18569,0.295589 0,0.162953 0.14021,0.250114 0.14401,0.08716 0.5116,0.128847 l 0.23874,0.03411 q 1.04215,0.132636 1.40216,0.435805 0.36001,0.303168 0.36001,0.95119 0,0.67834 -0.50023,1.019404 -0.50023,0.341064 -1.4931,0.341064 -0.42065,0 -0.87161,-0.06821 -0.44717,-0.06442 -0.92087,-0.19706 v -1.030772 q 0.40548,0.197059 0.82992,0.295589 0.42822,0.09853 0.86782,0.09853 0.39791,0 0.59876,-0.109899 0.20084,-0.109898 0.20084,-0.325906 0,-0.181901 -0.14021,-0.269062 -0.13643,-0.09095 -0.54949,-0.140215 l -0.23875,-0.03032 q -0.90571,-0.113688 -1.26952,-0.420646 -0.3638,-0.306958 -0.3638,-0.932243 0,-0.674549 0.46233,-1.000455 0.46234,-0.325906 1.41732,-0.325906 0.37517,0 0.78823,0.05684 0.41307,0.05684 0.89814,0.178111 z" /> + <path + id="path1274" + style="fill:#000000;stroke-width:0.105503" + d="m 133.43644,76.840596 q -0.42443,0 -0.64044,0.144005 -0.21222,0.144005 -0.21222,0.424436 0,0.257693 0.17053,0.405488 0.17432,0.144005 0.48128,0.144005 0.38275,0 0.64424,-0.272852 0.26148,-0.276641 0.26148,-0.689708 V 76.840596 Z M 135.50935,76.329 v 2.421557 h -1.36804 v -0.629074 q -0.27285,0.386539 -0.61392,0.564651 -0.34106,0.174321 -0.82992,0.174321 -0.65939,0 -1.07246,-0.38275 -0.40928,-0.386539 -0.40928,-1.000455 0,-0.746552 0.5116,-1.095196 0.51539,-0.348643 1.61437,-0.348643 h 0.79961 v -0.106109 q 0,-0.322117 -0.25391,-0.469911 -0.2539,-0.151584 -0.79202,-0.151584 -0.43581,0 -0.81098,0.08716 -0.37517,0.08716 -0.69729,0.261483 v -1.034562 q 0.43581,-0.106109 0.8754,-0.159163 0.4396,-0.05684 0.87919,-0.05684 1.14825,0 1.65606,0.454752 0.51159,0.450963 0.51159,1.470367 z" /> + <path + id="path1276" + style="fill:#000000;stroke-width:0.105503" + d="m 141.03839,76.166047 v 2.58451 h -1.36426 v -0.420646 -1.557528 q 0,-0.549492 -0.0265,-0.75792 -0.0227,-0.208429 -0.0834,-0.306958 -0.0796,-0.132637 -0.21601,-0.204639 -0.13642,-0.07579 -0.31074,-0.07579 -0.42444,0 -0.66697,0.329695 -0.24254,0.325906 -0.24254,0.905716 v 2.088072 h -1.35668 V 74.5062 h 1.35668 v 0.621495 q 0.30696,-0.371381 0.65181,-0.545703 0.34486,-0.178111 0.76171,-0.178111 0.73519,0 1.11415,0.450963 0.38275,0.450963 0.38275,1.311203 z" /> + <path + id="path1278" + style="fill:#000000;stroke-width:0.105503" + d="m 145.18421,75.127695 v -2.273763 h 1.36426 v 5.896625 h -1.36426 v -0.613916 q -0.28043,0.375171 -0.6177,0.549493 -0.33728,0.174321 -0.78066,0.174321 -0.78445,0 -1.28847,-0.621495 -0.50401,-0.625284 -0.50401,-1.606792 0,-0.981507 0.50401,-1.603003 0.50402,-0.625284 1.28847,-0.625284 0.43959,0 0.77687,0.178111 0.34106,0.174322 0.62149,0.545703 z m -0.89434,2.747463 q 0.4358,0 0.66318,-0.318326 0.23116,-0.318327 0.23116,-0.924664 0,-0.606337 -0.23116,-0.924663 -0.22738,-0.318327 -0.66318,-0.318327 -0.43202,0 -0.66318,0.318327 -0.22738,0.318326 -0.22738,0.924663 0,0.606337 0.22738,0.924664 0.23116,0.318326 0.66318,0.318326 z" /> + <path + id="path1280" + style="fill:#000000;stroke-width:0.105503" + d="m 82.276782,82.972176 v 1.197515 q -0.466121,-0.208428 -0.909505,-0.314537 -0.443383,-0.106109 -0.837502,-0.106109 -0.522966,0 -0.773079,0.144005 -0.250114,0.144005 -0.250114,0.447173 0,0.227377 0.166742,0.356223 0.170532,0.125057 0.613916,0.216008 l 0.621495,0.125057 q 0.943612,0.18948 1.34152,0.57602 0.397909,0.386539 0.397909,1.098985 0,0.936032 -0.557072,1.394574 -0.553282,0.454753 -1.693953,0.454753 -0.538124,0 -1.080038,-0.10232 -0.541913,-0.102319 -1.083826,-0.303168 v -1.231621 q 0.541913,0.28801 1.04593,0.435804 0.507807,0.144005 0.977718,0.144005 0.47749,0 0.731394,-0.159163 0.253903,-0.159164 0.253903,-0.454753 0,-0.265272 -0.174321,-0.409277 -0.170533,-0.144005 -0.685919,-0.257693 L 79.817329,86.0986 q -0.848871,-0.181901 -1.24299,-0.57981 -0.390329,-0.397908 -0.390329,-1.072458 0,-0.845081 0.545703,-1.299834 0.545703,-0.454752 1.568896,-0.454752 0.466121,0 0.95877,0.072 0.492648,0.06821 1.019403,0.208428 z" /> + <path + id="path1282" + style="fill:#000000;stroke-width:0.105503" + d="m 85.350152,83.002493 v 1.205094 h 1.398364 v 0.970139 h -1.398364 v 1.800062 q 0,0.295589 0.117477,0.401698 0.117478,0.10232 0.466122,0.10232 h 0.697287 v 0.970138 h -1.163409 q -0.803396,0 -1.140671,-0.333485 -0.333485,-0.337275 -0.333485,-1.140671 v -1.800062 h -0.674549 v -0.970139 h 0.674549 v -1.205094 z" /> + <path + id="path1284" + style="fill:#000000;stroke-width:0.105503" + d="m 89.598298,85.075407 q -0.450963,0 -0.689708,0.325906 -0.234955,0.322116 -0.234955,0.932242 0,0.610127 0.234955,0.936033 0.238745,0.322116 0.689708,0.322116 0.443384,0 0.678339,-0.322116 0.234956,-0.325906 0.234956,-0.936033 0,-0.610126 -0.234956,-0.932242 -0.234955,-0.325906 -0.678339,-0.325906 z m 0,-0.970139 q 1.095196,0 1.709112,0.591178 0.617705,0.591179 0.617705,1.637109 0,1.045931 -0.617705,1.637109 -0.613916,0.591179 -1.709112,0.591179 -1.098985,0 -1.72048,-0.591179 -0.617706,-0.591178 -0.617706,-1.637109 0,-1.04593 0.617706,-1.637109 0.621495,-0.591178 1.72048,-0.591178 z" /> + <path + id="path1286" + style="fill:#000000;stroke-width:0.105503" + d="m 96.063363,85.363417 q -0.178111,-0.08337 -0.356223,-0.121268 -0.174322,-0.04169 -0.352433,-0.04169 -0.522965,0 -0.807186,0.337274 -0.28043,0.333486 -0.28043,0.95877 v 1.955436 h -1.356679 v -4.244357 h 1.356679 v 0.697288 q 0.261482,-0.416857 0.598757,-0.606337 0.341064,-0.19327 0.814765,-0.19327 0.06821,0 0.147795,0.0076 0.07958,0.0038 0.231165,0.02274 z" /> + <path + id="path1288" + style="fill:#000000;stroke-width:0.105503" + d="m 98.640295,86.541984 q -0.424436,0 -0.640443,0.144005 -0.212218,0.144005 -0.212218,0.424435 0,0.257693 0.170532,0.405488 0.174322,0.144005 0.48128,0.144005 0.38275,0 0.644233,-0.272852 0.261482,-0.276641 0.261482,-0.689708 v -0.155373 z m 2.072915,-0.511597 v 2.421557 H 99.345161 V 87.82287 q -0.272851,0.38654 -0.613916,0.564651 -0.341064,0.174322 -0.829923,0.174322 -0.659391,0 -1.072458,-0.38275 -0.409277,-0.38654 -0.409277,-1.000456 0,-0.746552 0.511596,-1.095196 0.515387,-0.348643 1.614372,-0.348643 h 0.799606 v -0.106109 q 0,-0.322116 -0.253903,-0.469911 -0.253904,-0.151584 -0.792027,-0.151584 -0.435805,0 -0.810976,0.08716 -0.375171,0.08716 -0.697287,0.261482 v -1.034562 q 0.435804,-0.106108 0.875399,-0.159163 0.439594,-0.05684 0.879188,-0.05684 1.14825,0 1.656055,0.454753 0.5116,0.450962 0.5116,1.470366 z" /> + <path + id="path1290" + style="fill:#000000;stroke-width:0.105503" + d="m 104.86282,87.731919 q -0.28043,0.371382 -0.6177,0.545703 -0.33728,0.174322 -0.78066,0.174322 -0.77687,0 -1.28468,-0.610126 -0.5078,-0.613916 -0.5078,-1.561317 0,-0.951191 0.5078,-1.557528 0.50781,-0.610126 1.28468,-0.610126 0.44338,0 0.78066,0.174322 0.33727,0.174322 0.6177,0.549493 v -0.629075 h 1.36426 v 3.816132 q 0,1.023193 -0.64802,1.561317 -0.64423,0.541913 -1.87207,0.541913 -0.3979,0 -0.76928,-0.06063 -0.37139,-0.06063 -0.74656,-0.185691 v -1.0573 q 0.35623,0.204639 0.69729,0.303169 0.34106,0.102319 0.68592,0.102319 0.66697,0 0.97772,-0.291799 0.31074,-0.2918 0.31074,-0.913295 z m -0.89434,-2.641354 q -0.42065,0 -0.6556,0.310748 -0.23496,0.310747 -0.23496,0.879188 0,0.583599 0.22738,0.886767 0.22737,0.299379 0.66318,0.299379 0.42443,0 0.65939,-0.310747 0.23495,-0.310748 0.23495,-0.875399 0,-0.568441 -0.23495,-0.879188 -0.23496,-0.310748 -0.65939,-0.310748 z" /> + <path + id="path1292" + style="fill:#000000;stroke-width:0.105503" + d="m 111.76748,86.318397 v 0.38654 h -3.17189 q 0.0493,0.47749 0.34485,0.716235 0.29559,0.238745 0.82613,0.238745 0.42823,0 0.8754,-0.125057 0.45096,-0.128847 0.92467,-0.38654 v 1.045931 q -0.48128,0.181901 -0.96256,0.272852 -0.48128,0.09474 -0.96256,0.09474 -1.15204,0 -1.79249,-0.583599 -0.63665,-0.587389 -0.63665,-1.644689 0,-1.038351 0.62528,-1.633319 0.62908,-0.594968 1.72806,-0.594968 1.00046,0 1.59922,0.602547 0.60254,0.602547 0.60254,1.610582 z m -1.39457,-0.450963 q 0,-0.38654 -0.22738,-0.621495 -0.22358,-0.238745 -0.58738,-0.238745 -0.39412,0 -0.64045,0.223586 -0.24632,0.219798 -0.30696,0.636654 z" /> + <path + id="path1294" + style="fill:#000000;stroke-width:0.105503" + d="m 117.51631,85.075407 q -0.45096,0 -0.6897,0.325906 -0.23496,0.322116 -0.23496,0.932242 0,0.610127 0.23496,0.936033 0.23874,0.322116 0.6897,0.322116 0.44339,0 0.67834,-0.322116 0.23496,-0.325906 0.23496,-0.936033 0,-0.610126 -0.23496,-0.932242 -0.23495,-0.325906 -0.67834,-0.325906 z m 0,-0.970139 q 1.0952,0 1.70912,0.591178 0.6177,0.591179 0.6177,1.637109 0,1.045931 -0.6177,1.637109 -0.61392,0.591179 -1.70912,0.591179 -1.09898,0 -1.72048,-0.591179 -0.6177,-0.591178 -0.6177,-1.637109 0,-1.04593 0.6177,-1.637109 0.6215,-0.591178 1.72048,-0.591178 z" /> + <path + id="path1296" + style="fill:#000000;stroke-width:0.105503" + d="m 122.18511,87.838028 v 2.228288 h -1.35668 v -5.858729 h 1.35668 v 0.621495 q 0.28043,-0.371381 0.62149,-0.545703 0.34107,-0.178111 0.78445,-0.178111 0.78445,0 1.28847,0.625285 0.50401,0.621495 0.50401,1.603002 0,0.981508 -0.50401,1.606793 -0.50402,0.621495 -1.28847,0.621495 -0.44338,0 -0.78445,-0.174322 -0.34106,-0.178111 -0.62149,-0.549493 z m 0.90192,-2.747463 q -0.4358,0 -0.67076,0.322116 -0.23116,0.318327 -0.23116,0.920874 0,0.602547 0.23116,0.924664 0.23496,0.318327 0.67076,0.318327 0.43581,0 0.66318,-0.318327 0.23117,-0.318327 0.23117,-0.924664 0,-0.606336 -0.23117,-0.924663 -0.22737,-0.318327 -0.66318,-0.318327 z" /> + <path + id="path1298" + style="fill:#000000;stroke-width:0.105503" + d="m 127.86573,83.002493 v 1.205094 h 1.39836 v 0.970139 h -1.39836 v 1.800062 q 0,0.295589 0.11747,0.401698 0.11748,0.10232 0.46612,0.10232 h 0.69729 v 0.970138 h -1.16341 q -0.80339,0 -1.14067,-0.333485 -0.33348,-0.337275 -0.33348,-1.140671 v -1.800062 h -0.67455 v -0.970139 h 0.67455 v -1.205094 z" /> + <path + id="path1300" + style="fill:#000000;stroke-width:0.105503" + d="m 130.09401,84.207587 h 1.35668 v 4.244357 h -1.35668 z m 0,-1.652267 h 1.35668 v 1.106564 h -1.35668 z" /> + <path + id="path1302" + style="fill:#000000;stroke-width:0.105503" + d="m 134.77417,85.075407 q -0.45096,0 -0.68971,0.325906 -0.23495,0.322116 -0.23495,0.932242 0,0.610127 0.23495,0.936033 0.23875,0.322116 0.68971,0.322116 0.44339,0 0.67834,-0.322116 0.23496,-0.325906 0.23496,-0.936033 0,-0.610126 -0.23496,-0.932242 -0.23495,-0.325906 -0.67834,-0.325906 z m 0,-0.970139 q 1.0952,0 1.70911,0.591178 0.61771,0.591179 0.61771,1.637109 0,1.045931 -0.61771,1.637109 -0.61391,0.591179 -1.70911,0.591179 -1.09898,0 -1.72048,-0.591179 -0.6177,-0.591178 -0.6177,-1.637109 0,-1.04593 0.6177,-1.637109 0.6215,-0.591178 1.72048,-0.591178 z" /> + <path + id="path1304" + style="fill:#000000;stroke-width:0.105503" + d="m 142.35338,85.867434 v 2.58451 h -1.36426 v -0.420646 -1.557527 q 0,-0.549493 -0.0265,-0.757921 -0.0227,-0.208428 -0.0834,-0.306958 -0.0796,-0.132636 -0.21601,-0.204639 -0.13643,-0.07579 -0.31075,-0.07579 -0.42444,0 -0.66697,0.329696 -0.24253,0.325906 -0.24253,0.905715 v 2.088072 h -1.35668 v -4.244357 h 1.35668 v 0.621495 q 0.30695,-0.371381 0.65181,-0.545703 0.34485,-0.178111 0.76171,-0.178111 0.73518,0 1.11414,0.450963 0.38275,0.450963 0.38275,1.311203 z" /> + <path + id="path1306" + style="fill:#000000;stroke-width:0.105503" + d="m 146.92743,84.340223 v 1.030773 q -0.4358,-0.181901 -0.84129,-0.272852 -0.40549,-0.09095 -0.7655,-0.09095 -0.38654,0 -0.57602,0.09853 -0.18569,0.09474 -0.18569,0.295589 0,0.162953 0.14022,0.250114 0.144,0.08716 0.51159,0.128846 l 0.23875,0.03411 q 1.04214,0.132636 1.40215,0.435804 0.36001,0.303168 0.36001,0.951191 0,0.678339 -0.50022,1.019403 -0.50023,0.341065 -1.49311,0.341065 -0.42065,0 -0.87161,-0.06821 -0.44717,-0.06442 -0.92087,-0.19706 v -1.030772 q 0.40549,0.197059 0.82992,0.295589 0.42823,0.09853 0.86782,0.09853 0.39791,0 0.59876,-0.109899 0.20085,-0.109898 0.20085,-0.325906 0,-0.181901 -0.14022,-0.269062 -0.13642,-0.09095 -0.54949,-0.140215 l -0.23875,-0.03032 q -0.90571,-0.113688 -1.26951,-0.420646 -0.36381,-0.306958 -0.36381,-0.932242 0,-0.67455 0.46234,-1.000456 0.46233,-0.325906 1.41731,-0.325906 0.37517,0 0.78824,0.05684 0.41306,0.05684 0.89813,0.178111 z" /> + </g> + <g + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:7.72103px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke-width:0.105503" + id="text1939" + aria-label="Value Space and +Behaviour"> + <path + id="path1209" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -41.05733,73.092678 h 1.466577 l 1.500683,4.176144 1.496894,-4.176144 h 1.466577 l -2.095652,5.657879 h -1.739428 z" /> + <path + id="path1211" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -32.958945,76.840596 q -0.424436,0 -0.640444,0.144005 -0.212217,0.144005 -0.212217,0.424436 0,0.257693 0.170532,0.405488 0.174322,0.144005 0.48128,0.144005 0.38275,0 0.644232,-0.272852 0.261483,-0.276641 0.261483,-0.689708 V 76.840596 Z M -30.886032,76.329 v 2.421557 h -1.368047 v -0.629074 q -0.272851,0.386539 -0.613916,0.564651 -0.341064,0.174321 -0.829923,0.174321 -0.659391,0 -1.072458,-0.38275 -0.409278,-0.386539 -0.409278,-1.000455 0,-0.746552 0.511597,-1.095196 0.515386,-0.348643 1.614371,-0.348643 h 0.799607 v -0.106109 q 0,-0.322117 -0.253903,-0.469911 -0.253904,-0.151584 -0.792028,-0.151584 -0.435804,0 -0.810975,0.08716 -0.375171,0.08716 -0.697287,0.261483 v -1.034562 q 0.435804,-0.106109 0.875398,-0.159163 0.439594,-0.05684 0.879188,-0.05684 1.148251,0 1.656058,0.454752 0.511596,0.450963 0.511596,1.470367 z" /> + <path + id="path1213" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -29.624094,72.853932 h 1.356679 v 5.896625 h -1.356679 z" /> + <path + id="path1215" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="M -27.009267,77.098289 V 74.5062 h 1.364258 v 0.424436 q 0,0.344854 -0.0038,0.867819 -0.0038,0.519176 -0.0038,0.693498 0,0.511596 0.02653,0.738973 0.02653,0.223586 0.09095,0.325906 0.08337,0.132636 0.216008,0.204638 0.136426,0.072 0.310747,0.072 0.424436,0 0.666971,-0.325906 0.242534,-0.325906 0.242534,-0.905716 V 74.5062 h 1.356679 v 4.244357 h -1.356679 v -0.613916 q -0.306958,0.371381 -0.651812,0.549493 -0.341064,0.174321 -0.754131,0.174321 -0.735183,0 -1.121723,-0.450962 -0.38275,-0.450963 -0.38275,-1.311204 z" /> + <path + id="path1217" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -17.201771,76.61701 v 0.386539 h -3.171899 q 0.04927,0.47749 0.344854,0.716236 0.295589,0.238745 0.826134,0.238745 0.428225,0 0.875399,-0.125057 0.450962,-0.128847 0.924663,-0.38654 v 1.045931 q -0.48128,0.181901 -0.96256,0.272851 -0.481279,0.09474 -0.962559,0.09474 -1.15204,0 -1.792483,-0.583599 -0.636653,-0.587388 -0.636653,-1.644688 0,-1.038352 0.625284,-1.633319 0.629075,-0.594968 1.72806,-0.594968 1.000455,0 1.599213,0.602547 0.602547,0.602547 0.602547,1.610582 z m -1.394574,-0.450963 q 0,-0.38654 -0.227377,-0.621495 -0.223586,-0.238745 -0.587388,-0.238745 -0.394119,0 -0.640443,0.223586 -0.246325,0.219797 -0.306958,0.636654 z" /> + <path + id="path1219" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -9.4747663,73.270789 v 1.197515 q -0.4661213,-0.208428 -0.9095047,-0.314537 -0.443384,-0.106109 -0.837503,-0.106109 -0.522965,0 -0.773079,0.144005 -0.250114,0.144005 -0.250114,0.447173 0,0.227376 0.166742,0.356223 0.170533,0.125057 0.613916,0.216007 l 0.621496,0.125057 q 0.943611,0.189481 1.3415195,0.57602 0.3979084,0.38654 0.3979084,1.098986 0,0.936032 -0.5570718,1.394574 -0.5532821,0.454752 -1.6939531,0.454752 -0.538124,0 -1.080037,-0.102319 -0.541914,-0.102319 -1.083827,-0.303168 v -1.231622 q 0.541913,0.28801 1.045931,0.435805 0.507807,0.144005 0.977718,0.144005 0.47749,0 0.731393,-0.159164 0.253904,-0.159163 0.253904,-0.454752 0,-0.265272 -0.174322,-0.409277 -0.170532,-0.144005 -0.685918,-0.257693 l -0.564652,-0.125057 q -0.848871,-0.181901 -1.24299,-0.57981 -0.390329,-0.397908 -0.390329,-1.072458 0,-0.845082 0.545703,-1.299834 0.545703,-0.454753 1.568896,-0.454753 0.466122,0 0.95877,0.072 0.492649,0.06821 1.0194037,0.208428 z" /> + <path + id="path1221" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -6.5264561,78.136641 v 2.228287 H -7.8831345 V 74.5062 h 1.3566784 v 0.621495 q 0.2804307,-0.371381 0.6214951,-0.545703 0.3410644,-0.178111 0.7844481,-0.178111 0.7844481,0 1.2884655,0.625284 0.5040174,0.621496 0.5040174,1.603003 0,0.981508 -0.5040174,1.606792 -0.5040174,0.621495 -1.2884655,0.621495 -0.4433837,0 -0.7844481,-0.174321 -0.3410644,-0.178112 -0.6214951,-0.549493 z m 0.9019258,-2.747463 q -0.4358045,0 -0.6707599,0.322116 -0.2311659,0.318327 -0.2311659,0.920874 0,0.602547 0.2311659,0.924664 0.2349554,0.318326 0.6707599,0.318326 0.4358046,0 0.6631808,-0.318326 0.2311659,-0.318327 0.2311659,-0.924664 0,-0.606337 -0.2311659,-0.924663 -0.2273762,-0.318327 -0.6631808,-0.318327 z" /> + <path + id="path1223" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -0.425192,76.840596 q -0.4244357,0 -0.6404431,0.144005 -0.2122179,0.144005 -0.2122179,0.424436 0,0.257693 0.1705322,0.405488 0.1743218,0.144005 0.48127976,0.144005 0.38275005,0 0.64423275,-0.272852 0.26148271,-0.276641 0.26148271,-0.689708 V 76.840596 Z M 1.6477216,76.329 v 2.421557 H 0.27967442 v -0.629074 q -0.27285152,0.386539 -0.61391592,0.564651 -0.3410644,0.174321 -0.8299234,0.174321 -0.6593911,0 -1.072458,-0.38275 -0.4092773,-0.386539 -0.4092773,-1.000455 0,-0.746552 0.5115966,-1.095196 0.5153862,-0.348643 1.61437149,-0.348643 h 0.79960653 v -0.106109 q 0,-0.322117 -0.2539035,-0.469911 -0.2539035,-0.151584 -0.79202732,-0.151584 -0.4358045,0 -0.8109753,0.08716 -0.3751709,0.08716 -0.6972873,0.261483 v -1.034562 q 0.4358046,-0.106109 0.8753987,-0.159163 0.43959407,-0.05684 0.87918819,-0.05684 1.14825013,0 1.65605711,0.454752 0.5115966,0.450963 0.5115966,1.470367 z" /> + <path + id="path1225" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m 6.3392508,74.638836 v 1.106565 Q 6.0626097,75.55592 5.7821789,75.46497 q -0.2766411,-0.09095 -0.5760198,-0.09095 -0.5684407,0 -0.8867675,0.333486 -0.3145371,0.329695 -0.3145371,0.924663 0,0.594968 0.3145371,0.928453 0.3183268,0.329696 0.8867675,0.329696 0.3183267,0 0.6025471,-0.09474 0.2880099,-0.09474 0.5305446,-0.280431 V 78.6255 q -0.3183268,0.117478 -0.6480224,0.174322 -0.325906,0.06063 -0.6556015,0.06063 -1.1482502,0 -1.7962725,-0.587388 -0.6480224,-0.591178 -0.6480224,-1.640899 0,-1.04972 0.6480224,-1.637109 0.6480223,-0.591178 1.7962725,-0.591178 0.3334852,0 0.6556015,0.06063 0.325906,0.05684 0.6480224,0.174322 z" /> + <path + id="path1227" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m 11.747019,76.61701 v 0.386539 H 8.5751198 q 0.049265,0.47749 0.344854,0.716236 0.2955891,0.238745 0.8261337,0.238745 0.4282255,0 0.8753985,-0.125057 0.450963,-0.128847 0.924664,-0.38654 v 1.045931 q -0.48128,0.181901 -0.96256,0.272851 -0.48128,0.09474 -0.9625594,0.09474 -1.1520398,0 -1.7924829,-0.583599 -0.6366536,-0.587388 -0.6366536,-1.644688 0,-1.038352 0.6252848,-1.633319 0.6290743,-0.594968 1.7280596,-0.594968 1.0004555,0 1.5992135,0.602547 0.602547,0.602547 0.602547,1.610582 z m -1.394575,-0.450963 q 0,-0.38654 -0.227376,-0.621495 -0.2235867,-0.238745 -0.5873887,-0.238745 -0.3941189,0 -0.6404432,0.223586 -0.2463243,0.219797 -0.3069579,0.636654 z" /> + <path + id="path1229" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m 17.37837,76.840596 q -0.424436,0 -0.640443,0.144005 -0.212218,0.144005 -0.212218,0.424436 0,0.257693 0.170532,0.405488 0.174322,0.144005 0.48128,0.144005 0.38275,0 0.644233,-0.272852 0.261483,-0.276641 0.261483,-0.689708 V 76.840596 Z M 19.451284,76.329 v 2.421557 h -1.368047 v -0.629074 q -0.272852,0.386539 -0.613916,0.564651 -0.341065,0.174321 -0.829924,0.174321 -0.659391,0 -1.072458,-0.38275 -0.409277,-0.386539 -0.409277,-1.000455 0,-0.746552 0.511597,-1.095196 0.515386,-0.348643 1.614371,-0.348643 h 0.799607 v -0.106109 q 0,-0.322117 -0.253904,-0.469911 -0.253903,-0.151584 -0.792027,-0.151584 -0.435805,0 -0.810976,0.08716 -0.37517,0.08716 -0.697287,0.261483 v -1.034562 q 0.435805,-0.106109 0.875399,-0.159163 0.439594,-0.05684 0.879188,-0.05684 1.14825,0 1.656057,0.454752 0.511597,0.450963 0.511597,1.470367 z" /> + <path + id="path1231" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m 24.980316,76.166047 v 2.58451 h -1.364258 v -0.420646 -1.557528 q 0,-0.549492 -0.02653,-0.75792 -0.02274,-0.208429 -0.08337,-0.306958 -0.07958,-0.132637 -0.216007,-0.204639 -0.136426,-0.07579 -0.310748,-0.07579 -0.424435,0 -0.66697,0.329695 -0.242535,0.325906 -0.242535,0.905716 v 2.088072 H 20.713221 V 74.5062 h 1.356678 v 0.621495 q 0.306958,-0.371381 0.651812,-0.545703 0.344854,-0.178111 0.761711,-0.178111 0.735183,0 1.114143,0.450963 0.382751,0.450963 0.382751,1.311203 z" /> + <path + id="path1233" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m 29.126141,75.127695 v -2.273763 h 1.364258 v 5.896625 h -1.364258 v -0.613916 q -0.28043,0.375171 -0.617705,0.549493 -0.337275,0.174321 -0.780659,0.174321 -0.784448,0 -1.288465,-0.621495 -0.504018,-0.625284 -0.504018,-1.606792 0,-0.981507 0.504018,-1.603003 0.504017,-0.625284 1.288465,-0.625284 0.439594,0 0.776869,0.178111 0.341065,0.174322 0.621495,0.545703 z m -0.894346,2.747463 q 0.435804,0 0.66318,-0.318326 0.231166,-0.318327 0.231166,-0.924664 0,-0.606337 -0.231166,-0.924663 -0.227376,-0.318327 -0.66318,-0.318327 -0.432015,0 -0.663181,0.318327 -0.227376,0.318326 -0.227376,0.924663 0,0.606337 0.227376,0.924664 0.231166,0.318326 0.663181,0.318326 z" /> + <path + id="path1235" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -38.116597,84.984456 q 0.344854,0 0.522965,-0.151584 0.178112,-0.151584 0.178112,-0.447173 0,-0.2918 -0.178112,-0.443384 -0.178111,-0.155374 -0.522965,-0.155374 h -0.807186 v 1.197515 z m 0.04926,2.474612 q 0.439594,0 0.659391,-0.185691 0.223586,-0.18569 0.223586,-0.560861 0,-0.367592 -0.219797,-0.549493 -0.219797,-0.18569 -0.66318,-0.18569 h -0.856451 v 1.481735 z m 1.356678,-2.035018 q 0.469911,0.136426 0.727604,0.504018 0.257693,0.367591 0.257693,0.901926 0,0.818554 -0.553282,1.220252 -0.553282,0.401698 -1.682584,0.401698 h -2.421558 v -5.657879 h 2.190392 q 1.178567,0 1.705322,0.356223 0.530544,0.356222 0.530544,1.140671 0,0.413066 -0.19327,0.704866 -0.193269,0.28801 -0.560861,0.428225 z" /> + <path + id="path1237" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -30.291064,86.318397 v 0.38654 h -3.171899 q 0.04927,0.47749 0.344854,0.716235 0.295589,0.238745 0.826134,0.238745 0.428225,0 0.875399,-0.125057 0.450962,-0.128847 0.924663,-0.38654 v 1.045931 q -0.48128,0.181901 -0.96256,0.272852 -0.481279,0.09474 -0.962559,0.09474 -1.15204,0 -1.792483,-0.583599 -0.636653,-0.587389 -0.636653,-1.644689 0,-1.038351 0.625284,-1.633319 0.629075,-0.594968 1.72806,-0.594968 1.000455,0 1.599213,0.602547 0.602547,0.602547 0.602547,1.610582 z m -1.394574,-0.450963 q 0,-0.38654 -0.227377,-0.621495 -0.223586,-0.238745 -0.587388,-0.238745 -0.394119,0 -0.640443,0.223586 -0.246325,0.219798 -0.306958,0.636654 z" /> + <path + id="path1239" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -24.996987,85.867434 v 2.58451 h -1.364258 V 88.031298 86.48135 q 0,-0.557072 -0.02653,-0.7655 -0.02274,-0.208428 -0.08337,-0.306958 -0.07958,-0.132636 -0.216008,-0.204639 -0.136425,-0.07579 -0.310747,-0.07579 -0.424436,0 -0.666971,0.329696 -0.242534,0.325906 -0.242534,0.905715 v 2.088072 h -1.356679 V 82.55532 h 1.356679 v 2.273762 q 0.306958,-0.371381 0.651812,-0.545703 0.344854,-0.178111 0.76171,-0.178111 0.735183,0 1.114144,0.450963 0.38275,0.450963 0.38275,1.311203 z" /> + <path + id="path1241" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -21.836456,86.541984 q -0.424436,0 -0.640444,0.144005 -0.212217,0.144005 -0.212217,0.424435 0,0.257693 0.170532,0.405488 0.174322,0.144005 0.48128,0.144005 0.38275,0 0.644232,-0.272852 0.261483,-0.276641 0.261483,-0.689708 v -0.155373 z m 2.072913,-0.511597 v 2.421557 H -21.13159 V 87.82287 q -0.272852,0.38654 -0.613916,0.564651 -0.341064,0.174322 -0.829923,0.174322 -0.659391,0 -1.072458,-0.38275 -0.409278,-0.38654 -0.409278,-1.000456 0,-0.746552 0.511597,-1.095196 0.515386,-0.348643 1.614371,-0.348643 h 0.799607 v -0.106109 q 0,-0.322116 -0.253903,-0.469911 -0.253904,-0.151584 -0.792028,-0.151584 -0.435804,0 -0.810975,0.08716 -0.375171,0.08716 -0.697287,0.261482 v -1.034562 q 0.435804,-0.106108 0.875398,-0.159163 0.439594,-0.05684 0.879188,-0.05684 1.148251,0 1.656058,0.454753 0.511596,0.450962 0.511596,1.470366 z" /> + <path + id="path1243" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -19.035938,84.207587 h 1.356678 l 1.0573,2.933154 1.05351,-2.933154 h 1.360468 l -1.671215,4.244357 h -1.489315 z" /> + <path + id="path1245" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -13.442484,84.207587 h 1.356679 v 4.244357 h -1.356679 z m 0,-1.652267 h 1.356679 v 1.106564 h -1.356679 z" /> + <path + id="path1247" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -8.7623213,85.075407 q -0.4509629,0 -0.689708,0.325906 -0.2349555,0.322116 -0.2349555,0.932242 0,0.610127 0.2349555,0.936033 0.2387451,0.322116 0.689708,0.322116 0.4433837,0 0.6783392,-0.322116 0.2349555,-0.325906 0.2349555,-0.936033 0,-0.610126 -0.2349555,-0.932242 -0.2349555,-0.325906 -0.6783392,-0.325906 z m 0,-0.970139 q 1.0951957,0 1.7091116,0.591178 0.6177055,0.591179 0.6177055,1.637109 0,1.045931 -0.6177055,1.637109 -0.6139159,0.591179 -1.7091116,0.591179 -1.0989853,0 -1.7204807,-0.591179 -0.617705,-0.591178 -0.617705,-1.637109 0,-1.04593 0.617705,-1.637109 0.6214954,-0.591178 1.7204807,-0.591178 z" /> + <path + id="path1249" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -5.4956836,86.799677 v -2.59209 h 1.3642576 v 0.424436 q 0,0.344854 -0.00379,0.867819 -0.00379,0.519176 -0.00379,0.693498 0,0.511597 0.026527,0.738973 0.026527,0.223587 0.09095,0.325906 0.083371,0.132636 0.2160074,0.204638 0.1364258,0.072 0.3107476,0.072 0.4244357,0 0.6669703,-0.325906 0.2425347,-0.325906 0.2425347,-0.905715 v -2.095652 h 1.3566784 v 4.244357 h -1.3566784 v -0.613916 q -0.3069579,0.371382 -0.6518119,0.549493 -0.3410644,0.174322 -0.7541313,0.174322 -0.7351833,0 -1.1217229,-0.450963 -0.3827501,-0.450963 -0.3827501,-1.311203 z" /> + <path + id="path1251" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m 3.2279882,85.363417 q -0.1781114,-0.08337 -0.3562228,-0.121268 -0.1743218,-0.04169 -0.3524332,-0.04169 -0.5229654,0 -0.8071857,0.337274 -0.2804308,0.333486 -0.2804308,0.95877 v 1.955436 H 0.07503736 V 84.207587 H 1.4317157 v 0.697288 q 0.2614827,-0.416857 0.5987575,-0.606337 0.3410644,-0.19327 0.814765,-0.19327 0.068213,0 0.1477946,0.0076 0.079582,0.0038 0.2311658,0.02274 z" /> + </g> + <g + style="font-size:11.263px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000081;fill-opacity:1;stroke-width:0.264583" + id="text1968" + aria-label="type"> + <path + id="path1200" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#000081;fill-opacity:1;stroke-width:0.264583" + d="m -12.982713,110.86802 q -0.340778,0.22526 -0.825954,0.36965 -0.485175,0.1444 -1.051213,0.1444 -1.120524,0 -1.686562,-0.57759 -0.566038,-0.58336 -0.566038,-1.54794 v -3.08433 h -1.328456 v -1.08009 h 1.328456 v -1.34579 l 1.524837,-0.18482 v 1.53061 h 2.021564 l -0.155949,1.08009 h -1.865615 v 3.07855 q 0,0.47363 0.231036,0.69311 0.231036,0.21949 0.74509,0.21949 0.329227,0 0.600694,-0.0751 0.277243,-0.0809 0.502503,-0.20216 z" /> + <path + id="path1202" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#000081;fill-opacity:1;stroke-width:0.264583" + d="m -5.7917378,105.09212 -2.0735471,6.12823 q -0.3754333,1.12052 -1.1147482,1.76742 -0.7393148,0.65268 -2.0677709,0.74509 l -0.190605,-1.1032 q 0.612245,-0.0866 0.981903,-0.25991 0.375433,-0.17328 0.5949171,-0.4563 0.22526,-0.28302 0.3869851,-0.70466 h -0.5198308 l -2.0042364,-6.11667 h 1.611475 l 1.3862158,5.10012 1.4439743,-5.10012 z" /> + <path + id="path1204" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#000081;fill-opacity:1;stroke-width:0.264583" + d="m -1.2403471,104.91884 q 0.80284968,0 1.29380094,0.39854 0.49095126,0.39276 0.71043535,1.12052 0.22525999,0.72199 0.22525999,1.69812 0,0.94147 -0.27146716,1.67501 -0.27146717,0.73354 -0.79707382,1.15518 -0.51983075,0.41586 -1.2822492,0.41586 -0.9356953,0 -1.513285,-0.66423 v 2.84752 l -1.5248369,0.16172 v -8.63496 h 1.3400081 l 0.080863,0.74509 q 0.3581056,-0.47362 0.8086256,-0.69311 0.4562959,-0.22526 0.9299195,-0.22526 z m -0.4447441,1.14363 q -0.3869851,0 -0.6815559,0.23104 -0.2887948,0.23103 -0.5082789,0.57181 v 2.73777 q 0.4216405,0.6238 1.0743168,0.6238 0.5833657,0 0.88948821,-0.48517 0.31189844,-0.49096 0.31189844,-1.58838 0,-1.16095 -0.27724306,-1.62302 -0.27724309,-0.46785 -0.80862559,-0.46785 z" /> + <path + id="path1206" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#000081;fill-opacity:1;stroke-width:0.264583" + d="m 3.8308738,108.61542 q 0.069311,0.8606 0.508279,1.24181 0.4389681,0.38121 1.0685409,0.38121 0.4389682,0 0.8259533,-0.13862 0.3869852,-0.13862 0.7624185,-0.38698 l 0.6353487,0.87216 q -0.4274164,0.3581 -1.0223338,0.57759 -0.5891416,0.21948 -1.2995769,0.21948 -0.9934543,0 -1.6750102,-0.41009 -0.67578,-0.41009 -1.0223338,-1.13785 -0.3465538,-0.72776 -0.3465538,-1.67501 0,-0.91259 0.335002,-1.64613 0.3407779,-0.73354 0.9819025,-1.16096 0.6469005,-0.43319 1.5537164,-0.43319 1.2591456,0 1.9984604,0.82018 0.7393148,0.82018 0.7393148,2.26993 0,0.335 -0.028879,0.60647 z m 1.3111287,-2.62226 q -0.5544862,0 -0.9125918,0.39854 -0.3523297,0.39853 -0.4158646,1.24759 h 2.5760502 q -0.011552,-0.77397 -0.3176744,-1.20716 -0.3061225,-0.43897 -0.9299194,-0.43897 z" /> + </g> + <g + style="font-size:11.263px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#800000;fill-opacity:0.976587;stroke-width:0.265;stroke-miterlimit:4;stroke-dasharray:none" + id="text1972" + aria-label="instance"> + <path + id="path1183" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#800000;fill-opacity:0.976587;stroke-width:0.265;stroke-miterlimit:4;stroke-dasharray:none" + d="m 123.54934,104.04259 q 0.41586,0 0.68156,0.25991 0.26569,0.25992 0.26569,0.6469 0,0.38699 -0.26569,0.65268 -0.2657,0.25991 -0.68156,0.25991 -0.42164,0 -0.68733,-0.25991 -0.26569,-0.26569 -0.26569,-0.65268 0,-0.38698 0.26569,-0.6469 0.26569,-0.25991 0.68733,-0.25991 z m 0.98768,3.08433 v 5.03658 h 1.61147 v 1.08009 h -4.92684 v -1.08009 h 1.79053 v -3.95649 h -1.73277 v -1.08009 z" /> + <path + id="path1185" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#800000;fill-opacity:0.976587;stroke-width:0.265;stroke-miterlimit:4;stroke-dasharray:none" + d="m 127.95056,113.24359 v -6.11667 h 1.32845 l 0.10974,0.75664 q 0.7913,-0.92992 1.94071,-0.92992 0.82017,0 1.25337,0.4794 0.43896,0.47362 0.43896,1.33423 v 4.47632 h -1.52483 v -3.8814 q 0,-0.69311 -0.1444,-0.9819 -0.13862,-0.2888 -0.60069,-0.2888 -0.37544,0 -0.69889,0.23681 -0.32345,0.23681 -0.57759,0.57759 v 4.3377 z" /> + <path + id="path1187" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#800000;fill-opacity:0.976587;stroke-width:0.265;stroke-miterlimit:4;stroke-dasharray:none" + d="m 137.2093,112.29057 q 0.53716,0 0.86061,-0.18483 0.32923,-0.18483 0.32923,-0.53138 0,-0.21949 -0.10974,-0.37544 -0.10397,-0.16172 -0.41587,-0.29457 -0.3119,-0.13862 -0.93569,-0.30612 -0.58915,-0.15017 -1.03389,-0.36966 -0.43897,-0.22526 -0.68733,-0.57759 -0.24259,-0.35233 -0.24259,-0.88948 0,-0.79708 0.67001,-1.29958 0.67,-0.50828 1.87139,-0.50828 0.78552,0 1.37466,0.20793 0.58914,0.20216 1.01078,0.50828 l -0.6238,0.92992 q -0.36965,-0.23681 -0.80285,-0.38121 -0.42741,-0.15017 -0.92414,-0.15017 -0.53716,0 -0.78552,0.15595 -0.24259,0.15595 -0.24259,0.43319 0,0.19638 0.1213,0.335 0.12707,0.13285 0.45052,0.25992 0.32922,0.12129 0.93569,0.29457 0.59492,0.1675 1.03389,0.38698 0.44474,0.21949 0.68733,0.58337 0.24259,0.3581 0.24259,0.94724 0,0.66423 -0.38699,1.09743 -0.38698,0.43319 -1.02233,0.6469 -0.63535,0.20793 -1.36889,0.20793 -0.86639,0 -1.51329,-0.24837 -0.6469,-0.24836 -1.09742,-0.64112 l 0.7913,-0.88949 q 0.35811,0.28302 0.8144,0.46785 0.46207,0.18483 0.99923,0.18483 z" /> + <path + id="path1189" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#800000;fill-opacity:0.976587;stroke-width:0.265;stroke-miterlimit:4;stroke-dasharray:none" + d="m 147.09185,112.90281 q -0.34078,0.22526 -0.82596,0.36966 -0.48517,0.1444 -1.05121,0.1444 -1.12052,0 -1.68656,-0.57759 -0.56604,-0.58337 -0.56604,-1.54794 v -3.08433 h -1.32846 v -1.08009 h 1.32846 v -1.34579 l 1.52484,-0.18483 v 1.53062 h 2.02156 l -0.15595,1.08009 h -1.86561 v 3.07855 q 0,0.47363 0.23103,0.69311 0.23104,0.21948 0.74509,0.21948 0.32923,0 0.6007,-0.0751 0.27724,-0.0809 0.5025,-0.20216 z" /> + <path + id="path1191" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#800000;fill-opacity:0.976587;stroke-width:0.265;stroke-miterlimit:4;stroke-dasharray:none" + d="m 153.62437,111.63212 q 0,0.35233 0.10397,0.51405 0.10396,0.16173 0.335,0.23681 l -0.32923,1.02234 q -0.48517,-0.052 -0.83173,-0.24259 -0.34655,-0.19638 -0.53138,-0.58337 -0.34655,0.42164 -0.87794,0.62958 -0.5256,0.20793 -1.10319,0.20793 -0.9357,0 -1.48441,-0.53138 -0.54871,-0.53139 -0.54871,-1.38044 0,-0.97613 0.76242,-1.50174 0.7682,-0.53138 2.17174,-0.53138 h 0.85483 v -0.32923 q 0,-0.54293 -0.34078,-0.78552 -0.335,-0.24836 -0.9588,-0.24836 -0.29457,0 -0.73931,0.0809 -0.44474,0.0751 -0.90682,0.23681 l -0.36388,-1.04543 q 0.58337,-0.21949 1.17251,-0.32345 0.59492,-0.10397 1.08009,-0.10397 1.28803,0 1.91182,0.54871 0.6238,0.54293 0.6238,1.54216 z m -2.73777,0.68155 q 0.34655,0 0.69888,-0.1906 0.35233,-0.19638 0.56026,-0.55449 v -1.18983 h -0.60069 q -0.84906,0 -1.23027,0.27146 -0.37543,0.27147 -0.37543,0.7682 0,0.89526 0.94725,0.89526 z" /> + <path + id="path1193" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#800000;fill-opacity:0.976587;stroke-width:0.265;stroke-miterlimit:4;stroke-dasharray:none" + d="m 155.6748,113.24359 v -6.11667 h 1.32845 l 0.10974,0.75664 q 0.7913,-0.92992 1.94071,-0.92992 0.82017,0 1.25337,0.4794 0.43896,0.47362 0.43896,1.33423 v 4.47632 h -1.52483 v -3.8814 q 0,-0.69311 -0.1444,-0.9819 -0.13862,-0.2888 -0.60069,-0.2888 -0.37544,0 -0.69889,0.23681 -0.32345,0.23681 -0.57759,0.57759 v 4.3377 z" /> + <path + id="path1195" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#800000;fill-opacity:0.976587;stroke-width:0.265;stroke-miterlimit:4;stroke-dasharray:none" + d="m 165.68441,112.19238 q 0.40431,0 0.75664,-0.15018 0.35233,-0.15017 0.68733,-0.3812 l 0.69311,0.97612 q -0.40431,0.34078 -0.97612,0.56026 -0.57182,0.21949 -1.22449,0.21949 -0.96458,0 -1.65191,-0.39854 -0.68156,-0.39854 -1.04544,-1.12052 -0.36388,-0.72199 -0.36388,-1.67501 0,-0.94147 0.36966,-1.68079 0.37543,-0.73931 1.06276,-1.16095 0.69311,-0.42742 1.65191,-0.42742 0.65845,0 1.18983,0.1906 0.53716,0.18483 0.98191,0.55449 l -0.67578,0.9357 q -0.34078,-0.23104 -0.70466,-0.35811 -0.36388,-0.12707 -0.74509,-0.12707 -0.67578,0 -1.1032,0.49095 -0.42164,0.48518 -0.42164,1.5826 0,1.08587 0.43319,1.53061 0.43319,0.43897 1.08587,0.43897 z" /> + <path + id="path1197" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#800000;fill-opacity:0.976587;stroke-width:0.265;stroke-miterlimit:4;stroke-dasharray:none" + d="m 170.83649,110.65021 q 0.0693,0.86061 0.50828,1.24182 0.43897,0.38121 1.06854,0.38121 0.43897,0 0.82596,-0.13862 0.38698,-0.13862 0.76242,-0.38699 l 0.63535,0.87216 q -0.42742,0.35811 -1.02234,0.57759 -0.58914,0.21949 -1.29958,0.21949 -0.99345,0 -1.67501,-0.41009 -0.67578,-0.41009 -1.02233,-1.13785 -0.34655,-0.72777 -0.34655,-1.67501 0,-0.91259 0.335,-1.64613 0.34078,-0.73354 0.9819,-1.16096 0.6469,-0.43319 1.55372,-0.43319 1.25914,0 1.99846,0.82018 0.73931,0.82017 0.73931,2.26992 0,0.33501 -0.0289,0.60647 z m 1.31113,-2.62225 q -0.55448,0 -0.91259,0.39853 -0.35233,0.39854 -0.41586,1.2476 h 2.57605 q -0.0115,-0.77397 -0.31768,-1.20717 -0.30612,-0.43896 -0.92992,-0.43896 z" /> + </g> + <path + sodipodi:nodetypes="sssssssss" + inkscape:connector-curvature="0" + id="path1974" + style="opacity:0.25;fill:#000080;fill-opacity:0.4;stroke:none;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.2, 2.4;stroke-dashoffset:0;stroke-opacity:0.497957" + d="m -60.569299,125.94806 h 72.698771 c 1.14406,0 2.06509,0.92103 2.06509,2.06508 v 15.70853 c 0,1.14406 -0.92103,2.06509 -2.06509,2.06509 h -72.698771 c -1.14406,0 -2.06509,-0.92103 -2.06509,-2.06509 v -15.70853 c 0,-1.14405 0.92103,-2.06508 2.06509,-2.06508 z" /> + <g + style="font-size:11.263px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000081;fill-opacity:1;stroke-width:0.264583" + id="text1980" + aria-label="ABC"> + <path + id="path1176" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#000081;fill-opacity:1;stroke-width:0.264583" + d="m -29.753207,138.03049 h -2.628033 l -0.496728,1.83096 h -1.634579 l 2.500964,-7.98807 h 1.940701 l 2.495188,7.98807 h -1.680786 z m -2.345015,-1.18406 h 2.050444 l -1.022334,-3.78899 z" /> + <path + id="path1178" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#000081;fill-opacity:1;stroke-width:0.264583" + d="m -21.112481,137.54532 q 0,0.67578 -0.265692,1.1263 -0.259915,0.44474 -0.710435,0.71043 -0.45052,0.25992 -1.022334,0.36966 -0.571814,0.10974 -1.184059,0.10974 h -2.47786 v -7.98807 h 2.333463 q 0.779746,0 1.455526,0.18483 0.681556,0.18483 1.103196,0.62958 0.421641,0.43896 0.421641,1.21871 0,0.49095 -0.207932,0.84328 -0.202157,0.34656 -0.542935,0.56604 -0.335002,0.21948 -0.721987,0.31767 0.433192,0.0693 0.849057,0.27147 0.42164,0.19638 0.693108,0.59492 0.277243,0.39276 0.277243,1.04544 z m -1.946478,-3.5002 q 0,-0.54293 -0.340778,-0.77974 -0.340778,-0.23682 -0.993454,-0.23682 h -0.797074 v 2.10821 h 0.866385 q 0.641124,0 0.953023,-0.25414 0.311898,-0.25992 0.311898,-0.83751 z m 0.306123,3.45976 q 0,-0.72776 -0.415865,-0.98767 -0.410088,-0.2657 -1.039661,-0.2657 h -0.981903 v 2.42588 h 0.912592 q 0.381209,0 0.727763,-0.0866 0.35233,-0.0924 0.571814,-0.34078 0.22526,-0.25413 0.22526,-0.74509 z" /> + <path + id="path1180" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#000081;fill-opacity:1;stroke-width:0.264583" + d="m -16.514884,131.70011 q 0.83173,0 1.409319,0.21948 0.57759,0.21371 1.068541,0.61802 l -0.802849,0.95303 q -0.346554,-0.28302 -0.750867,-0.4332 -0.404313,-0.15595 -0.866385,-0.15595 -0.560262,0 -1.028109,0.29457 -0.462072,0.29458 -0.739315,0.94725 -0.277243,0.6469 -0.277243,1.70967 0,1.04543 0.265691,1.69234 0.271467,0.64112 0.733539,0.94147 0.467848,0.30034 1.056989,0.30034 0.623797,0 1.033886,-0.2137 0.415864,-0.21949 0.739315,-0.48518 l 0.74509,0.94147 q -0.42164,0.41587 -1.056989,0.71044 -0.629573,0.29457 -1.530613,0.29457 -1.045437,0 -1.865614,-0.47363 -0.820178,-0.4794 -1.288025,-1.40932 -0.467848,-0.93569 -0.467848,-2.2988 0,-1.34001 0.479399,-2.26415 0.485176,-0.92992 1.305353,-1.40932 0.825953,-0.4794 1.836735,-0.4794 z" /> + </g> + <g + style="font-size:11.263px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#830000;fill-opacity:1;stroke-width:0.264583" + id="text1984" + aria-label="instance"> + <path + id="path1159" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#830000;fill-opacity:1;stroke-width:0.264583" + d="m 183.76608,131.26282 q 0.41587,0 0.68156,0.25991 0.26569,0.25992 0.26569,0.6469 0,0.38699 -0.26569,0.65268 -0.26569,0.25991 -0.68156,0.25991 -0.42164,0 -0.68733,-0.25991 -0.26569,-0.26569 -0.26569,-0.65268 0,-0.38698 0.26569,-0.6469 0.26569,-0.25991 0.68733,-0.25991 z m 0.98768,3.08433 v 5.03658 h 1.61148 v 1.08009 h -4.92684 v -1.08009 h 1.79052 v -3.95649 h -1.73276 v -1.08009 z" /> + <path + id="path1161" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#830000;fill-opacity:1;stroke-width:0.264583" + d="m 188.1673,140.46382 v -6.11667 h 1.32846 l 0.10974,0.75664 q 0.7913,-0.92992 1.9407,-0.92992 0.82018,0 1.25337,0.4794 0.43897,0.47362 0.43897,1.33423 v 4.47632 h -1.52484 v -3.8814 q 0,-0.69311 -0.1444,-0.9819 -0.13862,-0.2888 -0.60069,-0.2888 -0.37543,0 -0.69888,0.23681 -0.32345,0.23681 -0.57759,0.57759 v 4.3377 z" /> + <path + id="path1163" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#830000;fill-opacity:1;stroke-width:0.264583" + d="m 197.42605,139.5108 q 0.53716,0 0.86061,-0.18483 0.32922,-0.18483 0.32922,-0.53138 0,-0.21949 -0.10974,-0.37544 -0.10397,-0.16172 -0.41586,-0.29457 -0.3119,-0.13862 -0.9357,-0.30612 -0.58914,-0.15017 -1.03389,-0.36966 -0.43896,-0.22526 -0.68733,-0.57759 -0.24259,-0.35233 -0.24259,-0.88948 0,-0.79708 0.67001,-1.29958 0.67,-0.50828 1.87139,-0.50828 0.78552,0 1.37466,0.20793 0.58914,0.20216 1.01078,0.50828 l -0.62379,0.92992 q -0.36966,-0.23681 -0.80285,-0.38121 -0.42742,-0.15017 -0.92415,-0.15017 -0.53715,0 -0.78552,0.15595 -0.24258,0.15595 -0.24258,0.43319 0,0.19638 0.12129,0.335 0.12707,0.13285 0.45052,0.25992 0.32923,0.12129 0.93569,0.29457 0.59492,0.1675 1.03389,0.38698 0.44474,0.21949 0.68733,0.58337 0.24259,0.3581 0.24259,0.94725 0,0.66422 -0.38699,1.09742 -0.38698,0.43319 -1.02233,0.6469 -0.63535,0.20793 -1.36889,0.20793 -0.86638,0 -1.51328,-0.24837 -0.6469,-0.24836 -1.09742,-0.64112 l 0.7913,-0.88949 q 0.3581,0.28302 0.8144,0.46785 0.46207,0.18483 0.99923,0.18483 z" /> + <path + id="path1165" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#830000;fill-opacity:1;stroke-width:0.264583" + d="m 207.30859,140.12304 q -0.34078,0.22526 -0.82595,0.36966 -0.48518,0.1444 -1.05122,0.1444 -1.12052,0 -1.68656,-0.57759 -0.56604,-0.58337 -0.56604,-1.54794 v -3.08433 h -1.32845 v -1.08009 h 1.32845 v -1.34579 l 1.52484,-0.18483 v 1.53062 h 2.02156 l -0.15594,1.08009 h -1.86562 v 3.07855 q 0,0.47363 0.23104,0.69311 0.23103,0.21948 0.74509,0.21948 0.32922,0 0.60069,-0.0751 0.27724,-0.0809 0.5025,-0.20216 z" /> + <path + id="path1167" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#830000;fill-opacity:1;stroke-width:0.264583" + d="m 213.84111,138.85235 q 0,0.35233 0.10397,0.51405 0.10397,0.16173 0.335,0.23681 l -0.32922,1.02234 q -0.48518,-0.052 -0.83173,-0.24259 -0.34656,-0.19638 -0.53139,-0.58337 -0.34655,0.42164 -0.87793,0.62958 -0.52561,0.20793 -1.1032,0.20793 -0.93569,0 -1.4844,-0.53138 -0.54871,-0.53139 -0.54871,-1.38044 0,-0.97613 0.76241,-1.50174 0.7682,-0.53138 2.17174,-0.53138 h 0.85483 v -0.32923 q 0,-0.54293 -0.34077,-0.78552 -0.33501,-0.24836 -0.9588,-0.24836 -0.29457,0 -0.73932,0.0809 -0.44474,0.0751 -0.90681,0.23681 l -0.36388,-1.04543 q 0.58336,-0.21949 1.1725,-0.32345 0.59492,-0.10397 1.0801,-0.10397 1.28802,0 1.91182,0.54871 0.62379,0.54293 0.62379,1.54216 z m -2.73777,0.68155 q 0.34655,0 0.69888,-0.1906 0.35233,-0.19638 0.56026,-0.55449 v -1.18983 h -0.60069 q -0.84906,0 -1.23027,0.27146 -0.37543,0.27147 -0.37543,0.7682 0,0.89526 0.94725,0.89526 z" /> + <path + id="path1169" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#830000;fill-opacity:1;stroke-width:0.264583" + d="m 215.89154,140.46382 v -6.11667 H 217.22 l 0.10974,0.75664 q 0.7913,-0.92992 1.9407,-0.92992 0.82018,0 1.25337,0.4794 0.43897,0.47362 0.43897,1.33423 v 4.47632 h -1.52484 v -3.8814 q 0,-0.69311 -0.1444,-0.9819 -0.13862,-0.2888 -0.60069,-0.2888 -0.37543,0 -0.69888,0.23681 -0.32345,0.23681 -0.57759,0.57759 v 4.3377 z" /> + <path + id="path1171" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#830000;fill-opacity:1;stroke-width:0.264583" + d="m 225.90115,139.41261 q 0.40432,0 0.75665,-0.15018 0.35233,-0.15017 0.68733,-0.3812 l 0.69311,0.97612 q -0.40432,0.34078 -0.97613,0.56026 -0.57181,0.21949 -1.22449,0.21949 -0.96458,0 -1.65191,-0.39854 -0.68155,-0.39854 -1.04544,-1.12052 -0.36388,-0.72199 -0.36388,-1.67501 0,-0.94147 0.36966,-1.68079 0.37543,-0.73931 1.06277,-1.16095 0.6931,-0.42742 1.6519,-0.42742 0.65845,0 1.18984,0.1906 0.53716,0.18483 0.9819,0.55449 l -0.67578,0.9357 q -0.34078,-0.23104 -0.70466,-0.35811 -0.36388,-0.12707 -0.74509,-0.12707 -0.67578,0 -1.1032,0.49095 -0.42164,0.48518 -0.42164,1.5826 0,1.08587 0.4332,1.53061 0.43319,0.43897 1.08586,0.43897 z" /> + <path + id="path1173" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#830000;fill-opacity:1;stroke-width:0.264583" + d="m 231.05324,137.87044 q 0.0693,0.86061 0.50828,1.24182 0.43897,0.38121 1.06854,0.38121 0.43897,0 0.82595,-0.13862 0.38699,-0.13862 0.76242,-0.38699 l 0.63535,0.87216 q -0.42742,0.35811 -1.02234,0.57759 -0.58914,0.21949 -1.29957,0.21949 -0.99346,0 -1.67501,-0.41009 -0.67578,-0.41009 -1.02234,-1.13785 -0.34655,-0.72777 -0.34655,-1.67501 0,-0.91259 0.335,-1.64613 0.34078,-0.73354 0.9819,-1.16096 0.64691,-0.43319 1.55372,-0.43319 1.25915,0 1.99846,0.82018 0.73932,0.82017 0.73932,2.26992 0,0.33501 -0.0289,0.60647 z m 1.31113,-2.62225 q -0.55449,0 -0.91259,0.39853 -0.35233,0.39854 -0.41587,1.2476 h 2.57605 q -0.0115,-0.77397 -0.31767,-1.20717 -0.30613,-0.43896 -0.92992,-0.43896 z" /> + </g> + <path + d="M 17.347598,126.00309 H 170.2081 c 1.14406,0 2.06509,0.92103 2.06509,2.06508 v 15.70853 c 0,1.14406 -0.92103,2.06509 -2.06509,2.06509 H 17.347598 c -1.14406,0 -2.06509,-0.92103 -2.06509,-2.06509 v -15.70853 c 0,-1.14405 0.92103,-2.06508 2.06509,-2.06508 z" + style="opacity:0.25;fill:#000080;fill-opacity:0.4;stroke:none;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.2, 2.4;stroke-dashoffset:0;stroke-opacity:0.497957" + id="path1986" + inkscape:connector-curvature="0" + sodipodi:nodetypes="sssssssss" /> + <g + style="font-size:11.263px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000081;fill-opacity:1;stroke-width:0.264583" + id="text1990" + aria-label="type"> + <path + id="path1150" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#000081;fill-opacity:1;stroke-width:0.264583" + d="m 86.078604,138.14328 q -0.340778,0.22526 -0.825953,0.36965 -0.485176,0.1444 -1.051214,0.1444 -1.120524,0 -1.686562,-0.57759 -0.566038,-0.58336 -0.566038,-1.54794 v -3.08433 h -1.328456 v -1.08009 h 1.328456 v -1.34578 l 1.524837,-0.18483 v 1.53061 h 2.021564 l -0.155949,1.08009 h -1.865615 v 3.07856 q 0,0.47362 0.231036,0.6931 0.231036,0.21949 0.745091,0.21949 0.329226,0 0.600693,-0.0751 0.277243,-0.0809 0.502503,-0.20216 z" /> + <path + id="path1152" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#000081;fill-opacity:1;stroke-width:0.264583" + d="m 93.26958,132.36738 -2.073547,6.12823 q -0.375434,1.12052 -1.114749,1.76742 -0.739314,0.65268 -2.067771,0.74509 l -0.190604,-1.10319 q 0.612245,-0.0866 0.981902,-0.25992 0.375433,-0.17328 0.594918,-0.4563 0.22526,-0.28301 0.386985,-0.70466 h -0.519831 l -2.004236,-6.11667 h 1.611475 l 1.386215,5.10012 1.443974,-5.10012 z" /> + <path + id="path1154" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#000081;fill-opacity:1;stroke-width:0.264583" + d="m 97.82097,132.1941 q 0.80285,0 1.293801,0.39854 0.490952,0.39276 0.710436,1.12052 0.225263,0.72199 0.225263,1.69812 0,0.94147 -0.271471,1.67501 -0.271467,0.73354 -0.797073,1.15518 -0.519831,0.41586 -1.28225,0.41586 -0.935695,0 -1.513285,-0.66423 v 2.84752 l -1.524836,0.16173 v -8.63497 h 1.340008 l 0.08086,0.74509 q 0.358106,-0.47362 0.808626,-0.69311 0.456296,-0.22526 0.929919,-0.22526 z m -0.444744,1.14363 q -0.386985,0 -0.681556,0.23104 -0.288795,0.23103 -0.508279,0.57181 v 2.73778 q 0.421641,0.62379 1.074317,0.62379 0.583366,0 0.889488,-0.48517 0.311899,-0.49095 0.311899,-1.58838 0,-1.16095 -0.277243,-1.62302 -0.277243,-0.46785 -0.808626,-0.46785 z" /> + <path + id="path1156" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#000081;fill-opacity:1;stroke-width:0.264583" + d="m 102.89219,135.89068 q 0.0693,0.86061 0.50828,1.24181 0.43897,0.38121 1.06854,0.38121 0.43897,0 0.82595,-0.13862 0.38699,-0.13862 0.76242,-0.38698 l 0.63535,0.87216 q -0.42741,0.3581 -1.02233,0.57759 -0.58914,0.21948 -1.29958,0.21948 -0.99345,0 -1.67501,-0.41009 -0.67578,-0.41009 -1.02233,-1.13785 -0.34656,-0.72776 -0.34656,-1.67501 0,-0.91259 0.33501,-1.64613 0.34077,-0.73354 0.9819,-1.16096 0.6469,-0.43319 1.55371,-0.43319 1.25915,0 1.99846,0.82018 0.73932,0.82018 0.73932,2.26993 0,0.335 -0.0289,0.60647 z m 1.31113,-2.62226 q -0.55449,0 -0.91259,0.39854 -0.35233,0.39853 -0.41587,1.24759 h 2.57605 q -0.0115,-0.77397 -0.31767,-1.20716 -0.30612,-0.43897 -0.92992,-0.43897 z" /> + </g> + <path + sodipodi:nodetypes="sssssssss" + inkscape:connector-curvature="0" + id="path1992" + style="opacity:0.25;fill:#000080;fill-opacity:0.4;stroke:none;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.2, 2.4;stroke-dashoffset:0;stroke-opacity:0.497957" + d="M -60.569299,153.16829 H 49.987465 c 1.14406,0 2.06509,0.92103 2.06509,2.06508 v 15.70853 c 0,1.14406 -0.92103,2.06509 -2.06509,2.06509 H -60.569299 c -1.14406,0 -2.06509,-0.92103 -2.06509,-2.06509 v -15.70853 c 0,-1.14405 0.92103,-2.06508 2.06509,-2.06508 z" /> + <g + style="font-size:11.263px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000081;fill-opacity:1;stroke-width:0.264583" + id="text1998" + aria-label="DType"> + <path + id="path1139" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#000081;fill-opacity:1;stroke-width:0.264583" + d="m -16.103363,161.78806 q 0,1.23027 -0.32345,2.02157 -0.323451,0.78552 -0.866385,1.22449 -0.542934,0.43897 -1.218714,0.61224 -0.670004,0.17328 -1.368888,0.17328 h -2.044668 v -7.98806 h 1.906046 q 0.745091,0 1.443975,0.16172 0.698883,0.15595 1.253369,0.57759 0.560262,0.42164 0.889489,1.20139 0.329226,0.77397 0.329226,2.01578 z m -1.651907,0 q 0,-0.88948 -0.167501,-1.43819 -0.161725,-0.54871 -0.444744,-0.83751 -0.283019,-0.29457 -0.641125,-0.39854 -0.358105,-0.10396 -0.74509,-0.10396 h -0.589142 v 5.63727 h 0.594918 q 0.542934,0 0.993454,-0.23681 0.45052,-0.23681 0.721987,-0.85483 0.277243,-0.6238 0.277243,-1.76743 z" /> + <path + id="path1141" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#000081;fill-opacity:1;stroke-width:0.264583" + d="m -11.482662,159.07339 v 6.74625 h -1.57682 v -6.74625 h -2.333462 v -1.24181 h 6.3130554 l -0.1617251,1.24181 z" /> + <path + id="path1143" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#000081;fill-opacity:1;stroke-width:0.264583" + d="m -2.3221052,159.70297 -2.0735471,6.12822 q -0.3754333,1.12053 -1.1147481,1.76743 -0.7393149,0.65267 -2.0677712,0.74509 l -0.1906046,-1.1032 q 0.6122451,-0.0866 0.9819025,-0.25991 0.3754333,-0.17328 0.5949174,-0.4563 0.22526,-0.28302 0.3869851,-0.70466 h -0.5198307 l -2.0042364,-6.11667 h 1.6114754 l 1.3862153,5.10011 1.4439743,-5.10011 z" /> + <path + id="path1145" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#000081;fill-opacity:1;stroke-width:0.264583" + d="m 2.229285,159.52969 q 0.8028497,0 1.293801,0.39854 0.4909512,0.39276 0.7104353,1.12052 0.22526,0.72199 0.22526,1.69811 0,0.94148 -0.2714671,1.67501 -0.2714672,0.73354 -0.7970738,1.15518 -0.5198308,0.41587 -1.2822492,0.41587 -0.9356954,0 -1.51328509,-0.66423 v 2.84752 l -1.52483686,0.16172 v -8.63496 H 0.4098774 l 0.0808626,0.74509 q 0.35810562,-0.47363 0.80862564,-0.69311 0.4562958,-0.22526 0.9299194,-0.22526 z m -0.4447441,1.14363 q -0.3869851,0 -0.6815558,0.23103 -0.2887949,0.23104 -0.50827899,0.57182 v 2.73777 q 0.42164049,0.6238 1.07431689,0.6238 0.5833656,0 0.8894882,-0.48518 0.3118984,-0.49095 0.3118984,-1.58837 0,-1.16095 -0.2772431,-1.62303 -0.277243,-0.46784 -0.8086256,-0.46784 z" /> + <path + id="path1147" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#000081;fill-opacity:1;stroke-width:0.264583" + d="m 7.3005069,163.22626 q 0.069311,0.86061 0.508279,1.24182 0.4389681,0.38121 1.0685409,0.38121 0.4389682,0 0.8259533,-0.13862 0.3869849,-0.13862 0.7624189,-0.38699 l 0.635348,0.87216 q -0.427416,0.35811 -1.022334,0.57759 -0.5891411,0.21949 -1.2995764,0.21949 -0.9934543,0 -1.6750102,-0.41009 -0.67578,-0.41009 -1.0223338,-1.13785 -0.3465538,-0.72777 -0.3465538,-1.67501 0,-0.91259 0.335002,-1.64613 0.3407779,-0.73354 0.9819025,-1.16096 0.6469005,-0.43319 1.5537164,-0.43319 1.2591456,0 1.9984603,0.82018 0.739315,0.82017 0.739315,2.26992 0,0.33501 -0.02888,0.60647 z m 1.3111287,-2.62225 q -0.5544862,0 -0.9125918,0.39853 -0.3523297,0.39854 -0.4158646,1.2476 h 2.5760502 q -0.011552,-0.77397 -0.3176744,-1.20717 -0.3061225,-0.43896 -0.9299194,-0.43896 z" /> + </g> + <path + d="m -60.569299,180.38852 h 72.698771 c 1.14406,0 2.06509,0.92103 2.06509,2.06508 v 15.70853 c 0,1.14406 -0.92103,2.06509 -2.06509,2.06509 h -72.698771 c -1.14406,0 -2.06509,-0.92103 -2.06509,-2.06509 V 182.4536 c 0,-1.14405 0.92103,-2.06508 2.06509,-2.06508 z" + style="opacity:0.25;fill:#000080;fill-opacity:0.4;stroke:none;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.2, 2.4;stroke-dashoffset:0;stroke-opacity:0.497957" + id="path2004" + inkscape:connector-curvature="0" + sodipodi:nodetypes="sssssssss" /> + <path + d="m 175.57697,180.55362 h 65.38081 c 1.14406,0 2.06509,0.92103 2.06509,2.06509 v 15.54342 c 0,1.14406 -0.92103,2.06509 -2.06509,2.06509 h -65.38081 c -1.14406,0 -2.06509,-0.92103 -2.06509,-2.06509 v -15.54342 c 0,-1.14406 0.92103,-2.06509 2.06509,-2.06509 z" + style="opacity:1;fill:#ddb9b9;fill-opacity:0.796078;stroke:none;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.2, 2.4;stroke-dashoffset:0;stroke-opacity:0.497957" + id="path2006" + inkscape:connector-curvature="0" + sodipodi:nodetypes="sssssssss" /> + <g + style="font-size:11.263px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000081;fill-opacity:1;stroke-width:0.264583" + id="text2010" + aria-label="base dtype"> + <path + id="path1120" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#000081;fill-opacity:1;stroke-width:0.264583" + d="m -56.5562,187.97729 q 0.306123,-0.39854 0.721988,-0.62957 0.42164,-0.23104 0.906816,-0.23104 1.19561,0 1.732769,0.87794 0.537158,0.87216 0.537158,2.33923 0,0.94148 -0.277243,1.67501 -0.277243,0.73354 -0.825953,1.15518 -0.542935,0.41587 -1.334233,0.41587 -0.99923,0 -1.565268,-0.75664 l -0.06931,0.58336 h -1.35156 v -8.55988 l 1.524836,-0.16172 z m 1.068541,4.46477 q 0.583366,0 0.912592,-0.49673 0.329226,-0.49673 0.329226,-1.59415 0,-1.16095 -0.300346,-1.62303 -0.300347,-0.46784 -0.825954,-0.46784 -0.381209,0 -0.67578,0.23103 -0.288794,0.23104 -0.508279,0.57182 v 2.73777 q 0.196381,0.30612 0.462072,0.47363 0.265692,0.1675 0.606469,0.1675 z" /> + <path + id="path1122" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#000081;fill-opacity:1;stroke-width:0.264583" + d="m -46.269343,191.79516 q 0,0.35233 0.103966,0.51405 0.103966,0.16173 0.335002,0.23681 l -0.329226,1.02234 q -0.485175,-0.052 -0.831729,-0.24259 -0.346554,-0.19638 -0.531383,-0.58337 -0.346553,0.42164 -0.877936,0.62958 -0.525607,0.20793 -1.103196,0.20793 -0.935696,0 -1.484406,-0.53138 -0.54871,-0.53139 -0.54871,-1.38044 0,-0.97613 0.762418,-1.50174 0.768195,-0.53138 2.171738,-0.53138 h 0.854832 v -0.32923 q 0,-0.54293 -0.340778,-0.78552 -0.335002,-0.24836 -0.958798,-0.24836 -0.294571,0 -0.739315,0.0809 -0.444744,0.0751 -0.906816,0.23681 l -0.363882,-1.04543 q 0.583366,-0.21949 1.172507,-0.32345 0.594918,-0.10397 1.080093,-0.10397 1.288025,0 1.911822,0.54871 0.623797,0.54293 0.623797,1.54216 z m -2.737775,0.68155 q 0.346554,0 0.698883,-0.1906 0.35233,-0.19638 0.560262,-0.55449 v -1.18983 h -0.600693 q -0.849057,0 -1.230266,0.27146 -0.375433,0.27147 -0.375433,0.7682 0,0.89526 0.947247,0.89526 z" /> + <path + id="path1124" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#000081;fill-opacity:1;stroke-width:0.264583" + d="m -41.891229,192.45361 q 0.537158,0 0.860609,-0.18483 0.329226,-0.18483 0.329226,-0.53138 0,-0.21949 -0.109742,-0.37544 -0.103967,-0.16172 -0.415865,-0.29457 -0.311898,-0.13862 -0.935695,-0.30612 -0.589142,-0.15017 -1.033886,-0.36966 -0.438968,-0.22526 -0.687332,-0.57759 -0.242587,-0.35233 -0.242587,-0.88948 0,-0.79708 0.670004,-1.29958 0.670004,-0.50828 1.87139,-0.50828 0.785522,0 1.374664,0.20793 0.589141,0.20216 1.010782,0.50828 l -0.623797,0.92992 q -0.369657,-0.23681 -0.80285,-0.38121 -0.427416,-0.15017 -0.924143,-0.15017 -0.537159,0 -0.785522,0.15595 -0.242588,0.15595 -0.242588,0.43319 0,0.19638 0.121294,0.335 0.12707,0.13285 0.45052,0.25992 0.329226,0.12129 0.935695,0.29457 0.594918,0.1675 1.033886,0.38698 0.444744,0.21949 0.687332,0.58337 0.242587,0.3581 0.242587,0.94725 0,0.66422 -0.386985,1.09742 -0.386985,0.43319 -1.022334,0.6469 -0.635348,0.20793 -1.368887,0.20793 -0.866385,0 -1.513285,-0.24837 -0.646901,-0.24836 -1.097421,-0.64112 l 0.791298,-0.88949 q 0.358106,0.28302 0.814402,0.46785 0.462071,0.18483 0.99923,0.18483 z" /> + <path + id="path1126" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#000081;fill-opacity:1;stroke-width:0.264583" + d="m -35.988279,190.81325 q 0.06931,0.86061 0.508279,1.24182 0.438968,0.38121 1.068541,0.38121 0.438968,0 0.825953,-0.13862 0.386985,-0.13862 0.762419,-0.38699 l 0.635348,0.87216 q -0.427416,0.35811 -1.022333,0.57759 -0.589142,0.21949 -1.299577,0.21949 -0.993455,0 -1.675011,-0.41009 -0.67578,-0.41009 -1.022333,-1.13785 -0.346554,-0.72777 -0.346554,-1.67501 0,-0.91259 0.335002,-1.64613 0.340778,-0.73354 0.981902,-1.16096 0.646901,-0.43319 1.553717,-0.43319 1.259145,0 1.99846,0.82018 0.739315,0.82017 0.739315,2.26992 0,0.33501 -0.02888,0.60647 z m 1.311129,-2.62225 q -0.554486,0 -0.912592,0.39853 -0.35233,0.39854 -0.415865,1.2476 h 2.57605 q -0.01155,-0.77397 -0.317674,-1.20717 -0.306122,-0.43896 -0.929919,-0.43896 z" /> + <path + id="path1128" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#000081;fill-opacity:1;stroke-width:0.264583" + d="m -19.879335,184.68503 1.524837,0.16172 v 8.55988 h -1.35156 l -0.09242,-0.72199 q -0.283019,0.40432 -0.710435,0.65268 -0.427417,0.24259 -0.993454,0.24259 -0.773971,0 -1.28225,-0.40431 -0.502503,-0.40432 -0.750866,-1.13208 -0.242588,-0.73354 -0.242588,-1.70389 0,-0.92992 0.288795,-1.65768 0.294571,-0.73354 0.837505,-1.14941 0.542934,-0.41586 1.293801,-0.41586 0.895264,0 1.47863,0.61802 z m -1.068541,3.5695 q -0.57759,0 -0.912592,0.5025 -0.329226,0.49673 -0.329226,1.58838 0,1.15518 0.306122,1.62302 0.306123,0.46785 0.825954,0.46785 0.381209,0 0.670004,-0.22526 0.288795,-0.23104 0.508279,-0.57181 v -2.78399 q -0.213709,-0.28301 -0.4794,-0.43896 -0.259915,-0.16173 -0.589141,-0.16173 z" /> + <path + id="path1130" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#000081;fill-opacity:1;stroke-width:0.264583" + d="m -11.215505,193.06585 q -0.340778,0.22526 -0.825954,0.36966 -0.485175,0.1444 -1.051213,0.1444 -1.120524,0 -1.686562,-0.57759 -0.566038,-0.58337 -0.566038,-1.54794 v -3.08433 h -1.328456 v -1.08009 h 1.328456 v -1.34579 l 1.524837,-0.18483 v 1.53062 h 2.021564 l -0.155949,1.08009 h -1.865615 v 3.07855 q 0,0.47363 0.231036,0.69311 0.231036,0.21948 0.745091,0.21948 0.329226,0 0.600693,-0.0751 0.277243,-0.0809 0.502503,-0.20216 z" /> + <path + id="path1132" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#000081;fill-opacity:1;stroke-width:0.264583" + d="m -4.0245292,187.28996 -2.0735471,6.12822 q -0.3754333,1.12053 -1.1147482,1.76743 -0.7393148,0.65267 -2.0677712,0.74509 l -0.1906046,-1.1032 q 0.6122451,-0.0866 0.9819025,-0.25991 0.3754334,-0.17328 0.5949175,-0.4563 0.2252599,-0.28302 0.3869851,-0.70466 H -8.027226 l -2.004236,-6.11667 h 1.611475 l 1.3862153,5.10011 1.4439743,-5.10011 z" /> + <path + id="path1134" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#000081;fill-opacity:1;stroke-width:0.264583" + d="m 0.52686192,187.11668 q 0.80284968,0 1.29380098,0.39854 0.4909513,0.39276 0.7104353,1.12052 0.22526,0.72199 0.22526,1.69811 0,0.94148 -0.2714671,1.67501 -0.2714672,0.73354 -0.7970738,1.15518 -0.5198308,0.41587 -1.28224922,0.41587 -0.93569535,0 -1.51328508,-0.66423 v 2.84752 l -1.5248368,0.16172 v -8.63496 h 1.3400081 l 0.080863,0.74509 q 0.35810559,-0.47363 0.80862557,-0.69311 0.45629588,-0.22526 0.92991945,-0.22526 z m -0.44474409,1.14363 q -0.38698511,0 -0.68155586,0.23103 -0.28879486,0.23104 -0.50827897,0.57182 v 2.73777 q 0.42164051,0.6238 1.07431689,0.6238 0.58336562,0 0.88948817,-0.48518 0.31189844,-0.49095 0.31189844,-1.58837 0,-1.16095 -0.27724306,-1.62303 -0.27724306,-0.46784 -0.80862561,-0.46784 z" /> + <path + id="path1136" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#000081;fill-opacity:1;stroke-width:0.264583" + d="m 5.5980838,190.81325 q 0.069311,0.86061 0.508279,1.24182 0.4389682,0.38121 1.0685409,0.38121 0.4389682,0 0.8259533,-0.13862 0.3869852,-0.13862 0.7624185,-0.38699 l 0.6353487,0.87216 q -0.4274164,0.35811 -1.0223338,0.57759 -0.5891416,0.21949 -1.2995769,0.21949 -0.9934543,0 -1.6750102,-0.41009 -0.67578,-0.41009 -1.0223338,-1.13785 -0.3465538,-0.72777 -0.3465538,-1.67501 0,-0.91259 0.335002,-1.64613 0.3407779,-0.73354 0.9819025,-1.16096 0.6469005,-0.43319 1.5537164,-0.43319 1.2591456,0 1.9984604,0.82018 0.7393149,0.82017 0.7393149,2.26992 0,0.33501 -0.02888,0.60647 z M 6.9092125,188.191 q -0.5544862,0 -0.9125918,0.39853 -0.3523297,0.39854 -0.4158646,1.2476 H 8.1568063 Q 8.1452545,189.06316 7.8391319,188.62996 7.5330094,188.191 6.9092125,188.191 Z" /> + </g> + <g + style="font-size:11.263px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#800000;fill-opacity:0.8;stroke-width:0.264583" + id="text2014" + aria-label="element"> + <path + id="path1105" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#800000;fill-opacity:0.8;stroke-width:0.264583" + d="m 186.26703,191.99035 q 0.0693,0.86061 0.50828,1.24182 0.43897,0.3812 1.06854,0.3812 0.43897,0 0.82596,-0.13862 0.38698,-0.13862 0.76241,-0.38698 l 0.63535,0.87216 q -0.42741,0.3581 -1.02233,0.57759 -0.58914,0.21948 -1.29958,0.21948 -0.99345,0 -1.67501,-0.41009 -0.67578,-0.41009 -1.02233,-1.13785 -0.34656,-0.72776 -0.34656,-1.67501 0,-0.91259 0.33501,-1.64613 0.34077,-0.73354 0.9819,-1.16095 0.6469,-0.4332 1.55372,-0.4332 1.25914,0 1.99846,0.82018 0.73931,0.82018 0.73931,2.26993 0,0.335 -0.0289,0.60647 z m 1.31113,-2.62226 q -0.55448,0 -0.91259,0.39854 -0.35233,0.39853 -0.41586,1.24759 h 2.57605 q -0.0116,-0.77397 -0.31768,-1.20716 -0.30612,-0.43897 -0.92992,-0.43897 z" /> + <path + id="path1107" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#800000;fill-opacity:0.8;stroke-width:0.264583" + d="m 194.80957,186.02385 v 6.7809 q 0,0.39854 0.23681,0.56604 0.23681,0.1675 0.62957,0.1675 0.24837,0 0.4794,-0.052 0.23104,-0.0577 0.43897,-0.13862 l 0.37543,1.03966 q -0.28879,0.15018 -0.70466,0.25992 -0.41008,0.10974 -0.95302,0.10974 -0.99923,0 -1.51328,-0.57181 -0.51406,-0.57182 -0.51406,-1.54217 v -5.53908 h -1.83096 v -1.08009 z" /> + <path + id="path1109" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#800000;fill-opacity:0.8;stroke-width:0.264583" + d="m 200.12915,191.99035 q 0.0693,0.86061 0.50828,1.24182 0.43897,0.3812 1.06854,0.3812 0.43897,0 0.82596,-0.13862 0.38698,-0.13862 0.76242,-0.38698 l 0.63534,0.87216 q -0.42741,0.3581 -1.02233,0.57759 -0.58914,0.21948 -1.29958,0.21948 -0.99345,0 -1.67501,-0.41009 -0.67578,-0.41009 -1.02233,-1.13785 -0.34655,-0.72776 -0.34655,-1.67501 0,-0.91259 0.335,-1.64613 0.34078,-0.73354 0.9819,-1.16095 0.6469,-0.4332 1.55372,-0.4332 1.25914,0 1.99846,0.82018 0.73931,0.82018 0.73931,2.26993 0,0.335 -0.0289,0.60647 z m 1.31113,-2.62226 q -0.55448,0 -0.91259,0.39854 -0.35233,0.39853 -0.41586,1.24759 h 2.57605 q -0.0116,-0.77397 -0.31768,-1.20716 -0.30612,-0.43897 -0.92992,-0.43897 z" /> + <path + id="path1111" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#800000;fill-opacity:0.8;stroke-width:0.264583" + d="m 210.10989,188.29377 q 0.57759,0 0.91259,0.38699 0.335,0.38121 0.335,1.36889 v 4.53407 h -1.32846 v -4.34347 q 0,-0.41009 -0.0635,-0.58337 -0.0635,-0.17905 -0.30035,-0.17905 -0.1906,0 -0.38698,0.11552 -0.19638,0.10974 -0.39854,0.39854 v 4.59183 h -1.1494 v -4.34347 q 0,-0.41009 -0.0635,-0.58337 -0.0635,-0.17905 -0.30034,-0.17905 -0.19061,0 -0.38699,0.11552 -0.19638,0.10974 -0.39854,0.39854 v 4.59183 h -1.34578 v -6.11667 h 1.13785 l 0.0982,0.63535 q 0.27147,-0.37543 0.57182,-0.58914 0.30034,-0.21949 0.72198,-0.21949 0.34656,0 0.61225,0.17328 0.27147,0.1675 0.38698,0.57759 0.26569,-0.335 0.58914,-0.54293 0.32923,-0.20794 0.75665,-0.20794 z" /> + <path + id="path1113" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#800000;fill-opacity:0.8;stroke-width:0.264583" + d="m 213.99127,191.99035 q 0.0693,0.86061 0.50828,1.24182 0.43897,0.3812 1.06854,0.3812 0.43897,0 0.82596,-0.13862 0.38698,-0.13862 0.76242,-0.38698 l 0.63534,0.87216 q -0.42741,0.3581 -1.02233,0.57759 -0.58914,0.21948 -1.29958,0.21948 -0.99345,0 -1.67501,-0.41009 -0.67578,-0.41009 -1.02233,-1.13785 -0.34655,-0.72776 -0.34655,-1.67501 0,-0.91259 0.335,-1.64613 0.34078,-0.73354 0.9819,-1.16095 0.6469,-0.4332 1.55372,-0.4332 1.25914,0 1.99846,0.82018 0.73931,0.82018 0.73931,2.26993 0,0.335 -0.0289,0.60647 z m 1.31113,-2.62226 q -0.55448,0 -0.91259,0.39854 -0.35233,0.39853 -0.41586,1.24759 H 216.55 q -0.0116,-0.77397 -0.31768,-1.20716 -0.30612,-0.43897 -0.92992,-0.43897 z" /> + <path + id="path1115" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#800000;fill-opacity:0.8;stroke-width:0.264583" + d="m 219.62276,194.58372 v -6.11667 h 1.32845 l 0.10974,0.75664 q 0.7913,-0.92992 1.94071,-0.92992 0.82017,0 1.25337,0.4794 0.43896,0.47363 0.43896,1.33423 v 4.47632 h -1.52483 v -3.8814 q 0,-0.69311 -0.1444,-0.9819 -0.13862,-0.2888 -0.60069,-0.2888 -0.37544,0 -0.69889,0.23682 -0.32345,0.23681 -0.57759,0.57759 v 4.33769 z" /> + <path + id="path1117" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#800000;fill-opacity:0.8;stroke-width:0.264583" + d="m 231.83299,194.24295 q -0.34078,0.22526 -0.82596,0.36965 -0.48517,0.1444 -1.05121,0.1444 -1.12052,0 -1.68656,-0.57759 -0.56604,-0.58336 -0.56604,-1.54794 v -3.08433 h -1.32846 v -1.08009 h 1.32846 v -1.34578 l 1.52484,-0.18483 v 1.53061 h 2.02156 l -0.15595,1.08009 h -1.86561 v 3.07856 q 0,0.47362 0.23103,0.6931 0.23104,0.21949 0.74509,0.21949 0.32923,0 0.6007,-0.0751 0.27724,-0.0809 0.5025,-0.20216 z" /> + </g> + <path + sodipodi:nodetypes="sssssssss" + inkscape:connector-curvature="0" + id="path2016" + style="opacity:0.25;fill:#000081;fill-opacity:0.4;stroke:none;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.2, 2.4;stroke-dashoffset:0;stroke-opacity:0.497957" + d="M 17.463123,180.38852 H 170.32495 c 1.14406,0 2.06509,0.92103 2.06509,2.06508 v 15.70853 c 0,1.14406 -0.92103,2.06509 -2.06509,2.06509 H 17.463123 c -1.14406,0 -2.06509,-0.92103 -2.06509,-2.06509 V 182.4536 c 0,-1.14405 0.92103,-2.06508 2.06509,-2.06508 z" /> + <g + style="font-size:11.263px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000081;fill-opacity:1;stroke-width:0.264583" + id="text2020" + aria-label="dtype"> + <path + id="path1094" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#000081;fill-opacity:1;stroke-width:0.264583" + d="m 81.083132,184.68503 1.524837,0.16172 v 8.55988 h -1.35156 l -0.09242,-0.72199 q -0.283019,0.40432 -0.710435,0.65268 -0.427416,0.24259 -0.993454,0.24259 -0.77397,0 -1.282249,-0.40431 -0.502503,-0.40432 -0.750867,-1.13208 -0.242588,-0.73354 -0.242588,-1.70389 0,-0.92992 0.288795,-1.65768 0.294571,-0.73354 0.837505,-1.14941 0.542935,-0.41586 1.293801,-0.41586 0.895264,0 1.47863,0.61802 z m -1.068541,3.5695 q -0.57759,0 -0.912592,0.5025 -0.329226,0.49673 -0.329226,1.58838 0,1.15518 0.306123,1.62302 0.306122,0.46785 0.825953,0.46785 0.381209,0 0.670004,-0.22526 0.288795,-0.23104 0.508279,-0.57181 v -2.78399 q -0.213708,-0.28301 -0.4794,-0.43896 -0.259915,-0.16173 -0.589141,-0.16173 z" /> + <path + id="path1096" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#000081;fill-opacity:1;stroke-width:0.264583" + d="m 89.746961,193.06585 q -0.340778,0.22526 -0.825953,0.36966 -0.485175,0.1444 -1.051213,0.1444 -1.120524,0 -1.686562,-0.57759 -0.566038,-0.58337 -0.566038,-1.54794 v -3.08433 h -1.328457 v -1.08009 h 1.328457 v -1.34579 l 1.524837,-0.18483 v 1.53062 h 2.021564 l -0.15595,1.08009 h -1.865614 v 3.07855 q 0,0.47363 0.231036,0.69311 0.231035,0.21948 0.74509,0.21948 0.329226,0 0.600694,-0.0751 0.277243,-0.0809 0.502503,-0.20216 z" /> + <path + id="path1098" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#000081;fill-opacity:1;stroke-width:0.264583" + d="m 96.937937,187.28996 -2.073547,6.12822 q -0.375433,1.12053 -1.114748,1.76743 -0.739315,0.65267 -2.067771,0.74509 l -0.190605,-1.1032 q 0.612245,-0.0866 0.981902,-0.25991 0.375434,-0.17328 0.594918,-0.4563 0.22526,-0.28302 0.386985,-0.70466 H 92.93524 l -2.004236,-6.11667 h 1.611475 l 1.386216,5.10011 1.443974,-5.10011 z" /> + <path + id="path1100" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#000081;fill-opacity:1;stroke-width:0.264583" + d="m 101.48933,187.11668 q 0.80285,0 1.2938,0.39854 0.49095,0.39276 0.71043,1.12052 0.22526,0.72199 0.22526,1.69811 0,0.94148 -0.27146,1.67501 -0.27147,0.73354 -0.79708,1.15518 -0.51983,0.41587 -1.28225,0.41587 -0.93569,0 -1.513282,-0.66423 v 2.84752 l -1.524837,0.16172 v -8.63496 h 1.340009 l 0.08086,0.74509 q 0.358108,-0.47363 0.808628,-0.69311 0.45629,-0.22526 0.92992,-0.22526 z m -0.44475,1.14363 q -0.38698,0 -0.68155,0.23103 -0.2888,0.23104 -0.508282,0.57182 v 2.73777 q 0.421642,0.6238 1.074322,0.6238 0.58336,0 0.88948,-0.48518 0.3119,-0.49095 0.3119,-1.58837 0,-1.16095 -0.27724,-1.62303 -0.27724,-0.46784 -0.80863,-0.46784 z" /> + <path + id="path1102" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#000081;fill-opacity:1;stroke-width:0.264583" + d="m 106.56055,190.81325 q 0.0693,0.86061 0.50828,1.24182 0.43897,0.38121 1.06854,0.38121 0.43897,0 0.82595,-0.13862 0.38699,-0.13862 0.76242,-0.38699 l 0.63535,0.87216 q -0.42742,0.35811 -1.02233,0.57759 -0.58915,0.21949 -1.29958,0.21949 -0.99346,0 -1.67501,-0.41009 -0.67578,-0.41009 -1.02234,-1.13785 -0.34655,-0.72777 -0.34655,-1.67501 0,-0.91259 0.335,-1.64613 0.34078,-0.73354 0.98191,-1.16096 0.6469,-0.43319 1.55371,-0.43319 1.25915,0 1.99846,0.82018 0.73932,0.82017 0.73932,2.26992 0,0.33501 -0.0289,0.60647 z m 1.31113,-2.62225 q -0.55449,0 -0.91259,0.39853 -0.35233,0.39854 -0.41587,1.2476 h 2.57605 q -0.0115,-0.77397 -0.31767,-1.20717 -0.30613,-0.43896 -0.92992,-0.43896 z" /> + </g> + <path + sodipodi:nodetypes="sssssssss" + inkscape:connector-curvature="0" + id="path2022" + style="opacity:1;fill:#ddb9b9;fill-opacity:0.796078;stroke:none;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.2, 2.4;stroke-dashoffset:0;stroke-opacity:0.497957" + d="m 175.57697,153.33338 h 65.38081 c 1.14406,0 2.06509,0.92103 2.06509,2.06509 v 15.54342 c 0,1.14406 -0.92103,2.06509 -2.06509,2.06509 h -65.38081 c -1.14406,0 -2.06509,-0.92103 -2.06509,-2.06509 v -15.54342 c 0,-1.14406 0.92103,-2.06509 2.06509,-2.06509 z" /> + <g + style="font-size:11.263px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#800000;fill-opacity:0.8;stroke-width:0.264583" + id="text2026" + aria-label="element"> + <path + id="path1079" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#800000;fill-opacity:0.8;stroke-width:0.264583" + d="m 186.26703,164.7701 q 0.0693,0.86061 0.50828,1.24182 0.43897,0.38121 1.06854,0.38121 0.43897,0 0.82596,-0.13862 0.38698,-0.13862 0.76241,-0.38699 l 0.63535,0.87216 q -0.42741,0.35811 -1.02233,0.57759 -0.58914,0.21949 -1.29958,0.21949 -0.99345,0 -1.67501,-0.41009 -0.67578,-0.41009 -1.02233,-1.13785 -0.34656,-0.72777 -0.34656,-1.67501 0,-0.9126 0.33501,-1.64613 0.34077,-0.73354 0.9819,-1.16096 0.6469,-0.43319 1.55372,-0.43319 1.25914,0 1.99846,0.82017 0.73931,0.82018 0.73931,2.26993 0,0.335 -0.0289,0.60647 z m 1.31113,-2.62226 q -0.55448,0 -0.91259,0.39854 -0.35233,0.39854 -0.41586,1.2476 h 2.57605 q -0.0116,-0.77398 -0.31768,-1.20717 -0.30612,-0.43897 -0.92992,-0.43897 z" /> + <path + id="path1081" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#800000;fill-opacity:0.8;stroke-width:0.264583" + d="m 194.80957,158.8036 v 6.7809 q 0,0.39854 0.23681,0.56604 0.23681,0.1675 0.62957,0.1675 0.24837,0 0.4794,-0.052 0.23104,-0.0578 0.43897,-0.13862 l 0.37543,1.03966 q -0.28879,0.15017 -0.70466,0.25991 -0.41008,0.10975 -0.95302,0.10975 -0.99923,0 -1.51328,-0.57182 -0.51406,-0.57181 -0.51406,-1.54216 v -5.53909 h -1.83096 v -1.08009 z" /> + <path + id="path1083" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#800000;fill-opacity:0.8;stroke-width:0.264583" + d="m 200.12915,164.7701 q 0.0693,0.86061 0.50828,1.24182 0.43897,0.38121 1.06854,0.38121 0.43897,0 0.82596,-0.13862 0.38698,-0.13862 0.76242,-0.38699 l 0.63534,0.87216 q -0.42741,0.35811 -1.02233,0.57759 -0.58914,0.21949 -1.29958,0.21949 -0.99345,0 -1.67501,-0.41009 -0.67578,-0.41009 -1.02233,-1.13785 -0.34655,-0.72777 -0.34655,-1.67501 0,-0.9126 0.335,-1.64613 0.34078,-0.73354 0.9819,-1.16096 0.6469,-0.43319 1.55372,-0.43319 1.25914,0 1.99846,0.82017 0.73931,0.82018 0.73931,2.26993 0,0.335 -0.0289,0.60647 z m 1.31113,-2.62226 q -0.55448,0 -0.91259,0.39854 -0.35233,0.39854 -0.41586,1.2476 h 2.57605 q -0.0116,-0.77398 -0.31768,-1.20717 -0.30612,-0.43897 -0.92992,-0.43897 z" /> + <path + id="path1085" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#800000;fill-opacity:0.8;stroke-width:0.264583" + d="m 210.10989,161.07353 q 0.57759,0 0.91259,0.38698 0.335,0.38121 0.335,1.36889 v 4.53408 h -1.32846 V 163.02 q 0,-0.41008 -0.0635,-0.58336 -0.0635,-0.17905 -0.30035,-0.17905 -0.1906,0 -0.38698,0.11551 -0.19638,0.10975 -0.39854,0.39854 v 4.59184 h -1.1494 V 163.02 q 0,-0.41008 -0.0635,-0.58336 -0.0635,-0.17905 -0.30034,-0.17905 -0.19061,0 -0.38699,0.11551 -0.19638,0.10975 -0.39854,0.39854 v 4.59184 h -1.34578 v -6.11668 h 1.13785 l 0.0982,0.63535 q 0.27147,-0.37543 0.57182,-0.58914 0.30034,-0.21948 0.72198,-0.21948 0.34656,0 0.61225,0.17327 0.27147,0.16751 0.38698,0.57759 0.26569,-0.335 0.58914,-0.54293 0.32923,-0.20793 0.75665,-0.20793 z" /> + <path + id="path1087" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#800000;fill-opacity:0.8;stroke-width:0.264583" + d="m 213.99127,164.7701 q 0.0693,0.86061 0.50828,1.24182 0.43897,0.38121 1.06854,0.38121 0.43897,0 0.82596,-0.13862 0.38698,-0.13862 0.76242,-0.38699 l 0.63534,0.87216 q -0.42741,0.35811 -1.02233,0.57759 -0.58914,0.21949 -1.29958,0.21949 -0.99345,0 -1.67501,-0.41009 -0.67578,-0.41009 -1.02233,-1.13785 -0.34655,-0.72777 -0.34655,-1.67501 0,-0.9126 0.335,-1.64613 0.34078,-0.73354 0.9819,-1.16096 0.6469,-0.43319 1.55372,-0.43319 1.25914,0 1.99846,0.82017 0.73931,0.82018 0.73931,2.26993 0,0.335 -0.0289,0.60647 z m 1.31113,-2.62226 q -0.55448,0 -0.91259,0.39854 -0.35233,0.39854 -0.41586,1.2476 H 216.55 q -0.0116,-0.77398 -0.31768,-1.20717 -0.30612,-0.43897 -0.92992,-0.43897 z" /> + <path + id="path1089" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#800000;fill-opacity:0.8;stroke-width:0.264583" + d="m 219.62276,167.36348 v -6.11668 h 1.32845 l 0.10974,0.75665 q 0.7913,-0.92992 1.94071,-0.92992 0.82017,0 1.25337,0.4794 0.43896,0.47362 0.43896,1.33423 v 4.47632 h -1.52483 v -3.8814 q 0,-0.69311 -0.1444,-0.98191 -0.13862,-0.28879 -0.60069,-0.28879 -0.37544,0 -0.69889,0.23681 -0.32345,0.23681 -0.57759,0.57759 v 4.3377 z" /> + <path + id="path1091" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#800000;fill-opacity:0.8;stroke-width:0.264583" + d="m 231.83299,167.0227 q -0.34078,0.22526 -0.82596,0.36966 -0.48517,0.1444 -1.05121,0.1444 -1.12052,0 -1.68656,-0.57759 -0.56604,-0.58337 -0.56604,-1.54794 v -3.08433 h -1.32846 v -1.0801 h 1.32846 v -1.34578 l 1.52484,-0.18483 v 1.53061 h 2.02156 l -0.15595,1.0801 h -1.86561 v 3.07855 q 0,0.47362 0.23103,0.69311 0.23104,0.21948 0.74509,0.21948 0.32923,0 0.6007,-0.0751 0.27724,-0.0809 0.5025,-0.20216 z" /> + </g> + <path + d="M 55.175507,153.27835 H 170.22016 c 1.14406,0 2.06509,0.92103 2.06509,2.06509 v 15.54342 c 0,1.14406 -0.92103,2.06509 -2.06509,2.06509 H 55.175507 c -1.14406,0 -2.06509,-0.92103 -2.06509,-2.06509 v -15.54342 c 0,-1.14406 0.92103,-2.06509 2.06509,-2.06509 z" + style="opacity:0.25;fill:#d99b00;fill-opacity:1;stroke:none;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.2, 2.4;stroke-dashoffset:0;stroke-opacity:0.497957" + id="path2031" + inkscape:connector-curvature="0" + sodipodi:nodetypes="sssssssss" /> + <g + style="font-size:11.263px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#b27d00;fill-opacity:1;stroke-width:0.264583" + id="text2035" + aria-label="dtype"> + <path + id="path1068" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#b27d00;fill-opacity:1;stroke-width:0.264583" + d="m 99.886927,157.49231 1.524833,0.16172 v 8.55988 h -1.35156 l -0.09241,-0.72198 q -0.283019,0.40431 -0.710435,0.65267 -0.427416,0.24259 -0.993454,0.24259 -0.773971,0 -1.28225,-0.40431 -0.502503,-0.40432 -0.750866,-1.13208 -0.242588,-0.73354 -0.242588,-1.70389 0,-0.92992 0.288795,-1.65768 0.294571,-0.73354 0.837505,-1.1494 0.542934,-0.41587 1.293801,-0.41587 0.895264,0 1.47863,0.61802 z m -1.068541,3.5695 q -0.57759,0 -0.912592,0.50251 -0.329226,0.49672 -0.329226,1.58837 0,1.15518 0.306122,1.62302 0.306123,0.46785 0.825954,0.46785 0.381209,0 0.670004,-0.22526 0.288795,-0.23103 0.508279,-0.57181 v -2.78398 q -0.213708,-0.28302 -0.4794,-0.43897 -0.259915,-0.16173 -0.589141,-0.16173 z" /> + <path + id="path1070" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#b27d00;fill-opacity:1;stroke-width:0.264583" + d="m 108.55076,165.87314 q -0.34078,0.22526 -0.82596,0.36965 -0.48517,0.1444 -1.05121,0.1444 -1.12052,0 -1.68656,-0.57759 -0.56604,-0.58337 -0.56604,-1.54794 v -3.08433 h -1.32846 v -1.08009 h 1.32846 v -1.34579 l 1.52484,-0.18482 v 1.53061 h 2.02156 l -0.15595,1.08009 h -1.86561 v 3.07855 q 0,0.47363 0.23103,0.69311 0.23104,0.21949 0.74509,0.21949 0.32923,0 0.6007,-0.0751 0.27724,-0.0809 0.5025,-0.20216 z" /> + <path + id="path1072" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#b27d00;fill-opacity:1;stroke-width:0.264583" + d="m 115.74173,160.09724 -2.07355,6.12822 q -0.37543,1.12053 -1.11474,1.76743 -0.73932,0.65268 -2.06777,0.74509 l -0.19061,-1.1032 q 0.61225,-0.0866 0.9819,-0.25991 0.37544,-0.17328 0.59492,-0.4563 0.22526,-0.28302 0.38699,-0.70466 h -0.51983 l -2.00424,-6.11667 h 1.61147 l 1.38622,5.10012 1.44397,-5.10012 z" /> + <path + id="path1074" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#b27d00;fill-opacity:1;stroke-width:0.264583" + d="m 120.29312,159.92396 q 0.80285,0 1.2938,0.39854 0.49095,0.39276 0.71044,1.12052 0.22526,0.72199 0.22526,1.69812 0,0.94147 -0.27147,1.67501 -0.27147,0.73353 -0.79707,1.15518 -0.51983,0.41586 -1.28225,0.41586 -0.9357,0 -1.51329,-0.66423 v 2.84752 l -1.52483,0.16172 v -8.63496 h 1.34 l 0.0809,0.74509 q 0.3581,-0.47362 0.80862,-0.69311 0.4563,-0.22526 0.92992,-0.22526 z m -0.44474,1.14363 q -0.38699,0 -0.68156,0.23103 -0.28879,0.23104 -0.50828,0.57182 v 2.73777 q 0.42164,0.6238 1.07432,0.6238 0.58337,0 0.88949,-0.48517 0.3119,-0.49096 0.3119,-1.58838 0,-1.16095 -0.27725,-1.62302 -0.27724,-0.46785 -0.80862,-0.46785 z" /> + <path + id="path1076" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#b27d00;fill-opacity:1;stroke-width:0.264583" + d="m 125.36434,163.62054 q 0.0693,0.8606 0.50828,1.24181 0.43897,0.38121 1.06854,0.38121 0.43897,0 0.82596,-0.13862 0.38698,-0.13862 0.76242,-0.38698 l 0.63534,0.87216 q -0.42741,0.3581 -1.02233,0.57759 -0.58914,0.21948 -1.29958,0.21948 -0.99345,0 -1.67501,-0.41009 -0.67578,-0.41009 -1.02233,-1.13785 -0.34655,-0.72776 -0.34655,-1.67501 0,-0.91259 0.335,-1.64613 0.34078,-0.73354 0.9819,-1.16096 0.6469,-0.43319 1.55372,-0.43319 1.25914,0 1.99846,0.82018 0.73931,0.82018 0.73931,2.26993 0,0.335 -0.0289,0.60647 z m 1.31113,-2.62226 q -0.55448,0 -0.91259,0.39853 -0.35233,0.39854 -0.41586,1.2476 h 2.57605 q -0.0116,-0.77397 -0.31768,-1.20716 -0.30612,-0.43897 -0.92992,-0.43897 z" /> + </g> + <path + style="fill:none;stroke:#808080;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 52.572927,70.114137 V 205.33633" + id="path3042" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cc" /> + <g + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:7.72103px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke-width:0.105503" + id="text3050" + aria-label="Python type"> + <path + id="path1047" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -121.47364,105.10011 h 2.42156 q 1.08004,0 1.65606,0.48128 0.57981,0.47749 0.57981,1.36426 0,0.89055 -0.57981,1.37183 -0.57602,0.47749 -1.65606,0.47749 h -0.96256 v 1.96302 h -1.459 z m 1.459,1.0573 v 1.58026 h 0.80719 q 0.42443,0 0.6556,-0.20464 0.23117,-0.20842 0.23117,-0.58738 0,-0.37896 -0.23117,-0.5836 -0.23117,-0.20464 -0.6556,-0.20464 z" /> + <path + id="path1049" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -116.25914,106.51363 h 1.35668 l 1.14067,2.8801 0.97014,-2.8801 h 1.35668 l -1.78491,4.64606 q -0.26906,0.70865 -0.62907,0.98908 -0.35622,0.28422 -0.94361,0.28422 h -0.78445 v -0.89055 h 0.42443 q 0.34486,0 0.50023,-0.1099 0.15917,-0.1099 0.24633,-0.39412 l 0.0379,-0.11748 z" /> + <path + id="path1051" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -109.16121,105.30854 v 1.20509 h 1.39836 v 0.97014 h -1.39836 v 1.80006 q 0,0.29559 0.11748,0.4017 0.11747,0.10232 0.46612,0.10232 h 0.69729 v 0.97014 h -1.16341 q -0.8034,0 -1.14067,-0.33349 -0.33349,-0.33727 -0.33349,-1.14067 v -1.80006 h -0.67455 v -0.97014 h 0.67455 v -1.20509 z" /> + <path + id="path1053" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -102.66583,108.17348 v 2.58451 h -1.36426 v -0.42065 -1.54995 q 0,-0.55707 -0.0265,-0.7655 -0.0227,-0.20842 -0.0834,-0.30695 -0.0796,-0.13264 -0.21601,-0.20464 -0.13643,-0.0758 -0.31075,-0.0758 -0.42444,0 -0.66697,0.3297 -0.24253,0.32591 -0.24253,0.90572 v 2.08807 h -1.35668 v -5.89663 h 1.35668 v 2.27377 q 0.30695,-0.37139 0.65181,-0.54571 0.34485,-0.17811 0.76171,-0.17811 0.73518,0 1.11414,0.45096 0.38275,0.45097 0.38275,1.31121 z" /> + <path + id="path1055" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -99.387821,107.38145 q -0.450963,0 -0.689709,0.32591 -0.23495,0.32211 -0.23495,0.93224 0,0.61013 0.23495,0.93603 0.238746,0.32212 0.689709,0.32212 0.443384,0 0.678339,-0.32212 0.234956,-0.3259 0.234956,-0.93603 0,-0.61013 -0.234956,-0.93224 -0.234955,-0.32591 -0.678339,-0.32591 z m 0,-0.97014 q 1.095196,0 1.709112,0.59118 0.617705,0.59118 0.617705,1.63711 0,1.04593 -0.617705,1.63711 -0.613916,0.59118 -1.709112,0.59118 -1.098989,0 -1.720479,-0.59118 -0.61771,-0.59118 -0.61771,-1.63711 0,-1.04593 0.61771,-1.63711 0.62149,-0.59118 1.720479,-0.59118 z" /> + <path + id="path1057" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -91.808612,108.17348 v 2.58451 h -1.364257 v -0.42065 -1.55753 q 0,-0.54949 -0.02653,-0.75792 -0.02274,-0.20842 -0.08337,-0.30695 -0.07958,-0.13264 -0.216007,-0.20464 -0.136426,-0.0758 -0.310748,-0.0758 -0.424435,0 -0.66697,0.3297 -0.242535,0.32591 -0.242535,0.90572 v 2.08807 h -1.356678 v -4.24436 h 1.356678 v 0.6215 q 0.306958,-0.37139 0.651812,-0.54571 0.344854,-0.17811 0.761711,-0.17811 0.735183,0 1.114143,0.45096 0.38275,0.45097 0.38275,1.31121 z" /> + <path + id="path1059" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -86.366739,105.30854 v 1.20509 h 1.398364 v 0.97014 h -1.398364 v 1.80006 q 0,0.29559 0.117478,0.4017 0.117478,0.10232 0.466121,0.10232 h 0.697287 v 0.97014 h -1.163408 q -0.803396,0 -1.140671,-0.33349 -0.333485,-0.33727 -0.333485,-1.14067 v -1.80006 h -0.67455 v -0.97014 h 0.67455 v -1.20509 z" /> + <path + id="path1061" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -84.695524,106.51363 h 1.356678 l 1.140671,2.8801 0.970139,-2.8801 h 1.356678 l -1.784903,4.64606 q -0.269062,0.70865 -0.629075,0.98908 -0.356222,0.28422 -0.943611,0.28422 h -0.784448 v -0.89055 h 0.424435 q 0.344854,0 0.500228,-0.1099 0.159164,-0.1099 0.246325,-0.39412 l 0.0379,-0.11748 z" /> + <path + id="path1063" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -77.722654,110.14407 v 2.22829 h -1.356678 v -5.85873 h 1.356678 v 0.6215 q 0.280431,-0.37139 0.621496,-0.54571 0.341064,-0.17811 0.784448,-0.17811 0.784448,0 1.288465,0.62529 0.504018,0.62149 0.504018,1.603 0,0.98151 -0.504018,1.60679 -0.504017,0.6215 -1.288465,0.6215 -0.443384,0 -0.784448,-0.17433 -0.341065,-0.17811 -0.621496,-0.54949 z m 0.901926,-2.74746 q -0.435804,0 -0.67076,0.32212 -0.231166,0.31832 -0.231166,0.92087 0,0.60255 0.231166,0.92466 0.234956,0.31833 0.67076,0.31833 0.435805,0 0.663181,-0.31833 0.231166,-0.31832 0.231166,-0.92466 0,-0.60634 -0.231166,-0.92466 -0.227376,-0.31833 -0.663181,-0.31833 z" /> + <path + id="path1065" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -69.286993,108.62444 v 0.38654 h -3.171899 q 0.04927,0.47749 0.344854,0.71624 0.295589,0.23874 0.826134,0.23874 0.428225,0 0.875398,-0.12506 0.450963,-0.12884 0.924664,-0.38654 v 1.04593 q -0.48128,0.18191 -0.96256,0.27286 -0.48128,0.0947 -0.962559,0.0947 -1.15204,0 -1.792483,-0.5836 -0.636654,-0.58739 -0.636654,-1.64469 0,-1.03835 0.625285,-1.63332 0.629074,-0.59497 1.72806,-0.59497 1.000455,0 1.599213,0.60255 0.602547,0.60255 0.602547,1.61058 z m -1.394575,-0.45096 q 0,-0.38654 -0.227376,-0.6215 -0.223587,-0.23874 -0.587389,-0.23874 -0.394118,0 -0.640443,0.22358 -0.246324,0.2198 -0.306958,0.63666 z" /> + </g> + <g + style="font-size:3.52778px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;white-space:pre;shape-inside:url(#rect3054)" + id="text3052" /> + <g + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:7.72103px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke-width:0.105503" + id="text3062" + aria-label="Python type +with ABC"> + <path + id="path1011" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -121.47364,128.2522 h 2.42156 q 1.08004,0 1.65606,0.48128 0.57981,0.47749 0.57981,1.36426 0,0.89055 -0.57981,1.37183 -0.57602,0.47749 -1.65606,0.47749 h -0.96256 v 1.96302 h -1.459 z m 1.459,1.0573 v 1.58027 h 0.80719 q 0.42443,0 0.6556,-0.20464 0.23117,-0.20843 0.23117,-0.58739 0,-0.37896 -0.23117,-0.5836 -0.23117,-0.20464 -0.6556,-0.20464 z" /> + <path + id="path1013" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -116.25914,129.66572 h 1.35668 l 1.14067,2.8801 0.97014,-2.8801 h 1.35668 l -1.78491,4.64606 q -0.26906,0.70865 -0.62907,0.98908 -0.35622,0.28423 -0.94361,0.28423 h -0.78445 v -0.89056 h 0.42443 q 0.34486,0 0.50023,-0.1099 0.15917,-0.1099 0.24633,-0.39412 l 0.0379,-0.11748 z" /> + <path + id="path1015" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -109.16121,128.46063 v 1.20509 h 1.39836 v 0.97014 h -1.39836 v 1.80006 q 0,0.29559 0.11748,0.4017 0.11747,0.10232 0.46612,0.10232 h 0.69729 v 0.97014 h -1.16341 q -0.8034,0 -1.14067,-0.33349 -0.33349,-0.33727 -0.33349,-1.14067 v -1.80006 h -0.67455 v -0.97014 h 0.67455 v -1.20509 z" /> + <path + id="path1017" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -102.66583,131.32557 v 2.58451 h -1.36426 v -0.42065 -1.54994 q 0,-0.55708 -0.0265,-0.7655 -0.0227,-0.20843 -0.0834,-0.30696 -0.0796,-0.13264 -0.21601,-0.20464 -0.13643,-0.0758 -0.31075,-0.0758 -0.42444,0 -0.66697,0.32969 -0.24253,0.32591 -0.24253,0.90572 v 2.08807 h -1.35668 v -5.89662 h 1.35668 v 2.27376 q 0.30695,-0.37138 0.65181,-0.5457 0.34485,-0.17812 0.76171,-0.17812 0.73518,0 1.11414,0.45097 0.38275,0.45096 0.38275,1.3112 z" /> + <path + id="path1019" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -99.387821,130.53354 q -0.450963,0 -0.689709,0.32591 -0.23495,0.32211 -0.23495,0.93224 0,0.61013 0.23495,0.93603 0.238746,0.32212 0.689709,0.32212 0.443384,0 0.678339,-0.32212 0.234956,-0.3259 0.234956,-0.93603 0,-0.61013 -0.234956,-0.93224 -0.234955,-0.32591 -0.678339,-0.32591 z m 0,-0.97014 q 1.095196,0 1.709112,0.59118 0.617705,0.59118 0.617705,1.63711 0,1.04593 -0.617705,1.63711 -0.613916,0.59118 -1.709112,0.59118 -1.098989,0 -1.720479,-0.59118 -0.61771,-0.59118 -0.61771,-1.63711 0,-1.04593 0.61771,-1.63711 0.62149,-0.59118 1.720479,-0.59118 z" /> + <path + id="path1021" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -91.808612,131.32557 v 2.58451 h -1.364257 v -0.42065 -1.55752 q 0,-0.5495 -0.02653,-0.75792 -0.02274,-0.20843 -0.08337,-0.30696 -0.07958,-0.13264 -0.216007,-0.20464 -0.136426,-0.0758 -0.310748,-0.0758 -0.424435,0 -0.66697,0.32969 -0.242535,0.32591 -0.242535,0.90572 v 2.08807 h -1.356678 v -4.24436 h 1.356678 v 0.6215 q 0.306958,-0.37138 0.651812,-0.5457 0.344854,-0.17812 0.761711,-0.17812 0.735183,0 1.114143,0.45097 0.38275,0.45096 0.38275,1.3112 z" /> + <path + id="path1023" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -86.366739,128.46063 v 1.20509 h 1.398364 v 0.97014 h -1.398364 v 1.80006 q 0,0.29559 0.117478,0.4017 0.117478,0.10232 0.466121,0.10232 h 0.697287 v 0.97014 h -1.163408 q -0.803396,0 -1.140671,-0.33349 -0.333485,-0.33727 -0.333485,-1.14067 v -1.80006 h -0.67455 v -0.97014 h 0.67455 v -1.20509 z" /> + <path + id="path1025" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -84.695524,129.66572 h 1.356678 l 1.140671,2.8801 0.970139,-2.8801 h 1.356678 l -1.784903,4.64606 q -0.269062,0.70865 -0.629075,0.98908 -0.356222,0.28423 -0.943611,0.28423 h -0.784448 v -0.89056 h 0.424435 q 0.344854,0 0.500228,-0.1099 0.159164,-0.1099 0.246325,-0.39412 l 0.0379,-0.11748 z" /> + <path + id="path1027" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -77.722654,133.29616 v 2.22829 h -1.356678 v -5.85873 h 1.356678 v 0.6215 q 0.280431,-0.37138 0.621496,-0.5457 0.341064,-0.17812 0.784448,-0.17812 0.784448,0 1.288465,0.62529 0.504018,0.62149 0.504018,1.603 0,0.98151 -0.504018,1.60679 -0.504017,0.6215 -1.288465,0.6215 -0.443384,0 -0.784448,-0.17432 -0.341065,-0.17811 -0.621496,-0.5495 z m 0.901926,-2.74746 q -0.435804,0 -0.67076,0.32212 -0.231166,0.31832 -0.231166,0.92087 0,0.60255 0.231166,0.92466 0.234956,0.31833 0.67076,0.31833 0.435805,0 0.663181,-0.31833 0.231166,-0.31832 0.231166,-0.92466 0,-0.60634 -0.231166,-0.92466 -0.227376,-0.31833 -0.663181,-0.31833 z" /> + <path + id="path1029" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -69.286993,131.77653 v 0.38654 h -3.171899 q 0.04927,0.47749 0.344854,0.71624 0.295589,0.23874 0.826134,0.23874 0.428225,0 0.875398,-0.12505 0.450963,-0.12885 0.924664,-0.38654 v 1.04593 q -0.48128,0.1819 -0.96256,0.27285 -0.48128,0.0947 -0.962559,0.0947 -1.15204,0 -1.792483,-0.5836 -0.636654,-0.58739 -0.636654,-1.64469 0,-1.03835 0.625285,-1.63332 0.629074,-0.59497 1.72806,-0.59497 1.000455,0 1.599213,0.60255 0.602547,0.60255 0.602547,1.61058 z m -1.394575,-0.45096 q 0,-0.38654 -0.227376,-0.6215 -0.223587,-0.23874 -0.587389,-0.23874 -0.394118,0 -0.640443,0.22359 -0.246324,0.21979 -0.306958,0.63665 z" /> + <path + id="path1031" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -121.91323,139.36711 h 1.31878 l 0.71245,2.92557 0.71623,-2.92557 h 1.1331 l 0.71244,2.89526 0.71624,-2.89526 h 1.31878 l -1.11793,4.24436 h -1.48174 l -0.71624,-2.918 -0.71244,2.918 h -1.48174 z" /> + <path + id="path1033" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -114.36434,139.36711 h 1.35668 v 4.24436 h -1.35668 z m 0,-1.65227 h 1.35668 v 1.10657 h -1.35668 z" /> + <path + id="path1035" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -110.2223,138.16202 v 1.20509 h 1.39836 v 0.97014 h -1.39836 v 1.80006 q 0,0.29559 0.11748,0.4017 0.11748,0.10232 0.46612,0.10232 h 0.69729 v 0.97014 h -1.16341 q -0.8034,0 -1.14067,-0.33349 -0.33349,-0.33727 -0.33349,-1.14067 v -1.80006 h -0.67455 v -0.97014 h 0.67455 v -1.20509 z" /> + <path + id="path1037" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -103.72692,141.02696 v 2.58451 h -1.36426 v -0.42065 -1.54995 q 0,-0.55707 -0.0265,-0.7655 -0.0227,-0.20843 -0.0834,-0.30696 -0.0796,-0.13263 -0.21601,-0.20463 -0.13643,-0.0758 -0.31075,-0.0758 -0.42443,0 -0.66697,0.3297 -0.24253,0.32591 -0.24253,0.90572 v 2.08807 h -1.35668 v -5.89663 h 1.35668 v 2.27377 q 0.30695,-0.37139 0.65181,-0.54571 0.34485,-0.17811 0.76171,-0.17811 0.73518,0 1.11414,0.45096 0.38275,0.45097 0.38275,1.31121 z" /> + <path + id="path1039" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -96.272765,142.58069 h -2.281342 l -0.360013,1.03078 h -1.46658 l 2.095655,-5.65788 h 1.739428 l 2.095651,5.65788 h -1.466576 z m -1.91754,-1.04972 h 1.549948 l -0.773079,-2.25102 z" /> + <path + id="path1041" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -91.43344,140.14398 q 0.344854,0 0.522965,-0.15158 0.178112,-0.15159 0.178112,-0.44718 0,-0.2918 -0.178112,-0.44338 -0.178111,-0.15538 -0.522965,-0.15538 h -0.807186 v 1.19752 z m 0.04927,2.47461 q 0.439594,0 0.659391,-0.18569 0.223586,-0.18569 0.223586,-0.56086 0,-0.36759 -0.219797,-0.54949 -0.219797,-0.18569 -0.66318,-0.18569 h -0.856451 v 1.48173 z m 1.356678,-2.03502 q 0.469911,0.13643 0.727604,0.50402 0.257693,0.36759 0.257693,0.90193 0,0.81855 -0.553282,1.22025 -0.553282,0.4017 -1.682584,0.4017 h -2.421558 v -5.65788 h 2.190392 q 1.178567,0 1.705322,0.35622 0.530544,0.35622 0.530544,1.14067 0,0.41307 -0.19327,0.70487 -0.193269,0.28801 -0.560861,0.42822 z" /> + <path + id="path1043" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -83.297161,143.30072 q -0.401698,0.20843 -0.837502,0.31454 -0.435805,0.10611 -0.909505,0.10611 -1.413523,0 -2.239657,-0.78824 -0.826133,-0.79203 -0.826133,-2.14492 0,-1.35668 0.826133,-2.14491 0.826134,-0.79203 2.239657,-0.79203 0.4737,0 0.909505,0.10611 0.435804,0.10611 0.837502,0.31453 v 1.17099 q -0.405488,-0.27664 -0.799606,-0.40549 -0.394119,-0.12884 -0.829924,-0.12884 -0.780658,0 -1.227832,0.50023 -0.447173,0.50022 -0.447173,1.37941 0,0.8754 0.447173,1.37563 0.447174,0.50023 1.227832,0.50023 0.435805,0 0.829924,-0.12885 0.394118,-0.12885 0.799606,-0.40549 z" /> + </g> + <g + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:7.72103px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke-width:0.105503" + id="text3070" + aria-label="NEP 41 Proposal"> + <path + id="path984" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -139.86458,159.57088 h 1.62953 l 2.05775,3.88056 v -3.88056 h 1.38321 v 5.65788 h -1.62953 l -2.05776,-3.88056 v 3.88056 h -1.3832 z" /> + <path + id="path986" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -133.3692,159.57088 h 3.9374 v 1.10278 h -2.4784 v 1.05351 h 2.33061 v 1.10277 h -2.33061 v 1.29604 h 2.56177 v 1.10278 h -4.02077 z" /> + <path + id="path988" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -128.06754,159.57088 h 2.42156 q 1.08003,0 1.65605,0.48128 0.57981,0.47749 0.57981,1.36426 0,0.89055 -0.57981,1.37183 -0.57602,0.47749 -1.65605,0.47749 h -0.96256 v 1.96302 h -1.459 z m 1.459,1.0573 v 1.58027 h 0.80718 q 0.42444,0 0.6556,-0.20464 0.23117,-0.20843 0.23117,-0.58739 0,-0.37896 -0.23117,-0.5836 -0.23116,-0.20464 -0.6556,-0.20464 z" /> + <path + id="path990" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -117.53244,160.77218 -1.59921,2.36851 h 1.59921 z m -0.24254,-1.2013 h 1.62195 v 3.56981 h 0.80719 v 1.0573 h -0.80719 v 1.03077 h -1.37941 v -1.03077 h -2.50872 v -1.25057 z" /> + <path + id="path992" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -114.08011,164.22072 h 1.28846 v -3.65696 l -1.32257,0.27285 v -0.99288 l 1.31499,-0.27285 h 1.387 v 4.64984 h 1.28846 v 1.00804 h -3.95634 z" /> + <path + id="path994" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -106.175,159.57088 h 2.42156 q 1.08004,0 1.65606,0.48128 0.57981,0.47749 0.57981,1.36426 0,0.89055 -0.57981,1.37183 -0.57602,0.47749 -1.65606,0.47749 h -0.96256 v 1.96302 h -1.459 z m 1.459,1.0573 v 1.58027 h 0.80719 q 0.42443,0 0.6556,-0.20464 0.23116,-0.20843 0.23116,-0.58739 0,-0.37896 -0.23116,-0.5836 -0.23117,-0.20464 -0.6556,-0.20464 z" /> + <path + id="path996" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -97.394486,162.14023 q -0.178112,-0.0834 -0.356223,-0.12127 -0.174322,-0.0417 -0.352433,-0.0417 -0.522966,0 -0.807186,0.33727 -0.280431,0.33349 -0.280431,0.95877 v 1.95544 h -1.356681 v -4.24436 h 1.356681 v 0.69729 q 0.261483,-0.41686 0.598758,-0.60634 0.341064,-0.19327 0.814765,-0.19327 0.06821,0 0.147794,0.008 0.07958,0.004 0.231166,0.0227 z" /> + <path + id="path998" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -94.700075,161.85222 q -0.450963,0 -0.689708,0.32591 -0.234955,0.32211 -0.234955,0.93224 0,0.61013 0.234955,0.93603 0.238745,0.32212 0.689708,0.32212 0.443384,0 0.678339,-0.32212 0.234956,-0.3259 0.234956,-0.93603 0,-0.61013 -0.234956,-0.93224 -0.234955,-0.32591 -0.678339,-0.32591 z m 0,-0.97014 q 1.095196,0 1.709112,0.59118 0.617705,0.59118 0.617705,1.63711 0,1.04593 -0.617705,1.63711 -0.613916,0.59118 -1.709112,0.59118 -1.098985,0 -1.72048,-0.59118 -0.617706,-0.59118 -0.617706,-1.63711 0,-1.04593 0.617706,-1.63711 0.621495,-0.59118 1.72048,-0.59118 z" /> + <path + id="path1000" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -90.031282,164.61484 v 2.22829 h -1.356678 v -5.85873 h 1.356678 v 0.6215 q 0.280431,-0.37138 0.621495,-0.54571 0.341065,-0.17811 0.784449,-0.17811 0.784448,0 1.288465,0.62529 0.504017,0.62149 0.504017,1.603 0,0.98151 -0.504017,1.60679 -0.504017,0.6215 -1.288465,0.6215 -0.443384,0 -0.784449,-0.17432 -0.341064,-0.17811 -0.621495,-0.5495 z m 0.901926,-2.74746 q -0.435804,0 -0.67076,0.32212 -0.231166,0.31832 -0.231166,0.92087 0,0.60255 0.231166,0.92466 0.234956,0.31833 0.67076,0.31833 0.435805,0 0.663181,-0.31833 0.231166,-0.31832 0.231166,-0.92466 0,-0.60634 -0.231166,-0.92466 -0.227376,-0.31833 -0.663181,-0.31833 z" /> + <path + id="path1002" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -83.812544,161.85222 q -0.450963,0 -0.689708,0.32591 -0.234955,0.32211 -0.234955,0.93224 0,0.61013 0.234955,0.93603 0.238745,0.32212 0.689708,0.32212 0.443384,0 0.67834,-0.32212 0.234955,-0.3259 0.234955,-0.93603 0,-0.61013 -0.234955,-0.93224 -0.234956,-0.32591 -0.67834,-0.32591 z m 0,-0.97014 q 1.095196,0 1.709112,0.59118 0.617705,0.59118 0.617705,1.63711 0,1.04593 -0.617705,1.63711 -0.613916,0.59118 -1.709112,0.59118 -1.098985,0 -1.72048,-0.59118 -0.617706,-0.59118 -0.617706,-1.63711 0,-1.04593 0.617706,-1.63711 0.621495,-0.59118 1.72048,-0.59118 z" /> + <path + id="path1004" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -77.184525,161.11704 v 1.03077 q -0.435804,-0.1819 -0.841292,-0.27285 -0.405488,-0.0909 -0.7655,-0.0909 -0.38654,0 -0.57602,0.0985 -0.185691,0.0947 -0.185691,0.29559 0,0.16295 0.140216,0.25011 0.144005,0.0872 0.511596,0.12885 l 0.238745,0.0341 q 1.042142,0.13263 1.402154,0.4358 0.360012,0.30317 0.360012,0.95119 0,0.67834 -0.500227,1.0194 -0.500228,0.34107 -1.493105,0.34107 -0.420646,0 -0.871609,-0.0682 -0.447173,-0.0644 -0.920873,-0.19706 v -1.03078 q 0.405487,0.19706 0.829923,0.29559 0.428225,0.0985 0.867819,0.0985 0.397909,0 0.598758,-0.1099 0.200849,-0.10989 0.200849,-0.3259 0,-0.1819 -0.140215,-0.26906 -0.136426,-0.0909 -0.549493,-0.14022 l -0.238745,-0.0303 q -0.905716,-0.11368 -1.269518,-0.42064 -0.363802,-0.30696 -0.363802,-0.93224 0,-0.67455 0.462332,-1.00046 0.462332,-0.32591 1.417312,-0.32591 0.375171,0 0.788238,0.0568 0.413067,0.0568 0.898136,0.17811 z" /> + <path + id="path1006" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -73.978521,163.3188 q -0.424436,0 -0.640444,0.144 -0.212217,0.14401 -0.212217,0.42444 0,0.25769 0.170532,0.40549 0.174322,0.144 0.481279,0.144 0.382751,0 0.644233,-0.27285 0.261483,-0.27664 0.261483,-0.68971 v -0.15537 z m 2.072913,-0.5116 v 2.42156 h -1.368047 v -0.62907 q -0.272852,0.38654 -0.613916,0.56465 -0.341064,0.17432 -0.829923,0.17432 -0.659391,0 -1.072458,-0.38275 -0.409278,-0.38654 -0.409278,-1.00046 0,-0.74655 0.511597,-1.09519 0.515386,-0.34865 1.614371,-0.34865 h 0.799607 v -0.10611 q 0,-0.32211 -0.253904,-0.46991 -0.253903,-0.15158 -0.792027,-0.15158 -0.435804,0 -0.810975,0.0872 -0.375171,0.0872 -0.697287,0.26148 v -1.03456 q 0.435804,-0.10611 0.875398,-0.15916 0.439594,-0.0568 0.879188,-0.0568 1.148251,0 1.656058,0.45476 0.511596,0.45096 0.511596,1.47036 z" /> + <path + id="path1008" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -70.643667,159.33214 h 1.356679 v 5.89662 h -1.356679 z" /> + </g> + <g + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:7.72103px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke-width:0.105503" + id="text3076" + aria-label="Alternative"> + <path + id="path961" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -113.68979,192.17046 h -2.28134 l -0.36001,1.03077 h -1.46658 l 2.09565,-5.65788 h 1.73943 l 2.09565,5.65788 h -1.46658 z m -1.91754,-1.04972 h 1.54995 l -0.77308,-2.25102 z" /> + <path + id="path963" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -111.17728,187.30461 h 1.35668 v 5.89662 h -1.35668 z" /> + <path + id="path965" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -107.03524,187.75178 v 1.2051 h 1.39836 v 0.97013 h -1.39836 v 1.80007 q 0,0.29559 0.11747,0.40169 0.11748,0.10232 0.46612,0.10232 h 0.69729 v 0.97014 h -1.16341 q -0.80339,0 -1.14067,-0.33348 -0.33348,-0.33728 -0.33348,-1.14067 v -1.80007 h -0.67455 v -0.97013 h 0.67455 v -1.2051 z" /> + <path + id="path967" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -100.57018,191.06769 v 0.38654 h -3.1719 q 0.0493,0.47749 0.34486,0.71623 0.29559,0.23875 0.82613,0.23875 0.42823,0 0.8754,-0.12506 0.45096,-0.12885 0.92466,-0.38654 v 1.04593 q -0.48128,0.1819 -0.96256,0.27285 -0.48128,0.0947 -0.96256,0.0947 -1.15204,0 -1.79248,-0.5836 -0.63665,-0.58739 -0.63665,-1.64469 0,-1.03835 0.62528,-1.63332 0.62908,-0.59496 1.72806,-0.59496 1.00046,0 1.59921,0.60254 0.60255,0.60255 0.60255,1.61059 z m -1.39457,-0.45097 q 0,-0.38654 -0.22738,-0.62149 -0.22359,-0.23875 -0.58739,-0.23875 -0.39412,0 -0.64044,0.22359 -0.24633,0.2198 -0.30696,0.63665 z" /> + <path + id="path969" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -96.390244,190.11271 q -0.178112,-0.0834 -0.356223,-0.12127 -0.174322,-0.0417 -0.352434,-0.0417 -0.522965,0 -0.807185,0.33728 -0.280431,0.33348 -0.280431,0.95877 v 1.95543 h -1.356678 v -4.24435 h 1.356678 v 0.69728 q 0.261483,-0.41685 0.598758,-0.60633 0.341064,-0.19327 0.814764,-0.19327 0.06821,0 0.147795,0.008 0.07958,0.004 0.231166,0.0227 z" /> + <path + id="path971" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -91.448601,190.61672 v 2.58451 h -1.364258 v -0.42064 -1.55753 q 0,-0.54949 -0.02653,-0.75792 -0.02274,-0.20843 -0.08337,-0.30696 -0.07958,-0.13264 -0.216007,-0.20464 -0.136426,-0.0758 -0.310748,-0.0758 -0.424435,0 -0.66697,0.3297 -0.242535,0.3259 -0.242535,0.90571 v 2.08807 h -1.356678 v -4.24435 h 1.356678 v 0.62149 q 0.306958,-0.37138 0.651812,-0.5457 0.344854,-0.17811 0.761711,-0.17811 0.735183,0 1.114144,0.45096 0.38275,0.45096 0.38275,1.3112 z" /> + <path + id="path973" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -88.288071,191.29127 q -0.424435,0 -0.640443,0.14401 -0.212218,0.144 -0.212218,0.42443 0,0.2577 0.170532,0.40549 0.174322,0.14401 0.48128,0.14401 0.38275,0 0.644233,-0.27286 0.261483,-0.27664 0.261483,-0.6897 v -0.15538 z m 2.072914,-0.51159 v 2.42155 h -1.368047 v -0.62907 q -0.272852,0.38654 -0.613916,0.56465 -0.341065,0.17432 -0.829924,0.17432 -0.659391,0 -1.072458,-0.38275 -0.409277,-0.38654 -0.409277,-1.00045 0,-0.74656 0.511597,-1.0952 0.515386,-0.34864 1.614371,-0.34864 h 0.799607 v -0.10611 q 0,-0.32212 -0.253904,-0.46991 -0.253903,-0.15159 -0.792027,-0.15159 -0.435805,0 -0.810976,0.0872 -0.37517,0.0872 -0.697287,0.26149 v -1.03457 q 0.435805,-0.1061 0.875399,-0.15916 0.439594,-0.0568 0.879188,-0.0568 1.14825,0 1.656057,0.45475 0.511597,0.45096 0.511597,1.47037 z" /> + <path + id="path975" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -83.471483,187.75178 v 1.2051 h 1.398364 v 0.97013 h -1.398364 v 1.80007 q 0,0.29559 0.117478,0.40169 0.117478,0.10232 0.466121,0.10232 h 0.697288 v 0.97014 h -1.163409 q -0.803396,0 -1.140671,-0.33348 -0.333485,-0.33728 -0.333485,-1.14067 v -1.80007 h -0.67455 v -0.97013 h 0.67455 v -1.2051 z" /> + <path + id="path977" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -81.243196,188.95688 h 1.356678 v 4.24435 h -1.356678 z m 0,-1.65227 h 1.356678 v 1.10656 h -1.356678 z" /> + <path + id="path979" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -79.117229,188.95688 h 1.356678 l 1.0573,2.93315 1.05351,-2.93315 h 1.360468 l -1.671216,4.24435 h -1.489314 z" /> + <path + id="path981" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + d="m -69.286993,191.06769 v 0.38654 h -3.171899 q 0.04927,0.47749 0.344854,0.71623 0.295589,0.23875 0.826134,0.23875 0.428225,0 0.875398,-0.12506 0.450963,-0.12885 0.924664,-0.38654 v 1.04593 q -0.48128,0.1819 -0.96256,0.27285 -0.48128,0.0947 -0.962559,0.0947 -1.15204,0 -1.792483,-0.5836 -0.636654,-0.58739 -0.636654,-1.64469 0,-1.03835 0.625285,-1.63332 0.629074,-0.59496 1.72806,-0.59496 1.000455,0 1.599213,0.60254 0.602547,0.60255 0.602547,1.61059 z m -1.394575,-0.45097 q 0,-0.38654 -0.227376,-0.62149 -0.223587,-0.23875 -0.587389,-0.23875 -0.394118,0 -0.640443,0.22359 -0.246324,0.2198 -0.306958,0.63665 z" /> + </g> + <path + sodipodi:nodetypes="cc" + inkscape:connector-curvature="0" + id="path960" + d="M 244.3569,149.56007 H -141.19857" + style="fill:none;stroke:#808080;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + </g> +</svg> diff --git a/doc/neps/_static/nep-0041-type-sketch.svg b/doc/neps/_static/nep-0041-type-sketch.svg new file mode 100644 index 000000000..9e597db9d --- /dev/null +++ b/doc/neps/_static/nep-0041-type-sketch.svg @@ -0,0 +1,523 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + inkscape:version="1.0rc1 (09960d6f05, 2020-04-09)" + sodipodi:docname="nep-0041-type-sketch.svg" + id="svg8" + version="1.1" + viewBox="0 0 390.05549 139.7222" + height="139.7222mm" + width="390.05548mm"> + <defs + id="defs2"> + <rect + x="-108.43283" + y="116.0488" + width="38.824516" + height="5.9122801" + id="rect3054" /> + <marker + inkscape:isstock="true" + style="overflow:visible" + id="marker7096" + refX="0" + refY="0" + orient="auto" + inkscape:stockid="Arrow1Send"> + <path + transform="matrix(-0.2,0,0,-0.2,-1.2,0)" + style="fill:#00b200;fill-opacity:1;fill-rule:evenodd;stroke:#00b200;stroke-width:1pt;stroke-opacity:1" + d="M 0,0 5,-5 -12.5,0 5,5 Z" + id="path7094" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible" + id="marker5628" + refX="0" + refY="0" + orient="auto" + inkscape:stockid="Arrow1Send"> + <path + transform="matrix(-0.2,0,0,-0.2,-1.2,0)" + style="fill:#000081;fill-opacity:1;fill-rule:evenodd;stroke:#000081;stroke-width:1pt;stroke-opacity:1" + d="M 0,0 5,-5 -12.5,0 5,5 Z" + id="path5626" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible" + id="marker5618" + refX="0" + refY="0" + orient="auto" + inkscape:stockid="Arrow1Sstart"> + <path + transform="matrix(0.2,0,0,0.2,1.2,0)" + style="fill:#000081;fill-opacity:1;fill-rule:evenodd;stroke:#000081;stroke-width:1pt;stroke-opacity:1" + d="M 0,0 5,-5 -12.5,0 5,5 Z" + id="path5616" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible" + id="marker4826" + refX="0" + refY="0" + orient="auto" + inkscape:stockid="Arrow1Send"> + <path + transform="matrix(-0.2,0,0,-0.2,-1.2,0)" + style="fill:#206120;fill-opacity:1;fill-rule:evenodd;stroke:#206120;stroke-width:1pt;stroke-opacity:1" + d="M 0,0 5,-5 -12.5,0 5,5 Z" + id="path4824" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:stockid="Arrow1Send" + orient="auto" + refY="0" + refX="0" + id="marker4400" + style="overflow:visible" + inkscape:isstock="true"> + <path + inkscape:connector-curvature="0" + id="path4398" + d="M 0,0 5,-5 -12.5,0 5,5 Z" + style="fill:#00b200;fill-opacity:1;fill-rule:evenodd;stroke:#00b200;stroke-width:1pt;stroke-opacity:1" + transform="matrix(-0.2,0,0,-0.2,-1.2,0)" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible" + id="marker4390" + refX="0" + refY="0" + orient="auto" + inkscape:stockid="Arrow1Send"> + <path + transform="matrix(-0.2,0,0,-0.2,-1.2,0)" + style="fill:#b7943d;fill-opacity:1;fill-rule:evenodd;stroke:#b7943d;stroke-width:1pt;stroke-opacity:1" + d="M 0,0 5,-5 -12.5,0 5,5 Z" + id="path4388" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible" + id="marker2037" + refX="0" + refY="0" + orient="auto" + inkscape:stockid="Arrow1Send"> + <path + transform="matrix(-0.2,0,0,-0.2,-1.2,0)" + style="fill:#f4ae00;fill-opacity:1;fill-rule:evenodd;stroke:#ffc433;stroke-width:1pt;stroke-opacity:1" + d="M 0,0 5,-5 -12.5,0 5,5 Z" + id="path2035" + inkscape:connector-curvature="0" /> + </marker> + <rect + id="rect1296" + height="8.8755655" + width="16.467854" + y="100.87298" + x="-2.9674385" /> + <marker + inkscape:isstock="true" + style="overflow:visible" + id="Arrow1Lend" + refX="0" + refY="0" + orient="auto" + inkscape:stockid="Arrow1Lend"> + <path + transform="matrix(-0.8,0,0,-0.8,-10,0)" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1" + d="M 0,0 5,-5 -12.5,0 5,5 Z" + id="path915" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible" + id="Arrow1Lstart" + refX="0" + refY="0" + orient="auto" + inkscape:stockid="Arrow1Lstart"> + <path + transform="matrix(0.8,0,0,0.8,10,0)" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1" + d="M 0,0 5,-5 -12.5,0 5,5 Z" + id="path912" + inkscape:connector-curvature="0" /> + </marker> + </defs> + <sodipodi:namedview + inkscape:guide-bbox="true" + showguides="true" + inkscape:window-maximized="1" + inkscape:window-y="27" + inkscape:window-x="0" + inkscape:window-height="1376" + inkscape:window-width="2560" + showgrid="false" + inkscape:document-rotation="0" + inkscape:current-layer="layer1" + inkscape:document-units="mm" + inkscape:cy="290.82008" + inkscape:cx="134.87089" + inkscape:zoom="0.98994949" + inkscape:pageshadow="2" + inkscape:pageopacity="0.0" + borderopacity="1.0" + bordercolor="#666666" + pagecolor="#ffffff" + id="base" + lock-margins="true" + fit-margin-top="2" + fit-margin-left="2" + fit-margin-right="2" + fit-margin-bottom="2" + objecttolerance="29.7" + gridtolerance="20.4" + guidetolerance="19.1" + inkscape:snap-perpendicular="true" + inkscape:snap-tangential="true" /> + <metadata + id="metadata5"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + id="layer1" + inkscape:groupmode="layer" + inkscape:label="Layer 1" + transform="translate(143.44857,-67.864137)"> + <path + sodipodi:nodetypes="sssssssss" + inkscape:connector-curvature="0" + id="path1976" + style="opacity:1;fill:#ddb9b9;fill-opacity:0.796078;stroke:none;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.2, 2.4;stroke-dashoffset:0;stroke-opacity:0.497957" + d="m 175.57699,126.11316 h 65.38081 c 1.14406,0 2.06509,0.92103 2.06509,2.06509 v 15.54342 c 0,1.14406 -0.92103,2.06509 -2.06509,2.06509 h -65.38081 c -1.14406,0 -2.06509,-0.92103 -2.06509,-2.06509 v -15.54342 c 0,-1.14406 0.92103,-2.06509 2.06509,-2.06509 z" /> + <path + sodipodi:nodetypes="cc" + inkscape:connector-curvature="0" + id="path3044" + d="M 172.89254,70.114137 V 205.33633" + style="fill:none;stroke:#808080;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <path + d="M 55.143494,98.892926 H 240.95778 c 1.14406,0 2.06509,0.921034 2.06509,2.065094 v 15.54342 c 0,1.14406 -0.92103,2.06509 -2.06509,2.06509 H 55.143494 c -1.14406,0 -2.06509,-0.92103 -2.06509,-2.06509 v -15.54342 c 0,-1.14406 0.92103,-2.065094 2.06509,-2.065094 z" + style="opacity:1;fill:#ddb9b9;fill-opacity:0.796609;stroke:none;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.2, 2.4;stroke-dashoffset:0;stroke-opacity:0.497957" + id="rect5208" + inkscape:connector-curvature="0" + sodipodi:nodetypes="sssssssss" /> + <path + d="M -60.569299,98.727824 H 50.002364 c 1.14406,0 2.06509,0.92103 2.06509,2.065086 v 15.70853 c 0,1.14406 -0.92103,2.06509 -2.06509,2.06509 H -60.569299 c -1.14406,0 -2.06509,-0.92103 -2.06509,-2.06509 v -15.70853 c 0,-1.144056 0.92103,-2.065086 2.06509,-2.065086 z" + style="opacity:0.25;fill:#000080;fill-opacity:0.4;stroke:none;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.2, 2.4;stroke-dashoffset:0;stroke-opacity:0.497957" + id="rect4618" + inkscape:connector-curvature="0" + sodipodi:nodetypes="sssssssss" /> + <g + style="font-size:6.7452px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;stroke-width:0.505891" + id="text4368" /> + <g + style="font-size:3.52778px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;white-space:pre;shape-inside:url(#rect1296)" + id="text1294" /> + <text + xml:space="preserve" + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:7.76111px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke-width:0.105503" + x="177.69284" + y="88.415688" + id="text1931"><tspan + sodipodi:role="line" + id="tspan1929" + x="177.69284" + y="88.415688" + style="fill:#000000;stroke-width:0.105503">Value Storage</tspan></text> + <text + id="text1935" + y="78.750557" + x="77.626938" + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:7.76111px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke-width:0.105503" + xml:space="preserve"><tspan + style="fill:#000000;stroke-width:0.105503" + y="78.750557" + x="77.626938" + id="tspan1933" + sodipodi:role="line">Parameters and</tspan><tspan + style="fill:#000000;stroke-width:0.105503" + y="88.451942" + x="77.626938" + sodipodi:role="line" + id="tspan3040">Storage options</tspan></text> + <text + id="text1939" + y="78.750557" + x="-41.095226" + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:7.72103px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke-width:0.105503" + xml:space="preserve"><tspan + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + y="78.750557" + x="-41.095226" + sodipodi:role="line" + id="tspan3034">Value Space and</tspan><tspan + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + y="88.451942" + x="-41.095226" + sodipodi:role="line" + id="tspan3038">Behaviour</tspan></text> + <text + xml:space="preserve" + style="font-size:11.263px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000081;fill-opacity:1;stroke-width:0.264583" + x="-19.191803" + y="111.20879" + id="text1968"><tspan + sodipodi:role="line" + id="tspan1965" + x="-19.191803" + y="111.20879" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#000081;fill-opacity:1;stroke-width:0.264583">type</tspan></text> + <text + id="text1972" + y="113.24359" + x="120.08958" + style="font-size:11.263px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#800000;fill-opacity:0.976587;stroke-width:0.265;stroke-miterlimit:4;stroke-dasharray:none" + xml:space="preserve"><tspan + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#800000;fill-opacity:0.976587;stroke-width:0.265;stroke-miterlimit:4;stroke-dasharray:none" + y="113.24359" + x="120.08958" + id="tspan1970" + sodipodi:role="line">instance</tspan></text> + <path + sodipodi:nodetypes="sssssssss" + inkscape:connector-curvature="0" + id="path1974" + style="opacity:0.25;fill:#000080;fill-opacity:0.4;stroke:none;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.2, 2.4;stroke-dashoffset:0;stroke-opacity:0.497957" + d="m -60.569299,125.94806 h 72.698771 c 1.14406,0 2.06509,0.92103 2.06509,2.06508 v 15.70853 c 0,1.14406 -0.92103,2.06509 -2.06509,2.06509 h -72.698771 c -1.14406,0 -2.06509,-0.92103 -2.06509,-2.06509 v -15.70853 c 0,-1.14405 0.92103,-2.06508 2.06509,-2.06508 z" /> + <text + id="text1980" + y="139.86145" + x="-34.512547" + style="font-size:11.263px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000081;fill-opacity:1;stroke-width:0.264583" + xml:space="preserve"><tspan + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#000081;fill-opacity:1;stroke-width:0.264583" + y="139.86145" + x="-34.512547" + id="tspan1978" + sodipodi:role="line">ABC</tspan></text> + <text + xml:space="preserve" + style="font-size:11.263px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#830000;fill-opacity:1;stroke-width:0.264583" + x="180.30632" + y="140.46382" + id="text1984"><tspan + sodipodi:role="line" + id="tspan1982" + x="180.30632" + y="140.46382" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#830000;fill-opacity:1;stroke-width:0.264583">instance</tspan></text> + <path + d="M 17.347598,126.00309 H 170.2081 c 1.14406,0 2.06509,0.92103 2.06509,2.06508 v 15.70853 c 0,1.14406 -0.92103,2.06509 -2.06509,2.06509 H 17.347598 c -1.14406,0 -2.06509,-0.92103 -2.06509,-2.06509 v -15.70853 c 0,-1.14405 0.92103,-2.06508 2.06509,-2.06508 z" + style="opacity:0.25;fill:#000080;fill-opacity:0.4;stroke:none;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.2, 2.4;stroke-dashoffset:0;stroke-opacity:0.497957" + id="path1986" + inkscape:connector-curvature="0" + sodipodi:nodetypes="sssssssss" /> + <text + xml:space="preserve" + style="font-size:11.263px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000081;fill-opacity:1;stroke-width:0.264583" + x="79.869514" + y="138.48405" + id="text1990"><tspan + sodipodi:role="line" + id="tspan1988" + x="79.869514" + y="138.48405" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#000081;fill-opacity:1;stroke-width:0.264583">type</tspan></text> + <path + sodipodi:nodetypes="sssssssss" + inkscape:connector-curvature="0" + id="path1992" + style="opacity:0.25;fill:#000080;fill-opacity:0.4;stroke:none;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.2, 2.4;stroke-dashoffset:0;stroke-opacity:0.497957" + d="M -60.569299,153.16829 H 49.987465 c 1.14406,0 2.06509,0.92103 2.06509,2.06508 v 15.70853 c 0,1.14406 -0.92103,2.06509 -2.06509,2.06509 H -60.569299 c -1.14406,0 -2.06509,-0.92103 -2.06509,-2.06509 v -15.70853 c 0,-1.14405 0.92103,-2.06508 2.06509,-2.06508 z" /> + <text + id="text1998" + y="165.81964" + x="-22.653231" + style="font-size:11.263px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000081;fill-opacity:1;stroke-width:0.264583" + xml:space="preserve"><tspan + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#000081;fill-opacity:1;stroke-width:0.264583" + y="165.81964" + x="-22.653231" + id="tspan1996" + sodipodi:role="line">DType</tspan></text> + <path + d="m -60.569299,180.38852 h 72.698771 c 1.14406,0 2.06509,0.92103 2.06509,2.06508 v 15.70853 c 0,1.14406 -0.92103,2.06509 -2.06509,2.06509 h -72.698771 c -1.14406,0 -2.06509,-0.92103 -2.06509,-2.06509 V 182.4536 c 0,-1.14405 0.92103,-2.06508 2.06509,-2.06508 z" + style="opacity:0.25;fill:#000080;fill-opacity:0.4;stroke:none;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.2, 2.4;stroke-dashoffset:0;stroke-opacity:0.497957" + id="path2004" + inkscape:connector-curvature="0" + sodipodi:nodetypes="sssssssss" /> + <path + d="m 175.57697,180.55362 h 65.38081 c 1.14406,0 2.06509,0.92103 2.06509,2.06509 v 15.54342 c 0,1.14406 -0.92103,2.06509 -2.06509,2.06509 h -65.38081 c -1.14406,0 -2.06509,-0.92103 -2.06509,-2.06509 v -15.54342 c 0,-1.14406 0.92103,-2.06509 2.06509,-2.06509 z" + style="opacity:1;fill:#ddb9b9;fill-opacity:0.796078;stroke:none;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.2, 2.4;stroke-dashoffset:0;stroke-opacity:0.497957" + id="path2006" + inkscape:connector-curvature="0" + sodipodi:nodetypes="sssssssss" /> + <text + xml:space="preserve" + style="font-size:11.263px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000081;fill-opacity:1;stroke-width:0.264583" + x="-59.010956" + y="193.40663" + id="text2010"><tspan + sodipodi:role="line" + id="tspan2008" + x="-59.010956" + y="193.40663" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#000081;fill-opacity:1;stroke-width:0.264583">base dtype</tspan></text> + <text + id="text2014" + y="194.58372" + x="184.03754" + style="font-size:11.263px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#800000;fill-opacity:0.8;stroke-width:0.264583" + xml:space="preserve"><tspan + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#800000;fill-opacity:0.8;stroke-width:0.264583" + y="194.58372" + x="184.03754" + id="tspan2012" + sodipodi:role="line">element</tspan></text> + <path + sodipodi:nodetypes="sssssssss" + inkscape:connector-curvature="0" + id="path2016" + style="opacity:0.25;fill:#000081;fill-opacity:0.4;stroke:none;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.2, 2.4;stroke-dashoffset:0;stroke-opacity:0.497957" + d="M 17.463123,180.38852 H 170.32495 c 1.14406,0 2.06509,0.92103 2.06509,2.06508 v 15.70853 c 0,1.14406 -0.92103,2.06509 -2.06509,2.06509 H 17.463123 c -1.14406,0 -2.06509,-0.92103 -2.06509,-2.06509 V 182.4536 c 0,-1.14405 0.92103,-2.06508 2.06509,-2.06508 z" /> + <text + id="text2020" + y="193.40663" + x="76.606812" + style="font-size:11.263px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000081;fill-opacity:1;stroke-width:0.264583" + xml:space="preserve"><tspan + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#000081;fill-opacity:1;stroke-width:0.264583" + y="193.40663" + x="76.606812" + id="tspan2018" + sodipodi:role="line">dtype</tspan></text> + <path + sodipodi:nodetypes="sssssssss" + inkscape:connector-curvature="0" + id="path2022" + style="opacity:1;fill:#ddb9b9;fill-opacity:0.796078;stroke:none;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.2, 2.4;stroke-dashoffset:0;stroke-opacity:0.497957" + d="m 175.57697,153.33338 h 65.38081 c 1.14406,0 2.06509,0.92103 2.06509,2.06509 v 15.54342 c 0,1.14406 -0.92103,2.06509 -2.06509,2.06509 h -65.38081 c -1.14406,0 -2.06509,-0.92103 -2.06509,-2.06509 v -15.54342 c 0,-1.14406 0.92103,-2.06509 2.06509,-2.06509 z" /> + <text + xml:space="preserve" + style="font-size:11.263px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#800000;fill-opacity:0.8;stroke-width:0.264583" + x="184.03754" + y="167.36348" + id="text2026"><tspan + sodipodi:role="line" + id="tspan2024" + x="184.03754" + y="167.36348" + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#800000;fill-opacity:0.8;stroke-width:0.264583">element</tspan></text> + <path + d="M 55.175507,153.27835 H 170.22016 c 1.14406,0 2.06509,0.92103 2.06509,2.06509 v 15.54342 c 0,1.14406 -0.92103,2.06509 -2.06509,2.06509 H 55.175507 c -1.14406,0 -2.06509,-0.92103 -2.06509,-2.06509 v -15.54342 c 0,-1.14406 0.92103,-2.06509 2.06509,-2.06509 z" + style="opacity:0.25;fill:#d99b00;fill-opacity:1;stroke:none;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.2, 2.4;stroke-dashoffset:0;stroke-opacity:0.497957" + id="path2031" + inkscape:connector-curvature="0" + sodipodi:nodetypes="sssssssss" /> + <text + id="text2035" + y="166.21391" + x="95.410606" + style="font-size:11.263px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#b27d00;fill-opacity:1;stroke-width:0.264583" + xml:space="preserve"><tspan + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Fira Code';-inkscape-font-specification:'Fira Code Semi-Bold';fill:#b27d00;fill-opacity:1;stroke-width:0.264583" + y="166.21391" + x="95.410606" + id="tspan2033" + sodipodi:role="line">dtype</tspan></text> + <path + style="fill:none;stroke:#808080;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 52.572927,70.114137 V 205.33633" + id="path3042" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cc" /> + <text + xml:space="preserve" + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:7.72103px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke-width:0.105503" + x="-122.18608" + y="110.75799" + id="text3050"><tspan + id="tspan3048" + sodipodi:role="line" + x="-122.18608" + y="110.75799" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503">Python type</tspan></text> + <text + xml:space="preserve" + id="text3052" + style="font-size:3.52778px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;white-space:pre;shape-inside:url(#rect3054);" /> + <text + id="text3062" + y="133.91008" + x="-122.18608" + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:7.72103px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke-width:0.105503" + xml:space="preserve"><tspan + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + y="133.91008" + x="-122.18608" + sodipodi:role="line" + id="tspan3060">Python type</tspan><tspan + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + y="143.61147" + x="-122.18608" + sodipodi:role="line" + id="tspan3064">with ABC</tspan></text> + <text + xml:space="preserve" + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:7.72103px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke-width:0.105503" + x="-140.57703" + y="165.22876" + id="text3070"><tspan + id="tspan3068" + sodipodi:role="line" + x="-140.57703" + y="165.22876" + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503">NEP 41 Proposal</tspan></text> + <text + id="text3076" + y="193.20123" + x="-117.83562" + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:7.72103px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke-width:0.105503" + xml:space="preserve"><tspan + style="font-size:7.76111px;fill:#000000;stroke-width:0.105503" + y="193.20123" + x="-117.83562" + sodipodi:role="line" + id="tspan3074">Alternative</tspan></text> + <path + sodipodi:nodetypes="cc" + inkscape:connector-curvature="0" + id="path960" + d="M 244.3569,149.56007 H -141.19857" + style="fill:none;stroke:#808080;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + </g> +</svg> diff --git a/doc/neps/nep-0029-deprecation_policy.rst b/doc/neps/nep-0029-deprecation_policy.rst index 4674d24ec..957674ee6 100644 --- a/doc/neps/nep-0029-deprecation_policy.rst +++ b/doc/neps/nep-0029-deprecation_policy.rst @@ -77,7 +77,7 @@ release in November 2020 should support Python 3.7 and newer. The current Python release cadence is 18 months so a 42 month window ensures that there will always be at least two minor versions of Python in the window. The window is extended 6 months beyond the anticipated two-release -interval for Python to provides resilience against small fluctuations / +interval for Python to provide resilience against small fluctuations / delays in its release schedule. Because Python minor version support is based only on historical diff --git a/doc/neps/nep-0040-legacy-datatype-impl.rst b/doc/neps/nep-0040-legacy-datatype-impl.rst index c247e3d62..39889109d 100644 --- a/doc/neps/nep-0040-legacy-datatype-impl.rst +++ b/doc/neps/nep-0040-legacy-datatype-impl.rst @@ -13,15 +13,15 @@ NEP 40 — Legacy Datatype Implementation in NumPy .. note:: - This NEP is part of a series of NEPs encompassing first information - about the previous dtype implementation and issues with it in NEP 40 - (this document). - :ref:`NEP 41 <NEP41>` then provides an overview and generic design choices - for the refactor. - Further NEPs 42 and 43 go into the technical details of the datatype - and universal function related internal and external API changes. - In some cases it may be necessary to consult the other NEPs for a full - picture of the desired changes and why these changes are necessary. + This NEP is first in a series: + + - NEP 40 (this document) explains the shortcomings of NumPy's dtype implementation. + + - :ref:`NEP 41 <NEP41>` gives an overview of our proposed replacement. + + - :ref:`NEP 42 <NEP42>` describes the new design's datatype-related APIs. + + - NEP 43 describes the new design's API for universal functions. @@ -44,6 +44,8 @@ of the current implementation of dtypes as well as a discussion. In many cases subsections will be split roughly to first describe the current implementation and then follow with an "Issues and Discussion" section. +.. _parametric-datatype-discussion: + Parametric Datatypes ^^^^^^^^^^^^^^^^^^^^ @@ -253,6 +255,8 @@ types such as ``np.inexact`` (see figure below). In fact, some control flow within NumPy currently uses ``issubclass(a.dtype.type, np.inexact)``. +.. _nep-0040_dtype-hierarchy: + .. figure:: _static/nep-0040_dtype-hierarchy.png **Figure:** Hierarchy of NumPy scalar types reproduced from the reference @@ -335,7 +339,7 @@ Each of these signatures is associated with a single inner-loop function defined in C, which does the actual calculation, and may be called multiple times. The main step in finding the correct inner-loop function is to call a -:c:type:`PyUFunc_TypeResolutionFunc` which retrieves the input dtypes from +:c:type:`PyUFunc_TypeResolutionFunc` which retrieves the input dtypes from the provided input arrays and will determine the full type signature (including output dtype) to be executed. @@ -366,7 +370,7 @@ It is currently only possible for user defined functions to be found/resolved if any of the inputs (or the outputs) has the user datatype, since it uses the `OO->O` signature. For example, given that a ufunc loop to implement ``fraction_divide(int, int) --> Fraction`` has been implemented, +-> Fraction`` has been implemented, the call ``fraction_divide(4, 5)`` (with no specific output dtype) will fail because the loop that includes the user datatype ``Fraction`` (as output) can only be found if any of @@ -572,7 +576,7 @@ Related Work ------------ * Julia types are an interesting blueprint for a type hierarchy, and define - abstract and concrete types [julia-types]_. + abstract and concrete types [julia-types]_. * In Julia promotion can occur based on abstract types. If a promoter is defined, it will cast the inputs and then Julia can then retry to find @@ -607,7 +611,7 @@ the following provides a subset for more recent ones: * https://hackmd.io/ok21UoAQQmOtSVk6keaJhw and https://hackmd.io/s/ryTFaOPHE (2019-04-30) Proposals for subclassing implementation approach. - + * Discussion about the calling convention of ufuncs and need for more powerful UFuncs: https://github.com/numpy/numpy/issues/12518 diff --git a/doc/neps/nep-0041-improved-dtype-support.rst b/doc/neps/nep-0041-improved-dtype-support.rst index 6dc4ea50c..d7a08562d 100644 --- a/doc/neps/nep-0041-improved-dtype-support.rst +++ b/doc/neps/nep-0041-improved-dtype-support.rst @@ -15,15 +15,15 @@ NEP 41 — First step towards a new Datatype System .. note:: - This NEP is part of a series of NEPs encompassing first information - about the previous dtype implementation and issues with it in - :ref:`NEP 40 <NEP40>`. - NEP 41 (this document) then provides an overview and generic design - choices for the refactor. - Further NEPs 42 and 43 go into the technical details of the datatype - and universal function related internal and external API changes. - In some cases it may be necessary to consult the other NEPs for a full - picture of the desired changes and why these changes are necessary. + This NEP is second in a series: + + - :ref:`NEP 40 <NEP40>` explains the shortcomings of NumPy's dtype implementation. + + - NEP 41 (this document) gives an overview of our proposed replacement. + + - :ref:`NEP 42 <NEP42>` describes the new design's datatype-related APIs. + + - NEP 43 describes the new design's API for universal functions. Abstract @@ -412,27 +412,28 @@ multiple development stages are required: * Phase II: Incrementally define or rework API - * Create a new and easily extensible API for defining new datatypes - and related functionality. (NEP 42) - - * Incrementally define all necessary functionality through the new API (NEP 42): - - * Defining operations such as ``np.common_type``. - * Allowing to define casting between datatypes. - * Add functionality necessary to create a numpy array from Python scalars - (i.e. ``np.array(...)``). - * … - - * Restructure how universal functions work (NEP 43), in order to: - - * make it possible to allow a `~numpy.ufunc` such as ``np.add`` to be - extended by user-defined datatypes such as Units. - - * allow efficient lookup for the correct implementation for user-defined - datatypes. - - * enable reuse of existing code. Units should be able to use the - normal math loops and add additional logic to determine output type. + * Incrementally define all necessary functionality through methods and + properties on the DType (NEP 42): + + * The properties of the class hierarchy and DType class itself, + including methods not covered by the following, most central, points. + * The functionality that will support dtype casting using ``arr.astype()`` + and casting related operations such as ``np.common_type``. + * The implementation of item access and storage, and the way shape and + dtype are determined when creating an array with ``np.array()`` + * Create a public C-API to define new DTypes. + + * Restructure how universal functions work (NEP 43), to allow extending + a `~numpy.ufunc` such as ``np.add`` for user-defined datatypes + such as Units: + + * Refactor how the low-level C functions are organized to make it + extensible and flexible enough for complicated DTypes such as Units. + * Implement registration and efficient lookup for these low-level C + functions as defined by the user. + * Define how promotion will be used to implement behaviour when casting + is required. For example ``np.float64(3) + np.int32(3)`` promotes the + ``int32`` to a ``float64``. * Phase III: Growth of NumPy and Scientific Python Ecosystem capabilities: @@ -583,7 +584,7 @@ special methods move from the dtype instances to methods on the new DType class. This is the typical design pattern used in Python. Organizing these methods and information in a more Pythonic way provides a solid foundation for refining and extending the API in the future. -The current API cannot be extended due to how it is exposed publically. +The current API cannot be extended due to how it is exposed publicly. This means for example that the methods currently stored in ``PyArray_ArrFuncs`` on each datatype (see :ref:`NEP 40 <NEP40>`) will be defined differently in the future and @@ -620,6 +621,49 @@ While DType and Scalar describe the same concept/type (e.g. an `int64`), it seems practical to split out the information and functionality necessary for numpy into the DType class. +The dtype instances provide parameters and storage options +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +From a computer science point of view a type defines the *value space* +(all possible values its instances can take) and their *behaviour*. +As proposed in this NEP, the DType class defines value space and behaviour. +The ``dtype`` instance can be seen as part of the value, so that the typical +Python ``instance`` corresponds to ``dtype + element`` (where *element* is the +data stored in the array). +An alternative view would be to define value space and behaviour on the +``dtype`` instances directly. +These two options are presented in the following figure and compared to +similar Python implementation patterns: + +.. image:: _static/nep-0041-type-sketch-no-fonts.svg + +The difference is in how parameters, such as string length or the datetime +units (``ms``, ``ns``, ...), and storage options, such as byte-order, are handled. +When implementing a Python (scalar) ``type`` parameters, for example the datetimes +unit, will be stored in the instance. +This is the design NEP 42 tries to mimic, however, the parameters are now part +of the dtype instance, meaning that part of the data stored in the instance +is shared by all array elements. +As mentioned previously, this means that the Python ``instance`` corresponds +to the ``dtype + element`` stored in a NumPy array. + +An more advanced approach in Python is to use a class factory and an abstract +base class (ABC). +This allows moving the parameter into the dynamically created ``type`` and +behaviour implementation may be specific to those parameters. +An alternative approach might use this model and implemented behaviour +directly on the ``dtype`` instance. + +We believe that the version as proposed here is easier to work with and understand. +Python class factories are not commonly used and NumPy does not use code +specialized for dtype parameters or byte-orders. +Making such specialization easier to implement such specialization does not +seem to be a priority. +One result of this choice is that some DTypes may only have a singleton instance +if they have no parameters or storage variation. +However, all of the NumPy dtypes require dynamically created instances due +to allowing metadata to be attached. + Scalars should not be instances of the datatypes (2) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/doc/neps/nep-0042-new-dtypes.rst b/doc/neps/nep-0042-new-dtypes.rst index b37555892..2d1e3a329 100644 --- a/doc/neps/nep-0042-new-dtypes.rst +++ b/doc/neps/nep-0042-new-dtypes.rst @@ -1,9 +1,12 @@ -======================================== -NEP 42 — Implementation of New DataTypes -======================================== +.. _NEP42: -:title: Extensible Datatypes for NumPy +============================================================================== +NEP 42 — User-extensible dtypes +============================================================================== + +:title: User-extensible dtypes :Author: Sebastian Berg +:Author: Ben Nathanson :Author: Marten van Kerkwijk :Status: Draft :Type: Standard @@ -12,666 +15,439 @@ NEP 42 — Implementation of New DataTypes .. note:: - This NEP is part of a series of NEPs encompassing first information - about the previous dtype implementation and issues with it in - :ref:`NEP 40 <NEP40>`. - :ref:`NEP 41 <NEP41>` then provides an overview and generic design - choices for the refactor. NEPs 42 (this document) - and 43 go into the technical details of the internal and external - API changes related to datatypes and universal functions, respectively. - In some cases it may be necessary to consult the other NEPs for a full - picture of the desired changes and why these changes are necessary. + This NEP is third in a series: + - :ref:`NEP 40 <NEP40>` explains the shortcomings of NumPy's dtype implementation. -Abstract --------- - -NEP 40 and 41 detailed the need for the creation of a new datatype system within -NumPy to better serve downstream use-cases and improve the maintainability -and the extensibility of NumPy. -A main issue with the current dtype API is that datatypes are written as -a single Python class with special instances for each of the actual datatypes. -While this certainly has been a practical approach in implementing numerical -datatypes, it does not allow to naturally split up logic. For example, -functions such as ``can_cast`` have explicit logic for each datatype. -Because of this monolithic code structure user-defined datatypes do not have -the same capabilities as NumPy datatypes have. -The current structure also makes understanding and modifying datatypes harder. -The current datatypes are not well encapsulated, so modifications targeting -a single datatype inevitably touch code involving others. -As detailed in NEP 41, the desired general design is to create classes for -each of the NumPy-provided datatypes, meaning that ``np.dtype("float64")`` -returns an instance of a ``Float64`` class which is a subclass of ``np.dtype``. -``np.dtype[float64]`` will also be used to denote this class. -This will allow moving all logic into special methods on the ``np.dtype`` -subclasses. This ``DType`` class would then serve as the central -extension point for adding new dtypes to NumPy. - -This document proposes the new API for the datatypes itself. -A second proposal NEP 43 details proposed changes to the universal -functions. -Note that only the implementation of both NEPs will provide the desired full -functionality. + - :ref:`NEP 41 <NEP41>` gives an overview of our proposed replacement. + - NEP 42 (this document) describes the new design's datatype-related APIs. -.. note:: + - NEP 43 describes the new design's API for universal functions. - At this time this NEP is in a preliminary state. Both internal and - external API may be adapted based on user input or implementation needs. - The general design principles and choices, while provisional, should not - be expected to change dramatically. +****************************************************************************** +Abstract +****************************************************************************** -Detailed Description --------------------- +NumPy's dtype architecture is monolithic, built around a single class that +handles each dtype as an instance. There's no principled way to expand it to +new dtypes, and the code is difficult to read and maintain. -NEP 41 layed out the creation of a class hierarchy for datatypes using the -new DType classes to provide all necessary implementations. -This NEP defines the specific choice of API necessary to define new DTypes. -Here, these are suggested as C-API slots; however, conceptually these -translate identically to Python methods. +As NEP 41 explains, we are proposing a new architecture that is modular and +open to user additions. dtypes will derive from a new ``DType`` class serving +as the extension point for new types. ``np.dtype("float64")`` will return an +instance of a ``Float64`` class, a subclass of root class ``np.dtype``. -Additionally, the NEP proposes to implement the notion of *abstract* DTypes. -Further, we detail – in part – how the proposed methods (C-API slots) -enable all necessary use cases. +This NEP is one of two that lay out the design and API of this new +architecture. This NEP addresses dtype implementation; NEP 43 addresses +universal functions. -Each section will begin with a short motivation of the issue or what -problem is addressed. This is followed by a description of the proposed -design choice, and then may list alternatives. +.. note:: + Details of the private and external APIs may change to reflect user + comments and implementation constraints. The underlying principles and + choices should not change significantly. -Nomenclature -"""""""""""" -As a brief note on nomenclature, it should be noted that ``dtype`` normally -denotes the dtype *instance*, which is the object attached to a numpy array. -On the other hand the ``DType`` class is the subclass of ``np.dtype``. -On the C-level we currently use the name ``descriptor`` or ``descr`` -interchangeably with *dtype instance*. ``descriptor`` or ``descr`` will be -used in proposed C-API names to differentiate dtype instances from DType -classes more clearly. -Note that the notion of dtype class is currently represented mainly as -the ``dtype.num`` and ``dtype.char``. -Please see the :ref:`dtype hierarchy figure <hierarchy_figure>` for an -illustration of this distinction. +****************************************************************************** +Motivation and scope +****************************************************************************** -There are currently classes in NumPy for numeric types e.g. -``np.float64``; however, -these are not DTypes but the corresponding scalar classes -(see also NEP 40 and 41 for discussion on why these are largely unrelated to -the proposed changes). +Our goal is to allow user code to create fully featured dtypes for a broad +variety of uses, from physical units (such as meters) to domain-specific +representations of geometric objects. NEP 41 describes a number of these new +dtypes and their benefits. +Any design supporting dtypes must consider: -Proposed access to DType class -"""""""""""""""""""""""""""""" +- How shape and dtype are determined when an array is created +- How array elements are stored and accessed +- The rules for casting dtypes to other dtypes -**Motivation:** +In addition: -Currently we often call ``np.dtype`` to create the dtype instance -corresponding to a given scalar type (e.g. ``np.dtype(np.int64)``). -Adding the DType classes may require a way to access the classes conveniently. +- We want dtypes to comprise a class hierarchy open to new types and to + subhierarchies, as motivated in :ref:`NEP 41 <NEP41>`. -**Description:** +And to provide this, -To avoid duplication, but also to expose the classes conveniently to users -we propose the addition of:: +- We need to define a user API. - np.dtype[np.int64] +All these are the subjects of this NEP. -as a class getter. This can work both for user and NumPy DTypes, -although, in many cases a library may choose to provide a more direct -way to access the specific DType class. -This method may initially be limited to concrete DTypes. -The main reason for this choice is to provide a single -clear and future-proof way to find the DType class given the -Python (scalar) class. +- The class hierarchy, its relation to the Python scalar types, and its + important attributes are described in `DType class`_. -This should not be a common operation, so providing this class getter reduces -the pressure of adding the new DType classes into the namespace. +- The functionality that will support dtype casting is described in `Casting`_. -*Note: This is currently a possible extension and not yet decided.* +- The implementation of item access and storage, and the way shape and dtype + are determined when creating an array, are described in `Array coercion`_. +- The functionality for users to define their own DTypes is described in + `Public C-API`_. -Hierarchy of DTypes and Abstract DTypes -""""""""""""""""""""""""""""""""""""""" +The API here and in NEP 43 is entirely on the C side. A Python-side version +will be proposed in a future NEP. +A future Python API is expected to be similar, but provide a more convenient +API to reuse the functionality of existing DTypes. +It could also provide shorthands to create structured DTypes similar to python's +`dataclasses <https://docs.python.org/3.8/library/dataclasses.html>`_. -**Motivation:** -The creation of DType classes has already been decided in NEP 41. -Here we discuss the notion of **abstract** DTypes. -There are multiple reasons for this: -1. It allows the definition of a class hierarchy, in principle allowing checks like - ``isinstance(np.dtype("float64"), np.inexact)``. - **This hierarchy may be a prerequisite to implementing dispatching - for universal functions (NEP 43)** -2. Abstract DTypes can enable code such as - ``arr.astype(Complex)`` to express the desire to cast to a - complex data type of unspecified precision. -3. It anticipates the creation of families of DTypes by users. - For example allowing the creation of an abstract ``Unit`` class with a concrete - ``Float64Unit``. In which case ``Unit(np.float64, "m")`` could be - identical to ``Float64Unit("m")``. - -A very concrete example is the current Pandas ``Categorical`` DType, -which may benefit from abstraction to allow the differentiation of -a categorical of integer values and one of general object values. -The reason for this is that we may want to reject -``common_dtype(CategoricalInt64, String)``, but accept -``common_dtype(CategoricalObject, String)`` to be the ``object`` DType. -The current Pandas ``Categorical`` DType combines both and must remain -representable. The solution is thus to make ``Categorical`` abstract with -the two subclasses ``CategoricalInt64`` and ``CategoricalObject`` -distinguishing the two. - - -**Description:** - -The figure below shows the proposed datatype hierarchy. -It should be noted that abstract DTypes are distinct in two ways: - -1. They do not have instances. Instantiating an abstract DType has to return - a concrete subclass or raise an error (default, and possibly enforced - initially). -2. Unlike concrete DTypes, abstract DTypes can be superclasses, they may also - serve like Python's abstract base classes (ABC). - (It may be possible to simply use/inherit from Python ABCs.) - -These two rules are identical to the type choices made for example in the -`Julia language <https://docs.julialang.org/en/v1/manual/types/#man-abstract-types-1>`_. -It allows for the creation of a datatype hierarchy, but avoids issues with -subclassing concrete DTypes directly. -For example, logic such as ``can_cast`` does not cleanly inherit from a -``Int64`` to a ``Datetime64`` even though the ``Datetime64`` could be seen -as an integer with only a unit attached (and thus implemented as a subclass). - -The main consequence for the DType implementer is that concrete DTypes can -never be subclasses of existing concrete DTypes. -End-users would not notice or need to know about this distinction. -However, subclassing may be a possible mechanism to extend the datatypes -in the future to allow specialized implementations for existing dtypes -such as a GPU float64 subclassing a NumPy float64. - -The combination of (initially) rejecting subclassing of concrete DTypes -while allowing it for abstract ones allows the transparent definition of -a class hierarchy, while avoiding potential issues with subclassing and -especially inheritance. - -As a technical implementation detail: the DType class will require C-side -storage of methods and additional information. -This requires the creation of a ``DTypeMeta`` class. -Each ``DType`` class is thus an instance of ``DTypeMeta`` with a well-defined -and extensible interface. -The end-user will not need to be aware of this. - -.. _hierarchy_figure: -.. figure:: _static/dtype_hierarchy.svg - :figclass: align-center - - -Methods/Slots defined for each DType -"""""""""""""""""""""""""""""""""""" - -NEP 41 detailed that all logic should be defined through special methods -on the DTypes. -This section will list a specific set of such methods (in the form of -Python methods). -The C-side equivalent slot signature will be summarized below after proposing -the general C-API for defining new Datatypes. -Note that while the slots are defined as special Python methods here, this is -for the readers convenience and *not* meant to imply the identical exposure -as a Python API. -This will need to be proposed in a separate, later, NEP. +****************************************************************************** +Backward compatibility +****************************************************************************** -Some of the methods may be similar or even reuse existing Python slots. -User-defined DType classes are discouraged from defining or using Python's -special slots without consulting the NumPy developers, in order to allow -defining them later. -For example ``dtype1 & dtype2`` could be a shorthand for -``np.common_dtype(dtype1, dtype2)``, and comparisons should be defined mainly -through casting logic. +The disruption is expected to be no greater than that of a typical NumPy +release. +- The main issues are noted in :ref:`NEP 41 <NEP41>` and will mostly affect + heavy users of the NumPy C-API. -Additional Information -^^^^^^^^^^^^^^^^^^^^^^ +- Eventually we will want to deprecate the API currently used for creating + user-defined dtypes. -In addition to the more detailed methods below, the following general -information is currently provided and will be defined on the class: +- Small, rarely noticed inconsistencies are likely to change. Examples: -* ``cls.parametric`` (see also `NEP 40 <NEP40>`_): + - ``np.array(np.nan, dtype=np.int64)`` behaves differently from + ``np.array([np.nan], dtype=np.int64)`` with the latter raising an error. + This may require identical results (either both error or both succeed). + - ``np.array([array_like])`` sometimes behaves differently from + ``np.array([np.array(array_like)])`` + - array operations may or may not preserve dtype metadata - * Parametric will be a flag in the (private) C-API. However, the - Python API will instead use a ``ParametricDType`` class from - which to inherit. (This is similar to Python's type flags, which include - flags for some basic subclasses such as subclasses of ``float`` or ``tuple``) - * This flag is mainly to simplify DType creation and casting and - allow for performance tweaks. - * DTypes which are not parametric must define a canonical dtype instance - which should be a singleton. - * Parametric dtypes require some additional methods (below). +The new code must pass NumPy's regular test suite, giving some assurance that +the changes are compatible with existing code. -* ``self.canonical`` method (Alternative: new instance attribute) +****************************************************************************** +Usage and impact +****************************************************************************** - * Instead of byteorder, we may want a ``canonical`` flag (reusing the - ISNBO flag – "is native byte order" seems possible here). - This flag signals that the data are stored in the default/canonical way. - In practice this is always an NBO check, but generalization should be possible. - A potential use-case is a complex-conjugated instance of Complex which - stores ``real - imag`` instead of ``real + imag`` and is thus not - the canonical storage. +We believe the few structures in this section are sufficient to consolidate +NumPy's present functionality and also to support complex user-defined DTypes. -* ``ensure_canonical(self) -> dtype`` return a new dtype (or ``self``). - The returned dtype must have the ``canonical`` flag set. +The rest of the NEP fills in details and provides support for the claim. -* ``DType.type`` is the associated scalar type. ``dtype.type`` will be a - class attribute and the current ``dtype.type`` field will be considered - deprecated. This may be relaxed if a use-case arises. +Again, though Python is used for illustration, the implementation is a C API only; a +future NEP will tackle the Python API. -Additionally, existing methods (and C-side fields) will be provided. -However, the fields ``kind`` and ``char`` will be set to ``\0`` -(NULL character) on the C-side. -While discouraged, except for NumPy builtin types, ``kind`` both will return -the ``__qualname__`` of the object to ensure uniqueness for all DTypes. -(the replacement for ``kind`` will be to use ``isinstance`` checks). +After implementing this NEP, creating a DType will be possible by implementing +the following outlined DType base class, +that is further described in `DType class`_: -Another example of methods that should be moved to the DType class are the -various sorting functions, which shall be implemented by defining a method: +.. code-block:: python + :dedent: 0 -* ``dtype_get_sort_function(self, sortkind="stable") -> sortfunction`` + class DType(np.dtype): + type : type # Python scalar type + parametric : bool # (may be indicated by superclass) -which must return ``NotImplemented`` if the given ``sortkind`` is not known. -Similarly, any function implemented previously which cannot be removed will -be implemented as a special method. -Since these methods can be deprecated and new (renamed) replacements added, -the API is not defined here and it is acceptable if it changes over time. + @property + def canonical(self) -> bool: + raise NotImplementedError -For some of the current "methods" defined on the dtype, including sorting, -a long term solution may be to instead create generalized ufuncs to provide -the functionality. + def ensure_canonical(self : DType) -> DType: + raise NotImplementedError -**Alternatives:** +For casting, a large part of the functionality is provided by the "methods" stored +in ``_castingimpl`` -Some of these flags could be implemented by inheriting -for example from a ``ParametricDType`` class. However, on the C-side as -an implementation detail it seems simpler to provide a flag. -This does not preclude the possibility of creating a ``ParametricDType`` -to Python to represent the same thing. +.. code-block:: python + :dedent: 0 -**Example:** + @classmethod + def common_dtype(cls : DTypeMeta, other : DTypeMeta) -> DTypeMeta: + raise NotImplementedError -The ``datetime64`` DType is considered parametric, due to its unit, and -unlike a float64 has no canonical representation. The associated ``type`` -is the ``np.datetime64`` scalar. + def common_instance(self : DType, other : DType) -> DType: + raise NotImplementedError + # A mapping of "methods" each detailing how to cast to another DType + # (further specified at the end of the section) + _castingimpl = {} -**Issues and Details:** +For array-coercion, also part of casting: -A potential DType such as ``Categorical`` will not be required to have a clear type -associated with it. Instead, the ``type`` may be ``object`` and the -categorical's values are arbitrary objects. -Unlike with well-defined scalars, this ``type`` cannot -not be used for the dtype discovery necessary for coercion -(compare section `DType Discovery during Array Coercion`_). - - -Coercion to and from Python Objects -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. code-block:: python + :dedent: 0 -**Motivation:** + def __dtype_setitem__(self, item_pointer, value): + raise NotImplementedError -When storing a single value in an array or taking it out of the array, -it is necessary to coerce (convert) it to and from the low-level -representation inside the array. + def __dtype_getitem__(self, item_pointer, base_obj) -> object: + raise NotImplementedError -**Description:** + @classmethod + def __discover_descr_from_pyobject__(cls, obj : object) -> DType: + raise NotImplementedError -Coercing to and from Python scalars requires two to three methods: + # initially private: + @classmethod + def _known_scalar_type(cls, obj : object) -> bool: + raise NotImplementedError -1. ``__dtype_setitem__(self, item_pointer, value)`` -2. ``__dtype_getitem__(self, item_pointer, base_obj) -> object`` - The ``base_obj`` should be ignored normally, it is provided *only* for - memory management purposes, pointing to an object owning the data. - It exists only to allow support of structured datatypes with subarrays - within NumPy, which (currently) return views into the array. - The function returns an equivalent Python scalar (i.e. typically a NumPy - scalar). -3. ``__dtype_get_pyitem__(self, item_pointer, base_obj) -> object`` - (initially hidden for new-style user-defined datatypes, may be exposed - on user request). This corresponds to the ``arr.item()`` method which - is also used by ``arr.tolist()`` and returns e.g. Python floats instead of - NumPy floats. -(The above is meant for C-API. A Python-side API would have to use byte -buffers or similar to implement this, which may be useful for prototyping.) +Other elements of the casting implementation is the ``CastingImpl``: -These largely correspond to the current definitions. When a certain scalar -has a known (different) dtype, NumPy may in the future use casting instead -of ``__dtype_setitem__``. -A user datatype is (initially) expected to implement ``__dtype_setitem__`` -for its own ``DType.type`` and all basic Python scalars it wishes to support -(e.g. integers, floats, datetime). -In the future a function "``known_scalartype``" may be added to allow a user -dtype to signal which Python scalars it can store directly. +.. code-block:: python + :dedent: 0 + casting = Union["safe", "same_kind", "unsafe"] -**Implementation:** + class CastingImpl: + # Object describing and performing the cast + casting : casting -The pseudo-code implementation for setting a single item in an array -from an arbitrary Python object ``value`` is (note that some of the -functions are only defined below):: - - def PyArray_Pack(dtype, item_pointer, value): - DType = type(dtype) - if DType.type is type(value) or DType.known_scalartype(type(value)): - return dtype.__dtype_setitem__(item_pointer, value) - - # The dtype cannot handle the value, so try casting: - arr = np.array(value) - if arr.dtype is object or arr.ndim != 0: - # not a numpy or user scalar; try using the dtype after all: - return dtype.__dtype_setitem__(item_pointer, value) - - arr.astype(dtype) - item_pointer.write(arr[()]) - -where the call to ``np.array()`` represents the dtype discovery and is -not actually performed. + def resolve_descriptors(self, Tuple[DType] : input) -> (casting, Tuple[DType]): + raise NotImplementedError -**Example:** + # initially private: + def _get_loop(...) -> lowlevel_C_loop: + raise NotImplementedError -Current ``datetime64`` returns ``np.datetime64`` scalars and can be assigned -from ``np.datetime64``. -However, the datetime ``__dtype_setitem__`` also allows assignment from -date strings ("2016-05-01") or Python integers. -Additionally the datetime ``__dtype_get_pyitem__`` function actually returns -Python ``datetime.datetime`` object (most of the time). +which describes the casting from one DType to another. +In NEP 43 this ``CastingImpl`` object is used unchanged to support +universal functions. -**Alternatives:** +****************************************************************************** +Definitions +****************************************************************************** +.. glossary:: -This may be seen as simply a cast to and from the ``object`` dtype. -However, it seems slightly more complicated. This is because -in general a Python object could itself be a zero-dimensional array or -scalar with an associated DType. -Thus, representing it as a normal cast would either require that: + dtype + The dtype *instance*; this is the object attached to a numpy array. -* The implementor handles all Python classes, even those for which - ``np.array(scalar).astype(UserDType)`` already works because - ``np.array(scalar)`` returns, say, a datetime64 array. -* The cast is actually added between a typed-object to dtype. And even - in this case a generic fallback (for example ``float64`` can use - ``float(scalar)`` to do the cast) is also necessary. + DType + Any subclass of the base type ``np.dtype``. -It is certainly possible to describe the coercion to and from Python objects -using the general casting machinery. However, it seems special enough to -handle specifically. + coercion + Conversion of Python types to NumPy arrays and values stored in a NumPy + array. + cast + Conversion of an array to a different dtype. -**Further Issues and Discussion:** + promotion + Finding a dtype that can perform an operation on a mix of dtypes without + loss of information. -The setitem function currently duplicates some code, such as coercion -from a string. ``datetime64`` allows assignment from string, but the same -conversion also occurs for casts from the string dtype to ``datetime64``. -In the future, we may expose a way to signal whether a conversion is known, -and otherwise a normal cast is made so that the item is effectively set to ``np.array(scalar).astype(requested_dtype)``. + safe cast + A cast is safe if no information is lost when changing type. -There is a general issue about the handling of subclasses. We anticipate to not -automatically detect the dtype for ``np.array(float64_subclass)`` to be -float64. The user can still provide ``dtype=np.float64``. However, the above -"assign by casting" using ``np.array(scalar_subclass).astype(requested_dtype)`` -will fail. +On the C level we use ``descriptor`` or ``descr`` to mean +*dtype instance*. In the proposed C-API, these terms will distinguish +dtype instances from DType classes. .. note:: + Perhaps confusingly, NumPy already has a class hierarchy for numeric types, as + seen :ref:`in the figure <nep-0040_dtype-hierarchy>` of NEP 40, and the new + DType hierarchy will resemble it. But the existing hierarchy is for scalar + types, not DTypes, and its existence is largely irrelevant here, as NEP 40 and + 41 explain. - This means that ``np.complex256`` should not use ``__float__`` in its - ``__dtype_setitem__`` method in the future unless it is a known floating - point type. If the scalar is a subclass of a different high precision - floating point type (e.g. ``np.float128``) then this will lose precision. - - -DType Discovery during Array Coercion -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -An important step in the usage of NumPy arrays is the creation of the array -itself from collections of generic Python objects. - -**Motivation:** - -Although the distinction is not clear currently, there are two main needs:: - - np.array([1, 2, 3, 4.]) - -needs to guess the correct dtype based on the Python objects inside. -Such an array may include a mix of datatypes, as long as they can be clearly -promoted. -Currently not clearly distinct (but partially existing for strings) is the -use case of:: - - # np.dtype[np.str_] can also be spelled np.str_ or "S" (which works today) - np.array([object(), None], dtype=np.dtype[np.str_]) - -which forces each object to be interpreted as string. This is anticipated -to be useful for example for categorical datatypes:: - - np.array([1, 2, 1, 1, 2], dtype=Categorical) +.. _DType class: -to allow the discovery the of all unique values. -(For NumPy ``datetime64`` this is also currently used to allow string input.) - -There are three further issues to consider: - -1. It may be desirable that datatypes can be created which are associated - to normal Python scalars (such as ``datetime.datetime``), which do not - have a ``dtype`` attribute already. -2. In general, a datatype could represent a sequence, however, NumPy currently - assumes that sequences are always collections of elements (the sequence cannot be an - element itself). An example for this is would be a ``vector`` DType. -3. An array may itself contain arrays with a specific dtype (even - general Python objects). For example: - ``np.array([np.array(None, dtype=object)], dtype=np.String)`` - poses the issue of how to handle the included array. - -Some of these difficulties arise due to the fact that finding the correct shape -of the output array and finding the correct datatype are closely related. - -**Implementation:** - -There are two distinct cases given above: First, when the user has provided no -dtype information, and second when the user provided a DType class – -a notion that is currently represented e.g. by the parametric instance ``"S"`` -representing a string of any length. - -In the first case, it is necessary to establish a mapping from the Python type(s) -of the constituent elements to the DType class. -When the DType class is known, the correct dtype instance still needs to be found. -This shall be implemented by leveraging two pieces of information: - -1. ``DType.type``: The current type attribute to indicate which Python scalar - type is associated with the DType class (this is a *class* attribute that always - exists for any datatype and is not limited to array coercion). -2. The reverse lookup will remain hardcoded for the basic Python types initially. - Otherwise the ``type`` attribute will be used, and at least initially may - enforce deriving the scalar from a NumPy-provided scalar base class. - This method may be expanded later (see alternatives). -3. ``__discover_descr_from_pyobject__(cls, obj) -> dtype``: A classmethod that - returns the correct descriptor given the input object. - *Note that only parametric DTypes have to implement this*, most datatypes - can simply use a default (singleton) dtype instance which is found only - based on the ``type(obj)`` of the Python object. +****************************************************************************** +The DType class +****************************************************************************** -The Python type which is already associated with a DType through the -``DType.type`` attribute maps from the DType to the Python type. -A DType may choose to automatically discover from this Python type. -This will be achieved using a global a mapping (dictionary-like) of:: +This section reviews the structure underlying the proposed DType class, +including the type hierarchy and the use of abstract DTypes. - known_python_types[type] = DType +Class getter +============================================================================== -To anticipate the possibility of creating both a Python type (``pytype``) -and ``DType`` dynamically, and thus the potential desire to delete them again, -this mapping should generally be weak. -This requires that the ``pytype`` holds on to the ``DType`` explicitly. -Thus, in addition to building the global mapping, NumPy will store -the ``DType`` as ``pytype.__associated_array_dtype__`` in the Python type. -This does *not* define the mapping and should *not* be accessed directly. -In particular potential inheritance of the attribute does not mean that -NumPy will use the superclasses ``DType`` automatically. -A new ``DType`` must be created for the subclass. +To create a dtype instance from a scalar type users now call ``np.dtype`` (for +instance, ``np.dtype(np.int64)``). -.. note:: +To get the DType of a scalar type, we propose this getter syntax:: - Python integers do not have a clear/concrete NumPy type associated with - them right now. This is because during array coercion NumPy currently - finds the first type capable of representing their value in the list - of `long`, `unsigned long`, `int64`, `unsigned int64`, and `object` - (on many machines `long` is 64 bit). - - Instead they will need to be implemented using an - ``AbstractPyInt``. This DType class can then provide - ``__discover_descr_from_pyobject__`` and return the actual dtype which - is e.g. ``np.dtype("int64")``. - For dispatching/promotion in ufuncs, it will also be necessary - to dynamically create ``AbstractPyInt[value]`` classes (creation can be - cached), so that they can provide the current value based promotion - functionality provided by ``np.result_type(python_integer, array)`` [1]_. - -To allow for a DType to accept specific inputs as known scalars, we will -initially use a ``known_scalar_type`` method. -This allows discovery of a ``vector`` as a scalar (element) instead of -a sequence (for the command ``np.array(vector, dtype=VectorDType)``) -even when ``vector`` is itself a sequence or even an array subclass. -This will *not* be public API initially, but may be made public at a later -time. - -This will work similar to the following pseudo-code:: + np.dtype[np.int64] - def find_dtype(array_like): - common_dtype = None - for element in array_like: - # default to object dtype, if unknown - DType = known_python_types.get(type(element), np.dtype[object]) - dtype = DType.__discover_descr_from_pyobject__(element) +The notation works equally well with built-in and user-defined DTypes +and is inspired by and potentially useful for type hinting. - if common_dtype is None: - common_dtype = dtype - else: - common_dtype = np.promote_types(common_dtype, dtype) +This getter eliminates the need to create an explicit name for every +DType, crowding the ``np`` namespace; the getter itself signifies the type. -In practice, we have to find out whether an element is actually a sequence. -This means that instead of using the ``object`` dtype directly, we have to -check whether or not it is a sequence. +Since getter calls won't be needed often, this is unlikely to be burdensome. +Classes can also offer concise alternatives. -The full algorithm (without user provided dtype) thus looks more like:: +The initial implementation probably will return only concrete (not abstract) +DTypes. - def find_dtype_recursive(array_like, dtype=None): - """ - Recursively find the dtype for a nested sequences (arrays are not - supported here). - """ - DType = known_python_types.get(type(element), None) +*This item is still under review.* - if DType is None and is_array_like(array_like): - # Code for a sequence, an array_like may have a DType we - # can use directly: - for element in array_like: - dtype = find_dtype_recursive(element, dtype=dtype) - return dtype - elif DType is None: - DType = np.dtype[object] +Hierarchy and abstract classes +============================================================================== - # Same as above +We will use abstract classes as building blocks of our extensible DType class +hierarchy. -If the user provides ``DType``, then this DType will be tried first, and the -``dtype`` may need to be cast before the promotion is performed. +1. Abstract classes are inherited cleanly, in principle allowing checks like + ``isinstance(np.dtype("float64"), np.inexact)``. -**Limitations:** - -The above issue 3. is currently (sometimes) supported by NumPy so that -the values of an included array are inspected. -Support in those cases may be kept for compatibility, however, -it will not be exposed to user datatypes. -This means that if e.g. an array with a parametric string dtype is coerced above -(or cast) to an array of a fixed length string dtype (with unknown length), -this will result in an error. -Such a conversion will require passing the correct DType (fixed length of the -string) or providing a utility function to the user. - -The use of a global type map means that an error or warning has to be given -if two DTypes wish to map to the same Python type. In most cases user -DTypes should only be implemented for types defined within the same library to -avoid the potential for conflicts. -It will be the DType implementor's responsibility to be careful about this and use -the flag to disable registration when in doubt. - -**Alternatives:** - -The above proposes to add a global mapping, however, initially limiting it -to types deriving from a NumPy subclass (and a fixed set of Python types). -This could be relaxed in the future. -Alternatively, we could rely on the scalar belonging to the user dtype to -implement ``scalar.__associated_array_dtype__`` or similar. - -Initially, the exact implementation shall be *undefined*, if -scalars will have to derive from a NumPy scalar, they will also have -a ``.__associated_array_dtype__`` attribute. -At this time, a future update may to use this instead of a global mapping, -however, it makes NumPy a hard dependency for the scalar class. - -An initial alternative suggestion was to use a two-pass approach instead. -The first pass would only find the correct DType class, and the second pass -would then find correct dtype instance (the second pass is often not necessary). -The advantage of this is that the DType class information is vital for universal -functions to decide which loop to execute. -The first pass would provide the full information necessary for value-based -casting currently implemented for scalars, giving even the possibility of -expanding it to e.g. list inputs ``np.add(np.array([8], dtype="uint8"), [4])`` -giving a ``uint8`` result. -This is mainly related to the question to how the common dtype is found above. -It seems unlikely that this is useful, and similar to a global, could be -added later if deemed necessary. - -**Further Issues and Discussion:** - -While it is possible to create e.g. a DType such as Categorical, array, -or vector which can only be used if `dtype=DType` is provided, if this -is necessary these will not roundtrip correctly when converted back -and forth:: +2. Abstract classes allow a single piece of code to handle a multiplicity of + input types. Code written to accept Complex objects can work with numbers + of any precision; the precision of the results is determined by the + precision of the arguments. + +3. There is room for user-created families of DTypes. We can envision an + abstract ``Unit`` class for physical units, with a concrete subclass like + ``Float64Unit``. Calling ``Unit(np.float64, "m")`` (``m`` for meters) would + be equivalent to ``Float64Unit("m")``. + +4. The implementation of universal functions in NEP 43 may require + a class hierarchy. + +**Example:** A NumPy ``Categorical`` class would be a match for pandas +``Categorical`` objects, which can contain integers or general Python objects. +NumPy needs a DType that it can assign a Categorical to, but it also needs +DTypes like ``CategoricalInt64`` and ``CategoricalObject`` such that +``common_dtype(CategoricalInt64, String)`` raises an error, but +``common_dtype(CategoricalObject, String)`` returns an ``object`` DType. In +our scheme, ``Categorical`` is an abstract type with ``CategoricalInt64`` and +``CategoricalObject`` subclasses. + + +Rules for the class structure, illustrated :ref:`below <nep42_hierarchy_figure>`: + +1. Abstract DTypes cannot be instantiated. Instantiating an abstract DType + raises an error, or perhaps returns an instance of a concrete subclass. + Raising an error will be the default behavior and may be required initially. + +2. While abstract DTypes may be superclasses, they may also act like Python's + abstract base classes (ABC) allowing registration instead of subclassing. + It may be possible to simply use or inherit from Python ABCs. + +3. Concrete DTypes may not be subclassed. In the future this might be relaxed + to allow specialized implementations such as a GPU float64 subclassing a + NumPy float64. + +The +`Julia language <https://docs.julialang.org/en/v1/manual/types/#man-abstract-types-1>`_ +has a similar prohibition against subclassing concrete types. +For example methods such as the later ``__common_instance__`` or +``__common_dtype__`` cannot work for a subclass unless they were designed +very carefully. +It helps avoid unintended vulnerabilities to implementation changes that +result from subclassing types that were not written to be subclassed. +We believe that the DType API should rather be extended to simplify wrapping +of existing functionality. + +The DType class requires C-side storage of methods and additional information, +to be implemented by a ``DTypeMeta`` class. Each ``DType`` class is an +instance of ``DTypeMeta`` with a well-defined and extensible interface; +end users ignore it. + +.. _nep42_hierarchy_figure: +.. figure:: _static/dtype_hierarchy.svg + :figclass: align-center - np.array(np.array(1, dtype=Categorical)[()]) -requires to pass the original ``dtype=Categorical`` or returns an array -with dtype ``object``. -While a general limitation, the round-tripping shall always be possible if -``dtype=old_dtype`` is provided. +Miscellaneous methods and attributes +============================================================================== + +This section collects definitions in the DType class that are not used in +casting and array coercion, which are described in detail below. + +* Existing dtype methods and C-side fields are preserved. + +* ``DType.type`` replaces ``dtype.type``. Unless a use case arises, + ``dtype.type`` will be deprecated. + This indicates a Python scalar type which represents the same values as + the DType. This is the same type as used in the proposed `Class getter`_ + and for `DType discovery during array coercion`_. + (This can may also be set for abstract DTypes, this is necessary + for array coercion.) + +* A new ``self.canonical`` property generalizes the notion of byte order to + indicate whether data has been stored in a default/canonical way. For + existing code, "canonical" will just signify native byte order, but it can + take on new meanings in new DTypes -- for instance, to distinguish a + complex-conjugated instance of Complex which stores ``real - imag`` instead + of ``real + imag`` and is thus not the canonical storage. The ISNBO ("is + native byte order") flag might be repurposed as the canonical flag. + +* Support is included for parametric DTypes. As explained in + :ref:`NEP 40 <parametric-datatype-discussion>`, parametric types have a + value associated with them. A DType will be deemed parametric if it + inherits from ParametricDType. + + Strings are one example of a parametric type -- ``S8`` is different from + ``S4`` because ``S4`` cannot store a length 8 string such as ``"length 8"`` + while ``S8`` can. + Similarly, the ``datetime64`` DType is parametric, since its unit must be specified. + The associated ``type`` is the ``np.datetime64`` scalar. + +* DType methods may resemble or even reuse existing Python slots. Thus Python + special slots are off-limits for user-defined DTypes (for instance, defining + ``Unit("m") > Unit("cm")``), since we may want to develop a meaning for these + operators that is common to all DTypes. + +* Sorting functions are moved to the DType class. They may be implemented by + defining a method ``dtype_get_sort_function(self, sortkind="stable") -> + sortfunction`` that must return ``NotImplemented`` if the given ``sortkind`` + is not known. + +* Functions that cannot be removed are implemented as special methods. + Many of these were previously defined part of the :c:type:`PyArray_ArrFuncs` + slot of the dtype instance (``PyArray_Descr *``) and include functions + such as ``nonzero``, ``fill`` (used for ``np.arange``), and + ``fromstr`` (used to parse text files). + These old methods will be deprecated and replacements + following the new design principles added. + The API is not defined here. Since these methods can be deprecated and renamed + replacements added, it is acceptable if these new methods have to be modified. + +* Use of ``kind`` for non-built-in types is discouraged in favor of + ``isinstance`` checks. ``kind`` will return the ``__qualname__`` of the + object to ensure uniqueness for all DTypes. On the C side, ``kind`` and + ``char`` are set to ``\0`` (NULL character). + While ``kind`` will be discouraged, the current ``np.issubdtype`` + may remain the preferred method for this type of check. + +* A method ``ensure_canonical(self) -> dtype`` returns a new dtype (or + ``self``) with the ``canonical`` flag set. + +* Since NumPy's approach is to provide functionality through unfuncs, + functions like sorting that will be implemented in DTypes might eventually be + reimplemented as generalized ufuncs. + +.. _casting: + +****************************************************************************** +Casting +****************************************************************************** -**Example:** +We review here the operations related to casting arrays: -The current datetime DType requires a ``__discover_descr_from_pyobject__`` -which returns the correct unit for string inputs. This allows it to support -the current:: +- Finding the "common dtype," currently exposed by ``np.promote_types`` or + ``np.result_type`` - np.array(["2020-01-02", "2020-01-02 11:24"], dtype="M8") +- The result of calling ``np.can_cast`` -By inspecting the date strings. Together with the below common dtype -operation, this allows it to automatically find that the datetime64 unit -should be "minutes". +We show how casting arrays with ``arr.astype(new_dtype)`` will be implemented. +`Common DType` operations +============================================================================== -Common DType Operations -^^^^^^^^^^^^^^^^^^^^^^^ +Common-type operations are vital for array coercion when input types are +mixed. They determine the output dtype of ``np.concatenate()`` and are useful +in themselves. -NumPy currently provides functions like ``np.result_type`` and -``np.promote_types`` for determining common types. +NumPy provides ``np.result_type`` and +``np.promote_types``. These differ in that ``np.result_type`` can take arrays and scalars as input -and implements value based promotion [1]_. +and implements value-based promotion [1]_. -To distinguish between the promotion occurring during universal function application, -we will call it "common type" operation here. +To distinguish between the promotion occurring during universal function +application, we will call it "common type" operation here. **Motivation:** -Common type operations are vital for array coercion when different -input types are mixed. -They also provide the logic currently used to decide the output dtype of -``np.concatenate()`` and on their own are quite useful. Furthermore, common type operations may be used to find the correct dtype to use for functions with different inputs (including universal functions). @@ -684,32 +460,33 @@ This includes an interesting distinction: (Hypothetical example: ``float_arr + string_arr -> string``, but the output string length is not the same as ``np.concatenate(float_arr, string_arr)).dtype``.) -2. Array coercion and concatenation require the common dtype *instance*. -**Implementation:** -The implementation of the common dtype (instance) determination -has some overlap with casting. -Casting from a specific dtype (Float64) to a String needs to find -the correct string length (a step that is mainly necessary for parametric dtypes). +2. Array coercion and concatenation require the common dtype *instance*. + +**Implementation:** The implementation of the common dtype (instance) +determination has some overlap with casting. Casting from a specific dtype +(Float64) to a String needs to find the correct string length (a step that is +mainly necessary for parametric dtypes). We propose the following implementation: -1. ``__common_dtype__(cls, other : DTypeMeta) -> DTypeMeta`` answers what the common - DType class is given two DType class objects. - It may return ``NotImplemented`` to defer to ``other``. - (For abstract DTypes, subclasses get precedence, concrete types are always - leaves, so always get preference or are tried from left to right). +1. ``__common_dtype__(cls, other : DTypeMeta) -> DTypeMeta`` answers what the + common DType class is, given two DType class objects. It may return + ``NotImplemented`` to defer to ``other``. (For abstract DTypes, subclasses + get precedence, concrete types are never superclasses, so always get preference + or are tried from left to right). + 2. ``__common_instance__(self: SelfT, other : SelfT) -> SelfT`` is used when two instances of the same DType are given. - For builtin dtypes (that are not parametric), this - currently always returns ``self`` (but ensures native byte order). + For built-in dtypes (that are not parametric), this + currently always returns ``self`` (but ensures canonical representation). This is to preserve metadata. We can thus provide a default implementation for non-parametric user dtypes. These two cases do *not* cover the case where two different dtype instances -need to be promoted. For example `">float64"` and `"S8"`. -The solution is partially "outsourced" to the casting machinery by -splitting the operation up into three steps: +need to be promoted. For example `">float64"` and `"S8"`. The solution is +partially "outsourced" to the casting machinery by splitting the operation up +into three steps: 1. ``Float64.__common_dtype__(type(>float64), type(S8))`` returns `String` (or defers to ``String.__common_dtype__``). @@ -717,15 +494,13 @@ splitting the operation up into three steps: to `"S32"` (see below for how casting will be defined). 3. ``String.__common_instance__("S8", "S32")`` returns the final `"S32"`. -The main reason for this is to avoid the need to implement -identical functionality multiple times. -The design (together with casting) naturally separates the concerns of -different Datatypes. -In the above example, Float64 does not need to know about the cast. -While the casting machinery (``CastingImpl[Float64, String]``) -could include the third step, it is not required to do so and the string -can always be extended (e.g. with new encodings) without extending the -``CastingImpl[Float64, String]``. +The main reason for this is to avoid the need to implement identical +functionality multiple times. The design (together with casting) naturally +separates the concerns of different Datatypes. In the above example, Float64 +does not need to know about the cast. While the casting machinery +(``CastingImpl[Float64, String]``) could include the third step, it is not +required to do so and the string can always be extended (e.g. with new +encodings) without extending the ``CastingImpl[Float64, String]``. This means the implementation will work like this:: @@ -744,7 +519,7 @@ This means the implementation will work like this:: # Find what dtype1 is cast to when cast to the common DType # by using the CastingImpl as described below: castingimpl = get_castingimpl(type(dtype1), common) - safety, (_, dtype1) = castingimpl.adjust_descriptors((dtype1, None)) + safety, (_, dtype1) = castingimpl.resolve_descriptors((dtype1, None)) assert safety == "safe" # promotion should normally be a safe cast if type(dtype2) is not common: @@ -755,12 +530,10 @@ This means the implementation will work like this:: Some of these steps may be optimized for non-parametric DTypes. -**Note:** - -A currently implemented fallback for the ``__common_dtype__`` operation -is to use the "safe" casting logic. -Since ``int16`` can safely cast to ``int64``, it is clear that -``np.promote_types(int16, int64)`` should be ``int64``. +**Note:** A currently implemented fallback for the ``__common_dtype__`` +operation is to use the "safe" casting logic. Since ``int16`` can safely cast +to ``int64``, it is clear that ``np.promote_types(int16, int64)`` should be +``int64``. However, this cannot define all such operations, and will fail for example for:: @@ -771,39 +544,35 @@ in most cases a safe-cast implies that this will be the result of the ``__common_dtype__`` method. Note that some exceptions may apply. For example casting ``int32`` to -a (long enough) string is – at least at this time – considered "safe". +a (long enough) string is at least at this time considered "safe". However ``np.promote_types(int32, String)`` will *not* be defined. -**Alternatives:** - -The use of casting for common dtype (instance) determination neatly separates -the concerns and allows for a minimal set of duplicate functionality -being implemented. -In cases of mixed DType (classes), it also adds an additional step -to finding the common dtype. -The common dtype (of two instances) could thus be implemented explicitly to avoid -this indirection, potentially only as a fast-path. -The above suggestion assumes that this is, however, not a speed relevant path, -since in most cases, e.g. in array coercion, only a single Python type (and thus -dtype) is involved. -The proposed design hinges in the implementation of casting to be -separated into its own ufunc-like object as described below. +**Alternatives:** The use of casting for common dtype (instance) determination +neatly separates the concerns and allows for a minimal set of duplicate +functionality being implemented. In cases of mixed DType (classes), it also +adds an additional step to finding the common dtype. The common dtype (of two +instances) could thus be implemented explicitly to avoid this indirection, +potentially only as a fast-path. The above suggestion assumes that this is, +however, not a speed relevant path, since in most cases, e.g. in array +coercion, only a single Python type (and thus dtype) is involved. The proposed +design hinges in the implementation of casting to be separated into its own +ufunc-like object as described below. In principle common DType could be defined only based on "safe casting" rules, if we order all DTypes and find the first one both can cast to safely. However, the issue with this approach is that a newly added DType can change the behaviour of an existing program. For example, a new ``int24`` would be -the first valid common type for ``int16`` and ``uint16``, demoting the currently -defined behaviour of ``int32``. -This API extension could be allowed in the future, while adding it may be -more involved, the current proposal for defining casts is fully opaque in -this regard and thus extensible. - -**Example:** - -``object`` always chooses ``object`` as the common DType. For ``datetime64`` -type promotion is defined with no other datatype, but if someone were to -implement a new higher precision datetime, then:: +the first valid common type for ``int16`` and ``uint16``, demoting the +currently defined behavior of ``int32``. +Both, the need of a linear type hierarchy and the potential of changing +existing behaviour by adding a new DType, are a downside to using a generic +rule based on "safe casting". +However, a more generic common DType could be implemented in the future, since +``__common_dtype__`` can in principle use casting information internally. + +**Example:** ``object`` always chooses ``object`` as the common DType. For +``datetime64`` type promotion is defined with no other datatype, but if +someone were to implement a new higher precision datetime, then:: HighPrecisionDatetime.__common_dtype__(np.dtype[np.datetime64]) @@ -811,33 +580,31 @@ would return ``HighPrecisionDatetime``, and the below casting may need to decide how to handle the datetime unit. -Casting -^^^^^^^ +The cast operation +============================================================================== -Maybe the most complex and interesting operation which is provided -by DTypes is the ability to cast from one dtype to another. -The casting operation is much like a typical function (universal function) on -arrays converting one input to a new output. -There are mainly two distinctions: +Perhaps the most complex and interesting DType operation is casting. Casting +is much like a typical universal function on arrays, converting one input to a +new output. There are two key distinctions: -1. Casting always requires an explicit output datatype to be given. -2. The NumPy iterator API requires access to lower-level functions than - is currently necessary for universal functions. +1. Casting always requires an explicit output datatype. +2. The NumPy iterator API requires access to functions that are lower-level + than what universal functions currently need. -Casting from one dtype to another can be complex, and generally a casting -function may not implement all details of each input datatype (such as -non-native byte order or unaligned access). -Thus casting naturally is performed in up to three steps: +Casting can be complex, and may not implement all details of each input +datatype (such as non-native byte order or unaligned access). Thus casting +naturally is performed in up to three steps: -1. The input datatype is normalized and prepared for the actual cast. +1. The given datatype is normalized and prepared for the actual cast. 2. The cast is performed. 3. The cast result, which is in a normalized form, is cast to the requested form (non-native byte order). -although often only step 2. is required. +Often only step 2 is required. Further, NumPy provides different casting kinds or safety specifiers: +* "equivalent" * "safe" * "same_kind" * "unsafe" @@ -845,66 +612,63 @@ Further, NumPy provides different casting kinds or safety specifiers: and in some cases a cast may even be represented as a simple view. -**Motivation:** - -Similar to the common dtype/DType operation above, we again have two use cases: +**Motivation:** Similar to the common dtype/DType operation above, we again +have two use cases: 1. ``arr.astype(np.String)`` (current spelling ``arr.astype("S")``) -2. ``arr.astype(np.dtype("S8"))``. +2. ``arr.astype(np.dtype("S8"))`` -Where the first case is also noted in NEP 40 and 41 as a design goal, since +where the first case is also noted in NEP 40 and 41 as a design goal, since ``np.String`` could also be an abstract DType as mentioned above. The implementation of casting should also come with as little duplicate -implementation as necessary, i.e. to avoid unnecessary methods on the -DTypes. +implementation as necessary, i.e. to avoid unnecessary methods on the DTypes. Furthermore, it is desirable that casting is implemented similar to universal functions. Analogous to the above, the following also need to be defined: 1. ``np.can_cast(dtype, DType, "safe")`` (instance to class) -2. ``np.can_cast(dtype, other_dtype, "safe")`` (casting an instance to another instance) +2. ``np.can_cast(dtype, other_dtype, "safe")`` (casting an instance to another + instance) -overloading the meaning of ``dtype`` to mean either class or instance -(on the Python level). -The question of ``np.can_cast(DType, OtherDType, "safe")`` is also a -possibility and may be used internally. -However, it is initially not necessary to expose to Python. +overloading the meaning of ``dtype`` to mean either class or instance (on the +Python level). The question of ``np.can_cast(DType, OtherDType, "safe")`` is +also a possibility and may be used internally. However, it is initially not +necessary to expose to Python. -**Implementation:** - -During DType creation, DTypes will have the ability to pass a list of -``CastingImpl`` objects, which can define casting to and from the DType. -One of these ``CastingImpl`` objects is special because it should define -the cast within the same DType (from one instance to another). -A DType which does not define this, must have only a single implementation -and not be parametric. +**Implementation:** During DType creation, DTypes will have the ability to +pass a list of ``CastingImpl`` objects, which can define casting to and from +the DType. One of these ``CastingImpl`` objects is special because it should +define the cast within the same DType (from one instance to another). A DType +which does not define this, must have only a single implementation and not be +parametric. Each ``CastingImpl`` has a specific DType signature: -``CastingImpl[InputDtype, RequestedDtype]``. -And implements the following methods and attributes: +``CastingImpl[InputDtype, RequestedDtype]`` +and implements the following methods and attributes: -* ``adjust_descriptors(self, Tuple[DType] : input) -> casting, Tuple[DType]``. +* ``resolve_descriptors(self, Tuple[DType] : input) -> casting, Tuple[DType]``. Here ``casting`` signals the casting safeness (safe, unsafe, or same-kind) and the output dtype tuple is used for more multi-step casting (see below). * ``get_transferfunction(...) -> function handling cast`` (signature to be decided). This function returns a low-level implementation of a strided casting function ("transfer function"). -* ``cast_kind`` attribute with one of safe, unsafe, or same-kind. Used to +* ``casting`` attribute with one of equivalent, safe, unsafe, or same-kind. Used to quickly decide casting safety when this is relevant. -``adjust_descriptors`` provides information about whether or +``resolve_descriptors`` provides information about whether or not a cast is safe and is of importance mainly for parametric DTypes. ``get_transferfunction`` provides NumPy with a function capable of performing the actual cast. Initially the implementation of ``get_transferfunction`` -will be *private*, and users will only be able to provide contiguous loops +will be *private*, and users will only be able to provide strided loops with the signature. -**Performing the Cast:** +**Performing the cast** .. _cast_figure: + .. figure:: _static/casting_flow.svg :figclass: align-center @@ -916,141 +680,116 @@ an ``int24`` to an ``S8`` string (which can hold all 24bit integers). Due to this limited implementation, the full cast has to do multiple conversions. The full process is: -1. Call ``CastingImpl[Int24, String].adjust_descriptors((int24, "S20"))``. +1. Call ``CastingImpl[Int24, String].resolve_descriptors((int24, "S20"))``. This provides the information that ``CastingImpl[Int24, String]`` only - implements the cast of ``int24`` to ``"S8``. + implements the cast of ``int24`` to ``"S8"``. 2. Since ``"S8"`` does not match ``"S20"``, use ``CastingImpl[String, String].get_transferfunction()`` to find the transfer (casting) function to convert an ``"S8"`` into an ``"S20"`` 3. Fetch the transfer function to convert an ``int24`` to an ``"S8"`` using ``CastingImpl[Int24, String].get_transferfunction()`` 4. Perform the actual cast using the two transfer functions: - ``int24(42) -> S8("42") -> S20("42")``. + ``int24(42) -> S8("42") -> S20("42")``. -Note that in this example the ``adjust_descriptors`` function plays a less +Note that in this example the ``resolve_descriptors`` function plays a less central role. It becomes more important for ``np.can_cast``. -Further, ``adjust_descriptors`` allows the implementation for +Further, ``resolve_descriptors`` allows the implementation for ``np.array(42, dtype=int24).astype(String)`` to call -``CastingImpl[Int24, String].adjust_descriptors((int24, None))``. +``CastingImpl[Int24, String].resolve_descriptors((int24, None))``. In this case the result of ``(int24, "S8")`` defines the correct cast: ``np.array(42, dtype=int24),astype(String) == np.array("42", dtype="S8")``. -**Casting Safety:** +**Casting safety** -To answer the question of casting safety -``np.can_cast(int24, "S20", casting="safe")``, only the ``adjust_descriptors`` -function is required and called is in the same way as in -`the figure describing a cast <cast_figure>`_. -In this case, the calls to ``adjust_descriptors``, will also provide the -information that ``int24 -> "S8"`` as well as ``"S8" -> "S20"`` are safe casts, -and thus also the ``int24 -> "S20"`` is a safe cast. +To answer the question of casting safety ``np.can_cast(int24, "S20", +casting="safe")``, only the ``resolve_descriptors`` function is required and +is called in the same way as in `the figure describing a cast <cast_figure>`_. +In this case, the calls to ``resolve_descriptors``, will also provide the +information that ``int24 -> "S8"`` as well as ``"S8" -> "S20"`` are safe +casts, and thus also the ``int24 -> "S20"`` is a safe cast. -The casting safety can currently be "equivalent" when a cast is both safe -and can be performed using only a view. -The information that a cast is a simple "view" will instead be handled by -an additional flag. Thus the ``casting`` can have the 6 values in total: -safe, unsafe, same-kind as well as safe+view, unsafe+view, same-kind+view. -Where the current "equivalent" is the same as safe+view. +In some cases, no cast is necessary. For example, on most Linux systems +``np.dtype("long")`` and ``np.dtype("longlong")`` are different dtypes but are +both 64bit integers. +In this case, the cast can be performed using ``long_arr.view("longlong")``. +The information that a cast is a +"view" will be handled by an additional flag. Thus the ``casting`` +can have the 8 values in total: equivalent, safe, unsafe, same-kind as well as equivalent+view, safe+view, +unsafe+view, and same-kind+view. +NumPy currently defines ``dtype1 == dtype2`` to be True only if byte order matches. +This functionality can be replaced with the combination of "equivalent" casting +and the "view" flag. -(For more information on the ``adjust_descriptor`` signature see the -C-API section below.) +(For more information on the ``resolve_descriptors`` signature see the C-API +section below and NEP 43.) -**Casting between instances of the same DType:** +**Casting between instances of the same DType** -In general one of the casting implementations define by the DType implementor +In general one of the casting implementations defined by the DType implementor must be ``CastingImpl[DType, DType]`` (unless there is only a singleton -instance). -To keep the casting to as few steps as possible, this implementation must -be capable any conversions between all instances of this DType. +instance). To keep the casting to as few steps as possible, this +implementation must initially be capable of any conversions between all instances of this +DType. -**General Multi-Step Casting** +**General multistep casting** In general we could implement certain casts, such as ``int8`` to ``int24`` -even if the user only provides an ``int16 -> int24`` cast. -This proposal currently does not provide this functionality. However, -it could be extended in the future to either find such casts dynamically, -or at least allow ``adjust_descriptors`` to return arbitrary ``dtypes``. -If ``CastingImpl[Int8, Int24].adjust_descriptors((int8, int24))`` returns -``(int16, int24)``, the actual casting process could be extended to include -the ``int8 -> int16`` cast. Unlike the above example, which is limited -to at most three steps. - - -**Alternatives:** - -The choice of using only the DType classes in the first step of finding the -correct ``CastingImpl`` means that the default implementation of -``__common_dtype__`` has a reasonable definition of "safe casting" between +even if the user only provides an ``int16 -> int24`` cast. This proposal +currently does not provide this functionality. However, it could be extended +in the future to either find such casts dynamically, or at least allow +``resolve_descriptors`` to return arbitrary ``dtypes``. If ``CastingImpl[Int8, +Int24].resolve_descriptors((int8, int24))`` returns ``(int16, int24)``, the +actual casting process could be extended to include the ``int8 -> int16`` +cast. This adds an additional step to the casting process. + + +**Alternatives:** The choice of using only the DType classes in the first step +of finding the correct ``CastingImpl`` means that the default implementation +of ``__common_dtype__`` has a reasonable definition of "safe casting" between DTypes classes (although e.g. the concatenate operation using it may still fail when attempting to find the actual common instance or cast). -The split into multiple steps may seem to add complexity -rather than reduce it, however, it consolidates that we have the two distinct -signatures of ``np.can_cast(dtype, DTypeClass)`` and ``np.can_cast(dtype, other_dtype)``. +The split into multiple steps may seem to add complexity rather than reduce +it, however, it consolidates that we have the two distinct signatures of +``np.can_cast(dtype, DTypeClass)`` and ``np.can_cast(dtype, other_dtype)``. Further, the above API guarantees the separation of concerns for user DTypes. -The user ``Int24`` dtype does not have to handle all string lengths if it -does not wish to do so. Further, if an encoding was added to the ``String`` -DType, this does not affect the overall cast. -The ``adjust_descriptor`` function can keep returning the default encoding -and the ``CastingImpl[String, String]`` can take care of any necessary encoding -changes. +The user ``Int24`` dtype does not have to handle all string lengths if it does +not wish to do so. Further, if an encoding was added to the ``String`` DType, +this does not affect the overall cast. The ``resolve_descriptors`` function can +keep returning the default encoding and the ``CastingImpl[String, String]`` +can take care of any necessary encoding changes. The main alternative to the proposed design is to move most of the information -which is here pushed into the ``CastingImpl`` directly into methods -on the DTypes. This, however, will not allow the close similarity between casting -and universal functions. On the up side, it reduces the necessary indirection -as noted below. - -An initial proposal defined two methods ``__can_cast_to__(self, other)`` -to dynamically return ``CastingImpl``. -The advantage of this addition is that it removes the requirement to know all -possible casts at DType creation time (of one of the involved DTypes). -Such API could be added at a later time. It should be noted, however, -that it would be mainly useful for inheritance-like logic, which can be -problematic. As an example two different ``Float64WithUnit`` implementations -both could infer that they can unsafely cast between one another when in fact -some combinations should cast safely or preserve the Unit (both of which the -"base" ``Float64`` would discard). -In the proposed implementation this is not possible, since the two implementations -are not aware of each other. - - -**Notes:** - -The proposed ``CastingImpl`` is designed to be compatible with the -``UFuncImpl`` proposed in NEP 43. -While initially it will be a distinct object or C-struct, the aim is that -``CastingImpl`` can be a subclass or extension of ``UFuncImpl``. -Once this happens, this may naturally allow the use of a ``CastingImpl`` to -pass around a specialized casting function directly. - -In the future, we may consider adding a way to spell out that specific -casts are known to be *not* possible. - -In the above text ``CastingImpl`` is described as a Python object. In practice, -the current plan is to implement it as a C-side structure stored on the ``from`` -datatype. -A Python side API to get an equivalent ``CastingImpl`` object will be created, -but storing it (similar to the current implementation) on the ``from`` datatype -avoids the creation of cyclic reference counts. - -The way dispatching works for ``CastingImpl`` is planned to be limited initially -and fully opaque. -In the future, it may or may not be moved into a special UFunc, or behave -more like a universal function. - - -**Example:** - -The implementation for casting integers to datetime would currently generally -say that this cast is unsafe (it is always an unsafe cast). -Its ``adjust_descriptors`` functions may look like:: - - def adjust_descriptors(input): - from_dtype, to_dtype = input +which is here pushed into the ``CastingImpl`` directly into methods on the +DTypes. This, however, will not allow the close similarity between casting and +universal functions. On the up side, it reduces the necessary indirection as +noted below. + +An initial proposal defined two methods ``__can_cast_to__(self, other)`` to +dynamically return ``CastingImpl``. The advantage of this addition is that it +removes the requirement to define all possible casts at DType creation time (of +one of the involved DTypes). +Such API could be added at a later time. This is similar to Python which +provides ``__getattr__`` for additional control over attribute lookup. + +**Notes:** The proposed ``CastingImpl`` is designed to be identical to the +``PyArrayMethod`` proposed in NEP 43 as part of restructuring ufuncs to handle +new DTypes. + +The way dispatching works for ``CastingImpl`` is planned to be limited +initially and fully opaque. In the future, it may or may not be moved into a +special UFunc, or behave more like a universal function. + + +**Example:** The implementation for casting integers to datetime would generally +say that this cast is unsafe (because it is always an unsafe cast). +Its ``resolve_descriptors`` function may look like:: + + def resolve_descriptors(self, given_dtypes): + from_dtype, to_dtype = given_dtypes from_dtype = from_dtype.ensure_canonical() # ensure not byte-swapped if to_dtype is None: @@ -1065,26 +804,384 @@ Its ``adjust_descriptors`` functions may look like:: .. note:: - While NumPy currently defines some of these casts, with the possible - exception of the unit-less ``timedelta64`` it may be better to not - define these cast at all. In general we expect that user defined - DTypes will be using other methods such as ``unit.drop_unit(arr)`` - or ``arr * unit.seconds``. + While NumPy currently defines integer to datetime casts, with the possible + exception of the unit-less ``timedelta64`` it may be better to not define + these casts at all. In general we expect that user defined DTypes will be + using custom methods such as ``unit.drop_unit(arr)`` or ``arr * + unit.seconds``. + + +****************************************************************************** +Array coercion +****************************************************************************** + +The following sections discuss the two aspects related to creating an array from +arbitrary python objects. This requires a defined protocol to store data +inside the array. Further, it requires the ability to find the correct dtype +when a user does not provide the dtype explicitly. + +Coercion to and from Python objects +============================================================================== + +**Motivation:** When storing a single value in an array or taking it out, it +is necessary to coerce (convert) it to and from the low-level representation +inside the array. + +**Description:** Coercing to and from Python scalars requires two to three +methods: + +1. ``__dtype_setitem__(self, item_pointer, value)`` +2. ``__dtype_getitem__(self, item_pointer, base_obj) -> object``; + ``base_obj`` is for memory management and usually ignored; it points to + an object owning the data. Its only role is to support structured datatypes + with subarrays within NumPy, which currently return views into the array. + The function returns an equivalent Python scalar (i.e. typically a NumPy + scalar). +3. ``__dtype_get_pyitem__(self, item_pointer, base_obj) -> object`` (initially + hidden for new-style user-defined datatypes, may be exposed on user + request). This corresponds to the ``arr.item()`` method also used by + ``arr.tolist()`` and returns Python floats, for example, instead of NumPy + floats. + +(The above is meant for C-API. A Python-side API would have to use byte +buffers or similar to implement this, which may be useful for prototyping.) + +These largely correspond to the current definitions. When a certain scalar +has a known (different) dtype, NumPy may in the future use casting instead of +``__dtype_setitem__``. A user datatype is (initially) expected to implement +``__dtype_setitem__`` for its own ``DType.type`` and all basic Python scalars +it wishes to support (e.g. ``int`` and ``float``). In the future a +function "``known_scalartype``" may be made public to allow a user dtype to signal +which Python scalars it can store directly. + + +**Implementation:** The pseudocode implementation for setting a single item in +an array from an arbitrary Python object ``value`` is (note that some +functions are only defined below):: + + def PyArray_Pack(dtype, item_pointer, value): + DType = type(dtype) + if DType.type is type(value) or DType.known_scalartype(type(value)): + return dtype.__dtype_setitem__(item_pointer, value) + + # The dtype cannot handle the value, so try casting: + arr = np.array(value) + if arr.dtype is object or arr.ndim != 0: + # not a numpy or user scalar; try using the dtype after all: + return dtype.__dtype_setitem__(item_pointer, value) + + arr.astype(dtype) + item_pointer.write(arr[()]) + +where the call to ``np.array()`` represents the dtype discovery and is +not actually performed. + +**Example:** Current ``datetime64`` returns ``np.datetime64`` scalars and can +be assigned from ``np.datetime64``. However, the datetime +``__dtype_setitem__`` also allows assignment from date strings ("2016-05-01") +or Python integers. Additionally the datetime ``__dtype_get_pyitem__`` +function actually returns a Python ``datetime.datetime`` object (most of the +time). + + +**Alternatives:** This functionality could also be implemented as a cast to and +from the ``object`` dtype. +However, coercion is slightly more complex than typical casts. +One reason is that in general a Python object could itself be a +zero-dimensional array or scalar with an associated DType. +Such an object has a DType, and the correct cast to another DType is already +defined:: + + np.array(np.float32(4), dtype=object).astype(np.float64) + +is identical to:: + + np.array(4, dtype=np.float32).astype(np.float64) + +Implementing the first ``object`` to ``np.float64`` cast explicitly, +would require the user to take to duplicate or fall back to existing +casting functionality. + +It is certainly possible to describe the coercion to and from Python objects +using the general casting machinery, +but the ``object`` dtype is special and important enough to be handled by NumPy +using the presented methods. + +**Further Issues and Discussion:** The ``__dtype_setitem__`` function currently duplicates +some code, such as coercion from a string. ``datetime64`` allows assignment +from string, but the same conversion also occurs for casting from the string +dtype to ``datetime64``. In the future, we may expose the ``known_scalartype`` +function to allow the user to implement such duplication. +For example, NumPy would normally use ``np.array(np.string_("2019")).astype(datetime64)``, +but ``datetime64`` could choose to use its ``__dtype_setitem__`` instead, +e.g. for performance reasons. + +There is an issue about how subclasses of scalars should be handled. +We anticipate to stop automatically detecting the dtype for +``np.array(float64_subclass)`` to be float64. +The user can still provide ``dtype=np.float64``. +However, the above automatic casting using ``np.array(scalar_subclass).astype(requested_dtype)`` +will fail. +In many cases, this is not an issue, since the Python ``__float__`` protocol +can be used instead. But in some cases, this will mean that subclasses of +Python scalars will behave differently. + +.. note:: + + *Example:* ``np.complex256`` should not use ``__float__`` in its + ``__dtype_setitem__`` method in the future unless it is a known floating + point type. If the scalar is a subclass of a different high precision + floating point type (e.g. ``np.float128``) then this currently loses + precision without notifying the user. + In that case ``np.array(float128_subclass(3), dtype=np.complex256)`` + may fail unless the ``float128_subclass`` is first converted to the + ``np.float128`` base class. + + +DType discovery during array coercion +============================================================================== + +An important step in the use of NumPy arrays is creation of the array +from collections of generic Python objects. + +**Motivation:** Although the distinction is not clear currently, there are two main needs:: + + np.array([1, 2, 3, 4.]) + +needs to guess the correct dtype based on the Python objects inside. +Such an array may include a mix of datatypes, as long as they can be +promoted. +A second use case is when users provide the output DType class, but not the +specific DType instance:: + + np.array([object(), None], dtype=np.dtype[np.string_]) # (or `dtype="S"`) + +In this case the user indicates that ``object()`` and ``None`` should be +interpreted as strings. +The need to consider the user provided DType also arises for a future +``Categorical``:: + + np.array([1, 2, 1, 1, 2], dtype=Categorical) + +which must interpret the numbers as unique categorical values rather than +integers. + +There are three further issues to consider: + +1. It may be desirable to create datatypes associated + with normal Python scalars (such as ``datetime.datetime``) that do not + have a ``dtype`` attribute already. +2. In general, a datatype could represent a sequence, however, NumPy currently + assumes that sequences are always collections of elements + (the sequence cannot be an element itself). + An example would be a ``vector`` DType. +3. An array may itself contain arrays with a specific dtype (even + general Python objects). For example: + ``np.array([np.array(None, dtype=object)], dtype=np.String)`` + poses the issue of how to handle the included array. + +Some of these difficulties arise because finding the correct shape +of the output array and finding the correct datatype are closely related. + +**Implementation:** There are two distinct cases above: + +1. The user has provided no dtype information. +2. The user provided a DType class -- as represented, for example, by ``"S"`` + representing a string of any length. + +In the first case, it is necessary to establish a mapping from the Python type(s) +of the constituent elements to the DType class. +Once the DType class is known, the correct dtype instance needs to be found. +In the case of strings, this requires to find the string length. + +These two cases shall be implemented by leveraging two pieces of information: + +1. ``DType.type``: The current type attribute to indicate which Python scalar + type is associated with the DType class (this is a *class* attribute that always + exists for any datatype and is not limited to array coercion). +2. ``__discover_descr_from_pyobject__(cls, obj) -> dtype``: A classmethod that + returns the correct descriptor given the input object. + Note that only parametric DTypes have to implement this. + For non-parametric DTypes using the default instance will always be acceptable. + +The Python scalar type which is already associated with a DType through the +``DType.type`` attribute maps from the DType to the Python scalar type. +At registration time, a DType may choose to allow automatically discover for +this Python scalar type. +This requires a lookup in the opposite direction, which will be implemented +using global a mapping (dictionary-like) of:: + + known_python_types[type] = DType + +Correct garbage collection requires additional care. +If both the Python scalar type (``pytype``) and ``DType`` are created dynamically, +they will potentially be deleted again. +To allow this, it must be possible to make the above mapping weak. +This requires that the ``pytype`` holds a reference of ``DType`` explicitly. +Thus, in addition to building the global mapping, NumPy will store the ``DType`` as +``pytype.__associated_array_dtype__`` in the Python type. +This does *not* define the mapping and should *not* be accessed directly. +In particular potential inheritance of the attribute does not mean that NumPy will use the +superclasses ``DType`` automatically. A new ``DType`` must be created for the +subclass. + +.. note:: + + Python integers do not have a clear/concrete NumPy type associated right + now. This is because during array coercion NumPy currently finds the first + type capable of representing their value in the list of `long`, `unsigned + long`, `int64`, `unsigned int64`, and `object` (on many machines `long` is + 64 bit). + + Instead they will need to be implemented using an ``AbstractPyInt``. This + DType class can then provide ``__discover_descr_from_pyobject__`` and + return the actual dtype which is e.g. ``np.dtype("int64")``. For + dispatching/promotion in ufuncs, it will also be necessary to dynamically + create ``AbstractPyInt[value]`` classes (creation can be cached), so that + they can provide the current value based promotion functionality provided + by ``np.result_type(python_integer, array)`` [1]_. + +To allow for a DType to accept inputs as scalars that are not basic Python +types or instances of ``DType.type``, we use ``known_scalar_type`` method. +This can allow discovery of a ``vector`` as a scalar (element) instead of a sequence +(for the command ``np.array(vector, dtype=VectorDType)``) even when ``vector`` is itself a +sequence or even an array subclass. This will *not* be public API initially, +but may be made public at a later time. + +**Example:** The current datetime DType requires a +``__discover_descr_from_pyobject__`` which returns the correct unit for string +inputs. This allows it to support:: + + np.array(["2020-01-02", "2020-01-02 11:24"], dtype="M8") + +By inspecting the date strings. Together with the common dtype +operation, this allows it to automatically find that the datetime64 unit +should be "minutes". + + +**NumPy Internal Implementation:** The implementation to find the correct dtype +will work similar to the following pseudocode:: + + def find_dtype(array_like): + common_dtype = None + for element in array_like: + # default to object dtype, if unknown + DType = known_python_types.get(type(element), np.dtype[object]) + dtype = DType.__discover_descr_from_pyobject__(element) + + if common_dtype is None: + common_dtype = dtype + else: + common_dtype = np.promote_types(common_dtype, dtype) + +In practice, the input to ``np.array()`` is a mix of sequences and array-like +objects, so that deciding what is an element requires to check whether it +is a sequence. +The full algorithm (without user provided dtypes) thus looks more like:: + + def find_dtype_recursive(array_like, dtype=None): + """ + Recursively find the dtype for a nested sequences (arrays are not + supported here). + """ + DType = known_python_types.get(type(element), None) + + if DType is None and is_array_like(array_like): + # Code for a sequence, an array_like may have a DType we + # can use directly: + for element in array_like: + dtype = find_dtype_recursive(element, dtype=dtype) + return dtype + + elif DType is None: + DType = np.dtype[object] + + # dtype discovery and promotion as in `find_dtype` above + +If the user provides ``DType``, then this DType will be tried first, and the +``dtype`` may need to be cast before the promotion is performed. + +**Limitations:** The motivational point 3. of a nested array +``np.array([np.array(None, dtype=object)], dtype=np.String)`` is currently +(sometimes) supported by inspecting all elements of the nested array. +User DTypes will implicitly handle these correctly if the nested array +is of ``object`` dtype. +In some other cases NumPy will retain backward compatibility for existing +functionality only. +NumPy uses such functionality to allow code such as:: + + >>> np.array([np.array(["2020-05-05"], dtype="S")], dtype=np.datetime64) + array([['2020-05-05']], dtype='datetime64[D]') + +which discovers the datetime unit ``D`` (days). +This possibility will not be accessible to user DTypes without an +intermediate cast to ``object`` or a custom function. + +The use of a global type map means that an error or warning has to be given if +two DTypes wish to map to the same Python type. In most cases user DTypes +should only be implemented for types defined within the same library to avoid +the potential for conflicts. It will be the DType implementor's responsibility +to be careful about this and use avoid registration when in doubt. + +**Alternatives:** Instead of a global mapping, we could rely on the scalar +attribute ``scalar.__associated_array_dtype__``. +This only creates a difference in behaviour for subclasses and the exact +implementation can be undefined initially. +Scalars will be expected to derive from a NumPy scalar. +In principle NumPy could, for a time, still choose to rely on the attribute. + +An earlier proposal for the ``dtype`` discovery algorithm, +was to use a two-pass approach. +First finding only the correct ``DType`` class and only then discovering the parametric +``dtype`` instance. +This was rejected for unnecessary complexity. +The main advantage of this method is that it would have enabled value +based promotion in universal functions, allowing:: + + np.add(np.array([8], dtype="uint8"), [4]) + +to return a ``uint8`` result (instead of ``int16``), which currently happens for:: + + np.add(np.array([8], dtype="uint8"), 4) +(note the list ``[4]`` instead of scalar ``4``). +This is not a feature NumPy currently has or desires to support. -C-Side API -^^^^^^^^^^ +**Further Issues and Discussion:** It is possible to create a DType +such as Categorical, array, or vector which can only be used if ``dtype=DType`` +is provided. Such DTypes cannot roundtrip correctly. For example:: + + np.array(np.array(1, dtype=Categorical)[()]) + +will result in an integer array. To get the original ``Categorical`` array +``dtype=Categorical`` will need to be passed explicitly. +This is a general limitation, but round-tripping is always possible if +``dtype=original_arr.dtype`` is passed. + + +.. _c-api: + +****************************************************************************** +Public C-API +****************************************************************************** A Python side API shall not be defined here. This is a general side approach. DType creation -"""""""""""""" +============================================================================== + +To create a new DType the user will need to define all the methods and +attributes as presented above and outlined in the `Usage and impact`_ +section. +Some additional methods similar to those currently defined as part of +:c:type:`PyArray_ArrFuncs` will be necessary and part of the slots struct +below. -As already mentioned in NEP 41, the interface to define new DTypes in C -is modeled after the limited API in Python: the above-mentioned slots -and some additional necessary information will thus be passed within a slots -struct and identified by ``ssize_t`` integers:: +As already mentioned in NEP 41, the interface to define this DType class in C is +modeled after the `Python limited API <https://www.python.org/dev/peps/pep-0384/>`_: +the above-mentioned slots and some additional necessary information will +thus be passed within a slots struct and identified by ``ssize_t`` integers:: static struct PyArrayMethodDef slots[] = { {NPY_dt_method, method_implementation}, @@ -1093,10 +1190,8 @@ struct and identified by ``ssize_t`` integers:: } typedef struct{ - PyTypeObject *typeobj; /* type of python scalar */ - int is_parametric; /* Is the dtype parametric? */ - int is_abstract; /* Is the dtype abstract? */ - int flags /* flags (to be discussed) */ + PyTypeObject *typeobj; /* type of python scalar or NULL */ + int flags /* flags, including parametric and abstract */ /* NULL terminated CastingImpl; is copied and references are stolen */ CastingImpl *castingimpls[]; PyType_Slot *slots; @@ -1105,20 +1200,19 @@ struct and identified by ``ssize_t`` integers:: PyObject* PyArray_InitDTypeMetaFromSpec(PyArrayDTypeMeta_Spec *dtype_spec); -all of this information will be copied during instantiation. +All of this information will be copied. -**TODO:** The DType author should be able to at define new methods for -their DType, up to defining a full type object and in the future possibly even -extending the ``PyArrayDTypeMeta_Type`` struct. -We have to decide on how (and what) to make available to the user initially. -A proposed initial solution may be to simply allow inheriting from an existing -class. -Further this prevents overriding some slots, such as `==` which may not be -desirable. +**TODO:** The DType author should be able to define new methods for their +DType, up to defining a full type object and in the future possibly even +extending the ``PyArrayDTypeMeta_Type`` struct. We have to decide on how (and +what) to make available to the user initially. A possible initial solution may +be to only allow inheriting from an existing class: ``class MyDType(np.dtype, +MyBaseclass)``. If ``np.dtype`` is first in the method resolution order, this +also prevents overriding some slots, such as ``==`` which may not be desirable. -The proposed method slots are (prepended with ``NPY_dt_``), these are -detailed above and given here for summary: +The ``slots`` will be identified by names which are prefixed with ``NPY_dt_`` +and are: * ``is_canonical(self) -> {0, 1}`` * ``ensure_canonical(self) -> dtype`` @@ -1129,205 +1223,142 @@ detailed above and given here for summary: * ``common_dtype(cls, other) -> DType, NotImplemented, or NULL`` * ``common_instance(self, other) -> dtype or NULL`` -If not set, most slots are filled with slots which either error or defer automatically. +Where possible, a default implementation will be provided if the slot is +ommitted or set to ``NULL``. Non-parametric dtypes do not have to implement: * ``discover_descr_from_pyobject`` (uses ``default_descr`` instead) * ``common_instance`` (uses ``default_descr`` instead) -* ``ensure_canonical`` (uses ``default_descr`` instead) - -Which will be correct for most dtypes *which do not store metadata*. - -Other slots may be replaced by convenience versions, e.g. sorting methods -can be defined by providing: +* ``ensure_canonical`` (uses ``default_descr`` instead). -* ``compare(self, char *item_ptr1, char *item_ptr2, int *res) -> {-1, 0}`` - *TODO: We would like an error return, is this reasonable? (similar to old - python compare)* - -which uses generic sorting functionality. In general, we could add a -functions such as: +Sorting is expected to be implemented using: * ``get_sort_function(self, NPY_SORTKIND sort_kind) -> {out_sortfunction, NotImplemented, NULL}``. - If the sortkind is not understood it may be allowed to return ``NotImplemented``. -in the future. However, for example sorting is likely better solved by the -implementation of multiple generalized ufuncs which are called internally. +Although for convenience, it will be sufficient if the user implements only: + +* ``compare(self, char *item_ptr1, char *item_ptr2, int *res) -> {-1, 0, 1}`` -**Limitations:** -Using the above ``PyArrayDTypeMeta_Spec`` struct, the structure itself can -only be extended clumsily (e.g. by adding a version tag to the ``slots`` -to indicate a new, longer version of the struct). -We could also provide the struct using a function, which however will require -memory management but would allow ABI-compatible extension -(the struct is freed again when the DType is created). +**Limitations:** Using the above ``PyArrayDTypeMeta_Spec`` struct, the +structure itself can only be extended clumsily (e.g. by adding a version tag +to the ``slots`` to indicate a new, longer version of the struct). We could +also provide the struct using a function, which however will require memory +management but would allow ABI-compatible extension (the struct is freed again +when the DType is created). CastingImpl -""""""""""" +============================================================================== The external API for ``CastingImpl`` will be limited initially to defining: -* ``cast_kind`` attribute, which can be one of the supported casting kinds. +* ``casting`` attribute, which can be one of the supported casting kinds. This is the safest cast possible. For example casting between two NumPy strings is of course "safe" in general, but may be "same kind" in a specific instance if the second string is shorter. If neither type is parametric the - ``adjust_descriptors`` must use it. -* ``adjust_descriptors(dtypes_in[2], dtypes_out[2], casting_out) -> int {0, -1}`` - The out dtypes must be set correctly to dtypes which the strided loop - (transfer function) can handle. Initially the result must have be instances - of the same DType class as the ``CastingImpl`` is defined for. - The ``casting_out`` will be set to ``NPY_SAFE_CASTING``, ``NPY_UNSAFE_CASTING``, - or ``NPY_SAME_KIND_CASTING``. With a new, additional, flag ``NPY_CAST_IS_VIEW`` - which can be set to indicate that no cast is necessary, but a simple view - is sufficient to perform the cast. - The cast should return ``-1`` when a custom error message is set and - ``NPY_NO_CASTING`` to indicate that a generic casting error should be - set (this is in most cases preferable). -* ``strided_loop(char **args, npy_intp *dimensions, npy_intp *strides, dtypes[2]) -> int {0, nonzero}`` (must currently succeed) - -This is identical to the proposed API for ufuncs. By default the two dtypes -are passed in as the last argument. On error return (if no error is set) a -generic error will be given. -More optimized loops are in use internally, and will be made available to users -in the future (see notes) -The iterator API does not currently support casting errors: this is -a bug that needs to be fixed. Until it is fixed the loop should always -succeed (return 0). - -Although verbose, the API shall mimic the one for creating a new DType. -The ``PyArrayCastingImpl_Spec`` will include a field for ``dtypes`` and -identical to a ``PyArrayUFuncImpl_Spec``:: + ``resolve_descriptors`` must use it. + +* ``resolve_descriptors(self, given_descrs[2], loop_descrs[2]) -> int {casting, -1}``: + The ``loop_descrs`` must be set correctly to dtypes which the strided loop + (transfer function) can handle. Initially the result must have instances + of the same DType class as the ``CastingImpl`` is defined for. The + ``casting`` will be set to ``NPY_EQUIV_CASTING``, ``NPY_SAFE_CASTING``, + ``NPY_UNSAFE_CASTING``, or ``NPY_SAME_KIND_CASTING``. + A new, additional flag, ``NPY_CAST_IS_VIEW``, can be set to indicate that + no cast is necessary and a view is sufficient to perform the cast. + The return value shall be ``-1`` to indicate that the cast is not possible. + If no error is set, a generic error message will be given. If an error is + already set it will be chained and may provide additional information. + Note that ``self`` represents additional call information; details are given + in NEP 43. + +* ``strided_loop(char **args, npy_intp *dimensions, npy_intp *strides, + ...) -> int {0, -1}`` (signature will be fully defined in NEP 43) + +This is identical to the proposed API for ufuncs. The additional ``...`` +part of the signature will include information such as the two ``dtype``\s. +More optimized loops are in use internally, and +will be made available to users in the future (see notes). + +Although verbose, the API shall mimic the one for creating a new DType: + +.. code-block:: C typedef struct{ - int needs_api; /* whether the cast requires the API */ - PyArray_DTypeMeta *in_dtype; /* input DType class */ - PyArray_DTypeMeta *out_dtype; /* output DType class */ + int flags; /* e.g. whether the cast requires the API */ + int nin, nout; /* Number of Input and outputs (always 1) */ + NPY_CASTING casting; /* The default casting level */ + PyArray_DTypeMeta *dtypes; /* input and output DType class */ /* NULL terminated slots defining the methods */ PyType_Slot *slots; - } PyArrayUFuncImpl_Spec; - -The actual creation function ``PyArrayCastingImpl_FromSpec()`` will additionally -require a ``casting`` parameter to define the default (maximum) casting safety. -The internal representation of ufuncs and casting implementations may differ -initially if it makes implementation simpler, but should be kept opaque to -allow future merging. + } PyArrayMethod_Spec; -**TODO:** It may be possible to make this more close to the ufuncs or even -use a single FromSpec. This API shall only be finalized after/when NEP 43 -is finalized. +The focus differs between casting and general ufuncs. For example for casts +``nin == nout == 1`` is always correct, while for ufuncs ``casting`` is +expected to be usually `"safe"`. -**Notes:** - -We may initially allow users to define only a single loop. -However, internally NumPy optimizes far more, and this should be made -public incrementally, by either allowing to provide multiple versions, such -as: +**Notes:** We may initially allow users to define only a single loop. However, +internally NumPy optimizes far more, and this should be made public +incrementally, either by allowing multiple versions, such as: * contiguous inner loop * strided inner loop * scalar inner loop -or more likely through an additional ``get_inner_loop`` function which has -additional information, such as the fixed strides (similar to our internal API). +or more likely through exposure of the ``get_loop`` function which is passed +additional information, such as the fixed strides (similar to our internal +API). -The above example does not yet include the definition of setup/teardown -functionality, which may overlap with ``get_inner_loop``. -Since these are similar to the UFunc machinery, this should be defined in -detail in NEP 43 and then incorporated identically into casting. +The above example does not yet include potential setup and error handling +requirements. Since these are similar to the UFunc machinery, this will be +defined in detail in NEP 43 and then incorporated identically into casting. -Also the ``needs_api`` decision may actually be moved into a setup function, -and removed or mainly provided as a convenience flag. +The slots/methods used will be prefixed ``NPY_uf_`` for similarity to the +ufunc machinery. -The slots/methods used will be prefixed ``NPY_uf_`` for similarity to the ufunc -machinery. +**Alternatives:** Aside from name changes, and possible signature tweaks, +there seem to be few alternatives to the above structure. +The proposed API using ``*_FromSpec`` function is a good way to achieve a stable +and extensible API. The slots design is extensible and can be +changed without breaking binary compatibility. +Convenience functions can still be provided to allow creation with less code. -Alternatives -"""""""""""" - -Aside from name changes, and possible signature tweaks, there seem to -be few alternatives to the above structure. -Keeping the creation process close the Python limited API has some advantage. -Convenience functions could still be provided to allow creation with less -code. -The central point in the above design is that the enumerated slots design -is extensible and can be changed without breaking binary compatibility. -A downside is the possible need to pass in e.g. integer flags using a void -pointer inside this structure. - -A downside of this is that compilers cannot warn about function -pointer incompatibilities. There is currently no proposed solution to this. - - -Issues -^^^^^^ - -Any possible design decision will have issues. - -The above split into Python objects has the disadvantage that reference cycles -naturally occur. For example a potential ``CastingImpl`` object needs to -hold on to both ``DTypes``. Further, a scalar type may want to own a -strong reference to the corresponding ``DType`` while the ``DType`` *must* -hold a strong reference to the scalar. -We do not believe that these reference cycles are an issue. The may -require implementation of of cyclic reference counting at some point, but -cyclic reference resolution is very common in Python and dtypes (especially -classes) are only a small number of objects. - -In some cases, the new split will add additional indirections to the code, -since methods on the DType have to be looked up and called. -This should not have serious performance impact and seems necessary to -achieve the desired flexibility. - -From a user-perspective, a more serious downside is that handling certain -functionality in the ``DType`` rather than directly can mean that error -messages need to be raised from places where less context is available. -This may mean that error messages can be less specific. -This will be alleviated by exception chaining. Also decisions such as -returning the casting safety (even when it is impossible to cast) allow -most exceptions to be set at a point where more context is available -and ensures uniform errors messages. +One downside of this approach is that compilers cannot warn about function pointer +incompatibilities. +****************************************************************************** Implementation --------------- +****************************************************************************** -Internally a few implementation details have to be decided. These will be -fully opaque to the user and can be changed at a later time. +Steps for implementation are outlined in :ref:`NEP 41 <NEP41>`. This includes +internal restructuring for the new casting and array-coercion. +First, the NumPy will internally be rewritten using the above methods for +casting and array-coercion. -This includes: +After that, the new public API will be added incrementally. +We plan to expose it in a preliminary state initially to allow modification +after some experience can be gained. +In addition to the features presented in detail in this NEP, all functionality +currently implemented on the dtypes will be replaced systematically. -* How ``CastingImpl`` lookup, and thus the decision whether a cast is possible, - is defined. (This is speed relevant, although mainly during a transition - phase where UFuncs where NEP 43 is not yet implemented). - Thus, it is not very relevant to the NEP. It is only necessary to ensure fast - lookup during the transition phase for the current builtin Numerical types. -* How the mapping from a python scalar (e.g. ``3.``) to the DType is - implemented. - -The main steps for implementation are outlined in :ref:`NEP 41 <NEP41>`. -This includes the internal restructure for how casting and array-coercion -works. -After this the new public API will be added incrementally. -This includes replacements for certain slots which are occasionally -directly used on the dtype (e.g. ``dtype->f->setitem``). - - -Discussion ----------- +****************************************************************************** +Alternatives +****************************************************************************** -There is a large space of possible implementations with many discussions -in various places, as well as initial thoughts and design documents. -These are listed in the discussion of NEP 40 and not repeated here for -brevity. +The space of possible implementations is large, so there have been many +discussions, conceptions, and design documents. These are listed in NEP 40. +Since this NEP encompasses multiple individual decisions, alternatives +are discussed in the above individual sections. +****************************************************************************** References ----------- +****************************************************************************** .. [1] NumPy currently inspects the value to allow the operations:: @@ -1335,10 +1366,11 @@ References np.array([1.2], dtype=np.float32) + 1. to return a ``uint8`` or ``float32`` array respectively. This is - further described in the documentation of `numpy.result_type`. + further described in the documentation for :func:`numpy.result_type`. +****************************************************************************** Copyright ---------- +****************************************************************************** This document has been placed in the public domain. diff --git a/doc/source/_static/numpy.css b/doc/source/_static/numpy.css new file mode 100644 index 000000000..22d08cc0d --- /dev/null +++ b/doc/source/_static/numpy.css @@ -0,0 +1,40 @@ +@import url('https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,400;0,700;0,900;1,400;1,700;1,900&family=Open+Sans:ital,wght@0,400;0,600;1,400;1,600&display=swap'); + +.navbar-brand img { + height: 75px; +} +.navbar-brand { + height: 75px; +} + +body { + font-family: 'Open Sans', sans-serif; + color:#4A4A4A; /* numpy.org body color */ +} + +pre, code { + font-size: 100%; + line-height: 155%; +} + +h1 { + font-style: "Lato", sans-serif; + color: #013243; /* warm black */ + font-weight: 700; + letter-spacing: -.04em; + text-align: right; + margin-top: 3rem; + margin-bottom: 4rem; + font-size: 3rem; +} + + +h2 { + color: #4d77cf; /* han blue */ + letter-spacing: -.03em; +} + +h3 { + color: #013243; /* warm black */ + letter-spacing: -.03em; +} diff --git a/doc/source/_templates/indexcontent.html b/doc/source/_templates/indexcontent.html index 5929e755d..6633aa9be 100644 --- a/doc/source/_templates/indexcontent.html +++ b/doc/source/_templates/indexcontent.html @@ -56,7 +56,7 @@ <p class="biglink"><a class="biglink" href="{{ pathto("bugs") }}">Reporting bugs</a></p> <p class="biglink"><a class="biglink" href="{{ pathto("release") }}">Release Notes</a></p> </td><td width="50%"> - <p class="biglink"><a class="biglink" href="{{ pathto("about") }}">About NumPy</a></p> + <p class="biglink"><a class="biglink" href="{{ pathto("doc_conventions") }}">Document conventions</a></p> <p class="biglink"><a class="biglink" href="{{ pathto("license") }}">License of NumPy</a></p> </td></tr> </table> diff --git a/doc/source/_templates/layout.html b/doc/source/_templates/layout.html index 0b0ba6271..e2812fdd5 100644 --- a/doc/source/_templates/layout.html +++ b/doc/source/_templates/layout.html @@ -1,16 +1,10 @@ {% extends "!layout.html" %} {%- block extrahead %} - <!-- this is added via javascript in versionwarning.js --> +{{ super() }} +<link rel="stylesheet" href="{{ pathto('_static/numpy.css', 1) }}" type="text/css" /> + + <!-- PR #17220: This is added via javascript in versionwarning.js --> <!-- link rel="canonical" href="http://numpy.org/doc/stable/{{ pagename }}{{ file_suffix }}" / --> -<style> -.navbar-brand img { - height: 75px; -} -.navbar-brand { - height: 75px; -} -</style> -{{ super() }} {% endblock %} diff --git a/doc/source/about.rst b/doc/source/about.rst deleted file mode 100644 index 3e83833d1..000000000 --- a/doc/source/about.rst +++ /dev/null @@ -1,62 +0,0 @@ -About NumPy -=========== - -NumPy is the fundamental package -needed for scientific computing with Python. This package contains: - -- a powerful N-dimensional :ref:`array object <arrays>` -- sophisticated :ref:`(broadcasting) functions <ufuncs>` -- basic :ref:`linear algebra functions <routines.linalg>` -- basic :ref:`Fourier transforms <routines.fft>` -- sophisticated :ref:`random number capabilities <numpyrandom>` -- tools for integrating Fortran code -- tools for integrating C/C++ code - -Besides its obvious scientific uses, *NumPy* can also be used as an -efficient multi-dimensional container of generic data. Arbitrary -data types can be defined. This allows *NumPy* to seamlessly and -speedily integrate with a wide variety of databases. - -NumPy is a successor for two earlier scientific Python libraries: -Numeric and Numarray. - -NumPy community ---------------- - -NumPy is a distributed, volunteer, open-source project. *You* can help -us make it better; if you believe something should be improved either -in functionality or in documentation, don't hesitate to contact us --- or -even better, contact us and participate in fixing the problem. - -Our main means of communication are: - -- `scipy.org website <https://scipy.org/>`__ - -- `Mailing lists <https://scipy.org/scipylib/mailing-lists.html>`__ - -- `NumPy Issues <https://github.com/numpy/numpy/issues>`__ (bug reports go here) - -- `Old NumPy Trac <http://projects.scipy.org/numpy>`__ (dead link) - -More information about the development of NumPy can be found at our `Developer Zone <https://scipy.scipy.org/scipylib/dev-zone.html>`__. - -The project management structure can be found at our :doc:`governance page <dev/governance/index>` - - -About this documentation -======================== - -Conventions ------------ - -Names of classes, objects, constants, etc. are given in **boldface** font. -Often they are also links to a more detailed documentation of the -referred object. - -This manual contains many examples of use, usually prefixed with the -Python prompt ``>>>`` (which is not a part of the example code). The -examples assume that you have first entered:: - ->>> import numpy as np - -before running the examples. diff --git a/doc/source/dev/conduct/code_of_conduct.rst b/doc/source/dev/conduct/code_of_conduct.rst deleted file mode 100644 index f2f0a536d..000000000 --- a/doc/source/dev/conduct/code_of_conduct.rst +++ /dev/null @@ -1,163 +0,0 @@ -NumPy Code of Conduct -===================== - - -Introduction ------------- - -This code of conduct applies to all spaces managed by the NumPy project, -including all public and private mailing lists, issue trackers, wikis, blogs, -Twitter, and any other communication channel used by our community. The NumPy -project does not organise in-person events, however events related to our -community should have a code of conduct similar in spirit to this one. - -This code of conduct should be honored by everyone who participates in -the NumPy community formally or informally, or claims any affiliation with the -project, in any project-related activities and especially when representing the -project, in any role. - -This code is not exhaustive or complete. It serves to distill our common -understanding of a collaborative, shared environment and goals. Please try to -follow this code in spirit as much as in letter, to create a friendly and -productive environment that enriches the surrounding community. - - -Specific Guidelines -------------------- - -We strive to: - -1. Be open. We invite anyone to participate in our community. We prefer to use - public methods of communication for project-related messages, unless - discussing something sensitive. This applies to messages for help or - project-related support, too; not only is a public support request much more - likely to result in an answer to a question, it also ensures that any - inadvertent mistakes in answering are more easily detected and corrected. - -2. Be empathetic, welcoming, friendly, and patient. We work together to resolve - conflict, and assume good intentions. We may all experience some frustration - from time to time, but we do not allow frustration to turn into a personal - attack. A community where people feel uncomfortable or threatened is not a - productive one. - -3. Be collaborative. Our work will be used by other people, and in turn we will - depend on the work of others. When we make something for the benefit of the - project, we are willing to explain to others how it works, so that they can - build on the work to make it even better. Any decision we make will affect - users and colleagues, and we take those consequences seriously when making - decisions. - -4. Be inquisitive. Nobody knows everything! Asking questions early avoids many - problems later, so we encourage questions, although we may direct them to - the appropriate forum. We will try hard to be responsive and helpful. - -5. Be careful in the words that we choose. We are careful and respectful in - our communication and we take responsibility for our own speech. Be kind to - others. Do not insult or put down other participants. We will not accept - harassment or other exclusionary behaviour, such as: - - - Violent threats or language directed against another person. - - Sexist, racist, or otherwise discriminatory jokes and language. - - Posting sexually explicit or violent material. - - Posting (or threatening to post) other people's personally identifying information ("doxing"). - - Sharing private content, such as emails sent privately or non-publicly, - or unlogged forums such as IRC channel history, without the sender's consent. - - Personal insults, especially those using racist or sexist terms. - - Unwelcome sexual attention. - - Excessive profanity. Please avoid swearwords; people differ greatly in their sensitivity to swearing. - - Repeated harassment of others. In general, if someone asks you to stop, then stop. - - Advocating for, or encouraging, any of the above behaviour. - - -Diversity Statement -------------------- - -The NumPy project welcomes and encourages participation by everyone. We are -committed to being a community that everyone enjoys being part of. Although -we may not always be able to accommodate each individual's preferences, we try -our best to treat everyone kindly. - -No matter how you identify yourself or how others perceive you: we welcome you. -Though no list can hope to be comprehensive, we explicitly honour diversity in: -age, culture, ethnicity, genotype, gender identity or expression, language, -national origin, neurotype, phenotype, political beliefs, profession, race, -religion, sexual orientation, socioeconomic status, subculture and technical -ability, to the extent that these do not conflict with this code of conduct. - - -Though we welcome people fluent in all languages, NumPy development is -conducted in English. - -Standards for behaviour in the NumPy community are detailed in the Code of -Conduct above. Participants in our community should uphold these standards -in all their interactions and help others to do so as well (see next section). - - -Reporting Guidelines --------------------- - -We know that it is painfully common for internet communication to start at or -devolve into obvious and flagrant abuse. We also recognize that sometimes -people may have a bad day, or be unaware of some of the guidelines in this Code -of Conduct. Please keep this in mind when deciding on how to respond to a -breach of this Code. - -For clearly intentional breaches, report those to the Code of Conduct committee -(see below). For possibly unintentional breaches, you may reply to the person -and point out this code of conduct (either in public or in private, whatever is -most appropriate). If you would prefer not to do that, please feel free to -report to the Code of Conduct Committee directly, or ask the Committee for -advice, in confidence. - -You can report issues to the NumPy Code of Conduct committee, at -numpy-conduct@googlegroups.com. Currently, the committee consists of: - -- Stefan van der Walt -- Melissa Weber Mendonça -- Anirudh Subramanian - -If your report involves any members of the committee, or if they feel they have -a conflict of interest in handling it, then they will recuse themselves from -considering your report. Alternatively, if for any reason you feel -uncomfortable making a report to the committee, then you can also contact: - -- Senior `NumFOCUS staff <https://numfocus.org/code-of-conduct#persons-responsible>`__: conduct@numfocus.org - - -Incident reporting resolution & Code of Conduct enforcement ------------------------------------------------------------ - -*This section summarizes the most important points, more details can be found -in* :ref:`CoC_reporting_manual`. - -We will investigate and respond to all complaints. The NumPy Code of Conduct -Committee and the NumPy Steering Committee (if involved) will protect the -identity of the reporter, and treat the content of complaints as confidential -(unless the reporter agrees otherwise). - -In case of severe and obvious breaches, e.g. personal threat or violent, sexist -or racist language, we will immediately disconnect the originator from NumPy -communication channels; please see the manual for details. - -In cases not involving clear severe and obvious breaches of this code of -conduct, the process for acting on any received code of conduct violation -report will be: - -1. acknowledge report is received -2. reasonable discussion/feedback -3. mediation (if feedback didn't help, and only if both reporter and reportee agree to this) -4. enforcement via transparent decision (see :ref:`CoC_resolutions`) by the - Code of Conduct Committee - -The committee will respond to any report as soon as possible, and at most -within 72 hours. - - -Endnotes --------- - -We are thankful to the groups behind the following documents, from which we -drew content and inspiration: - -- `The SciPy Code of Conduct <https://docs.scipy.org/doc/scipy/reference/dev/conduct/code_of_conduct.html>`_ - diff --git a/doc/source/dev/conduct/report_handling_manual.rst b/doc/source/dev/conduct/report_handling_manual.rst deleted file mode 100644 index d39b615bb..000000000 --- a/doc/source/dev/conduct/report_handling_manual.rst +++ /dev/null @@ -1,220 +0,0 @@ -:orphan: - -.. _CoC_reporting_manual: - -NumPy Code of Conduct - How to follow up on a report ----------------------------------------------------- - -This is the manual followed by NumPy's Code of Conduct Committee. It's used -when we respond to an issue to make sure we're consistent and fair. - -Enforcing the Code of Conduct impacts our community today and for the future. -It's an action that we do not take lightly. When reviewing enforcement -measures, the Code of Conduct Committee will keep the following values and -guidelines in mind: - -* Act in a personal manner rather than impersonal. The Committee can engage - the parties to understand the situation, while respecting the privacy and any - necessary confidentiality of reporters. However, sometimes it is necessary - to communicate with one or more individuals directly: the Committee's goal is - to improve the health of our community rather than only produce a formal - decision. - -* Emphasize empathy for individuals rather than judging behavior, avoiding - binary labels of "good" and "bad/evil". Overt, clear-cut aggression and - harassment exists and we will be address that firmly. But many scenarios - that can prove challenging to resolve are those where normal disagreements - devolve into unhelpful or harmful behavior from multiple parties. - Understanding the full context and finding a path that re-engages all is - hard, but ultimately the most productive for our community. - -* We understand that email is a difficult medium and can be isolating. - Receiving criticism over email, without personal contact, can be - particularly painful. This makes it especially important to keep an - atmosphere of open-minded respect of the views of others. It also means - that we must be transparent in our actions, and that we will do everything - in our power to make sure that all our members are treated fairly and with - sympathy. - -* Discrimination can be subtle and it can be unconscious. It can show itself - as unfairness and hostility in otherwise ordinary interactions. We know - that this does occur, and we will take care to look out for it. We would - very much like to hear from you if you feel you have been treated unfairly, - and we will use these procedures to make sure that your complaint is heard - and addressed. - -* Help increase engagement in good discussion practice: try to identify where - discussion may have broken down and provide actionable information, pointers - and resources that can lead to positive change on these points. - -* Be mindful of the needs of new members: provide them with explicit support - and consideration, with the aim of increasing participation from - underrepresented groups in particular. - -* Individuals come from different cultural backgrounds and native languages. - Try to identify any honest misunderstandings caused by a non-native speaker - and help them understand the issue and what they can change to avoid causing - offence. Complex discussion in a foreign language can be very intimidating, - and we want to grow our diversity also across nationalities and cultures. - -*Mediation*: voluntary, informal mediation is a tool at our disposal. In -contexts such as when two or more parties have all escalated to the point of -inappropriate behavior (something sadly common in human conflict), it may be -useful to facilitate a mediation process. This is only an example: the -Committee can consider mediation in any case, mindful that the process is meant -to be strictly voluntary and no party can be pressured to participate. If the -Committee suggests mediation, it should: - -* Find a candidate who can serve as a mediator. -* Obtain the agreement of the reporter(s). The reporter(s) have complete - freedom to decline the mediation idea, or to propose an alternate mediator. -* Obtain the agreement of the reported person(s). -* Settle on the mediator: while parties can propose a different mediator than - the suggested candidate, only if common agreement is reached on all terms can - the process move forward. -* Establish a timeline for mediation to complete, ideally within two weeks. - -The mediator will engage with all the parties and seek a resolution that is -satisfactory to all. Upon completion, the mediator will provide a report -(vetted by all parties to the process) to the Committee, with recommendations -on further steps. The Committee will then evaluate these results (whether -satisfactory resolution was achieved or not) and decide on any additional -action deemed necessary. - - -How the committee will respond to reports -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -When the committee (or a committee member) receives a report, they will first -determine whether the report is about a clear and severe breach (as defined -below). If so, immediate action needs to be taken in addition to the regular -report handling process. - -Clear and severe breach actions -+++++++++++++++++++++++++++++++ - -We know that it is painfully common for internet communication to start at or -devolve into obvious and flagrant abuse. We will deal quickly with clear and -severe breaches like personal threats, violent, sexist or racist language. - -When a member of the Code of Conduct committee becomes aware of a clear and -severe breach, they will do the following: - -* Immediately disconnect the originator from all NumPy communication channels. -* Reply to the reporter that their report has been received and that the - originator has been disconnected. -* In every case, the moderator should make a reasonable effort to contact the - originator, and tell them specifically how their language or actions - qualify as a "clear and severe breach". The moderator should also say - that, if the originator believes this is unfair or they want to be - reconnected to NumPy, they have the right to ask for a review, as below, by - the Code of Conduct Committee. - The moderator should copy this explanation to the Code of Conduct Committee. -* The Code of Conduct Committee will formally review and sign off on all cases - where this mechanism has been applied to make sure it is not being used to - control ordinary heated disagreement. - -Report handling -+++++++++++++++ - -When a report is sent to the committee they will immediately reply to the -reporter to confirm receipt. This reply must be sent within 72 hours, and the -group should strive to respond much quicker than that. - -If a report doesn't contain enough information, the committee will obtain all -relevant data before acting. The committee is empowered to act on the Steering -Council’s behalf in contacting any individuals involved to get a more complete -account of events. - -The committee will then review the incident and determine, to the best of their -ability: - -* What happened. -* Whether this event constitutes a Code of Conduct violation. -* Who are the responsible party(ies). -* Whether this is an ongoing situation, and there is a threat to anyone's - physical safety. - -This information will be collected in writing, and whenever possible the -group's deliberations will be recorded and retained (i.e. chat transcripts, -email discussions, recorded conference calls, summaries of voice conversations, -etc). - -It is important to retain an archive of all activities of this committee to -ensure consistency in behavior and provide institutional memory for the -project. To assist in this, the default channel of discussion for this -committee will be a private mailing list accessible to current and future -members of the committee as well as members of the Steering Council upon -justified request. If the Committee finds the need to use off-list -communications (e.g. phone calls for early/rapid response), it should in all -cases summarize these back to the list so there's a good record of the process. - -The Code of Conduct Committee should aim to have a resolution agreed upon within -two weeks. In the event that a resolution can't be determined in that time, the -committee will respond to the reporter(s) with an update and projected timeline -for resolution. - - -.. _CoC_resolutions: - -Resolutions -~~~~~~~~~~~ - -The committee must agree on a resolution by consensus. If the group cannot reach -consensus and deadlocks for over a week, the group will turn the matter over to -the Steering Council for resolution. - - -Possible responses may include: - -* Taking no further action - - - if we determine no violations have occurred. - - if the matter has been resolved publicly while the committee was considering responses. - -* Coordinating voluntary mediation: if all involved parties agree, the - Committee may facilitate a mediation process as detailed above. -* Remind publicly, and point out that some behavior/actions/language have been - judged inappropriate and why in the current context, or can but hurtful to - some people, requesting the community to self-adjust. -* A private reprimand from the committee to the individual(s) involved. In this - case, the group chair will deliver that reprimand to the individual(s) over - email, cc'ing the group. -* A public reprimand. In this case, the committee chair will deliver that - reprimand in the same venue that the violation occurred, within the limits of - practicality. E.g., the original mailing list for an email violation, but - for a chat room discussion where the person/context may be gone, they can be - reached by other means. The group may choose to publish this message - elsewhere for documentation purposes. -* A request for a public or private apology, assuming the reporter agrees to - this idea: they may at their discretion refuse further contact with the - violator. The chair will deliver this request. The committee may, if it - chooses, attach "strings" to this request: for example, the group may ask a - violator to apologize in order to retain one’s membership on a mailing list. -* A "mutually agreed upon hiatus" where the committee asks the individual to - temporarily refrain from community participation. If the individual chooses - not to take a temporary break voluntarily, the committee may issue a - "mandatory cooling off period". -* A permanent or temporary ban from some or all NumPy spaces (mailing lists, - gitter.im, etc.). The group will maintain records of all such bans so that - they may be reviewed in the future or otherwise maintained. - -Once a resolution is agreed upon, but before it is enacted, the committee will -contact the original reporter and any other affected parties and explain the -proposed resolution. The committee will ask if this resolution is acceptable, -and must note feedback for the record. - -Finally, the committee will make a report to the NumPy Steering Council (as -well as the NumPy core team in the event of an ongoing resolution, such as a -ban). - -The committee will never publicly discuss the issue; all public statements will -be made by the chair of the Code of Conduct Committee or the NumPy Steering -Council. - - -Conflicts of Interest -~~~~~~~~~~~~~~~~~~~~~ - -In the event of any conflict of interest, a committee member must immediately -notify the other members, and recuse themselves if necessary. diff --git a/doc/source/dev/development_workflow.rst b/doc/source/dev/development_workflow.rst index d5a49a9f9..1665cfddb 100644 --- a/doc/source/dev/development_workflow.rst +++ b/doc/source/dev/development_workflow.rst @@ -188,6 +188,16 @@ Standard acronyms to start the commit message with are:: REL: related to releasing numpy +.. _workflow_mailing_list: + +Get the mailing list's opinion +======================================================= + +If you plan a new feature or API change, it's wisest to first email the +NumPy `mailing list <https://mail.python.org/mailman/listinfo/numpy-discussion>`_ +asking for comment. If you haven't heard back in a week, it's +OK to ping the list again. + .. _asking-for-merging: Asking for your changes to be merged with the main repo @@ -197,15 +207,24 @@ When you feel your work is finished, you can create a pull request (PR). Github has a nice help page that outlines the process for `filing pull requests`_. If your changes involve modifications to the API or addition/modification of a -function, you should - -- send an email to the `NumPy mailing list`_ with a link to your PR along with - a description of and a motivation for your changes. This may generate - changes and feedback. It might be prudent to start with this step if your - change may be controversial. -- add a release note to the ``doc/release/upcoming_changes/`` directory, - following the instructions and format in the - ``doc/release/upcoming_changes/README.rst`` file. +function, add a release note to the ``doc/release/upcoming_changes/`` +directory, following the instructions and format in the +``doc/release/upcoming_changes/README.rst`` file. + + +.. _workflow_PR_timeline: + +Getting your PR reviewed +======================== + +We review pull requests as soon as we can, typically within a week. If you get +no review comments within two weeks, feel free to ask for feedback by +adding a comment on your PR (this will notify maintainers). + +If your PR is large or complicated, asking for input on the numpy-discussion +mailing list may also be useful. + + .. _rebasing-on-master: diff --git a/doc/source/dev/index.rst b/doc/source/dev/index.rst index c4f35b68f..020df0b2b 100644 --- a/doc/source/dev/index.rst +++ b/doc/source/dev/index.rst @@ -9,7 +9,6 @@ Contributing to NumPy .. toctree:: :hidden: - conduct/code_of_conduct Git Basics <gitwash/index> development_environment development_workflow @@ -293,7 +292,6 @@ The rest of the story .. toctree:: :maxdepth: 2 - conduct/code_of_conduct Git Basics <gitwash/index> development_environment development_workflow diff --git a/doc/source/doc_conventions.rst b/doc/source/doc_conventions.rst new file mode 100644 index 000000000..e2bc419d1 --- /dev/null +++ b/doc/source/doc_conventions.rst @@ -0,0 +1,23 @@ +.. _documentation_conventions: + +############################################################################## +Documentation conventions +############################################################################## + +- Names that look like :func:`numpy.array` are links to detailed + documentation. + +- Examples often include the Python prompt ``>>>``. This is not part of the + code and will cause an error if typed or pasted into the Python + shell. It can be safely typed or pasted into the IPython shell; the ``>>>`` + is ignored. + +- Examples often use ``np`` as an alias for ``numpy``; that is, they assume + you've run:: + + >>> import numpy as np + +- If you're a code contributor writing a docstring, see :ref:`docstring_intro`. + +- If you're a writer contributing ordinary (non-docstring) documentation, see + :ref:`userdoc_guide`. diff --git a/doc/source/docs/howto_document.rst b/doc/source/docs/howto_document.rst index 9f9068ab3..ff726c67c 100644 --- a/doc/source/docs/howto_document.rst +++ b/doc/source/docs/howto_document.rst @@ -1,12 +1,41 @@ .. _howto-document: -A Guide to NumPy/SciPy Documentation -==================================== +A Guide to NumPy Documentation +============================== + +.. _userdoc_guide: User documentation -******************* -NumPy text documents should follow the `Google developer documentation style guide <https://developers.google.com/style>`_. +****************** +- In general, we follow the + `Google developer documentation style guide <https://developers.google.com/style>`_. + +- NumPy style governs cases where: + + - Google has no guidance, or + - We prefer not to use the Google style + + Our current rules: + + - We pluralize *index* as *indices* rather than + `indexes <https://developers.google.com/style/word-list#letter-i>`_, + following the precedent of :func:`numpy.indices`. + + - For consistency we also pluralize *matrix* as *matrices*. + +- Grammatical issues inadequately addressed by the NumPy or Google rules are + decided by the section on "Grammar and Usage" in the most recent edition of + the `Chicago Manual of Style + <https://en.wikipedia.org/wiki/The_Chicago_Manual_of_Style>`_. + +- We welcome being + `alerted <https://github.com/numpy/numpy/issues>`_ to cases + we should add to the NumPy style rules. + + + +.. _docstring_intro: Docstrings ********** diff --git a/doc/source/f2py/allocarr_session.dat b/doc/source/f2py/allocarr_session.dat index 754d9cb8b..ba168c22a 100644 --- a/doc/source/f2py/allocarr_session.dat +++ b/doc/source/f2py/allocarr_session.dat @@ -1,8 +1,11 @@ >>> import allocarr >>> print(allocarr.mod.__doc__) -b - 'f'-array(-1,-1), not allocated -foo - Function signature: - foo() +b : 'f'-array(-1,-1), not allocated +foo() + +Wrapper for ``foo``. + + >>> allocarr.mod.foo() b is not allocated diff --git a/doc/source/f2py/common_session.dat b/doc/source/f2py/common_session.dat index 0a38bec27..2595bfbd5 100644 --- a/doc/source/f2py/common_session.dat +++ b/doc/source/f2py/common_session.dat @@ -1,8 +1,8 @@ >>> import common >>> print(common.data.__doc__) -i - 'i'-scalar -x - 'i'-array(4) -a - 'f'-array(2,3) +i : 'i'-scalar +x : 'i'-array(4) +a : 'f'-array(2,3) >>> common.data.i = 5 >>> common.data.x[1] = 2 diff --git a/doc/source/f2py/moddata_session.dat b/doc/source/f2py/moddata_session.dat index e3c758041..824bd86fc 100644 --- a/doc/source/f2py/moddata_session.dat +++ b/doc/source/f2py/moddata_session.dat @@ -1,10 +1,14 @@ >>> import moddata >>> print(moddata.mod.__doc__) -i - 'i'-scalar -x - 'i'-array(4) -a - 'f'-array(2,3) -foo - Function signature: - foo() +i : 'i'-scalar +x : 'i'-array(4) +a : 'f'-array(2,3) +b : 'f'-array(-1,-1), not allocated +foo() + +Wrapper for ``foo``. + + >>> moddata.mod.i = 5 >>> moddata.mod.x[:2] = [1,2] diff --git a/doc/source/glossary.rst b/doc/source/glossary.rst index 4a59c990b..17071c8f1 100644 --- a/doc/source/glossary.rst +++ b/doc/source/glossary.rst @@ -6,20 +6,27 @@ Glossary (`n`,) - A tuple with one element. The trailing comma distinguishes a one-element - tuple from a parenthesized ``n``. + A parenthesized number followed by a comma denotes a tuple with one + element. The trailing comma distinguishes a one-element tuple from a + parenthesized ``n``. -1 - Used as a dimension entry, ``-1`` instructs NumPy to choose the length - that will keep the total number of elements the same. + - **In a dimension entry**, instructs NumPy to choose the length + that will keep the total number of array elements the same. + >>> np.arange(12).reshape(4, -1).shape + (4, 3) - ``...`` - An :py:data:`Ellipsis` + - **In an index**, any negative value + `denotes <https://docs.python.org/dev/faq/programming.html#what-s-a-negative-index>`_ + indexing from the right. - **When indexing an array**, shorthand that the missing axes, if they - exist, are full slices. + . . . + An :py:data:`Ellipsis`. + + - **When indexing an array**, shorthand that the missing axes, if they + exist, are full slices. >>> a = np.arange(24).reshape(2,3,4) @@ -35,13 +42,13 @@ Glossary >>> a[0,...,0].shape (3,) - It can be used at most once; ``a[...,0,...]`` raises an :exc:`IndexError`. + It can be used at most once; ``a[...,0,...]`` raises an :exc:`IndexError`. - **In printouts**, NumPy substitutes ``...`` for the middle elements of - large arrays. To see the entire array, use `numpy.printoptions` + - **In printouts**, NumPy substitutes ``...`` for the middle elements of + large arrays. To see the entire array, use `numpy.printoptions` - ``:`` + : The Python :term:`python:slice` operator. In ndarrays, slicing can be applied to every axis: @@ -73,14 +80,14 @@ Glossary For details, see :ref:`combining-advanced-and-basic-indexing`. - ``<`` + < In a dtype declaration, indicates that the data is :term:`little-endian` (the bracket is big on the right). :: >>> dt = np.dtype('<f') # little-endian single-precision float - ``>`` + > In a dtype declaration, indicates that the data is :term:`big-endian` (the bracket is big on the left). :: @@ -95,54 +102,67 @@ Glossary along an axis - Axes are defined for arrays with more than one dimension. A - 2-dimensional array has two corresponding axes: the first running - vertically downwards across rows (axis 0), and the second running - horizontally across columns (axis 1). + An operation `along axis n` of array ``a`` behaves as if its argument + were an array of slices of ``a`` where each slice has a successive + index of axis `n`. - Many operations can take place along one of these axes. For example, - we can sum each row of an array, in which case we operate along - columns, or axis 1:: + For example, if ``a`` is a 3 x `N` array, an operation along axis 0 + behaves as if its argument were an array containing slices of each row: - >>> x = np.arange(12).reshape((3,4)) + >>> np.array((a[0,:], a[1,:], a[2,:])) #doctest: +SKIP - >>> x - array([[ 0, 1, 2, 3], - [ 4, 5, 6, 7], - [ 8, 9, 10, 11]]) + To make it concrete, we can pick the operation to be the array-reversal + function :func:`numpy.flip`, which accepts an ``axis`` argument. We + construct a 3 x 4 array ``a``: - >>> x.sum(axis=1) - array([ 6, 22, 38]) + >>> a = np.arange(12).reshape(3,4) + >>> a + array([[ 0, 1, 2, 3], + [ 4, 5, 6, 7], + [ 8, 9, 10, 11]]) + Reversing along axis 0 (the row axis) yields - array - A homogeneous container of numerical elements. Each element in the - array occupies a fixed amount of memory (hence homogeneous), and - can be a numerical element of a single type (such as float, int - or complex) or a combination (such as ``(float, int, float)``). Each - array has an associated data-type (or ``dtype``), which describes - the numerical type of its elements:: + >>> np.flip(a,axis=0) + array([[ 8, 9, 10, 11], + [ 4, 5, 6, 7], + [ 0, 1, 2, 3]]) - >>> x = np.array([1, 2, 3], float) + Recalling the definition of `along an axis`, ``flip`` along axis 0 is + treating its argument as if it were - >>> x - array([ 1., 2., 3.]) + >>> np.array((a[0,:], a[1,:], a[2,:])) + array([[ 0, 1, 2, 3], + [ 4, 5, 6, 7], + [ 8, 9, 10, 11]]) - >>> x.dtype # floating point number, 64 bits of memory per element - dtype('float64') + and the result of ``np.flip(a,axis=0)`` is to reverse the slices: + >>> np.array((a[2,:],a[1,:],a[0,:])) + array([[ 8, 9, 10, 11], + [ 4, 5, 6, 7], + [ 0, 1, 2, 3]]) - # More complicated data type: each array element is a combination of - # and integer and a floating point number - >>> np.array([(1, 2.0), (3, 4.0)], dtype=[('x', np.int64), ('y', float)]) - array([(1, 2.), (3, 4.)], dtype=[('x', '<i8'), ('y', '<f8')]) - Fast element-wise operations, called a :term:`ufunc`, operate on arrays. + array + Used synonymously in the NumPy docs with :term:`ndarray`. array_like - Any sequence that can be interpreted as an ndarray. This includes - nested lists, tuples, scalars and existing arrays. + Any :doc:`scalar <reference/arrays.scalars>` or + :term:`python:sequence` + that can be interpreted as an ndarray. In addition to ndarrays + and scalars this category includes lists (possibly nested and with + different element types) and tuples. Any argument accepted by + :doc:`numpy.array <reference/generated/numpy.array>` + is array_like. :: + + >>> a = np.array([[1, 2.0], [0, 0], (1+1j, 3.)]) + + >>> a + array([[1.+0.j, 2.+0.j], + [0.+0.j, 0.+0.j], + [1.+1.j, 3.+0.j]]) array scalar @@ -152,7 +172,6 @@ Glossary axis - Another term for an array dimension. Axes are numbered left to right; axis 0 is the first element in the shape tuple. @@ -167,7 +186,6 @@ Glossary >>> a array([[[ 0, 1, 2], [ 3, 4, 5]], - <BLANKLINE> [[ 6, 7, 8], [ 9, 10, 11]]]) @@ -206,19 +224,16 @@ Glossary .base If an array does not own its memory, then its - :doc:`base <reference/generated/numpy.ndarray.base>` attribute - returns the object whose memory the array is referencing. That object - may be borrowing the memory from still another object, so the - owning object may be ``a.base.base.base...``. Despite advice to the - contrary, testing ``base`` is not a surefire way to determine if two - arrays are :term:`view`\ s. + :doc:`base <reference/generated/numpy.ndarray.base>` attribute returns + the object whose memory the array is referencing. That object may be + referencing the memory from still another object, so the owning object + may be ``a.base.base.base...``. Some writers erroneously claim that + testing ``base`` determines if arrays are :term:`view`\ s. For the + correct way, see :func:`numpy.shares_memory`. big-endian - When storing a multi-byte value in memory as a sequence of bytes, the - sequence addresses/sends/stores the most significant byte first (lowest - address) and the least significant byte last (highest address). Common in - micro-processors and used for transmission of data over network protocols. + See `Endianness <https://en.wikipedia.org/wiki/Endianness>`_. BLAS @@ -226,244 +241,145 @@ Glossary broadcast - NumPy can do operations on arrays whose shapes are mismatched:: + *broadcasting* is NumPy's ability to process ndarrays of + different sizes as if all were the same size. - >>> x = np.array([1, 2]) - >>> y = np.array([[3], [4]]) + It permits an elegant do-what-I-mean behavior where, for instance, + adding a scalar to a vector adds the scalar value to every element. - >>> x - array([1, 2]) + >>> a = np.arange(3) + >>> a + array([0, 1, 2]) - >>> y - array([[3], - [4]]) + >>> a + [3, 3, 3] + array([3, 4, 5]) + + >>> a + 3 + array([3, 4, 5]) - >>> x + y - array([[4, 5], - [5, 6]]) + Ordinarly, vector operands must all be the same size, because NumPy + works element by element -- for instance, ``c = a * b`` is :: - See `basics.broadcasting` for more information. + c[0,0,0] = a[0,0,0] * b[0,0,0] + c[0,0,1] = a[0,0,1] * b[0,0,1] + ... + + But in certain useful cases, NumPy can duplicate data along "missing" + axes or "too-short" dimensions so shapes will match. The duplication + costs no memory or time. For details, see + :doc:`Broadcasting. <user/basics.broadcasting>` C order - See `row-major` + Same as :term:`row-major`. column-major - A way to represent items in a N-dimensional array in the 1-dimensional - computer memory. In column-major order, the leftmost index "varies the - fastest": for example the array:: - - [[1, 2, 3], - [4, 5, 6]] + See `Row- and column-major order <https://en.wikipedia.org/wiki/Row-_and_column-major_order>`_. - is represented in the column-major order as:: - [1, 4, 2, 5, 3, 6] + contiguous + An array is contiguous if + * it occupies an unbroken block of memory, and + * array elements with higher indexes occupy higher addresses (that + is, no :term:`stride` is negative). - Column-major order is also known as the Fortran order, as the Fortran - programming language uses it. copy - See :term:`view`. - decorator - An operator that transforms a function. For example, a ``log`` - decorator may be defined to print debugging information upon - function execution:: - - >>> def log(f): - ... def new_logging_func(*args, **kwargs): - ... print("Logging call with parameters:", args, kwargs) - ... return f(*args, **kwargs) - ... - ... return new_logging_func - - Now, when we define a function, we can "decorate" it using ``log``:: - - >>> @log - ... def add(a, b): - ... return a + b - - Calling ``add`` then yields: - - >>> add(1, 2) - Logging call with parameters: (1, 2) {} - 3 - - - dictionary - Resembling a language dictionary, which provides a mapping between - words and descriptions thereof, a Python dictionary is a mapping - between two objects:: - - >>> x = {1: 'one', 'two': [1, 2]} - - Here, `x` is a dictionary mapping keys to values, in this case - the integer 1 to the string "one", and the string "two" to - the list ``[1, 2]``. The values may be accessed using their - corresponding keys:: - - >>> x[1] - 'one' - - >>> x['two'] - [1, 2] - - Note that dictionaries are not stored in any specific order. Also, - most mutable (see *immutable* below) objects, such as lists, may not - be used as keys. - - For more information on dictionaries, read the - `Python tutorial <https://docs.python.org/tutorial/>`_. - - dimension - See :term:`axis`. dtype - The datatype describing the (identically typed) elements in an ndarray. It can be changed to reinterpret the array contents. For details, see :doc:`Data type objects (dtype). <reference/arrays.dtypes>` fancy indexing - Another term for :term:`advanced indexing`. field - In a :term:`structured data type`, each sub-type is called a `field`. + In a :term:`structured data type`, each subtype is called a `field`. The `field` has a name (a string), a type (any valid dtype), and - an optional `title`. See :ref:`arrays.dtypes` + an optional `title`. See :ref:`arrays.dtypes`. Fortran order - See `column-major` + Same as :term:`column-major`. flattened - Collapsed to a one-dimensional array. See `numpy.ndarray.flatten` - for details. + See :term:`ravel`. homogeneous - Describes a block of memory comprised of blocks, each block comprised of - items and of the same size, and blocks are interpreted in exactly the - same way. In the simplest case each block contains a single item, for - instance int32 or float64. - + All elements of a homogeneous array have the same type. ndarrays, in + contrast to Python lists, are homogeneous. The type can be complicated, + as in a :term:`structured array`, but all elements have that type. - immutable - An object that cannot be modified after execution is called - immutable. Two common examples are strings and tuples. + NumPy `object arrays <#term-object-array>`_, which contain references to + Python objects, fill the role of heterogeneous arrays. itemsize The size of the dtype element in bytes. - list - A Python container that can hold any number of objects or items. - The items do not have to be of the same type, and can even be - lists themselves:: - - >>> x = [2, 2.0, "two", [2, 2.0]] - - The list `x` contains 4 items, each which can be accessed individually:: - - >>> x[2] # the string 'two' - 'two' - - >>> x[3] # a list, containing an integer 2 and a float 2.0 - [2, 2.0] - - It is also possible to select more than one item at a time, - using *slicing*:: - - >>> x[0:2] # or, equivalently, x[:2] - [2, 2.0] - - In code, arrays are often conveniently expressed as nested lists:: - - - >>> np.array([[1, 2], [3, 4]]) - array([[1, 2], - [3, 4]]) - - For more information, read the section on lists in the `Python - tutorial <https://docs.python.org/tutorial/>`_. For a mapping - type (key-value), see *dictionary*. - - little-endian - When storing a multi-byte value in memory as a sequence of bytes, the - sequence addresses/sends/stores the least significant byte first (lowest - address) and the most significant byte last (highest address). Common in - x86 processors. + See `Endianness <https://en.wikipedia.org/wiki/Endianness>`_. mask - A boolean array, used to select only certain elements for an operation:: + A boolean array used to select only certain elements for an operation: - >>> x = np.arange(5) - >>> x - array([0, 1, 2, 3, 4]) + >>> x = np.arange(5) + >>> x + array([0, 1, 2, 3, 4]) - >>> mask = (x > 2) - >>> mask - array([False, False, False, True, True]) + >>> mask = (x > 2) + >>> mask + array([False, False, False, True, True]) - >>> x[mask] = -1 - >>> x - array([ 0, 1, 2, -1, -1]) + >>> x[mask] = -1 + >>> x + array([ 0, 1, 2, -1, -1]) masked array - Array that suppressed values indicated by a mask:: + Bad or missing data can be cleanly ignored by putting it in a masked + array, which has an internal boolean array indicating invalid + entries. Operations with masked arrays ignore these entries. :: - >>> x = np.ma.masked_array([np.nan, 2, np.nan], [True, False, True]) - >>> x + >>> a = np.ma.masked_array([np.nan, 2, np.nan], [True, False, True]) + >>> a masked_array(data=[--, 2.0, --], mask=[ True, False, True], fill_value=1e+20) - >>> x + [1, 2, 3] + >>> a + [1, 2, 3] masked_array(data=[--, 4.0, --], mask=[ True, False, True], fill_value=1e+20) - - Masked arrays are often used when operating on arrays containing - missing or invalid entries. + For details, see :doc:`Masked arrays. <reference/maskedarray>` matrix - A 2-dimensional ndarray that preserves its two-dimensional nature - throughout operations. It has certain special operations, such as ``*`` - (matrix multiplication) and ``**`` (matrix power), defined:: - - >>> x = np.mat([[1, 2], [3, 4]]) - >>> x - matrix([[1, 2], - [3, 4]]) - - >>> x**2 - matrix([[ 7, 10], - [15, 22]]) + NumPy's two-dimensional + :doc:`matrix class <reference/generated/numpy.matrix>` + should no longer be used; use regular ndarrays. ndarray - See *array*. + :doc:`NumPy's basic structure <reference/arrays>`. object array - An array whose dtype is ``object``; that is, it contains references to Python objects. Indexing the array dereferences the Python objects, so unlike other ndarrays, an object array has the ability to hold @@ -471,72 +387,43 @@ Glossary ravel - - `numpy.ravel` and `numpy.ndarray.flatten` both flatten an ndarray. ``ravel`` - will return a view if possible; ``flatten`` always returns a copy. - - Flattening collapses a multi-dimensional array to a single dimension; + :doc:`numpy.ravel \ + <reference/generated/numpy.ravel>` + and :doc:`numpy.flatten \ + <reference/generated/numpy.ndarray.flatten>` + both flatten an ndarray. ``ravel`` will return a view if possible; + ``flatten`` always returns a copy. + + Flattening collapses a multimdimensional array to a single dimension; details of how this is done (for instance, whether ``a[n+1]`` should be the next row or next column) are parameters. record array - An :term:`ndarray` with :term:`structured data type` which has been - subclassed as ``np.recarray`` and whose dtype is of type ``np.record``, - making the fields of its data type to be accessible by attribute. - - - reference - If ``a`` is a reference to ``b``, then ``(a is b) == True``. Therefore, - ``a`` and ``b`` are different names for the same Python object. + A :term:`structured array` with allowing access in an attribute style + (``a.field``) in addition to ``a['field']``. For details, see + :doc:`numpy.recarray. <reference/generated/numpy.recarray>` row-major - A way to represent items in a N-dimensional array in the 1-dimensional - computer memory. In row-major order, the rightmost index "varies - the fastest": for example the array:: - - [[1, 2, 3], - [4, 5, 6]] - - is represented in the row-major order as:: - - [1, 2, 3, 4, 5, 6] - - Row-major order is also known as the C order, as the C programming - language uses it. New NumPy arrays are by default in row-major order. + See `Row- and column-major order <https://en.wikipedia.org/wiki/Row-_and_column-major_order>`_. + NumPy creates arrays in row-major order by default. - slice - Used to select only certain elements from a sequence: + scalar + In NumPy, usually a synonym for :term:`array scalar`. - >>> x = range(5) - >>> x - [0, 1, 2, 3, 4] - >>> x[1:3] # slice from 1 to 3 (excluding 3 itself) - [1, 2] - - >>> x[1:5:2] # slice from 1 to 5, but skipping every second element - [1, 3] - - >>> x[::-1] # slice a sequence in reverse - [4, 3, 2, 1, 0] - - Arrays may have more than one dimension, each which can be sliced - individually: - - >>> x = np.array([[1, 2], [3, 4]]) - >>> x - array([[1, 2], - [3, 4]]) - - >>> x[:, 1] - array([2, 4]) + shape + A tuple showing the length of each dimension of an ndarray. The + length of the tuple itself is the number of dimensions + (:doc:`numpy.ndim <reference/generated/numpy.ndarray.ndim>`). + The product of the tuple elements is the number of elements in the + array. For details, see + :doc:`numpy.ndarray.shape <reference/generated/numpy.ndarray.shape>`. stride - Physical memory is one-dimensional; strides provide a mechanism to map a given index to an address in memory. For an N-dimensional array, its ``strides`` attribute is an N-element tuple; advancing from index @@ -555,56 +442,70 @@ Glossary <https://arxiv.org/pdf/1102.1523.pdf>`_ - structure - See :term:`structured data type` - - structured array - Array whose :term:`dtype` is a :term:`structured data type`. structured data type - A data type composed of other datatypes + Users can create arbitrarily complex :term:`dtypes <dtype>` + that can include other arrays and dtypes. These composite dtypes are called + :doc:`structured data types. <user/basics.rec>` - subarray data type - A :term:`structured data type` may contain a :term:`ndarray` with its - own dtype and shape: + subarray + An array nested in a :term:`structured data type`, as ``b`` is here: + + >>> dt = np.dtype([('a', np.int32), ('b', np.float32, (3,))]) + >>> np.zeros(3, dtype=dt) + array([(0, [0., 0., 0.]), (0, [0., 0., 0.]), (0, [0., 0., 0.])], + dtype=[('a', '<i4'), ('b', '<f4', (3,))]) - >>> dt = np.dtype([('a', np.int32), ('b', np.float32, (3,))]) - >>> np.zeros(3, dtype=dt) - array([(0, [0., 0., 0.]), (0, [0., 0., 0.]), (0, [0., 0., 0.])], - dtype=[('a', '<i4'), ('b', '<f4', (3,))]) + + subarray data type + An element of a structured datatype that behaves like an ndarray. title - In addition to field names, structured array fields may have an - associated :ref:`title <titles>` which is an alias to the name and is - commonly used for plotting. + An alias for a field name in a structured datatype. + + + type + In NumPy, usually a synonym for :term:`dtype`. For the more general + Python meaning, :term:`see here. <python:type>` ufunc - Universal function. A fast element-wise, :term:`vectorized - <vectorization>` array operation. Examples include ``add``, ``sin`` and - ``logical_or``. + NumPy's fast element-by-element computation (:term:`vectorization`) + gives a choice which function gets applied. The general term for the + function is ``ufunc``, short for ``universal function``. NumPy routines + have built-in ufuncs, but users can also + :doc:`write their own. <reference/ufuncs>` vectorization - Optimizing a looping block by specialized code. In a traditional sense, - vectorization performs the same operation on multiple elements with - fixed strides between them via specialized hardware. Compilers know how - to take advantage of well-constructed loops to implement such - optimizations. NumPy uses :ref:`vectorization <whatis-vectorization>` - to mean any optimization via specialized code performing the same - operations on multiple elements, typically achieving speedups by - avoiding some of the overhead in looking up and converting the elements. - + NumPy hands off array processing to C, where looping and computation are + much faster than in Python. To exploit this, programmers using NumPy + eliminate Python loops in favor of array-to-array operations. + :term:`vectorization` can refer both to the C offloading and to + structuring NumPy code to leverage it. view - An array that does not own its data, but refers to another array's - data instead. For example, we may create a view that only shows - every second element of another array:: + Without touching underlying data, NumPy can make one array appear + to change its datatype and shape. + + An array created this way is a `view`, and NumPy often exploits the + performance gain of using a view versus making a new array. + + A potential drawback is that writing to a view can alter the original + as well. If this is a problem, NumPy instead needs to create a + physically distinct array -- a `copy`. + + Some NumPy routines always return views, some always return copies, some + may return one or the other, and for some the choice can be specified. + Responsiblity for managing views and copies falls to the programmer. + :func:`numpy.shares_memory` will check whether ``b`` is a view of + ``a``, but an exact answer isn't always feasible, as the documentation + page explains. >>> x = np.arange(5) >>> x @@ -618,15 +519,3 @@ Glossary >>> y array([3, 2, 4]) - - wrapper - Python is a high-level (highly abstracted, or English-like) language. - This abstraction comes at a price in execution speed, and sometimes - it becomes necessary to use lower level languages to do fast - computations. A wrapper is code that provides a bridge between - high and the low level languages, allowing, e.g., Python to execute - code written in C or Fortran. - - Examples include ctypes, SWIG and Cython (which wraps C and C++) - and f2py (which wraps Fortran). - diff --git a/doc/source/reference/arrays.indexing.rst b/doc/source/reference/arrays.indexing.rst index 180a79dae..b2a9f1d21 100644 --- a/doc/source/reference/arrays.indexing.rst +++ b/doc/source/reference/arrays.indexing.rst @@ -34,7 +34,7 @@ Basic Slicing and Indexing Basic slicing extends Python's basic concept of slicing to N dimensions. Basic slicing occurs when *obj* is a :class:`slice` object (constructed by ``start:stop:step`` notation inside of brackets), an -integer, or a tuple of slice objects and integers. :const:`Ellipsis` +integer, or a tuple of slice objects and integers. :py:data:`Ellipsis` and :const:`newaxis` objects can be interspersed with these as well. @@ -43,7 +43,7 @@ well. In order to remain backward compatible with a common usage in Numeric, basic slicing is also initiated if the selection object is any non-ndarray and non-tuple sequence (such as a :class:`list`) containing - :class:`slice` objects, the :const:`Ellipsis` object, or the :const:`newaxis` + :class:`slice` objects, the :py:data:`Ellipsis` object, or the :const:`newaxis` object, but not for integer arrays or other embedded sequences. .. index:: @@ -129,7 +129,7 @@ concepts to remember include: [5], [6]]]) -- :const:`Ellipsis` expands to the number of ``:`` objects needed for the +- :py:data:`Ellipsis` expands to the number of ``:`` objects needed for the selection tuple to index all dimensions. In most cases, this means that length of the expanded selection tuple is ``x.ndim``. There may only be a single ellipsis present. @@ -333,7 +333,7 @@ the subspace defined by the basic indexing (excluding integers) and the subspace from the advanced indexing part. Two cases of index combination need to be distinguished: -* The advanced indexes are separated by a slice, :const:`Ellipsis` or :const:`newaxis`. +* The advanced indexes are separated by a slice, :py:data:`Ellipsis` or :const:`newaxis`. For example ``x[arr1, :, arr2]``. * The advanced indexes are all next to each other. For example ``x[..., arr1, arr2, :]`` but *not* ``x[arr1, :, 1]`` diff --git a/doc/source/reference/arrays.interface.rst b/doc/source/reference/arrays.interface.rst index 73e4aef0c..49772a298 100644 --- a/doc/source/reference/arrays.interface.rst +++ b/doc/source/reference/arrays.interface.rst @@ -231,13 +231,15 @@ as:: The flags member may consist of 5 bits showing how the data should be interpreted and one bit showing how the Interface should be -interpreted. The data-bits are :const:`CONTIGUOUS` (0x1), -:const:`FORTRAN` (0x2), :const:`ALIGNED` (0x100), :const:`NOTSWAPPED` -(0x200), and :const:`WRITEABLE` (0x400). A final flag -:const:`ARR_HAS_DESCR` (0x800) indicates whether or not this structure +interpreted. The data-bits are :c:macro:`NPY_ARRAY_C_CONTIGUOUS` (0x1), +:c:macro:`NPY_ARRAY_F_CONTIGUOUS` (0x2), :c:macro:`NPY_ARRAY_ALIGNED` (0x100), +:c:macro:`NPY_ARRAY_NOTSWAPPED` (0x200), and :c:macro:`NPY_ARRAY_WRITEABLE` (0x400). A final flag +:c:macro:`NPY_ARR_HAS_DESCR` (0x800) indicates whether or not this structure has the arrdescr field. The field should not be accessed unless this flag is present. + .. c:macro:: NPY_ARR_HAS_DESCR + .. admonition:: New since June 16, 2006: In the past most implementations used the ``desc`` member of the ``PyCObject`` diff --git a/doc/source/reference/c-api/array.rst b/doc/source/reference/c-api/array.rst index cfe4d2d51..9fe45d2de 100644 --- a/doc/source/reference/c-api/array.rst +++ b/doc/source/reference/c-api/array.rst @@ -3259,6 +3259,8 @@ Memory management :c:data:`NPY_USE_PYMEM` is 0, if :c:data:`NPY_USE_PYMEM` is 1, then the Python memory allocator is used. + .. c:macro:: NPY_USE_PYMEM + .. c:function:: int PyArray_ResolveWritebackIfCopy(PyArrayObject* obj) If ``obj.flags`` has :c:data:`NPY_ARRAY_WRITEBACKIFCOPY` or (deprecated) @@ -3289,9 +3291,13 @@ be accomplished using two groups of macros. Typically, if one macro in a group is used in a code block, all of them must be used in the same code block. Currently, :c:data:`NPY_ALLOW_THREADS` is defined to the python-defined :c:data:`WITH_THREADS` constant unless the environment -variable :c:data:`NPY_NOSMP` is set in which case +variable ``NPY_NOSMP`` is set in which case :c:data:`NPY_ALLOW_THREADS` is defined to be 0. +.. c:macro:: NPY_ALLOW_THREADS + +.. c:macro:: WITH_THREADS + Group 1 """"""" diff --git a/doc/source/reference/c-api/config.rst b/doc/source/reference/c-api/config.rst index c3e2c98af..cec5b973a 100644 --- a/doc/source/reference/c-api/config.rst +++ b/doc/source/reference/c-api/config.rst @@ -52,12 +52,15 @@ information is available to the pre-processor. .. c:macro:: NPY_SIZEOF_LONG_DOUBLE - sizeof(longdouble) (A macro defines **NPY_SIZEOF_LONGDOUBLE** as well.) +.. c:macro:: NPY_SIZEOF_LONGDOUBLE + + sizeof(longdouble) .. c:macro:: NPY_SIZEOF_PY_INTPTR_T - Size of a pointer on this platform (sizeof(void \*)) (A macro defines - NPY_SIZEOF_INTP as well.) +.. c:macro:: NPY_SIZEOF_INTP + + Size of a pointer on this platform (sizeof(void \*)) Platform information @@ -102,6 +105,12 @@ Platform information One of :c:data:`NPY_CPU_BIG`, :c:data:`NPY_CPU_LITTLE`, or :c:data:`NPY_CPU_UNKNOWN_ENDIAN`. + .. c:macro:: NPY_CPU_BIG + + .. c:macro:: NPY_CPU_LITTLE + + .. c:macro:: NPY_CPU_UNKNOWN_ENDIAN + Compiler directives ------------------- diff --git a/doc/source/reference/c-api/dtype.rst b/doc/source/reference/c-api/dtype.rst index a04d85212..47b998302 100644 --- a/doc/source/reference/c-api/dtype.rst +++ b/doc/source/reference/c-api/dtype.rst @@ -414,6 +414,12 @@ Printf Formatting For help in printing, the following strings are defined as the correct format specifier in printf and related commands. - :c:data:`NPY_LONGLONG_FMT`, :c:data:`NPY_ULONGLONG_FMT`, - :c:data:`NPY_INTP_FMT`, :c:data:`NPY_UINTP_FMT`, - :c:data:`NPY_LONGDOUBLE_FMT` +.. c:macro:: NPY_LONGLONG_FMT + +.. c:macro:: NPY_ULONGLONG_FMT + +.. c:macro:: NPY_INTP_FMT + +.. c:macro:: NPY_UINTP_FMT + +.. c:macro:: NPY_LONGDOUBLE_FMT diff --git a/doc/source/reference/c-api/iterator.rst b/doc/source/reference/c-api/iterator.rst index 7eac8c367..ae96bb3fb 100644 --- a/doc/source/reference/c-api/iterator.rst +++ b/doc/source/reference/c-api/iterator.rst @@ -1264,7 +1264,7 @@ functions provide that information. NPY_MAX_INTP is placed in the stride. Once the iterator is prepared for iteration (after a reset if - :c:data:`NPY_DELAY_BUFALLOC` was used), call this to get the strides + :c:data:`NPY_ITER_DELAY_BUFALLOC` was used), call this to get the strides which may be used to select a fast inner loop function. For example, if the stride is 0, that means the inner loop can always load its value into a variable once, then use the variable throughout the loop, diff --git a/doc/source/reference/c-api/types-and-structures.rst b/doc/source/reference/c-api/types-and-structures.rst index ee57d4680..cc961df3a 100644 --- a/doc/source/reference/c-api/types-and-structures.rst +++ b/doc/source/reference/c-api/types-and-structures.rst @@ -315,7 +315,7 @@ PyArrayDescr_Type and PyArray_Descr Bits set for the object data-type: ( :c:data:`NPY_LIST_PICKLE` \| :c:data:`NPY_USE_GETITEM` \| :c:data:`NPY_ITEM_IS_POINTER` \| - :c:data:`NPY_REFCOUNT` \| :c:data:`NPY_NEEDS_INIT` \| + :c:data:`NPY_ITEM_REFCOUNT` \| :c:data:`NPY_NEEDS_INIT` \| :c:data:`NPY_NEEDS_PYAPI`). .. c:function:: PyDataType_FLAGCHK(PyArray_Descr *dtype, int flags) @@ -1395,7 +1395,7 @@ PyArrayInterface as the *descr* key in :obj:`__array_interface__`). This can be ``NULL`` if *typekind* and *itemsize* provide enough information. This field is also ignored unless - :c:data:`ARR_HAS_DESCR` flag is on in *flags*. + :c:data:`NPY_ARR_HAS_DESCR` flag is on in *flags*. Internally used structures diff --git a/doc/source/reference/routines.set.rst b/doc/source/reference/routines.set.rst index b12d3d5f5..149c33a8b 100644 --- a/doc/source/reference/routines.set.rst +++ b/doc/source/reference/routines.set.rst @@ -3,6 +3,11 @@ Set routines .. currentmodule:: numpy +.. autosummary:: + :toctree: generated/ + + lib.arraysetops + Making proper sets ------------------ .. autosummary:: diff --git a/doc/source/user/basics.rec.rst b/doc/source/user/basics.rec.rst index f579b0d85..bb4ed89e9 100644 --- a/doc/source/user/basics.rec.rst +++ b/doc/source/user/basics.rec.rst @@ -575,11 +575,14 @@ Record Arrays ============= As an optional convenience numpy provides an ndarray subclass, -:class:`numpy.recarray`, and associated helper functions in the -:mod:`numpy.lib.recfunctions` submodule (aliased as ``numpy.rec``), that allows -access to fields of structured arrays by attribute instead of only by index. -Record arrays also use a special datatype, :class:`numpy.record`, that allows +:class:`numpy.recarray` that allows access to fields of structured arrays by +attribute instead of only by index. +Record arrays use a special datatype, :class:`numpy.record`, that allows field access by attribute on the structured scalars obtained from the array. +The :mod:`numpy.rec` module provides functions for creating recarrays from +various objects. +Additional helper functions for creating and manipulating structured arrays +can be found in :mod:`numpy.lib.recfunctions`. The simplest way to create a record array is with ``numpy.rec.array``:: diff --git a/doc/source/user/index.rst b/doc/source/user/index.rst index 3a79f0f2e..11a019b48 100644 --- a/doc/source/user/index.rst +++ b/doc/source/user/index.rst @@ -26,7 +26,10 @@ classes contained in the package, see the :ref:`reference`. howtos_index -.. These are stuck here to avoid the "WARNING: document isn't included in any +.. Links to these files are placed directly in the top-level html + (doc/source/_templates/indexcontent.html, which appears for the URLs + numpy.org/devdocs and numpy.org/doc/XX) and are not in any toctree, so + we include them here to avoid a "WARNING: document isn't included in any toctree" message .. toctree:: @@ -39,5 +42,5 @@ classes contained in the package, see the :ref:`reference`. ../docs/index ../bugs ../release - ../about + ../doc_conventions ../license diff --git a/doc/source/user/quickstart.rst b/doc/source/user/quickstart.rst index b1af81886..8e38234c5 100644 --- a/doc/source/user/quickstart.rst +++ b/doc/source/user/quickstart.rst @@ -23,7 +23,7 @@ https://scipy.org/install.html for instructions. **Learner profile** This tutorial is intended as a quick overview of -algebra and arrays in NumPy and want to understand how n-dimensional +algebra and arrays in NumPy. It demonstrates how n-dimensional (:math:`n>=2`) arrays are represented and can be manipulated. In particular, if you don't know how to apply common functions to n-dimensional arrays (without using for-loops), or if you want to understand axis and shape properties for |