Skip to content

Commit

Permalink
Fixed annotated variable assignments broken with suppress_type_checks()
Browse files Browse the repository at this point in the history
Fixes #380.
  • Loading branch information
agronholm committed Aug 15, 2023
1 parent 6dbdf5d commit 5ac9b96
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 26 deletions.
5 changes: 5 additions & 0 deletions docs/versionhistory.rst
Expand Up @@ -3,6 +3,11 @@ Version history

This library adheres to `Semantic Versioning 2.0 <https://semver.org/#semantic-versioning-200>`_.

**UNRELEASED**

- Fixed ``suppress_type_checks()`` causing annotated variable assignments to always
assign ``None`` (`#380 <https://github.com/agronholm/typeguard/issues/380>`_)

**4.1.0** (2023-07-30)

- Added support for passing a tuple as ``expected_type`` to ``check_type()``, making it
Expand Down
50 changes: 25 additions & 25 deletions src/typeguard/_functions.py
Expand Up @@ -247,7 +247,7 @@ def check_variable_assignment(
value: object, varname: str, annotation: Any, memo: TypeCheckMemo
) -> Any:
if _suppression.type_checks_suppressed:
return
return value

try:
check_type_internal(value, annotation, memo)
Expand All @@ -265,36 +265,36 @@ def check_variable_assignment(
def check_multi_variable_assignment(
value: Any, targets: list[dict[str, Any]], memo: TypeCheckMemo
) -> Any:
if _suppression.type_checks_suppressed:
return

if max(len(target) for target in targets) == 1:
iterated_values = [value]
else:
iterated_values = list(value)

for expected_types in targets:
value_index = 0
for ann_index, (varname, expected_type) in enumerate(expected_types.items()):
if varname.startswith("*"):
varname = varname[1:]
keys_left = len(expected_types) - 1 - ann_index
next_value_index = len(iterated_values) - keys_left
obj: object = iterated_values[value_index:next_value_index]
value_index = next_value_index
else:
obj = iterated_values[value_index]
value_index += 1

try:
check_type_internal(obj, expected_type, memo)
except TypeCheckError as exc:
qualname = qualified_name(obj, add_class_prefix=True)
exc.append_path_element(f"value assigned to {varname} ({qualname})")
if memo.config.typecheck_fail_callback:
memo.config.typecheck_fail_callback(exc, memo)
if not _suppression.type_checks_suppressed:
for expected_types in targets:
value_index = 0
for ann_index, (varname, expected_type) in enumerate(
expected_types.items()
):
if varname.startswith("*"):
varname = varname[1:]
keys_left = len(expected_types) - 1 - ann_index
next_value_index = len(iterated_values) - keys_left
obj: object = iterated_values[value_index:next_value_index]
value_index = next_value_index
else:
raise
obj = iterated_values[value_index]
value_index += 1

try:
check_type_internal(obj, expected_type, memo)
except TypeCheckError as exc:
qualname = qualified_name(obj, add_class_prefix=True)
exc.append_path_element(f"value assigned to {varname} ({qualname})")
if memo.config.typecheck_fail_callback:
memo.config.typecheck_fail_callback(exc, memo)
else:
raise

return iterated_values[0] if len(iterated_values) == 1 else iterated_values

Expand Down
12 changes: 11 additions & 1 deletion tests/test_instrumentation.py
Expand Up @@ -8,7 +8,7 @@
import pytest
from pytest import FixtureRequest

from typeguard import TypeCheckError, config, install_import_hook
from typeguard import TypeCheckError, config, install_import_hook, suppress_type_checks
from typeguard._importhook import OPTIMIZATION

pytestmark = pytest.mark.filterwarnings("error:no type annotations present")
Expand Down Expand Up @@ -332,3 +332,13 @@ def test_literal_in_union(dummymodule):
def test_typevar_forwardref(dummymodule):
instance = dummymodule.typevar_forwardref(dummymodule.DummyClass)
assert isinstance(instance, dummymodule.DummyClass)


def test_suppress_annotated_assignment(dummymodule):
with suppress_type_checks():
assert dummymodule.literal_in_union("foo") == "foo"


def test_suppress_annotated_multi_assignment(dummymodule):
with suppress_type_checks():
assert dummymodule.multi_assign_single_value() == (6, 6, 6)

0 comments on commit 5ac9b96

Please sign in to comment.