Skip to content

Commit

Permalink
Fixed AnnotationTransformer removing quotes from Literals
Browse files Browse the repository at this point in the history
This bug was a side effect of 4c04b12.

Fixes #399.
  • Loading branch information
agronholm committed Sep 11, 2023
1 parent 2a58441 commit ec87739
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 6 deletions.
3 changes: 3 additions & 0 deletions docs/versionhistory.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ This library adheres to
- Fixed ``Callable`` erroneously rejecting a callable that has the requested amount of
positional arguments but they have defaults
(`#400 <https://github.com/agronholm/typeguard/issues/400>`_)
- Fixed a regression introduced in v4.1.4 where the elements of ``Literal`` got quotes
removed from them by the AST transformer
(`#399 <https://github.com/agronholm/typeguard/issues/399>`_)

**4.1.4** (2023-09-10)

Expand Down
10 changes: 4 additions & 6 deletions src/typeguard/_transformer.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,10 @@ def __init__(self, transformer: TypeguardTransformer):
self._level = 0

def visit(self, node: AST) -> Any:
# Don't process Literals
if isinstance(node, expr) and self._memo.name_matches(node, *literal_names):
return node

self._level += 1
new_node = super().visit(node)
self._level -= 1
Expand All @@ -365,12 +369,6 @@ def visit(self, node: AST) -> Any:

return new_node

def generic_visit(self, node: AST) -> AST:
if isinstance(node, expr) and self._memo.name_matches(node, *literal_names):
return node

return super().generic_visit(node)

def visit_BinOp(self, node: BinOp) -> Any:
self.generic_visit(node)

Expand Down
29 changes: 29 additions & 0 deletions tests/test_transformer.py
Original file line number Diff line number Diff line change
Expand Up @@ -1805,3 +1805,32 @@ def foo() -> int:
'''
).strip()
)


def test_literal() -> None:
# Regression test for #399
node = parse(
dedent(
"""
from typing import Literal
def foo(x: Literal['a', 'b']) -> None:
pass
"""
)
)
TypeguardTransformer().visit(node)
assert (
unparse(node)
== dedent(
"""
from typeguard import TypeCheckMemo
from typeguard._functions import check_argument_types
from typing import Literal
def foo(x: Literal['a', 'b']) -> None:
memo = TypeCheckMemo(globals(), locals())
check_argument_types('foo', {'x': (x, Literal['a', 'b'])}, memo)
"""
).strip()
)

0 comments on commit ec87739

Please sign in to comment.