Skip to content

Commit

Permalink
beartype.door API tests x 6.
Browse files Browse the repository at this point in the history
This commit is the next in a commit chain repairing currently failing
tests pertaining to the `beartype.door` subpackage, recently implemented
by Harvard microscopist and general genius @tlambert03 in PR #136.
Specifically, this commit:

* Resolves all pending `pyright` complaints concerning the
  `beartype.door` subpackage. Thankfully, `pyright` now *finally* passes
  across all supported Python versions.
* Extricates the `HINT_SIGNS_ORIGIN_ISINSTANCEABLE_ARGS_*` family of
  sign sets into the more suitable
  `beartype._data.hint.pep.sign.datapepsignset` submodule.
* Extricates the unit test exercising those sets into a more suitable
  new
  `beartype_test.a00_util.a00_data.hint.pep.sign.test_datapepsignset`
  test submodule.

(*Suitable suit table!*)
  • Loading branch information
leycec committed Jul 13, 2022
1 parent 2a9bf72 commit 30080c2
Show file tree
Hide file tree
Showing 12 changed files with 437 additions and 278 deletions.
312 changes: 191 additions & 121 deletions beartype/_data/hint/pep/sign/datapepsignset.py
Expand Up @@ -4,11 +4,10 @@
# See "LICENSE" for further details.

'''
Project-wide **PEP-compliant type hint sign sets** (i.e., frozen set globals
aggregating instances of the
:class:`beartype._data.hint.pep.sign.datapepsigncls.HintSign` class,
enabling efficient categorization of signs as belonging to various categories
of PEP-compliant type hints).
Project-wide **type hint sign sets** (i.e., frozen set globals aggregating
instances of the :class:`beartype._data.hint.pep.sign.datapepsigncls.HintSign`
class, enabling efficient categorization of signs as belonging to various
categories of type hints).
This private submodule is *not* intended for importation by downstream callers.
'''
Expand Down Expand Up @@ -151,69 +150,74 @@
:func:`beartype.beartype` decorator).
'''

# ....................{ SIGNS ~ return }....................
HINT_SIGNS_RETURN_GENERATOR_ASYNC = frozenset((
# ....................{ SETS ~ kind }....................
HINT_SIGNS_SEQUENCE_ARGS_1 = frozenset((
# ..................{ PEP (484|585) }..................
HintSignAsyncGenerator,
HintSignAsyncIterable,
HintSignAsyncIterator,
HintSignByteString,
HintSignList,
HintSignMutableSequence,
HintSignSequence,
))
'''
Frozen set of all signs uniquely identifying **PEP-compliant asynchronous
generator return type hints** (i.e., hints permissible as the return
annotations of asynchronous generators).
Frozen set of all **standard sequence signs** (i.e., arbitrary objects uniquely
identifying PEP-compliant type hints accepting exactly one subscripted type
hint argument constraining *all* items of compliant sequences, which
necessarily satisfy the :class:`collections.abc.Sequence` protocol with
guaranteed ``O(1)`` indexation across all sequence items).
See Also
----------
:data:`HINT_SIGNS_RETURN_GENERATOR_SYNC`
Further discussion.
'''
This set intentionally excludes the:
* :attr:`typing.AnyStr` sign, which accepts only the :class:`str` and
:class:`bytes` types as its sole subscripted argument, which does *not*
unconditionally constrain *all* items (i.e., unencoded and encoded characters
respectively) of compliant sequences but instead parametrizes this attribute.
* :attr:`typing.ByteString` sign, which accepts *no* subscripted arguments.
:attr:`typing.ByteString` is simply an alias for the
:class:`collections.abc.ByteString` abstract base class (ABC) and thus
already handled by our fallback logic for supported PEP-compliant type hints.
* :attr:`typing.Deque` sign, whose compliant objects (i.e.,
:class:`collections.deque` instances) only `guarantee O(n) indexation across
all sequence items <collections.deque_>`__:
HINT_SIGNS_RETURN_GENERATOR_SYNC = frozenset((
# ..................{ PEP (484|585) }..................
HintSignGenerator,
HintSignIterable,
HintSignIterator,
))
'''
Frozen set of all signs uniquely identifying **PEP-compliant synchronous
generator return type hints** (i.e., hints permissible as the return
annotations of synchronous generators).
Indexed access is ``O(1)`` at both ends but slows to ``O(n)`` in the
middle. For fast random access, use lists instead.
Generator callables are simply syntactic sugar for non-generator callables
returning generator objects. For this reason, generator callables *must* be
annotated as returning a type compatible with generator objects -- including:
* :attr:`typing.NamedTuple` sign, which embeds a variadic number of
PEP-compliant field type hints and thus requires special-cased handling.
* :attr:`typing.Text` sign, which accepts *no* subscripted arguments.
:attr:`typing.Text` is simply an alias for the builtin :class:`str` type and
thus handled elsewhere as a PEP-noncompliant type hint.
* :attr:`typing.Tuple` sign, which accepts a variadic number of subscripted
arguments and thus requires special-cased handling.
* :data:`HintSignGenerator`, the narrowest abstract base class (ABC) to which
all generator objects necessarily conform.
* :data:`HintSignIterator`, the immediate superclass of
:data:`HintSignGenerator`.
* :data:`HintSignIterable`, the immediate superclass of
:data:`HintSignIterator`.
.. _collections.deque:
https://docs.python.org/3/library/collections.html#collections.deque
'''

Technically, :pep:`484` states that generator callables may only be annotated
as only returning a subscription of the :attr:`typing.Generator` factory:

The return type of generator functions can be annotated by the generic type
``Generator[yield_type, send_type, return_type]`` provided by ``typing.py``
module:
Pragmatically, official documentation for the :mod:`typing` module seemingly
*never* standardized by an existing PEP additionally states that generator
callables may be annotated as also returning a subscription of either the
:attr:`typing.Iterable` or :attr:`typing.Iterator` factories:
HINT_SIGNS_UNION = frozenset((
# ..................{ PEP 484 }..................
HintSignOptional,
HintSignUnion,
))
'''
Frozen set of all **union signs** (i.e., arbitrary objects uniquely identifying
:pep:`484`-compliant type hints unifying one or more subscripted type hint
arguments into a disjunctive set union of these arguments).
Alternatively, annotate your generator as having a return type of either
``Iterable[YieldType]`` or ``Iterator[YieldType]``:
If the active Python interpreter targets:
See Also
----------
https://github.com/beartype/beartype/issues/65#issuecomment-954468111
Further discussion.
* Python >= 3.9, the :attr:`typing.Optional` and :attr:`typing.Union`
attributes are distinct.
* Python < 3.9, the :attr:`typing.Optional` attribute reduces to the
:attr:`typing.Union` attribute, in which case this set is technically
semantically redundant. Since tests of both object identity and set
membership are ``O(1)``, this set incurs no significant performance penalty
versus direct usage of the :attr:`typing.Union` attribute and is thus
unconditionally used as is irrespective of Python version.
'''

# ....................{ SIGNS ~ type }....................
# ....................{ SIGNS ~ origin }....................
HINT_SIGNS_ORIGIN_ISINSTANCEABLE = frozenset((
# ..................{ PEP (484|585) }..................
HintSignAbstractSet,
Expand Down Expand Up @@ -271,7 +275,140 @@
:func:`beartype.beartype` decorator.
'''

