Name | range-typed-integers JSON |
Version |
1.0.1
JSON |
| download |
home_page | |
Summary | Integer type aliases that specify valid value ranges. |
upload_time | 2022-05-27 11:48:24 |
maintainer | |
docs_url | None |
author | |
requires_python | >=3.8 |
license | MIT |
keywords |
|
VCS |
|
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
Range-Typed Integers
====================
This package provides integer types that have a specific range of valid values.
.. _mypy: https://mypy.readthedocs.io/
Usage
-----
The package provides some types (as `NewType`_) that represent their respective `Rust integer type`_:
``u8``, ``u16``, ``u32``, ``u64``, ``i8``, ``i16``, ``i32`` and ``i64``::
from range_typed_integers import u8, i8
# u8 is an unsigned 8-bit integer so its range is 0-255:
a: u8 = 12 # valid
a: u8 = -12 # invalid - The type checker should mark this as an error.
a: u8 = 900 # invalid - The type checker should mark this as an error.
The types are defined as ``NewTypes`` of ``ValueRange`` annotated integers. This is also how
you can define your own custom ranged integer types. As an example this is literally how
``range_typed_integers.i8`` is defined::
from typing import Annotated, NewType
from range_typed_integers import ValueRange
i8 = NewType('i8', Annotated[int, ValueRange(-128, 127)])
To cast values to typed integers, you can:
- use the NewType's constructor: ``i8(12)``
- Use the "checked constructors": ``i8_checked(12)``.
These will raise a ``IntegerBoundError`` if the value is out of range (subclass of ``OverflowError``).
- use the `cast`_ function: ``cast(i8, 12)``
.. _Rust integer type: https://doc.rust-lang.org/book/ch03-02-data-types.html#integer-types
.. _NewType: https://docs.python.org/3/library/typing.html#newtype
.. _cast: https://docs.python.org/3/library/typing.html#typing.cast
Runtime checking
----------------
You can use the function ``check_int`` to check if an integer fits into any integer type.::
>>> from range_typed_integers import check_int, u8
>>>
>>> class A
... field: u8
...
>>> # You can use this directly with a type.
>>> check_int(u8, 0)
True
>>> check_int(u8, -1)
False
>>> # Or have the function look up the type annotations for an attribute on an object.
>>> check_int((A, 'field'), 0)
True
>>> check_int((A, 'field'), 256)
False
>>> # You can also use this with non-ranged integers (will always return True).
>>> check_int(int, 1234567)
True
>>> # Or even arbitrary types (will always return True and do no type validation).
>>> check_int(str, 1234)
True
For ease-of-use the types shipped with this package, also have "checked constructors" (eg. ``u8_checked``),
that will cast a value to their type and raise an ``IntegerBoundError`` if the value is out of range.
MyPy and Python Support
-----------------------
This is only truly supported in Python 3.9+, due to the lack of the ``Annotated`` type in earlier versions.
However 3.8 is also supported via ``typing_extensions``. Note however, that MyPy with Python 3.8 will not accept
``Annotated`` as a type to use with ``NewType``.
Raw data
{
"_id": null,
"home_page": "",
"name": "range-typed-integers",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": "",
"keywords": "",
"author": "",
"author_email": "Marco 'Capypara' K\u00f6pcke <hello@capypara.de>",
"download_url": "",
"platform": null,
"description": "Range-Typed Integers\n====================\n\nThis package provides integer types that have a specific range of valid values.\n\n.. _mypy: https://mypy.readthedocs.io/\n\nUsage\n-----\nThe package provides some types (as `NewType`_) that represent their respective `Rust integer type`_:\n``u8``, ``u16``, ``u32``, ``u64``, ``i8``, ``i16``, ``i32`` and ``i64``::\n\n from range_typed_integers import u8, i8\n\n # u8 is an unsigned 8-bit integer so its range is 0-255:\n a: u8 = 12 # valid\n a: u8 = -12 # invalid - The type checker should mark this as an error.\n a: u8 = 900 # invalid - The type checker should mark this as an error.\n\nThe types are defined as ``NewTypes`` of ``ValueRange`` annotated integers. This is also how\nyou can define your own custom ranged integer types. As an example this is literally how\n``range_typed_integers.i8`` is defined::\n\n from typing import Annotated, NewType\n from range_typed_integers import ValueRange\n\n i8 = NewType('i8', Annotated[int, ValueRange(-128, 127)])\n\nTo cast values to typed integers, you can:\n\n- use the NewType's constructor: ``i8(12)``\n- Use the \"checked constructors\": ``i8_checked(12)``.\n These will raise a ``IntegerBoundError`` if the value is out of range (subclass of ``OverflowError``).\n- use the `cast`_ function: ``cast(i8, 12)``\n\n.. _Rust integer type: https://doc.rust-lang.org/book/ch03-02-data-types.html#integer-types\n.. _NewType: https://docs.python.org/3/library/typing.html#newtype\n.. _cast: https://docs.python.org/3/library/typing.html#typing.cast\n\nRuntime checking\n----------------\nYou can use the function ``check_int`` to check if an integer fits into any integer type.::\n\n >>> from range_typed_integers import check_int, u8\n >>>\n >>> class A\n ... field: u8\n ...\n >>> # You can use this directly with a type.\n >>> check_int(u8, 0)\n True\n >>> check_int(u8, -1)\n False\n >>> # Or have the function look up the type annotations for an attribute on an object.\n >>> check_int((A, 'field'), 0)\n True\n >>> check_int((A, 'field'), 256)\n False\n >>> # You can also use this with non-ranged integers (will always return True).\n >>> check_int(int, 1234567)\n True\n >>> # Or even arbitrary types (will always return True and do no type validation).\n >>> check_int(str, 1234)\n True\n\nFor ease-of-use the types shipped with this package, also have \"checked constructors\" (eg. ``u8_checked``),\nthat will cast a value to their type and raise an ``IntegerBoundError`` if the value is out of range.\n\nMyPy and Python Support\n-----------------------\nThis is only truly supported in Python 3.9+, due to the lack of the ``Annotated`` type in earlier versions.\n\nHowever 3.8 is also supported via ``typing_extensions``. Note however, that MyPy with Python 3.8 will not accept\n``Annotated`` as a type to use with ``NewType``.\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Integer type aliases that specify valid value ranges.",
"version": "1.0.1",
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"md5": "ff8901e86953d35fa680991fc7501b65",
"sha256": "35d39a41642503c5c5117e26798713f081b1beece1b2afd8f1ba70c8d90f63c5"
},
"downloads": -1,
"filename": "range_typed_integers-1.0.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "ff8901e86953d35fa680991fc7501b65",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 17851,
"upload_time": "2022-05-27T11:48:24",
"upload_time_iso_8601": "2022-05-27T11:48:24.199212Z",
"url": "https://files.pythonhosted.org/packages/2e/49/565350c6fab3f5a3e2c46633290117060e70e2501544cdf3bde1d1d5d0fe/range_typed_integers-1.0.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2022-05-27 11:48:24",
"github": false,
"gitlab": false,
"bitbucket": false,
"lcname": "range-typed-integers"
}