-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
support propertied decorators #13008
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -846,6 +846,8 @@ def analyze_overload_sigs_and_impl( | |
# that. | ||
non_overload_indexes.append(i) | ||
else: | ||
if item.var.is_property: | ||
self.fail("Decorated property not supported", item) | ||
item.func.is_overload = True | ||
types.append(callable) | ||
elif isinstance(item, FuncDef): | ||
|
@@ -957,16 +959,16 @@ def analyze_property_with_multi_part_definition(self, defn: OverloadedFuncDef) - | |
deleted_items = [] | ||
for i, item in enumerate(items[1:]): | ||
if isinstance(item, Decorator): | ||
if len(item.decorators) == 1: | ||
if len(item.decorators) >= 1: | ||
node = item.decorators[0] | ||
Comment on lines
+962
to
963
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the first item must be the setter - any other decorator is after the setter: good:
bad:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "@overload" support is still broken, however: from typing import TypeVar, Generic, overload
from typing_extensions import Self
T_str_or_bytes = TypeVar("T_str_or_bytes", bound=str | bytes)
class Foo(Generic[T_str_or_bytes]):
def __init__(self, v: T_str_or_bytes) -> None:
self._v = v
@property
@overload
def ham(self: Foo[str]) -> str:
return self._v
@property
@overload # E: Decorated property not supported
def ham(self: Foo[bytes]) -> bytes:
return self._v |
||
if isinstance(node, MemberExpr): | ||
if node.name == 'setter': | ||
# The first item represents the entire property. | ||
first_item.var.is_settable_property = True | ||
# Get abstractness from the original definition. | ||
item.func.is_abstract = first_item.func.is_abstract | ||
else: | ||
self.fail("Decorated property not supported", item) | ||
else: | ||
self.fail("Decorated property not supported", item) | ||
item.func.accept(self) | ||
else: | ||
self.fail(f'Unexpected definition for property "{first_item.func.name}"', | ||
|
@@ -1047,6 +1049,7 @@ def visit_decorator(self, dec: Decorator) -> None: | |
d.accept(self) | ||
removed: List[int] = [] | ||
no_type_check = False | ||
could_be_decorated_property = False | ||
for i, d in enumerate(dec.decorators): | ||
# A bunch of decorators are special cased here. | ||
if refers_to_fullname(d, 'abc.abstractmethod'): | ||
|
@@ -1094,14 +1097,16 @@ def visit_decorator(self, dec: Decorator) -> None: | |
removed.append(i) | ||
else: | ||
self.fail("@final cannot be used with non-method functions", d) | ||
elif not dec.var.is_property: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if a decorator shows up before "is_property" gets set then it's
else we are in the propertied decorator scenario:
|
||
could_be_decorated_property = True | ||
for i in reversed(removed): | ||
del dec.decorators[i] | ||
if (not dec.is_overload or dec.var.is_property) and self.type: | ||
dec.var.info = self.type | ||
dec.var.is_initialized_in_class = True | ||
if not no_type_check and self.recurse_into_functions: | ||
dec.func.accept(self) | ||
if dec.decorators and dec.var.is_property: | ||
if could_be_decorated_property and dec.decorators and dec.var.is_property: | ||
self.fail('Decorated property not supported', dec) | ||
if dec.func.is_abstract and dec.func.is_final: | ||
self.fail(f"Method {dec.func.name} is both abstract and final", dec) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this puts back the "Decorated property not supported" warning on overloads: