range-typed-integers


Namerange-typed-integers JSON
Version 1.0.1 PyPI version JSON
download
home_page
SummaryInteger type aliases that specify valid value ranges.
upload_time2022-05-27 11:48:24
maintainer
docs_urlNone
author
requires_python>=3.8
licenseMIT
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"
}
        
Elapsed time: 0.06846s