Skip to content

Commit

Permalink
"typing_extensions.Annotated" x 19.
Browse files Browse the repository at this point in the history
This commit is the next in a commit chain adding transparent support
for the third-party `typing_extensions.Annotated` type hint back-ported
to Python < 3.9, en route to resolving #34. Once finalized, this will
enable usage of beartype validators under Python < 3.9 via this hint.
Specifically, this commit continues disastrously breaking literally
everything by continuing to disembowel the feckless
`beartype._util.hint.data.pep.datapep` submodule and its untrustworthy
`beartype._util.hint.data.pep.proposal` crony subpackage in favour of
`beartype._util.hint.data.pep.sign`, which is the only subpackage left
standing. Save us from our reckless selves, GitHub! (*Stubby tubers!*)
  • Loading branch information
leycec committed Jun 29, 2021
1 parent 87e8d47 commit 722b52f
Show file tree
Hide file tree
Showing 15 changed files with 225 additions and 274 deletions.
23 changes: 14 additions & 9 deletions beartype/_decor/_cache/cachehint.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
#Checkmate, "typing". Checkmate.

# ....................{ IMPORTS }....................
from beartype._cave._cavefast import NoneType
from beartype._util.hint.utilhinttest import die_unless_hint
from collections.abc import Callable
from typing import Any, Dict, Union
Expand All @@ -65,13 +66,13 @@
This dictionary caches:
* `PEP 585`_-compliant type hints, which do *not* cache themselves.
* `PEP 563`_-compliant **deferred type hints** (i.e., type hints persisted as
* :pep:`585`-compliant type hints, which do *not* cache themselves.
* :pep:`563`-compliant **deferred type hints** (i.e., type hints persisted as
evaluatable strings rather than actual type hints), enabled if the active
Python interpreter targets either:
* Python 3.7.0 *and* the module declaring this callable explicitly enables
`PEP 563`_ support with a leading dunder importation of the form ``from
:pep:`563` support with a leading dunder importation of the form ``from
__future__ import annotations``.
* Python 4.0.0, where `PEP 563`_ is expected to be mandatory.
Expand All @@ -97,11 +98,6 @@
instead persisted for the lifetime of the active Python process. Ergo,
temporarily caching hints in an LRU cache is pointless, as there are *no*
space savings in dropping stale references to unused hints.
.. _PEP 563:
https://www.python.org/dev/peps/pep-0563
.. _PEP 585:
https://www.python.org/dev/peps/pep-0585
'''

# ....................{ CACHERS }....................
Expand Down Expand Up @@ -171,12 +167,21 @@ def coerce_hint_pep(
* A supported PEP-compliant type hint.
'''

# ..................{ PEP 484 }..................
# If this hint is the PEP 484-compliant "None" singleton, coerce this hint
# into the type of that singleton. This is explicitly required by PEP 484
# *and* implicitly required by Python convention, where the bodies of
# callables annotated as returning "None" are understood to contain *no*
# explicit "return" statements and thus implicitly return "None".
if hint is None:
hint = func.__annotations__[pith_name] = NoneType
# ..................{ NON-PEP }..................
# If this hint is a PEP-noncompliant tuple union, coerce this union into
# the equivalent PEP-compliant union subscripted by the same child hints.
# By definition, PEP-compliant unions are a strict superset of
# PEP-noncompliant tuple unions and thus accept all child hints accepted by
# the latter.
if isinstance(hint, tuple):
elif isinstance(hint, tuple):
assert callable(func), f'{repr(func)} not callable.'
assert isinstance(pith_name, str), f'{pith_name} not string.'

Expand Down
21 changes: 6 additions & 15 deletions beartype/_decor/_code/_pep/_pephint.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,6 @@
)
from beartype._util.data.utildatadict import update_mapping
from beartype._util.data.hint.datahint import HINTS_IGNORABLE_SHALLOW
from beartype._util.data.hint.pep.datapep import (
HINT_SIGNS_SUPPORTED_DEEP as HINT_SIGNS_SUPPORTED_DEEP_BAD,
HINT_SIGNS_TYPE_STDLIB,
)
from beartype._util.data.hint.pep.proposal.datapep484 import (
HINT_PEP484_SIGNS_UNION)
from beartype._util.data.hint.pep.datapepattr import (
HINT_PEP586_ATTR_LITERAL,
HINT_PEP593_ATTR_ANNOTATED,
Expand All @@ -107,6 +101,7 @@
HINT_SIGNS_SEQUENCE_ARGS_1,
HINT_SIGNS_SUPPORTED_DEEP,
HINT_SIGNS_TYPE_STDLIB,
HINT_SIGNS_UNION,
)
from beartype._util.func.utilfuncscope import (
CallableScope,
Expand Down Expand Up @@ -1050,9 +1045,9 @@ def _enqueue_hint_child(pith_child_expr: str) -> str:
# for that attribute *MUST* also be added to the parallel:
# * "beartype._util.hint.pep.errormain" submodule, which
# raises exceptions on the current pith failing this check.
# * "beartype._util.data.hint.pep.datapep.HINT_SIGNS_SUPPORTED_DEEP"
# frozen set of all supported unsubscripted "typing" attributes
# for which this function generates deeply type-checking code.
# * "beartype._util.data.hint.pep.sign.datapepsignset.HINT_SIGNS_SUPPORTED_DEEP"
# frozen set of all signs for which this function generates
# deeply type-checking code.
#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

#FIXME: Python 3.10 provides proper syntactic support for "case"
Expand Down Expand Up @@ -1115,7 +1110,7 @@ def _enqueue_hint_child(pith_child_expr: str) -> str:
# benefit from Python >= 3.8-specific assignment expressions. This
# differs from "typing" pseudo-containers, which narrow the current
# pith expression and thus do benefit from these expressions.
if hint_curr_sign in HINT_PEP484_SIGNS_UNION:
if hint_curr_sign in HINT_SIGNS_UNION:
# Assert this union is subscripted by one or more child hints.
# Note this should *ALWAYS* be the case, as:
#
Expand Down Expand Up @@ -1333,11 +1328,7 @@ def _enqueue_hint_child(pith_child_expr: str) -> str:
#FIXME: Remove this branch *AFTER* deeply supporting all
#hints.
# Currently unsupported with deep type-checking...
(
hint_curr_sign not in HINT_SIGNS_SUPPORTED_DEEP and
#FIXME: Remove this shuddering horror after refactoring!
hint_curr_sign not in HINT_SIGNS_SUPPORTED_DEEP_BAD
)
hint_curr_sign not in HINT_SIGNS_SUPPORTED_DEEP
)
):
# Then generate trivial code shallowly type-checking the current
Expand Down
4 changes: 1 addition & 3 deletions beartype/_decor/_error/errormain.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,6 @@
get_cause_or_none_literal)
from beartype._decor._error._proposal._errorpep593 import (
get_cause_or_none_annotated)
from beartype._util.data.hint.pep.datapep import (
HINT_SIGNS_TYPE_STDLIB,
)
from beartype._util.data.hint.pep.proposal.datapep484 import (
HINT_PEP484_SIGNS_UNION)
from beartype._util.data.hint.pep.sign.datapepsigns import (
Expand All @@ -103,6 +100,7 @@
)
from beartype._util.data.hint.pep.sign.datapepsignset import (
HINT_SIGNS_SEQUENCE_ARGS_1,
HINT_SIGNS_TYPE_STDLIB,
)
from beartype._util.hint.utilhinttest import die_unless_hint
from beartype._util.py.utilpyversion import IS_PYTHON_AT_LEAST_3_9
Expand Down
26 changes: 0 additions & 26 deletions beartype/_util/data/hint/datahint.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
'''

# ....................{ IMPORTS }....................
from beartype._util.data.hint.pep.datapep import HINT_PEP_ATTRS_IGNORABLE
from beartype._util.data.hint.pep.proposal.datapep484 import (
HINT_PEP484_TYPE_FORWARDREF)

Expand Down Expand Up @@ -40,28 +39,3 @@
such that all type hints forward referencing user-defined types are instances
of these superclasses).
'''


HINTS_IGNORABLE_SHALLOW = HINT_PEP_ATTRS_IGNORABLE | {
# The PEP-noncompliant builtin "object" type is the transitive superclass
# of all classes, parameters and return values annotated as "object"
# unconditionally match *ALL* objects under isinstance()-based type
# covariance and thus semantically reduce to unannotated parameters and
# return values. This is literally the "beartype.cave.AnyType" type.
object,
}
'''
Frozen set of all **shallowly ignorable type hints** (i.e., annotations
unconditionally ignored by the :func:`beartype.beartype` decorator).
Caveats
----------
**The high-level**
:func:`beartype._util.hint.pep.utilhinttest.is_hint_ignorable` **tester
function should always be called in lieu of testing type hints against this
low-level set.** This set is merely shallow and thus excludes **deeply
ignorable type hints** (e.g., :data:`Union[Any, bool, str]`). Since there exist
a countably infinite number of deeply ignorable type hints, this set is
necessarily constrained to the substantially smaller finite subset of only
shallowly ignorable type hints.
'''
14 changes: 0 additions & 14 deletions beartype/_util/data/hint/pep/datapepmap.py

This file was deleted.

0 comments on commit 722b52f

Please sign in to comment.