Skip to content

Commit bb9df16

Browse files
Fix FP for invalid-name with typing.Annotated (#10699)
1 parent 25000a2 commit bb9df16

File tree

3 files changed

+30
-11
lines changed

3 files changed

+30
-11
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fixed false positive for ``invalid-name`` with ``typing.Annotated``.
2+
3+
Closes #10696

pylint/checkers/base/name_checker/checker.py

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -488,17 +488,7 @@ def visit_assignname( # pylint: disable=too-many-branches,too-many-statements
488488
return
489489

490490
# Check classes (TypeVar's are classes so they need to be excluded first)
491-
elif isinstance(inferred_assign_type, nodes.ClassDef) or (
492-
isinstance(inferred_assign_type, bases.Instance)
493-
and {"EnumMeta", "TypedDict"}.intersection(
494-
{
495-
ancestor.name
496-
for ancestor in cast(
497-
InferenceResult, inferred_assign_type
498-
).mro()
499-
}
500-
)
501-
):
491+
elif self._should_check_class_regex(inferred_assign_type):
502492
self._check_name("class", node.name, node)
503493

504494
# Don't emit if the name redefines an import in an ImportError except handler
@@ -576,6 +566,28 @@ def _meets_exception_for_non_consts(
576566
regexp = self._name_regexps["variable"]
577567
return regexp.match(name) is not None
578568

569+
def _should_check_class_regex(
570+
self, inferred_assign_type: InferenceResult | None
571+
) -> bool:
572+
if isinstance(inferred_assign_type, nodes.ClassDef):
573+
return True
574+
if isinstance(inferred_assign_type, bases.Instance) and {
575+
"EnumMeta",
576+
"TypedDict",
577+
}.intersection(
578+
{
579+
ancestor.name
580+
for ancestor in cast(InferenceResult, inferred_assign_type).mro()
581+
}
582+
):
583+
return True
584+
if (
585+
isinstance(inferred_assign_type, nodes.FunctionDef)
586+
and inferred_assign_type.qname() == "typing.Annotated"
587+
):
588+
return True
589+
return False
590+
579591
def _recursive_check_names(self, args: list[nodes.AssignName]) -> None:
580592
"""Check names in a possibly recursive list <arg>."""
581593
for arg in args:

tests/functional/i/invalid/invalid_name/invalid_name_module_level.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,7 @@ def A(): # [invalid-name]
5151
VERSION = version("ty") # uninferable
5252
except PackageNotFoundError:
5353
VERSION = "0.0.0"
54+
55+
56+
from typing import Annotated
57+
IntWithAnnotation = Annotated[int, "anything"]

0 commit comments

Comments
 (0)