Skip to content

Commit

Permalink
Parameter default type-checking x 2.
Browse files Browse the repository at this point in the history
This commit is the next in a commit chain type-checking the default
values of optional parameters accepted by `@beartype`-decorated
callables, en-route to resolving feature request #154 kindly submitted
by @dosisod (Logan Hunt) a literal lifetime ago when @leycec still had
hair. And what kind of an unabashedly superheroic name is "Logan Hunt,"
anyway? He was destined for greatness. Specifically, this commit
refactors ANSI colour handling throughout the codebase for internal
maintainability, usability, and sanity. (*Unasked for majority for Majora's mask!*)
  • Loading branch information
leycec committed Mar 22, 2024
1 parent dfe4791 commit a5b876b
Show file tree
Hide file tree
Showing 17 changed files with 354 additions and 278 deletions.
2 changes: 1 addition & 1 deletion beartype/_check/error/_errortype.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
from beartype._util.text.utiltextansi import color_hint
from beartype._util.text.utiltextjoin import join_delimited_disjunction_types
from beartype._util.text.utiltextlabel import label_type
from beartype._check.error._util.errorutiltext import represent_pith
from beartype._util.text.utiltextrepr import represent_pith

# ....................{ GETTERS ~ instance : type }....................
def find_cause_instance_type(cause: ViolationCause) -> ViolationCause:
Expand Down
2 changes: 1 addition & 1 deletion beartype/_check/error/_pep/errorpep484604union.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
from beartype.roar._roarexc import _BeartypeCallHintPepRaiseException
from beartype._data.hint.pep.sign.datapepsignset import HINT_SIGNS_UNION
from beartype._check.error._errorcause import ViolationCause
from beartype._check.error._util.errorutiltext import represent_pith
from beartype._util.hint.pep.utilpepget import (
get_hint_pep_origin_type_isinstanceable_or_none)
from beartype._util.hint.pep.utilpeptest import is_hint_pep
Expand All @@ -26,6 +25,7 @@
suffix_str_unless_suffixed,
uppercase_str_char_first,
)
from beartype._util.text.utiltextrepr import represent_pith

# ....................{ GETTERS }....................
def find_cause_union(cause: ViolationCause) -> ViolationCause:
Expand Down
2 changes: 1 addition & 1 deletion beartype/_check/error/_pep/errorpep586.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from beartype._util.hint.pep.proposal.utilpep586 import (
get_hint_pep586_literals)
from beartype._util.text.utiltextjoin import join_delimited_disjunction
from beartype._check.error._util.errorutiltext import represent_pith
from beartype._util.text.utiltextrepr import represent_pith

# ....................{ GETTERS }....................
def find_cause_literal(cause: ViolationCause) -> ViolationCause:
Expand Down
4 changes: 2 additions & 2 deletions beartype/_check/error/_pep/errorpep593.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@

# ....................{ IMPORTS }....................
from beartype.roar._roarexc import _BeartypeCallHintPepRaiseException
from beartype._data.hint.pep.sign.datapepsigns import HintSignAnnotated
from beartype._check.error._errorcause import ViolationCause
from beartype._check.error._util.errorutiltext import represent_pith
from beartype._data.hint.pep.sign.datapepsigns import HintSignAnnotated
from beartype._util.hint.pep.proposal.utilpep593 import (
get_hint_pep593_metadata,
get_hint_pep593_metahint,
)
from beartype._data.code.datacodeindent import CODE_INDENT_1
from beartype._util.text.utiltextrepr import represent_pith

# ....................{ GETTERS }....................
def find_cause_annotated(cause: ViolationCause) -> ViolationCause:
Expand Down
2 changes: 1 addition & 1 deletion beartype/_check/error/_pep/pep484/errornoreturn.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
from beartype.typing import Callable
from beartype._data.hint.pep.sign.datapepsigns import HintSignNoReturn
from beartype._check.error._errorcause import ViolationCause
from beartype._check.error._util.errorutiltext import represent_pith
from beartype._util.text.utiltextlabel import label_callable
from beartype._util.text.utiltextrepr import represent_pith

