|
| 1 | +.. image:: https://travis-ci.org/agronholm/typeguard.svg?branch=master |
| 2 | + :target: https://travis-ci.org/agronholm/typeguard |
| 3 | + :alt: Build Status |
| 4 | +.. image:: https://coveralls.io/repos/agronholm/typeguard/badge.svg?branch=master&service=github |
| 5 | + :target: https://coveralls.io/github/agronholm/typeguard?branch=master |
| 6 | + :alt: Code Coverage |
| 7 | + |
| 8 | +This library provides run-time type checking for functions defined with argument type annotations. |
| 9 | + |
| 10 | +The ``typing`` module introduced in Python 3.5 (and available on PyPI for older versions of |
| 11 | +Python 3) is supported. See below for details. |
| 12 | + |
| 13 | +There are three principal ways to use type checking, each with its pros and cons: |
| 14 | + |
| 15 | +#. calling ``check_argument_types()`` from within the function body: |
| 16 | + |
| 17 | + * debugger friendly (except when running with the pydev debugger with the C extension installed) |
| 18 | + * cannot check the type of the return value |
| 19 | + * does not work reliably with dynamically defined type hints (e.g. in nested functions) |
| 20 | +#. decorating the function with ``@typechecked``: |
| 21 | + |
| 22 | + * 100% reliable at finding the function object to be checked (does not need to check the garbage |
| 23 | + collector) |
| 24 | + * can check the type of the return value |
| 25 | + * adds an extra frame to the call stack for every call to a decorated function |
| 26 | +#. using ``with TypeChecker('packagename'):``: |
| 27 | + |
| 28 | + * emits warnings instead of raising ``TypeError`` |
| 29 | + * eliminates boilerplate |
| 30 | + * multiple TypeCheckers can be stacked/nested |
| 31 | + * noninvasive (only records type violations; does not raise exceptions) |
| 32 | + * does not work reliably with dynamically defined type hints (e.g. in nested functions) |
| 33 | + * may cause problems with badly behaving debuggers or profilers |
| 34 | + |
| 35 | +If a function is called with incompatible argument types or a ``@typechecked`` decorated function |
| 36 | +returns a value incompatible with the declared type, a descriptive ``TypeError`` exception is |
| 37 | +raised. |
| 38 | + |
| 39 | +Type checks can be fairly expensive so it is recommended to run Python in "optimized" mode |
| 40 | +(``python -O`` or setting the ``PYTHONOPTIMIZE`` environment variable) when running code containing |
| 41 | +type checks in production. The optimized mode will disable the type checks, by virtue of removing |
| 42 | +all ``assert`` statements and setting the ``__debug__`` constant to ``False``. |
| 43 | + |
| 44 | +Using ``check_argument_types()``: |
| 45 | + |
| 46 | +.. code-block:: python3 |
| 47 | +
|
| 48 | + from typeguard import check_argument_types |
| 49 | +
|
| 50 | + def some_function(a: int, b: float, c: str, *args: str): |
| 51 | + assert check_argument_types() |
| 52 | + ... |
| 53 | +
|
| 54 | +Using ``@typechecked``: |
| 55 | + |
| 56 | +.. code-block:: python3 |
| 57 | +
|
| 58 | + from typeguard import typechecked |
| 59 | +
|
| 60 | + @typechecked |
| 61 | + def some_function(a: int, b: float, c: str, *args: str) -> bool: |
| 62 | + ... |
| 63 | +
|
| 64 | +To enable type checks even in optimized mode: |
| 65 | + |
| 66 | +.. code-block:: python3 |
| 67 | +
|
| 68 | + @typechecked(always=True) |
| 69 | + def foo(a: str, b: int, c: Union[str, int]) -> bool: |
| 70 | + ... |
| 71 | +
|
| 72 | +Using ``TypeChecker``: |
| 73 | + |
| 74 | +.. code-block:: python3 |
| 75 | +
|
| 76 | + from warnings import filterwarnings |
| 77 | +
|
| 78 | + from typeguard import TypeChecker, TypeWarning |
| 79 | +
|
| 80 | + # Display all TypeWarnings, not just the first one |
| 81 | + filterwarnings('always', category=TypeWarning) |
| 82 | +
|
| 83 | + # Run your entire application inside this context block |
| 84 | + with TypeChecker(['mypackage', 'otherpackage']): |
| 85 | + mypackage.run_app() |
| 86 | +
|
| 87 | + # Alternatively, manually start (and stop) the checker: |
| 88 | + checker = TypeChecker('mypackage') |
| 89 | + checker.start() |
| 90 | + mypackage.start_app() |
| 91 | +
|
| 92 | +.. hint:: Some other things you can do with ``TypeChecker``: |
| 93 | + |
| 94 | + * display all warnings from the start with ``python -W always::typeguard.TypeWarning`` |
| 95 | + * redirect them to logging using ``logging.captureWarnings()`` |
| 96 | + * record warnings in your pytest test suite and fail test(s) if you get any |
| 97 | + (see the `pytest documentation <http://doc.pytest.org/en/latest/recwarn.html>`_ about that) |
| 98 | + |
| 99 | +To directly check a value against the specified type: |
| 100 | + |
| 101 | +.. code-block:: python3 |
| 102 | +
|
| 103 | + from typeguard import check_type |
| 104 | +
|
| 105 | + check_type('variablename', [1234], List[int]) |
| 106 | +
|
| 107 | +
|
| 108 | +The following types from the ``typing`` package have specialized support: |
| 109 | + |
| 110 | +============== ============================================================ |
| 111 | +Type Notes |
| 112 | +============== ============================================================ |
| 113 | +``Callable`` Argument count is checked but types are not (yet) |
| 114 | +``Dict`` Keys and values are typechecked |
| 115 | +``List`` Contents are typechecked |
| 116 | +``NamedTuple`` Field values are typechecked |
| 117 | +``Set`` Contents are typechecked |
| 118 | +``Tuple`` Contents are typechecked |
| 119 | +``Type`` |
| 120 | +``TypeVar`` Constraints, bound types and co/contravariance are supported |
| 121 | + but custom generic types are not (due to type erasure) |
| 122 | +``Union`` |
| 123 | +============== ============================================================ |
| 124 | + |
| 125 | + |
| 126 | +Project links |
| 127 | +------------- |
| 128 | + |
| 129 | +* `Change log <https://github.com/agronholm/typeguard/blob/master/CHANGELOG.rst>`_ |
| 130 | +* `Source repository <https://github.com/agronholm/typeguard>`_ |
| 131 | +* `Issue tracker <https://github.com/agronholm/typeguard/issues>`_ |
0 commit comments