# ....................{ SIGNS ~ origin : args }....................
HINT_SIGNS_ORIGIN_ISINSTANCEABLE_ARGS_1 = frozenset((
HintSignAbstractSet,
HintSignAsyncContextManager,
HintSignAsyncIterable,
HintSignAsyncIterator,
HintSignAwaitable,
HintSignCollection,
HintSignContainer,
HintSignContextManager,
HintSignCounter,
HintSignDeque,
HintSignFrozenSet,
HintSignIterable,
HintSignIterator,
HintSignKeysView,
HintSignList,
HintSignMatch,
HintSignMappingView,
HintSignMutableSequence,
HintSignMutableSet,
HintSignPattern,
HintSignReversible,
HintSignSequence,
HintSignSet,
HintSignType,
HintSignValuesView,
))
'''
Frozen set of all signs uniquely identifying **single-argument PEP-compliant
type hints** (i.e., type hints subscriptable by only one child type hint)
originating from an **isinstanceable origin type** (i.e., isinstanceable class
such that *all* objects satisfying this hint are instances of this class).
Note that the corresponding types in the typing module will have an ``_nparams``
instance variable with a value equal to 1.
'''


HINT_SIGNS_ORIGIN_ISINSTANCEABLE_ARGS_2 = frozenset((
HintSignAsyncGenerator,
# HintSignCallable, # defined explicitly below
HintSignChainMap,
HintSignDefaultDict,
HintSignDict,
HintSignItemsView,
HintSignMapping,
HintSignMutableMapping,
HintSignOrderedDict,
))
'''
Frozen set of all signs uniquely identifying **two-argument PEP-compliant
type hints** (i.e., type hints subscriptable by exactly two child type hints)
Note that the corresponding types in the typing module will have an ``_nparams``
instance variable with a value equal to 2.
'''


HINT_SIGNS_ORIGIN_ISINSTANCEABLE_ARGS_3 = frozenset((
HintSignCoroutine,
HintSignGenerator,
))
'''
Frozen set of all signs uniquely identifying **three-argument PEP-compliant
type hints** (i.e., type hints subscriptable by exactly three child type hints)
Note that the corresponding types in the typing module will have an ``_nparams``
instance variable with a value equal to 3.
'''

# ....................{ SIGNS ~ return }....................
HINT_SIGNS_RETURN_GENERATOR_ASYNC = frozenset((
# ..................{ PEP (484|585) }..................
HintSignAsyncGenerator,
HintSignAsyncIterable,
HintSignAsyncIterator,
))
'''
Frozen set of all signs uniquely identifying **PEP-compliant asynchronous
generator return type hints** (i.e., hints permissible as the return
annotations of asynchronous generators).
See Also
----------
:data:`HINT_SIGNS_RETURN_GENERATOR_SYNC`
Further discussion.
'''