# ....................{ GETTERS }....................
def find_cause_noreturn(cause: ViolationCause) -> ViolationCause:
Expand Down
16 changes: 6 additions & 10 deletions beartype/_check/error/_pep/pep484585/errormapping.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,12 @@
Tuple,
Hashable,
)
from beartype._data.hint.pep.sign.datapepsignset import (
HINT_SIGNS_MAPPING)
from beartype._data.hint.pep.sign.datapepsignset import HINT_SIGNS_MAPPING
from beartype._check.error._errorcause import ViolationCause
from beartype._check.error._errortype import (
find_cause_type_instance_origin)
from beartype._check.error._util.errorutiltext import (
prefix_pith_type,
represent_pith,
)
from beartype._check.error._errortype import find_cause_type_instance_origin
from beartype._util.hint.utilhinttest import is_hint_ignorable
from beartype._util.text.utiltextprefix import prefix_pith_type
from beartype._util.text.utiltextrepr import represent_pith

# ....................{ FINDERS }....................
def find_cause_mapping(cause: ViolationCause) -> ViolationCause:
Expand Down Expand Up @@ -118,7 +114,7 @@ def find_cause_mapping(cause: ViolationCause) -> ViolationCause:
# Human-readable substring prefixing this failure with
# metadata describing this key.
cause_deep.cause_str_or_none = (
f'{prefix_pith_type(cause.pith)}'
f'{prefix_pith_type(pith=cause.pith, is_color=True)}'
f'key {cause_deep.cause_str_or_none}'
)

Expand All @@ -140,7 +136,7 @@ def find_cause_mapping(cause: ViolationCause) -> ViolationCause:
# Human-readable substring prefixing this failure with
# metadata describing this value.
cause_deep.cause_str_or_none = (
f'{prefix_pith_type(cause.pith)}'
f'{prefix_pith_type(pith=cause.pith, is_color=True)}'
f'key {represent_pith(pith_key)} '
f'value {cause_deep.cause_str_or_none}'
)
Expand Down
13 changes: 5 additions & 8 deletions beartype/_check/error/_pep/pep484585/errorsequence.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,13 @@
from beartype._data.hint.pep.sign.datapepsignset import (
HINT_SIGNS_SEQUENCE_ARGS_1)
from beartype._check.error._errorcause import ViolationCause
from beartype._check.error._errortype import (
find_cause_type_instance_origin)
from beartype._check.error._util.errorutiltext import (
prefix_pith_type,
represent_pith,
)
from beartype._check.error._errortype import find_cause_type_instance_origin
from beartype._util.hint.pep.proposal.pep484585.utilpep484585 import (
is_hint_pep484585_tuple_empty)
from beartype._util.hint.utilhinttest import is_hint_ignorable
from beartype._util.text.utiltextansi import color_type
from beartype._util.text.utiltextprefix import prefix_pith_type
from beartype._util.text.utiltextrepr import represent_pith

# ....................{ FINDERS }....................
def find_cause_sequence_args_1(cause: ViolationCause) -> ViolationCause:
Expand Down Expand Up @@ -176,7 +173,7 @@ def find_cause_tuple(cause: ViolationCause) -> ViolationCause:
# Human-readable substring prefixing this failure with metadata
# describing this item.
cause_deep.cause_str_or_none = (
f'{prefix_pith_type(cause.pith)}'
f'{prefix_pith_type(pith=cause.pith, is_color=True)}'
f'index {color_type(str(pith_item_index))} '
f'item {cause_deep.cause_str_or_none}'
)
Expand Down Expand Up @@ -289,7 +286,7 @@ def _find_cause_sequence(cause: ViolationCause) -> ViolationCause:
# Human-readable substring prefixing this failure with
# metadata describing this item.
cause_deep.cause_str_or_none = (
f'{prefix_pith_type(cause.pith)}'
f'{prefix_pith_type(pith=cause.pith, is_color=True)}'
f'index {color_type(str(pith_item_index))} '
f'item {cause_deep.cause_str_or_none}'
)
Expand Down
168 changes: 0 additions & 168 deletions beartype/_check/error/_util/errorutiltext.py

