8000 Add support for Self type by ilevkivskyi · Pull Request #14041 · python/mypy · GitHub
[go: up one dir, main page]

Skip to content

Add support for Self type #14041

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

Merged
merged 26 commits into from
Nov 15, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
b205241
Start working on Self type
ilevkivskyi Nov 7, 2022
5e5bd6f
Add support for special forms; some fixes
ilevkivskyi Nov 7, 2022
7f91f3f
More fixes; more tests
ilevkivskyi Nov 7, 2022
80a11f6
Improve a test
ilevkivskyi Nov 8, 2022
2eb0db1
More tests few more fixes
ilevkivskyi Nov 8, 2022
535d936
Add incremental tests
ilevkivskyi Nov 8, 2022
ca7c7e8
Add docs
ilevkivskyi Nov 8, 2022
2ee66ec
Minor cleanup
ilevkivskyi Nov 8, 2022
ccb74a7
Fix self-compilation
ilevkivskyi Nov 8, 2022
504fe2c
Best effort support for unusual locations for self
ilevkivskyi Nov 8, 2022
1a99961
Some cleanups
ilevkivskyi Nov 9, 2022
ce8d345
Enable ClassVar (to some safe extent)
ilevkivskyi Nov 9, 2022
324eff2
Allow redundant Self by default; add error code
ilevkivskyi Nov 9, 2022
d96cfdc
Prohibit Self with arguments
ilevkivskyi Nov 9, 2022
0b953cf
Address CR; minor cleanups
ilevkivskyi Nov 10, 2022
5829804
Prohibit unclear cases; some more tests
ilevkivskyi Nov 10, 2022
3ec47b9
Make ClassVar in generics better
ilevkivskyi Nov 10, 2022
24dd649
More cleanup
ilevkivskyi Nov 10, 2022
ac6234d
Fix TypeVar id clash
ilevkivskyi Nov 11, 2022
61c0589
Final tweaks + couple tests
ilevkivskyi Nov 12, 2022
cbd97b1
Fix another bug from mypy_primer
ilevkivskyi Nov 12, 2022
362d84a
Fix upper bound for Self
ilevkivskyi Nov 12, 2022
a5740eb
More CR (docstring)
ilevkivskyi Nov 12, 2022
6694f3b
Fix Self import; fix method bodies; simplify id handling
ilevkivskyi Nov 12, 2022
3f86bf2
Allow using plain class in final classes
ilevkivskyi Nov 12, 2022
16e017d
Merge branch 'master' into self-type
ilevkivskyi Nov 14, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Minor cleanup
  • Loading branch information
ilevkivskyi committed Nov 8, 2022
commit 2ee66ec731a72c8fd59f5269edfb50f4c5326ad1
3 changes: 1 addition & 2 deletions mypy/plugins/dataclasses.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,9 @@
TypeVarType,
get_proper_type,
)

# The set of decorators that generate dataclasses.
from mypy.typevars import fill_typevars

# The set of decorators that generate dataclasses.
dataclass_makers: Final = {"dataclass", "dataclasses.dataclass"}
# The set of functions that generate dataclass fields.
field_makers: Final = {"dataclasses.field"}
Expand Down
9 changes: 8 additions & 8000 amp; 1 deletion mypy/semanal.py
Original file line number Diff line number Diff line change
Expand Up @@ -987,6 +987,12 @@ def update_function_type_variables(self, fun_type: CallableType, defn: FuncItem)
return has_self_type

def setup_self_type(self) -> None:
"""Setup a (shared) Self type variable for current class.

We intentionally don't add it to the class symbol table,
so it can be accessed only by mypy and will not cause
clashes with user defined names.
"""
assert self.type is not None
info = self.type
if info.self_type is not None:
Expand Down Expand Up @@ -3142,7 +3148,8 @@ def process_type_annotation(self, s: AssignmentStmt) -> None:
s.type, lambda name: self.lookup_qualified(name, s, suppress_errors=True)
)
if has_self_type and self.type:
if self.type.typeddict_type or self.type.tuple_type:
if self.type.typeddict_type or self.type.is_named_tuple:
# Annotations have special meaning in TypedDicts and NamedTuples.
return
self.setup_self_type()
analyzed = self.anal_type(s.type, allow_tuple_literal=allow_tuple_literal)
Expand Down
4 changes: 2 additions & 2 deletions mypy/semanal_namedtuple.py
Original file line number Diff line number Diff line change
Expand Up @@ -420,7 +420,7 @@ def parse_namedtuple_args(
return items, types, defaults, typename, tvar_defs, True

def parse_namedtuple_fields_with_types(
self, nodes: list[Expression], call: CallExpr, existing_info: TypeInfo | None
self, nodes: list[Expression], context: Context, existing_info: TypeInfo | None
) -> tuple[list[str], list[Type], list[Expression], bool] | None:
"""Parse typed named tuple fields.

Expand Down Expand Up @@ -449,7 +449,7 @@ def parse_namedtuple_fields_with_types(
type,
allow_placeholder=not self.options.disable_recursive_aliases
and not self.api.is_func_scope(),
self_type_override=special_self_type(existing_info, call),
self_type_override=special_self_type(existing_info, context),
)
# Workaround #4987 and avoid introducing a bogus UnboundType
if isinstance(analyzed, UnboundType):
Expand Down
4 changes: 2 additions & 2 deletions mypy/semanal_typeddict.py
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,7 @@ def parse_typeddict_args(
def parse_typeddict_fields_with_types(
self,
dict_items: list[tuple[Expression | None, Expression]],
call: CallExpr,
context: Context,
existing_info: TypeInfo | None,
) -> tuple[list[str], list[Type], bool] | None:
"""Parse typed dict items passed as pairs (name expression, type expression).
Expand Down Expand Up @@ -506,7 +506,7 @@ def parse_typeddict_fields_with_types(
allow_required=True,
allow_placeholder=not self.options.disable_recursive_aliases
and not self.api.is_func_scope(),
self_type_override=special_self_type(existing_info, call),
self_type_override=special_self_type(existing_info, context),
)
if analyzed is None:
return None
Expand Down
2 changes: 1 addition & 1 deletion mypy/typeanal.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ def __init__(
# Names of type aliases encountered while analysing a type will be collected here.
self.aliases_used: set[str] = set()
# Used by special forms like TypedDicts and NamedTuples, where Self type
# needs a special handling (for such types the target TypeInfo not be
# needs a special handling (for such types the target TypeInfo may not be
# created yet when analyzing Self type, unlike for regular classes).
self.self_type_override = self_type_override

Expand Down
8 changes: 8 additions & 0 deletions test-data/unit/check-selftype.test
Original file line number Diff line number Diff line change
Expand Up @@ -1424,3 +1424,11 @@ class D(C): ...

reveal_type(C) # N: Revealed type is "def (other: __main__.C) -> __main__.C"
reveal_type(D) # N: Revealed type is "def (other: __main__.D) -> __main__.D"

[case testTypingSelfCorrectName]
from typing import Self, List

class C:
Self = List[C]
def meth(self) -> Self: ...
reveal_type(C.meth) # N: Revealed type is "def (self: __main__.C) -> builtins.list[__main__.C]"
0