Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

__qualname__ and __module__ are available in class bodies #16215

Merged
merged 2 commits into from Oct 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 4 additions & 1 deletion mypy/semanal.py
Expand Up @@ -5569,7 +5569,7 @@ def lookup(
if not suppress_errors:
self.name_not_defined(name, ctx)
return None
# 2. Class attributes (if within class definition)
# 2a. Class attributes (if within class definition)
if self.type and not self.is_func_scope() and name in self.type.names:
node = self.type.names[name]
if not node.implicit:
Expand All @@ -5579,6 +5579,9 @@ def lookup(
# Defined through self.x assignment
implicit_name = True
implicit_node = node
# 2b. Class attributes __qualname__ and __module__
if self.type and not self.is_func_scope() and name in {"__qualname__", "__module__"}:
return SymbolTableNode(MDEF, Var(name, self.str_type()))
# 3. Local (function) scopes
for table in reversed(self.locals):
if table is not None and name in table:
Expand Down
8 changes: 8 additions & 0 deletions test-data/unit/check-classes.test
Expand Up @@ -8001,3 +8001,11 @@ f5(1) # E: Argument 1 to "f5" has incompatible type "int"; expected "Integral"
# N: Types from "numbers" aren't supported for static type checking \
# N: See https://peps.python.org/pep-0484/#the-numeric-tower \
# N: Consider using a protocol instead, such as typing.SupportsFloat

[case testImplicitClassScopedNames]
class C:
reveal_type(__module__) # N: Revealed type is "builtins.str"
reveal_type(__qualname__) # N: Revealed type is "builtins.str"
def f(self) -> None:
__module__ # E: Name "__module__" is not defined
__qualname__ # E: Name "__qualname__" is not defined