This file was deleted.

26 changes: 18 additions & 8 deletions beartype/_check/error/errorget.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,16 +86,16 @@
from beartype._check.error._errorcause import ViolationCause
from beartype._check.error._util.errorutilcolor import (
strip_text_ansi_if_configured)
from beartype._check.error._util.errorutiltext import (
prefix_callable_arg_value,
prefix_callable_return_value,
prefix_pith_value,
)
from beartype._util.text.utiltextansi import color_hint
from beartype._util.text.utiltextmunge import (
suffix_str_unless_suffixed,
uppercase_str_char_first,
)
from beartype._util.text.utiltextprefix import (
prefix_callable_return_value,
prefix_callable_arg_value,
prefix_pith_value,
)
from beartype._util.text.utiltextrepr import represent_object
from collections.abc import Callable as CallableABC

Expand Down Expand Up @@ -366,7 +366,10 @@ class variable or method annotated by this hint *or* :data:`None`).
exception_cls = conf.violation_door_type

# Suffix this exception prefix with an additional noun for disambiguity.
exception_prefix = f'{exception_prefix}value {prefix_pith_value(obj)}'
exception_prefix = (
f'{exception_prefix}value '
f'{prefix_pith_value(pith=obj, is_color=True)}'
)
# Else, the caller passed a parameter name. In this case...
else:
# If the caller also passed an exception prefix, raise an exception.
Expand All @@ -383,13 +386,20 @@ class variable or method annotated by this hint *or* :data:`None`).
# Default these exception locals appropriately
exception_cls = conf.violation_return_type
exception_prefix = prefix_callable_return_value(
func=func, return_value=obj) # type: ignore[arg-type]
func=func, # type: ignore[arg-type]
return_value=obj,
is_color=True,
)
# Else, the passed object is a parameter. In this case...
else:
# Default these exception locals appropriately
exception_cls = conf.violation_param_type
exception_prefix = prefix_callable_arg_value(
func=func, arg_name=pith_name, arg_value=obj) # type: ignore[arg-type]
func=func, # type: ignore[arg-type]
arg_name=pith_name,
arg_value=obj,
is_color=True,
)

# Uppercase the first character of this violation prefix for readability.
exception_prefix = uppercase_str_char_first(exception_prefix)
Expand Down
2 changes: 1 addition & 1 deletion beartype/_data/error/dataerrmagic.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
This private submodule is *not* intended for importation by downstream callers.
'''

# ....................{ CODE ~ operator }....................
# ....................{ STRINGS }....................
EXCEPTION_PLACEHOLDER = '$%ROOT_PITH_LABEL/~'
'''
Non-human-readable source substring to be globally replaced by a human-readable
Expand Down
3 changes: 2 additions & 1 deletion beartype/_decor/wrap/_wrapargs.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
from beartype._data.func.datafuncarg import ARG_NAME_RETURN
from beartype._decor.wrap.wrapsnip import (
CODE_INIT_ARGS_LEN,
EXCEPTION_PREFIX_DEFAULT_VALUE,
PARAM_KIND_TO_CODE_LOCALIZE,
)
from beartype._decor.wrap._wraputil import unmemoize_func_wrapper_code
Expand Down Expand Up @@ -200,7 +201,7 @@ def code_check_args(bear_call: BeartypeCall) -> str:
die_if_unbearable(
obj=arg_default,
hint=hint,
exception_prefix=EXCEPTION_PLACEHOLDER,
exception_prefix=EXCEPTION_PREFIX_DEFAULT_VALUE,
)
# Else, this default value satisfies this hint.
# Else, this parameter is mandatory.
Expand Down

0 comments on commit a5b876b

Please sign in to comment.