Name | numtypes JSON |
Version |
0.3.0
JSON |
| download |
home_page | None |
Summary | A small library providing utilities for better type hinting of NumPy arrays. |
upload_time | 2025-08-02 12:16:08 |
maintainer | None |
docs_url | None |
author | None |
requires_python | >=3.13 |
license | MIT |
keywords |
arrays
numpy
shape
type-hints
typing
|
VCS |
|
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
# NumTypes
[](https://www.python.org/downloads/)
[](https://numpy.org/)
[](https://github.com/microsoft/pyright)
[](https://gitlab.com/zurabm/numtypes/-/blob/master/LICENSE)
Type hints for NumPy arrays without the hassle! 🎉
## 🎯 Motivation
If you've ever tried to add type hints to code using NumPy, you've probably noticed that the built-in type annotations for arrays are not very useful:
```python
import numpy as np
def translate_box(corners: np.ndarray) -> np.ndarray:
# What are the dimensions? What's the data type? 🤷
return corners + ?
```
The NumPy typing module provides an alias `NDArray`, but it doesn't support shape information. Only data types can be specified, like this:
```python
...
from numpy.typing import NDArray
def translate_box(corners: NDArray[np.float32]) -> NDArray[np.float32]:
# But that's not very helpful, is it? We still don't know how the corners are represented.
return corners + ?
```
You can be more specific if you use `ndarray` directly, but now it becomes very verbose:
```python
...
def translate_box(corners: np.ndarray[tuple[int, int], np.dtype[np.float32]]) -> np.ndarray[tuple[int, int], np.dtype[np.float32]]:
# Still, you don't know if a row represents a point, or if the columns represent points. Is it 2D or 3D?
return corners + ?
```
If you want to specify the exact shape, then it's even worse:
```python
...
from typing import Literal
def translate_box(
corners: np.ndarray[tuple[Literal[8], Literal[3]], np.dtype[np.float32]]
) -> np.ndarray[tuple[Literal[8], Literal[3]], np.dtype[np.float32]]:
translation = np.array([1.0, -1.0, 0.0], dtype=corners.dtype)
return corners + translation[np.newaxis, :] # NumPy would also lose the type information here
```
**NumTypes** alleviates this issue by providing more concise syntax that:
- documents the array shapes and data types at the desired specificity,
- tells your type checker what to expect, and
- helps it out whenever it gets confused by NumPy.
This library doesn't do any magic, it just provides sensible type aliases and leverages existing typing features (like type guards) in Python to give you better type hints. In fact, it's such a thin wrapper around NumPy's existing types that you could implement it yourself! But doing it every time for every project is tedious, so this library does it for you.
## ✨ Features
- **Precise shape typing** - Specify exact dimensions or use wildcards for flexibility
- **dtype support** - Full support for NumPy data types
- **Runtime shape validation** - Verify array shapes at runtime with `shape_of()`, while helping your type checker in the process
- **Convenient & concise aliases** - `Vector`, `Matrix`, `IntArray`, `BoolArray`, and more
- **Pyright compatible** - Tested and working with Pyright/Pylance
- **Minimal overhead** - Runtime validation is optional, lightweight and can easily be disabled
## 📦 Installation
```bash
pip install numtypes
```
## 🚀 Quick Start
The above use case can be simplified with **NumTypes** like this:
```python
from numtypes import FloatArray, Dims, D
def translate_box(corners: FloatArray[Dims[D[8], D[3]]]) -> FloatArray[Dims[D[8], D[3]]]:
translation = np.array([1.0, -1.0, 0.0], dtype=corners.dtype)
result = corners + translation[np.newaxis, :]
# Simple syntax for validating the shape and helping the type checker.
assert shape_of(result, matches=(8, 3))
return result # The type checker now knows this is a FloatArray with shape (8, 3)
```
Nevertheless, in most cases you will likely use more flexible shapes, like `Dim1`, `Dim2`, etc. This allows you to specify the dimensionality without worrying about the exact size:
```python
from numtypes import UByteArray, Dim1, Dim2
def flatten_image(image: UByteArray[Dim2]) -> UByteArray[Dim1]:
return image.reshape(-1) # This actually works with NumPy alone, since it is able to figure out the type.
```
## 📖 Usage
### Basic Array Types
The most common pattern is using `Dim1`, `Dim2`, `Dim3`, etc. for arrays with a known number of dimensions:
```python
from numtypes import Array, Dim1, Dim2, Dim3
import numpy as np
# Some NumPy functions infer type info properly
zeros_1d: Array[Dim1] = np.zeros((5,))
zeros_2d: Array[Dim2] = np.zeros((5, 5))
tensor: Array[Dim3] = np.ones((10, 20, 30))
# The most helpful part is knowing what arrays represent and how they are shaped.
def some_function(array_1: Array[Dim2], array_2: Array[Dim3], *arrays: Array[Dim1]) -> Array[Dim2]:
...
```
### Specifying Exact Shapes
When you need to be more specific about dimensions:
```python
from numtypes import FloatArray, IntArray, Dims, D, N
# Exact shape specification
corners: FloatArray[Dims[D[8], D[3]]] # 8 corners × 3 coordinates
embeddings: FloatArray[Dims[D[1000], D[384]]] # 1000 embeddings × 384 dimensions
# Using N for flexible dimensions (equivalent to -1)
batch: IntArray[Dims[N, D[224], D[224], D[3]]] # Any batch size × 224×224 RGB images
sequence: Array[Dims[N, D[768]]] # Any sequence length × 768 features
# In the following example, it's immediately clear how the vectors are represented.
def operation_on_3d_vectors(vectors: Array[Dims[N, D[3]]]) -> Array[Dims[N, D[3]]]:
...
```
### Creating Typed Arrays
NumTypes provides helper functions to create arrays with explicit type information:
```python
from numtypes import array, array_1d, array_2d, Float, Double, Int
# Create with exact shape
arr = array([1, 2, 3], shape=(3,)) # Array[Dims[D[3]]]
mat = array([[1, 2], [3, 4]], shape=(2, 2)) # Array[Dims[D[2], D[2]]]
# Convenience functions for common cases
vec = array_1d([1, 2, 3]) # Vector (alias for Array[Dim1])
mat = array_2d([[1, 2], [3, 4]]) # Matrix (alias for Array[Dim2])
# Specify data types
float_arr = array([1.0, 2.0], shape=(2,), dtype=np.float32) # Array[Dims[D[2]], Float]
double_arr = array_1d([1.0, 2.0], dtype=np.float64) # Array[Dim1, Double]
int_arr = array([1, 2], shape=(2,), dtype=np.int32) # Array[Dims[D[2]], Int]
```
### Runtime Shape Validation
Use `shape_of()` to validate shapes at runtime while providing type information to your type checker:
```python
from numtypes import shape_of, Array, UnknownShape, AnyShape
def process_batch(images: Array) -> Array:
# Validate the shape
assert shape_of(images, matches=(32, 224, 224, 3))
# Type checker now knows images has shape (32, 224, 224, 3)
normalized = images / 255.0
# Validate the output shape if needed
assert shape_of(normalized, matches=(32, 224, 224, 3))
return normalized
# Flexible shape validation
assert shape_of(data, matches=(-1, 128)) # Any number of rows, exactly 128 columns
assert shape_of(sequence, matches=(100, -1, -1)) # 100 sequences of any shape
```
### Type Aliases for Common Use Cases
NumTypes provides convenient type aliases for common array types and shapes:
```python
from numtypes import Vector, Matrix, IntArray, BoolArray, FloatArray, IndexArray, Long
# Data type aliases
mask: BoolArray[Dim2] # 2D boolean array
indices: IntArray[Dim1] # 1D integer array
scores: FloatArray[Dims[D[100]]] # Exactly 100 float scores (float32)
labels: Array[Dims[D[1000]], Long] # 1000 int64 labels
# Shape aliases
embedding: Vector[D[384]] # 1D array of 384 elements
rotation: Matrix[D[3], D[3]] # 3×3 matrix
# Special arrays
sorted_indices: IndexArray[UnknownShape] = np.argsort(scores) # From argsort
```
You can still use any NumPy data type directly, but these aliases help with readability in common cases.
### Working with NumPy Operations
> ⚠️ **Important**: Many NumPy operations currently lose type information. For example, adding
> two arrays or computing the mean will result in an array with an unknown shape. In general,
> you don't always need to know the exact shape of an array after every operation. As such,
> it makes the most sense to use `shape_of()` to validate the shape of the result only when you need it,
> e.g. when passing an array as an argument to a function, or when returning it from a function.
Here's how to handle common cases:
```python
# These provide type info correctly.
zeros: Array[Dim2] = np.zeros((5, 5))
ones: Array[Dim3] = np.ones((3, 4, 5))
# Operations that preserve type info
negated: Array[Dim2] = -zeros # Still an Array[Dim2]
# Operations that lose type info - use shape_of to recover it
data: Array[Dim2] = array_2d([[1.0, 2.0], [3.0, 4.0]])
mean_per_row = data.mean(axis=1) # Type checker doesn't know the shape
assert shape_of(mean_per_row, matches=(-1,)) # Now it knows it's 1D
# Alternative: use type annotations with `# type: ignore` statements or type casts.
mean_per_row: Array[Dim1] = data.mean(axis=1) # type: ignore
# For complex operations, validate intermediate results
def matrix_operation(a: Matrix, b: Matrix) -> Vector:
assert shape_of(a, matches=(10, 20))
assert shape_of(b, matches=(20, 30))
result = a @ b # Matrix multiplication
assert shape_of(result, matches=(10, 30))
flattened = result.reshape(-1)
assert shape_of(flattened, matches=(300,))
return flattened
```
### Debugging Shape Mismatches
NumTypes supports configuration for debugging shape validation failures:
```python
from numtypes import config
import ipdb
# Configure a debugger to be called on shape mismatch, e.g. ipdb
config.configure(debugger=ipdb.set_trace)
# Configure logging for shape mismatches
config.configure(logger=lambda msg: print(f"Shape mismatch: {msg}"))
array = ... # Some NumPy array
# Now shape_of will trigger these on failure
assert shape_of(array, matches=(10, 10)) # Will call debugger/logger if shape doesn't match
```
### Removing Runtime Validation
Because the idiomatic usage of `shape_of()` leverages the built in assert statement, you can easily remove runtime validation
by just enabling optimization for your Python interpreter. This is done by running Python with the `-O` flag:
```bash
python -O your_script.py
```
This won't affect the type checking, but will remove whatever overhead the runtime validations introduce.
## ⚙️ Type Checker Compatibility
**Note**: This library is currently only tested with **Pyright** (including Pylance in VS Code).
Compatibility with mypy and other type checkers is not guaranteed.
## Other Limitations
- **Python Compatibility**: This library requires Python 3.13 or later, due to the latest typing features/syntax used.
- **Structured Arrays**: This library does not support structured arrays (i.e. arrays with named fields).
- **Type Coverage**: The convenience aliases probably don't cover every use case. You can always define your own types using the provided `Array`, `Dims`, and `DimX` classes though. If a type feels too common to be missing, please open an issue or PR!
- **Suboptimal Syntax**: The current syntax is not perfect, but it is a trade-off between conciseness and type safety. Even though the ideal
type annotations would look like `Array[8, 3, 2, Float]`, this is currently not possible with the syntax Python currently supports. Although
one could make `Array[8, 3, 2, Float]` work using `__class_getitem__`, it would currently not be understandable for type checkers.
## 🤝 Contributing
TODO: Contributing guide coming soon! For now, feel free to open issues and PRs.
## 📄 License
This project is licensed under the MIT License - see the [LICENSE](https://gitlab.com/zurabm/numtypes/-/blob/master/LICENSE) file for details.
Raw data
{
"_id": null,
"home_page": null,
"name": "numtypes",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.13",
"maintainer_email": null,
"keywords": "arrays, numpy, shape, type-hints, typing",
"author": null,
"author_email": "Zurab Mujirishvili <zurab.mujirishvili@fau.de>",
"download_url": "https://files.pythonhosted.org/packages/58/a0/28a63548f03b48922709f4900b4def78a7bd00171b47e1a5a51cf34e8324/numtypes-0.3.0.tar.gz",
"platform": null,
"description": "# NumTypes\n\n[](https://www.python.org/downloads/)\n[](https://numpy.org/)\n[](https://github.com/microsoft/pyright)\n[](https://gitlab.com/zurabm/numtypes/-/blob/master/LICENSE)\n\nType hints for NumPy arrays without the hassle! \ud83c\udf89\n\n## \ud83c\udfaf Motivation\n\nIf you've ever tried to add type hints to code using NumPy, you've probably noticed that the built-in type annotations for arrays are not very useful:\n\n```python\nimport numpy as np\n\ndef translate_box(corners: np.ndarray) -> np.ndarray:\n # What are the dimensions? What's the data type? \ud83e\udd37\n return corners + ?\n```\n\nThe NumPy typing module provides an alias `NDArray`, but it doesn't support shape information. Only data types can be specified, like this:\n\n```python\n...\nfrom numpy.typing import NDArray\n\ndef translate_box(corners: NDArray[np.float32]) -> NDArray[np.float32]:\n # But that's not very helpful, is it? We still don't know how the corners are represented.\n return corners + ?\n```\n\nYou can be more specific if you use `ndarray` directly, but now it becomes very verbose:\n\n```python\n...\n\ndef translate_box(corners: np.ndarray[tuple[int, int], np.dtype[np.float32]]) -> np.ndarray[tuple[int, int], np.dtype[np.float32]]:\n # Still, you don't know if a row represents a point, or if the columns represent points. Is it 2D or 3D?\n return corners + ?\n```\n\nIf you want to specify the exact shape, then it's even worse:\n\n```python\n...\nfrom typing import Literal\n\ndef translate_box(\n corners: np.ndarray[tuple[Literal[8], Literal[3]], np.dtype[np.float32]]\n) -> np.ndarray[tuple[Literal[8], Literal[3]], np.dtype[np.float32]]:\n translation = np.array([1.0, -1.0, 0.0], dtype=corners.dtype)\n return corners + translation[np.newaxis, :] # NumPy would also lose the type information here\n```\n\n**NumTypes** alleviates this issue by providing more concise syntax that:\n - documents the array shapes and data types at the desired specificity,\n - tells your type checker what to expect, and\n - helps it out whenever it gets confused by NumPy.\n\nThis library doesn't do any magic, it just provides sensible type aliases and leverages existing typing features (like type guards) in Python to give you better type hints. In fact, it's such a thin wrapper around NumPy's existing types that you could implement it yourself! But doing it every time for every project is tedious, so this library does it for you.\n\n## \u2728 Features\n\n- **Precise shape typing** - Specify exact dimensions or use wildcards for flexibility\n- **dtype support** - Full support for NumPy data types\n- **Runtime shape validation** - Verify array shapes at runtime with `shape_of()`, while helping your type checker in the process\n- **Convenient & concise aliases** - `Vector`, `Matrix`, `IntArray`, `BoolArray`, and more\n- **Pyright compatible** - Tested and working with Pyright/Pylance\n- **Minimal overhead** - Runtime validation is optional, lightweight and can easily be disabled\n\n## \ud83d\udce6 Installation\n\n```bash\npip install numtypes\n```\n\n## \ud83d\ude80 Quick Start\n\nThe above use case can be simplified with **NumTypes** like this:\n\n```python\nfrom numtypes import FloatArray, Dims, D\n\ndef translate_box(corners: FloatArray[Dims[D[8], D[3]]]) -> FloatArray[Dims[D[8], D[3]]]:\n translation = np.array([1.0, -1.0, 0.0], dtype=corners.dtype)\n result = corners + translation[np.newaxis, :]\n\n # Simple syntax for validating the shape and helping the type checker.\n assert shape_of(result, matches=(8, 3))\n\n return result # The type checker now knows this is a FloatArray with shape (8, 3)\n```\n\nNevertheless, in most cases you will likely use more flexible shapes, like `Dim1`, `Dim2`, etc. This allows you to specify the dimensionality without worrying about the exact size:\n\n```python\nfrom numtypes import UByteArray, Dim1, Dim2\n\ndef flatten_image(image: UByteArray[Dim2]) -> UByteArray[Dim1]:\n return image.reshape(-1) # This actually works with NumPy alone, since it is able to figure out the type.\n```\n\n## \ud83d\udcd6 Usage\n\n### Basic Array Types\n\nThe most common pattern is using `Dim1`, `Dim2`, `Dim3`, etc. for arrays with a known number of dimensions:\n\n```python\nfrom numtypes import Array, Dim1, Dim2, Dim3\nimport numpy as np\n\n# Some NumPy functions infer type info properly\nzeros_1d: Array[Dim1] = np.zeros((5,))\nzeros_2d: Array[Dim2] = np.zeros((5, 5))\ntensor: Array[Dim3] = np.ones((10, 20, 30))\n\n# The most helpful part is knowing what arrays represent and how they are shaped.\ndef some_function(array_1: Array[Dim2], array_2: Array[Dim3], *arrays: Array[Dim1]) -> Array[Dim2]:\n ...\n```\n\n### Specifying Exact Shapes\n\nWhen you need to be more specific about dimensions:\n\n```python\nfrom numtypes import FloatArray, IntArray, Dims, D, N\n\n# Exact shape specification\ncorners: FloatArray[Dims[D[8], D[3]]] # 8 corners \u00d7 3 coordinates\nembeddings: FloatArray[Dims[D[1000], D[384]]] # 1000 embeddings \u00d7 384 dimensions\n\n# Using N for flexible dimensions (equivalent to -1)\nbatch: IntArray[Dims[N, D[224], D[224], D[3]]] # Any batch size \u00d7 224\u00d7224 RGB images\nsequence: Array[Dims[N, D[768]]] # Any sequence length \u00d7 768 features\n\n# In the following example, it's immediately clear how the vectors are represented.\ndef operation_on_3d_vectors(vectors: Array[Dims[N, D[3]]]) -> Array[Dims[N, D[3]]]:\n ...\n```\n\n### Creating Typed Arrays\n\nNumTypes provides helper functions to create arrays with explicit type information:\n\n```python\nfrom numtypes import array, array_1d, array_2d, Float, Double, Int\n\n# Create with exact shape\narr = array([1, 2, 3], shape=(3,)) # Array[Dims[D[3]]]\nmat = array([[1, 2], [3, 4]], shape=(2, 2)) # Array[Dims[D[2], D[2]]]\n\n# Convenience functions for common cases\nvec = array_1d([1, 2, 3]) # Vector (alias for Array[Dim1])\nmat = array_2d([[1, 2], [3, 4]]) # Matrix (alias for Array[Dim2])\n\n# Specify data types\nfloat_arr = array([1.0, 2.0], shape=(2,), dtype=np.float32) # Array[Dims[D[2]], Float]\ndouble_arr = array_1d([1.0, 2.0], dtype=np.float64) # Array[Dim1, Double]\nint_arr = array([1, 2], shape=(2,), dtype=np.int32) # Array[Dims[D[2]], Int]\n```\n\n### Runtime Shape Validation\n\nUse `shape_of()` to validate shapes at runtime while providing type information to your type checker:\n\n```python\nfrom numtypes import shape_of, Array, UnknownShape, AnyShape\n\ndef process_batch(images: Array) -> Array:\n # Validate the shape\n assert shape_of(images, matches=(32, 224, 224, 3))\n \n # Type checker now knows images has shape (32, 224, 224, 3)\n normalized = images / 255.0\n \n # Validate the output shape if needed\n assert shape_of(normalized, matches=(32, 224, 224, 3))\n return normalized\n\n# Flexible shape validation\nassert shape_of(data, matches=(-1, 128)) # Any number of rows, exactly 128 columns\nassert shape_of(sequence, matches=(100, -1, -1)) # 100 sequences of any shape\n```\n\n### Type Aliases for Common Use Cases\n\nNumTypes provides convenient type aliases for common array types and shapes:\n\n```python\nfrom numtypes import Vector, Matrix, IntArray, BoolArray, FloatArray, IndexArray, Long\n\n# Data type aliases\nmask: BoolArray[Dim2] # 2D boolean array\nindices: IntArray[Dim1] # 1D integer array \nscores: FloatArray[Dims[D[100]]] # Exactly 100 float scores (float32)\nlabels: Array[Dims[D[1000]], Long] # 1000 int64 labels\n\n# Shape aliases\nembedding: Vector[D[384]] # 1D array of 384 elements\nrotation: Matrix[D[3], D[3]] # 3\u00d73 matrix\n\n# Special arrays\nsorted_indices: IndexArray[UnknownShape] = np.argsort(scores) # From argsort\n```\n\nYou can still use any NumPy data type directly, but these aliases help with readability in common cases.\n\n### Working with NumPy Operations\n\n> \u26a0\ufe0f **Important**: Many NumPy operations currently lose type information. For example, adding\n> two arrays or computing the mean will result in an array with an unknown shape. In general,\n> you don't always need to know the exact shape of an array after every operation. As such,\n> it makes the most sense to use `shape_of()` to validate the shape of the result only when you need it,\n> e.g. when passing an array as an argument to a function, or when returning it from a function. \n\nHere's how to handle common cases:\n\n```python\n# These provide type info correctly.\nzeros: Array[Dim2] = np.zeros((5, 5))\nones: Array[Dim3] = np.ones((3, 4, 5))\n\n# Operations that preserve type info\nnegated: Array[Dim2] = -zeros # Still an Array[Dim2]\n\n# Operations that lose type info - use shape_of to recover it\ndata: Array[Dim2] = array_2d([[1.0, 2.0], [3.0, 4.0]])\nmean_per_row = data.mean(axis=1) # Type checker doesn't know the shape\nassert shape_of(mean_per_row, matches=(-1,)) # Now it knows it's 1D\n\n# Alternative: use type annotations with `# type: ignore` statements or type casts.\nmean_per_row: Array[Dim1] = data.mean(axis=1) # type: ignore\n\n# For complex operations, validate intermediate results\ndef matrix_operation(a: Matrix, b: Matrix) -> Vector:\n assert shape_of(a, matches=(10, 20))\n assert shape_of(b, matches=(20, 30))\n \n result = a @ b # Matrix multiplication\n assert shape_of(result, matches=(10, 30))\n \n flattened = result.reshape(-1)\n assert shape_of(flattened, matches=(300,))\n \n return flattened\n```\n\n### Debugging Shape Mismatches\n\nNumTypes supports configuration for debugging shape validation failures:\n\n```python\nfrom numtypes import config\nimport ipdb\n\n# Configure a debugger to be called on shape mismatch, e.g. ipdb\nconfig.configure(debugger=ipdb.set_trace)\n\n# Configure logging for shape mismatches\nconfig.configure(logger=lambda msg: print(f\"Shape mismatch: {msg}\"))\n\narray = ... # Some NumPy array\n\n# Now shape_of will trigger these on failure\nassert shape_of(array, matches=(10, 10)) # Will call debugger/logger if shape doesn't match\n```\n\n### Removing Runtime Validation\n\nBecause the idiomatic usage of `shape_of()` leverages the built in assert statement, you can easily remove runtime validation\nby just enabling optimization for your Python interpreter. This is done by running Python with the `-O` flag:\n\n```bash\npython -O your_script.py\n```\n\nThis won't affect the type checking, but will remove whatever overhead the runtime validations introduce.\n\n## \u2699\ufe0f Type Checker Compatibility\n\n**Note**: This library is currently only tested with **Pyright** (including Pylance in VS Code). \nCompatibility with mypy and other type checkers is not guaranteed.\n\n## Other Limitations\n\n- **Python Compatibility**: This library requires Python 3.13 or later, due to the latest typing features/syntax used.\n- **Structured Arrays**: This library does not support structured arrays (i.e. arrays with named fields).\n- **Type Coverage**: The convenience aliases probably don't cover every use case. You can always define your own types using the provided `Array`, `Dims`, and `DimX` classes though. If a type feels too common to be missing, please open an issue or PR!\n- **Suboptimal Syntax**: The current syntax is not perfect, but it is a trade-off between conciseness and type safety. Even though the ideal\ntype annotations would look like `Array[8, 3, 2, Float]`, this is currently not possible with the syntax Python currently supports. Although\none could make `Array[8, 3, 2, Float]` work using `__class_getitem__`, it would currently not be understandable for type checkers.\n\n## \ud83e\udd1d Contributing\n\nTODO: Contributing guide coming soon! For now, feel free to open issues and PRs.\n\n## \ud83d\udcc4 License\n\nThis project is licensed under the MIT License - see the [LICENSE](https://gitlab.com/zurabm/numtypes/-/blob/master/LICENSE) file for details.\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "A small library providing utilities for better type hinting of NumPy arrays.",
"version": "0.3.0",
"project_urls": {
"Bug Tracker": "https://gitlab.com/zurabm/numtypes/issues",
"Documentation": "https://gitlab.com/zurabm/numtypes/-/blob/master/README.md",
"Homepage": "https://gitlab.com/zurabm/numtypes"
},
"split_keywords": [
"arrays",
" numpy",
" shape",
" type-hints",
" typing"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "3861c7a0b842dfe2e2fffd6a0ea1d4a2f0a9ca2044d00caef10a322f8e7f280e",
"md5": "c876ab12b96b8936264442998801e17a",
"sha256": "fa32138c0273be4fed839b16cbed87a26f06578ceb62f207470fcb1fd38c88b3"
},
"downloads": -1,
"filename": "numtypes-0.3.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "c876ab12b96b8936264442998801e17a",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.13",
"size": 10231,
"upload_time": "2025-08-02T12:16:05",
"upload_time_iso_8601": "2025-08-02T12:16:05.897037Z",
"url": "https://files.pythonhosted.org/packages/38/61/c7a0b842dfe2e2fffd6a0ea1d4a2f0a9ca2044d00caef10a322f8e7f280e/numtypes-0.3.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "58a028a63548f03b48922709f4900b4def78a7bd00171b47e1a5a51cf34e8324",
"md5": "e3d46d62f3adf3e07bd6aa7f15b8c3f3",
"sha256": "dcf86e557ad95b2f243467ba5e56171e0c5f671caf06e95f03e4f1e61486fe13"
},
"downloads": -1,
"filename": "numtypes-0.3.0.tar.gz",
"has_sig": false,
"md5_digest": "e3d46d62f3adf3e07bd6aa7f15b8c3f3",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.13",
"size": 32304359,
"upload_time": "2025-08-02T12:16:08",
"upload_time_iso_8601": "2025-08-02T12:16:08.729179Z",
"url": "https://files.pythonhosted.org/packages/58/a0/28a63548f03b48922709f4900b4def78a7bd00171b47e1a5a51cf34e8324/numtypes-0.3.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-02 12:16:08",
"github": false,
"gitlab": true,
"bitbucket": false,
"codeberg": false,
"gitlab_user": "zurabm",
"gitlab_project": "numtypes",
"lcname": "numtypes"
}