HINT_SIGNS_RETURN_GENERATOR_SYNC = frozenset((
# ..................{ PEP (484|585) }..................
HintSignGenerator,
HintSignIterable,
HintSignIterator,
))
'''
Frozen set of all signs uniquely identifying **PEP-compliant synchronous
generator return type hints** (i.e., hints permissible as the return
annotations of synchronous generators).
Generator callables are simply syntactic sugar for non-generator callables
returning generator objects. For this reason, generator callables *must* be
annotated as returning a type compatible with generator objects -- including:
* :data:`HintSignGenerator`, the narrowest abstract base class (ABC) to which
all generator objects necessarily conform.
* :data:`HintSignIterator`, the immediate superclass of
:data:`HintSignGenerator`.
* :data:`HintSignIterable`, the immediate superclass of
:data:`HintSignIterator`.
Technically, :pep:`484` states that generator callables may only be annotated
as only returning a subscription of the :attr:`typing.Generator` factory:
The return type of generator functions can be annotated by the generic type
``Generator[yield_type, send_type, return_type]`` provided by ``typing.py``
module:
Pragmatically, official documentation for the :mod:`typing` module seemingly
*never* standardized by an existing PEP additionally states that generator
callables may be annotated as also returning a subscription of either the
:attr:`typing.Iterable` or :attr:`typing.Iterator` factories:
Alternatively, annotate your generator as having a return type of either
``Iterable[YieldType]`` or ``Iterator[YieldType]``:
See Also
----------
https://github.com/beartype/beartype/issues/65#issuecomment-954468111
Further discussion.
'''

# ....................{ SIGNS ~ type }....................
HINT_SIGNS_TYPE_MIMIC = frozenset((
# ..................{ PEP 484 }..................
HintSignNewType,
Expand Down Expand Up @@ -395,70 +532,3 @@
Frozen set of all **supported signs** (i.e., arbitrary objects uniquely
identifying PEP-compliant type hints).
'''

# ....................{ SETS ~ kind }....................
HINT_SIGNS_SEQUENCE_ARGS_1 = frozenset((
# ..................{ PEP (484|585) }..................
HintSignByteString,
HintSignList,
HintSignMutableSequence,
HintSignSequence,
))
'''
Frozen set of all **standard sequence signs** (i.e., arbitrary objects uniquely
identifying PEP-compliant type hints accepting exactly one subscripted type
hint argument constraining *all* items of compliant sequences, which
necessarily satisfy the :class:`collections.abc.Sequence` protocol with
guaranteed ``O(1)`` indexation across all sequence items).
This set intentionally excludes the:
* :attr:`typing.AnyStr` sign, which accepts only the :class:`str` and
:class:`bytes` types as its sole subscripted argument, which does *not*
unconditionally constrain *all* items (i.e., unencoded and encoded characters
respectively) of compliant sequences but instead parametrizes this attribute.
* :attr:`typing.ByteString` sign, which accepts *no* subscripted arguments.
:attr:`typing.ByteString` is simply an alias for the
:class:`collections.abc.ByteString` abstract base class (ABC) and thus
already handled by our fallback logic for supported PEP-compliant type hints.
* :attr:`typing.Deque` sign, whose compliant objects (i.e.,
:class:`collections.deque` instances) only `guarantee O(n) indexation across
all sequence items <collections.deque_>`__:
Indexed access is ``O(1)`` at both ends but slows to ``O(n)`` in the
middle. For fast random access, use lists instead.
* :attr:`typing.NamedTuple` sign, which embeds a variadic number of
PEP-compliant field type hints and thus requires special-cased handling.
* :attr:`typing.Text` sign, which accepts *no* subscripted arguments.
:attr:`typing.Text` is simply an alias for the builtin :class:`str` type and
thus handled elsewhere as a PEP-noncompliant type hint.
* :attr:`typing.Tuple` sign, which accepts a variadic number of subscripted
arguments and thus requires special-cased handling.
.. _collections.deque:
https://docs.python.org/3/library/collections.html#collections.deque
'''


HINT_SIGNS_UNION = frozenset((
# ..................{ PEP 484 }..................
HintSignOptional,
HintSignUnion,
))
'''
Frozen set of all **union signs** (i.e., arbitrary objects uniquely identifying
:pep:`484`-compliant type hints unifying one or more subscripted type hint
arguments into a disjunctive set union of these arguments).
If the active Python interpreter targets:
* Python >= 3.9, the :attr:`typing.Optional` and :attr:`typing.Union`
attributes are distinct.
* Python < 3.9, the :attr:`typing.Optional` attribute reduces to the
:attr:`typing.Union` attribute, in which case this set is technically
semantically redundant. Since tests of both object identity and set
membership are ``O(1)``, this set incurs no significant performance penalty
versus direct usage of the :attr:`typing.Union` attribute and is thus
unconditionally used as is irrespective of Python version.
'''

0 comments on commit 30080c2

Please sign in to comment.