├── .github └── workflows │ └── pythonapp.yml ├── CONTRIBUTING.md ├── HISTORY.md ├── LICENSE ├── MANIFEST.in ├── README.md ├── USERDOCS.md ├── constraints-3.10.txt ├── constraints-3.11.txt ├── constraints-3.7.txt ├── constraints-3.8.txt ├── constraints-3.9.txt ├── dependencies ├── build-requirements.txt ├── pandas-requirements.txt ├── qa-requirements.txt └── requirements.txt ├── nptyping ├── __init__.py ├── assert_isinstance.py ├── base_meta_classes.py ├── error.py ├── ndarray.py ├── ndarray.pyi ├── nptyping_type.py ├── package_info.py ├── pandas_ │ ├── __init__.py │ ├── dataframe.py │ ├── dataframe.pyi │ └── typing_.py ├── py.typed ├── recarray.py ├── recarray.pyi ├── shape.py ├── shape.pyi ├── shape_expression.py ├── structure.py ├── structure.pyi ├── structure_expression.py ├── typing_.py └── typing_.pyi ├── resources ├── logo.pdn └── logo.png ├── setup.cfg ├── setup.py ├── tasks.py └── tests ├── __init__.py ├── pandas_ ├── __init__.py ├── test_dataframe.py ├── test_fork_sync.py └── test_mypy_dataframe.py ├── test_assert_isinstance.py ├── test_base_meta_classes.py ├── test_beartype.py ├── test_help_texts.py ├── test_helpers ├── __init__.py ├── check_mypy_on_code.py └── temp_file.py ├── test_lib_export.py ├── test_mypy.py ├── test_ndarray.py ├── test_package_info.py ├── test_performance.py ├── test_pyright.py ├── test_recarray.py ├── test_shape.py ├── test_shape_expression.py ├── test_structure.py ├── test_structure_expression.py ├── test_typeguard.py └── test_wheel.py /.github/workflows/pythonapp.yml: -------------------------------------------------------------------------------- 1 | name: nptyping 2 | 3 | on: [push] 4 | 5 | jobs: 6 | 7 | test: 8 | runs-on: ${{ matrix.os }} 9 | strategy: 10 | matrix: 11 | python-version: [ '3.7', '3.8', '3.9', '3.10', '3.11' ] 12 | os: [ ubuntu-latest, macOS-latest, windows-latest ] 13 | name: Python ${{ matrix.python-version }} on ${{ matrix.os }} 14 | steps: 15 | - uses: actions/checkout@master 16 | - name: Setup python 17 | uses: actions/setup-python@v1 18 | with: 19 | python-version: ${{ matrix.python-version }} 20 | architecture: x64 21 | - name: Install Dependencies 22 | run: | 23 | python -m pip install --upgrade pip 24 | pip install invoke 25 | invoke venv install 26 | - name: Coverage 27 | run: | 28 | invoke coverage 29 | invoke run --command="-m codecov" 30 | 31 | qa: 32 | runs-on: windows-latest 33 | steps: 34 | - uses: actions/checkout@master 35 | - name: Setup python 36 | uses: actions/setup-python@v1 37 | with: 38 | python-version: '3.10' 39 | architecture: x64 40 | - name: Install Dependencies 41 | run: | 42 | python -m pip install --upgrade pip 43 | pip install invoke 44 | invoke venv install 45 | - name: Doctest 46 | run: | 47 | invoke doctest 48 | - name: Pylint 49 | run: | 50 | invoke pylint 51 | - name: Style 52 | run: | 53 | invoke format --check 54 | 55 | report: 56 | needs: test 57 | runs-on: windows-latest 58 | steps: 59 | - name: Coverage Report 60 | uses: codecov/codecov-action@v1 61 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | # *Contributing* 6 | 7 | * [Introduction](#Introduction) 8 | * [Bug reporting](#Bug-reporting) 9 | * [Pull requests](#Pull-requests) 10 | * [Development](#Development) 11 | 12 | ## Introduction 13 | Thank you for showing interest in contributing to this library. This document is intended to be a guideline to make any 14 | contribution as smooth as possible. 15 | 16 | ## Bug reporting 17 | When reporting a bug, please first check if it has been reported already in the list of 18 | [issues](https://github.com/ramonhagenaars/nptyping/issues). Also check the 19 | [closed ones](https://github.com/ramonhagenaars/nptyping/issues?q=is%3Aissue+is%3Aclosed). 20 | 21 | If your bug was not specified earlier, please [open a new issue](https://github.com/ramonhagenaars/nptyping/issues/new). 22 | When describing your bug, try to be as clear as possible. At least provide: 23 | 24 | * the Python version you used 25 | * the `nptyping` version you used 26 | * the Operating system you were on 27 | 28 | If applicable and possible, provide a complete stacktrace of the error. 29 | 30 | ## Pull requests 31 | You are free to open pull requests: this is highly appreciated! To avoid any waste of valuable developer time, it is 32 | recommended to first [open a new issue](https://github.com/ramonhagenaars/nptyping/issues/new) describing the 33 | feature/fix that you propose. This is not mandatory though. 34 | 35 | A pull request can be merged when: 36 | * all [checks](https://github.com/ramonhagenaars/nptyping/actions) are green 37 | * the content is deemed an improvement 38 | * the code is deemed acceptable 39 | 40 | ## Development 41 | Prerequisites: 42 | * A Python version within the `nptyping` [supported range](https://github.com/ramonhagenaars/nptyping/blob/master/nptyping/package_info.py) 43 | * An IDE to your liking 44 | 45 | ### Step 1: clone this repository 46 | Clone this repo in a space on your machine that you have sufficient rights on. For more info on cloning, please refer to 47 | the [Github Docs](https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls). 48 | 49 | ### Step 2: install invoke 50 | The build tool `invoke` is used in this repository. It is recommended to install it in your global python setup: 51 | ``` 52 | pip install invoke 53 | ``` 54 | 55 | ### Step 3: setup a ready-to-go virtual environment 56 | Make sure you cd to the directory of this repo that contains `tasks.py`. Then you can execute the following: 57 | ``` 58 | invoke venv install 59 | ``` 60 | 61 | When done, you can check all available build options by executing: 62 | ``` 63 | invoke --list 64 | ``` 65 | 66 | #### Optional: different Python versions 67 | Optionally, you can create multiple virtual environments for different Python versions. To do so, make sure you have 68 | `invoke` installed on that Python version, then use that specific Python interpreter to create a virtual environment. 69 | Here is an example of how that command would look like on a Windows machine: 70 | ``` 71 | C:\Users\guidovanrossum\AppData\Local\Programs\Python\Python38\python -m invoke venv 72 | ``` 73 | If you now invoke the tests, it will by default execute them using multiple virtual environments. this lets you check 74 | compatibility with different Python versions. 75 | 76 | ### Step 4: start developing 77 | You are now ready to go. You might want to point your IDEs interpreter to the Python executable in the created virtual 78 | environment. 79 | 80 | While you develop, it is a good idea to run the following tasks every now and then: 81 | ``` 82 | invoke format qa coverage 83 | ``` 84 | 85 | Happy coding! 86 | -------------------------------------------------------------------------------- /HISTORY.md: -------------------------------------------------------------------------------- 1 | # History 2 | 3 | ## 2.5.0 (2023-02-20) 4 | 5 | - Added the column wildcard in structure expressions to allow expressing 'a structure with at least ...'. 6 | - Fixed the `help` text for functions that use `nptyping` types as hints. 7 | - Fixed the distribution of `dataframe.pyi` that was missing. 8 | - Fixed the sdist to include tests and dependencies. 9 | 10 | ## 2.4.1 (2022-11-16) 11 | 12 | - Fixed compatibility with `mypy==0.991`. 13 | 14 | ## 2.4.0 (2022-11-14) 15 | 16 | - Added hint for pandas DataFrame. 17 | - Fixed bug for checking against a Structure where a different number of fields did not fail the check. 18 | - Changed `nptyping.Int` pointing to the more generic `numpy.integer` rather than `numpy.int32`. 19 | - Added support for Python 3.11 with the exception of `pandas.DataFrame`. 20 | 21 | ## 2.3.1 (2022-08-30) 22 | 23 | - Fixed mypy error of inheriting final dtype as of numpy==1.23.1. 24 | - Allowed for quotes in shape expressions to appease PyCharm. 25 | 26 | ## 2.3.0 (2022-08-28) 27 | 28 | - Added support for subarrays with shape expressions inside structure expressions. 29 | - Added support for wildcards in structure expressions. 30 | 31 | ## 2.2.0 (2022-06-26) 32 | 33 | - Added support for expressing "at least N dimensions". 34 | 35 | ## 2.1.3 (2022-06-19) 36 | 37 | - Fixed typing issue with Pyright/Pylance that caused the message: "Literal" is not a class 38 | - Fixed wrong error message when an invalid `Structure` was provided to `NDArray`. 39 | 40 | ## 2.1.2 (2022-06-08) 41 | 42 | - Fixed bug that caused MyPy to fail with the message: Value of type variable "_DType_co" of "ndarray" cannot be "floating[Any]" 43 | 44 | ## 2.1.1 (2022-06-01) 45 | 46 | - Fixed bug that numpy ndarrays were incorrectly instance checked against `RecArray`. 47 | 48 | ## 2.1.0 (2022-06-01) 49 | 50 | - Added `Structure` and "structure expressions" to support structured arrays. 51 | - Added `RecArray`. 52 | 53 | ## 2.0.1 (2022-04-28) 54 | 55 | Thanks to [Jasha10](https://github.com/Jasha10) for this release. 56 | - Added an improved default message for `assert_isinstance`. 57 | 58 | Also some typos in README, in `test_mypy.py` and some style corrections. 59 | 60 | ## 2.0.0 (2022-04-07) 61 | 62 | Changes since `1.4.4`: 63 | - Changed the interface of `NDArray` into `NDArray[SHAPE, DTYPE]` 64 | - Added MyPy-acceptance (limited static type checking) 65 | - Added support for variables 66 | - Added support for labels and named dimensions 67 | - Added support for all numpy dtypes with `NDArray` 68 | - Added support for dynamic type checker: beartype 69 | - Added support for dynamic type checker: typeguard 70 | - Added autocompletion for all attributes of `ndarray` 71 | - Added CONTRIBUTING.md 72 | - Removed support for Python 3.5 and Python 3.6 73 | 74 | ## 2.0.0a2 (2022-03-27) 75 | 76 | - Changed the interface of `NDArray`: switched the order to `NDArray[SHAPE, DTYPE]` to be compatible to `numpy.ndarray.pyi` 77 | - Added autocompletion for all attributes of `ndarray` by changing the implementation of `NDArray` 78 | - Added CONTRIBUTING.md 79 | - Added support for dynamic type checker: beartype 80 | - Added support for dynamic type checker: typeguard 81 | 82 | ## 2.0.0a1 (2022-03-19) 83 | 84 | - Changed the interface of `NDArray` 85 | - Added MyPy-acceptance (limited static type checking) 86 | - Added support for variables 87 | - Added support for labels and named dimensions 88 | - Added support for all numpy dtypes with `NDArray` 89 | - Removed support for Python 3.5 and Python 3.6 90 | 91 | ## 1.4.4 (2021-09-10) 92 | 93 | - Fixed instance checks with 0d arrays. 94 | 95 | ## 1.4.3 (2021-08-05) 96 | 97 | - Fixed setup.py to exclude test(-resources) in the wheel. 98 | 99 | ## 1.4.2 (2021-05-08) 100 | 101 | - Fixed instance check that was incompatible with `typish==1.9.2`. 102 | 103 | ## 1.4.1 (2021-03-23) 104 | 105 | - Fixed instance checks of some types that did not properly respond to non-numpy types. 106 | - Fixed instance checks with ``nptyping.Object``. 107 | - Fixed identities of NPTyping instances: ``NDArray[(3,), int] is NDArray[(3,), int]``. 108 | 109 | ## 1.4.0 (2020-12-23) 110 | 111 | - Added ``SubArrayType`` 112 | - Added ``StructuredType`` 113 | - Added support for unsigned integers with ``py_type``. 114 | 115 | ## 1.3.0 (2020-07-21) 116 | 117 | - Added ``Complex128`` 118 | 119 | ## 1.2.0 (2020-06-20) 120 | 121 | - Added ``Bool`` 122 | - Added ``Datetime64`` 123 | - Added ``Timedelta64`` 124 | 125 | ## 1.1.0 (2020-05-30) 126 | 127 | - Removed ``Array`` 128 | - Added ``get_type`` 129 | - Added ``Int`` 130 | - Added ``UInt`` 131 | - Added ``Float`` 132 | - Added ``Unicode`` 133 | - Added ``Number`` 134 | - Added ``NPType`` 135 | 136 | ## 1.0.1 (2020-04-05) 137 | 138 | - Added a hash function to ``_NDArrayMeta``. 139 | 140 | ## 1.0.0 (2020-03-22) 141 | 142 | - Added ``NDArray`` 143 | - Deprecated ``Array`` 144 | 145 | ## 0.3.0 (2019-09-11) 146 | 147 | - Forbidden instantiation of ``Array`` 148 | - Added support for hinting ndarray methods 149 | 150 | ## 0.2.0 (2019-02-09) 151 | 152 | - Added support for heterogeneous arrays 153 | - Added HISTORY.rst 154 | 155 | ## 0.1.0 (2019-02-05) 156 | 157 | - Initial release 158 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2022, Ramon Hagenaars 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | # See also: 2 | # https://packaging.python.org/guides/using-manifest-in/#how-files-are-included-in-an-sdist 3 | include CONTRIBUTING.md 4 | include HISTORY.md 5 | include USERDOCS.md 6 | include dependencies/* 7 | include dependencies/**/* 8 | include resources/* 9 | include resources/**/* 10 | include tests/*.py 11 | include tests/**/*.py 12 | recursive-exclude *.pyc 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![PyPI version](https://img.shields.io/pypi/pyversions/nptyping.svg)](https://img.shields.io/pypi/pyversions/nptyping.svg) 2 | [![Downloads](https://pepy.tech/badge/nptyping/month)](https://pepy.tech/project/nptyping) 3 | [![PyPI version](https://badge.fury.io/py/nptyping.svg)](https://badge.fury.io/py/nptyping) 4 | [![codecov](https://codecov.io/gh/ramonhagenaars/nptyping/branch/master/graph/badge.svg)](https://codecov.io/gh/ramonhagenaars/nptyping) 5 | [![Code style](https://img.shields.io/badge/code%20style-black-black)](https://img.shields.io/badge/code%20style-black-black) 6 | 7 | 8 |

9 | 10 | 11 | 12 |

13 | 14 | 🧊 *Type hints for `NumPy`*
15 | 🐼 *Type hints for `pandas.DataFrame`*
16 | 💡 *Extensive dynamic type checks for dtypes shapes and structures*
17 | 🚀 *[Jump to the Quickstart](https://github.com/ramonhagenaars/nptyping/blob/master/USERDOCS.md#Quickstart)* 18 | 19 | Example of a hinted `numpy.ndarray`: 20 | 21 | ```python 22 | >>> from nptyping import NDArray, Int, Shape 23 | 24 | >>> arr: NDArray[Shape["2, 2"], Int] 25 | 26 | ``` 27 | 28 | Example of a hinted `pandas.DataFrame`: 29 | 30 | ```python 31 | >>> from nptyping import DataFrame, Structure as S 32 | 33 | >>> df: DataFrame[S["name: Str, x: Float, y: Float"]] 34 | 35 | ``` 36 | 37 | ### Installation 38 | 39 | | Command | Description | 40 | |:---------------------------------|-------------------------------| 41 | | `pip install nptyping` | Install the basics | 42 | | `pip install nptyping[pandas]` | Install with pandas extension | 43 | | `pip install nptyping[complete]` | Install with all extensions | 44 | 45 | ### Instance checking 46 | 47 | Example of instance checking: 48 | ```python 49 | >>> import numpy as np 50 | 51 | >>> isinstance(np.array([[1, 2], [3, 4]]), NDArray[Shape["2, 2"], Int]) 52 | True 53 | 54 | >>> isinstance(np.array([[1., 2.], [3., 4.]]), NDArray[Shape["2, 2"], Int]) 55 | False 56 | 57 | >>> isinstance(np.array([1, 2, 3, 4]), NDArray[Shape["2, 2"], Int]) 58 | False 59 | 60 | ``` 61 | 62 | `nptyping` also provides `assert_isinstance`. In contrast to `assert isinstance(...)`, this won't cause IDEs or MyPy 63 | complaints. Here is an example: 64 | ```python 65 | >>> from nptyping import assert_isinstance 66 | 67 | >>> assert_isinstance(np.array([1]), NDArray[Shape["1"], Int]) 68 | True 69 | 70 | ``` 71 | 72 | ### NumPy Structured arrays 73 | 74 | You can also express structured arrays using `nptyping.Structure`: 75 | ```python 76 | >>> from nptyping import Structure 77 | 78 | >>> Structure["name: Str, age: Int"] 79 | Structure['age: Int, name: Str'] 80 | 81 | ``` 82 | 83 | Here is an example to see it in action: 84 | ```python 85 | >>> from typing import Any 86 | >>> import numpy as np 87 | >>> from nptyping import NDArray, Structure 88 | 89 | >>> arr = np.array([("Peter", 34)], dtype=[("name", "U10"), ("age", "i4")]) 90 | >>> isinstance(arr, NDArray[Any, Structure["name: Str, age: Int"]]) 91 | True 92 | 93 | ``` 94 | 95 | Subarrays can be expressed with a shape expression between square brackets: 96 | ```python 97 | >>> Structure["name: Int[3, 3]"] 98 | Structure['name: Int[3, 3]'] 99 | 100 | ``` 101 | 102 | ### NumPy Record arrays 103 | The recarray is a specialization of a structured array. You can use `RecArray` 104 | to express them. 105 | 106 | ```python 107 | >>> from nptyping import RecArray 108 | 109 | >>> arr = np.array([("Peter", 34)], dtype=[("name", "U10"), ("age", "i4")]) 110 | >>> rec_arr = arr.view(np.recarray) 111 | >>> isinstance(rec_arr, RecArray[Any, Structure["name: Str, age: Int"]]) 112 | True 113 | 114 | ``` 115 | 116 | ### Pandas DataFrames 117 | Pandas DataFrames can be expressed with `Structure` also. To make it more concise, you may want to alias `Structure`. 118 | ```python 119 | >>> from nptyping import DataFrame, Structure as S 120 | 121 | >>> df: DataFrame[S["x: Float, y: Float"]] 122 | 123 | ``` 124 | 125 | ### More examples 126 | 127 | Here is an example of a rich expression that can be done with `nptyping`: 128 | ```python 129 | def plan_route( 130 | locations: NDArray[Shape["[from, to], [x, y]"], Float] 131 | ) -> NDArray[Shape["* stops, [x, y]"], Float]: 132 | ... 133 | 134 | ``` 135 | 136 | More examples can be found in the [documentation](https://github.com/ramonhagenaars/nptyping/blob/master/USERDOCS.md#Examples). 137 | 138 | ## Documentation 139 | 140 | * [User documentation](https://github.com/ramonhagenaars/nptyping/blob/master/USERDOCS.md)
141 | The place to go if you are using this library.

142 | 143 | * [Release notes](https://github.com/ramonhagenaars/nptyping/blob/master/HISTORY.md)
144 | To see what's new, check out the release notes.

145 | 146 | * [Contributing](https://github.com/ramonhagenaars/nptyping/blob/master/CONTRIBUTING.md)
147 | If you're interested in developing along, find the guidelines here.

148 | 149 | * [License](https://github.com/ramonhagenaars/nptyping/blob/master/LICENSE)
150 | If you want to check out how open source this library is. 151 | -------------------------------------------------------------------------------- /USERDOCS.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | # *User documentation* 6 | 7 | * [Introduction](#Introduction) 8 | * [Quickstart](#Quickstart) 9 | * [Usage](#Usage) 10 | * [NDArray](#NDArray) 11 | * [Shape expressions](#Shape-expressions) 12 | * [Syntax](#Syntax-shape-expressions) 13 | * [Validation](#Validation) 14 | * [Normalization](#Normalization) 15 | * [Variables](#Variables) 16 | * [Wildcards](#Shape-Wildcards) 17 | * [N dimensions](#N-dimensions) 18 | * [Dimension breakdowns](#Dimension-breakdowns) 19 | * [Labels](#Labels) 20 | * [DTypes](#DTypes) 21 | * [Structure expressions](#Structure-expressions) 22 | * [Syntax](#Syntax-structure-expressions) 23 | * [Subarrays](#Subarrays) 24 | * [Wildcards](#Structure-Wildcards) 25 | * [RecArray](#RecArray) 26 | * [Pandas DataFrame](#Pandas-DataFrame) 27 | * [Examples](#Examples) 28 | * [Similar projects](#Similar-projects) 29 | * [FAQ](#FAQ) 30 | * [About](#About) 31 | 32 | ## Introduction 33 | 34 | Thank you for showing interest in this library. 35 | 36 | The intended audience of this document, are Pythoneers using `numpy`, that want to make their code more readable and 37 | secure with type hints. 38 | 39 | In this document, all features that `nptyping` has to offer can be found. If you think that something is missing or not 40 | clear enough, please check the [issue section](https://github.com/ramonhagenaars/nptyping/issues) to see if you can find 41 | your answer there. Don't forget to also check the 42 | [closed issues](https://github.com/ramonhagenaars/nptyping/issues?q=is%3Aissue+is%3Aclosed). Otherwise, feel free to 43 | raise your question [in a new issue](https://github.com/ramonhagenaars/nptyping/issues/new). 44 | 45 | You will find a lot of code blocks in this document. If you wonder why they are written the way they are (e.g. with the 46 | `>>>` and the `...`): all code blocks are tested using [doctest](https://docs.python.org/3/library/doctest.html). 47 | 48 | ## Quickstart 49 | Install `nptyping` for the type hints and the recommended `beartype` for dynamic type checks: 50 | ```shell 51 | pip install nptyping[complete], beartype 52 | ``` 53 | 54 | Use the combination of these packages to add type safety and readability: 55 | ```python 56 | # File: myfile.py 57 | 58 | >>> from nptyping import DataFrame, Structure as S 59 | >>> from beartype import beartype 60 | 61 | >>> @beartype # The function signature is now type safe 62 | ... def fun(df: DataFrame[S["a: Int, b: Str"]]) -> DataFrame[S["a: Int, b: Str"]]: 63 | ... return df 64 | 65 | ``` 66 | 67 | On your production environments, run Python in optimized mode. This disables the type checks done by beartype and any 68 | overhead it may cause: 69 | ```shell 70 | python -OO myfile.py 71 | ``` 72 | You're now good to go. You can sleep tight knowing that today you made your codebase safer and more transparent. 73 | 74 | ## Usage 75 | 76 | ### NDArray 77 | The `NDArray` is the main character of this library and can be used to describe `numpy.ndarray`. 78 | 79 | ```python 80 | >>> from nptyping import NDArray 81 | 82 | ``` 83 | The `NDArray` can take 2 arguments between brackets: the dtype and the shape of the array that is being described. This 84 | takes the form `NDArray[Shape[], ]`. For example: 85 | 86 | ```python 87 | >>> from nptyping import UInt16, Shape 88 | >>> NDArray[Shape["5, 3"], UInt16] 89 | NDArray[Shape['5, 3'], UShort] 90 | 91 | ``` 92 | You can use `typing.Any` to denote any dtype or any shape: 93 | ```python 94 | >>> from typing import Any 95 | >>> NDArray[Any, Any] 96 | NDArray[Any, Any] 97 | 98 | ``` 99 | 100 | ### Shape expressions 101 | You can denote the shape of an array using what we call a **shape expression**. This expression - a string - can be put 102 | into `Shape` and can then be used in an `NDArray`. 103 | ```python 104 | >>> from nptyping import Shape 105 | 106 | ``` 107 | An example of a shape expression in an `NDArray`: 108 | ```python 109 | >>> from typing import Any 110 | 111 | >>> NDArray[Shape["3, 4"], Any] 112 | NDArray[Shape['3, 4'], Any] 113 | 114 | ``` 115 | The above example shows an expression of a shape consisting of 2 dimensions of respectively size 3 and size 4. a fitting 116 | array would be: `np.array([[11, 12, 13, 14], [21, 22, 23, 24], [31, 32, 33, 34]])`. 117 | 118 | `Shape` is actually just a rich alias for `typing.Literal`: 119 | ```python 120 | >>> from typing import Literal 121 | 122 | >>> Shape["2, 2"] == Literal['2, 2'] 123 | True 124 | 125 | ``` 126 | This also means that you can use `typing.Literal` instead of `Shape` if you want. 127 | 128 | #### Syntax shape expressions 129 | 130 | A shape expression is just a comma separated list of dimensions. A dimension can be denoted by its size, like is done in 131 | the former examples. But you can also use variables, labels, wildcards and dimension breakdowns: 132 | ```python 133 | >>> Shape["3, 3 withLabel, *, Var, [entry1, entry2, entry3]"] 134 | Shape['3, 3 withLabel, *, Var, [entry1, entry2, entry3]'] 135 | 136 | ``` 137 | The shape expression above denotes a shape of size 3, 3, any, any, 3. For more details on the concepts of variables, 138 | labels, wildcards and dimension breakdowns, they are described in the following sections. 139 | 140 | The syntax of a shape expression can be formalized in BNF. Extra whitespacing is allowed (e.g. around commas), but this 141 | is not included in the schema below (to avoid extra complexity). 142 | ``` 143 | shape-expression = |"," 144 | dimensions = |"," 145 | dimension = | 146 | labeled-dimension = " "