Skip to content

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

Closed
wants to merge 3 commits into from

Conversation

graingert
Copy link
Contributor

@graingert graingert commented Jun 22, 2022

Description

Fixes #1362 (well not really it fixes propertied decorator support not decorated properties)

Test Plan

test case is here, but I don't know how best to integrate it in CI:

from collections.abc import Callable
from typing import ParamSpec, TypeVar

P = ParamSpec("P")
T = TypeVar("T")

import functools

def some_decorator(f: Callable[P, int]) -> Callable[P, str]:
    @functools.wraps(f)
    def decorator(*args: P.args, **kwargs: P.kwargs) -> str:
        return f"{f(*args, **kwargs)}"
        
    return decorator
    
    
def some_decorator2(p: property) -> property:
    return p

class Foo:
    
    # this is a propertied decorator and fairly normal
    @property  # type: ignore[misc]
    @some_decorator
    def foo(self) -> int:
        pass
    

    # this is a decorated property and an unusual construct 
    @some_decorator2
    @property
    def bar(self) -> int:
        pass
    
    
f = Foo()
reveal_type(f.foo)

@@ -1094,14 +1095,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:
Copy link
Contributor Author

@graingert graingert Jun 22, 2022

Choose a reason for hiding this comment

The 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

@decorator
@property
def foo(...)

else we are in the propertied decorator scenario:

@property
@decorator
def foo(...)

@github-actions

This comment has been minimized.

@graingert graingert force-pushed the fix-propertied-decorators branch from 8e294bb to 82849bd Compare June 22, 2022 11:04
Comment on lines +960 to 961
if len(item.decorators) >= 1:
node = item.decorators[0]
Copy link
Contributor Author

Choose a reason for hiding this comment

The 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:

@foo.setter
@dec
def foo(self, ...):
    ...

bad:

@dec
@foo.setter
def foo(self, ...):
    ...

Copy link
Contributor Author

@graingert graingert Jun 22, 2022

Choose a reason for hiding this comment

The 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

@github-actions

This comment has been minimized.

1 similar comment
@github-actions

This comment has been minimized.

@@ -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)
Copy link
Contributor Author

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:

from typing import overload
class A:
    @overload  # E: An overloaded function outside a stub file must have an implementation
    def f(self) -> int: pass
    @property  # E: Decorated property not supported
    @overload
    def f(self) -> int: pass

@graingert graingert marked this pull request as ready for review June 22, 2022 11:53
@graingert
Copy link
Contributor Author

looks like someone else already had a go at this #11719

@graingert graingert closed this Jun 22, 2022
@graingert graingert deleted the fix-propertied-decorators branch June 22, 2022 11:59
@github-actions
Copy link
Contributor

Diff from mypy_primer, showing the effect of this PR on open source code:

twine (https://github.com/pypa/twine)
+ twine/auth.py:31: error: Unused "type: ignore" comment
+ twine/auth.py:41: error: Unused "type: ignore" comment

spark (https://github.com/apache/spark)
+ python/pyspark/sql/session.py:445: error: Unused "type: ignore" comment
+ python/pyspark/sql/session.py:451: error: Unused "type: ignore" comment
+ python/pyspark/sql/session.py:457: error: Unused "type: ignore" comment
+ python/pyspark/sql/dataframe.py:170: error: Unused "type: ignore" comment
+ python/pyspark/sql/dataframe.py:181: error: Unused "type: ignore" comment
+ python/pyspark/sql/dataframe.py:187: error: Unused "type: ignore" comment
+ python/pyspark/sql/streaming/query.py:46: error: Unused "type: ignore" comment
+ python/pyspark/sql/streaming/query.py:57: error: Unused "type: ignore" comment
+ python/pyspark/sql/streaming/query.py:65: error: Unused "type: ignore" comment
+ python/pyspark/sql/streaming/query.py:75: error: Unused "type: ignore" comment
+ python/pyspark/sql/streaming/query.py:101: error: Unused "type: ignore" comment
+ python/pyspark/sql/streaming/query.py:109: error: Unused "type: ignore" comment
+ python/pyspark/mllib/linalg/__init__.py:1620: error: Unused "type: ignore" comment
+ python/pyspark/mllib/linalg/__init__.py:1629: error: Unused "type: ignore" comment
+ python/pyspark/ml/util.py:648: error: Unused "type: ignore" comment
+ python/pyspark/ml/util.py:657: error: Unused "type: ignore" comment
+ python/pyspark/mllib/regression.py:120: error: Unused "type: ignore" comment
+ python/pyspark/mllib/regression.py:126: error: Unused "type: ignore" comment
+ python/pyspark/mllib/classification.py:76: error: Unused "type: ignore" comment
+ python/pyspark/mllib/classification.py:217: error: Unused "type: ignore" comment
+ python/pyspark/mllib/classification.py:225: error: Unused "type: ignore" comment
+ python/pyspark/ml/base.py:399: error: Unused "type: ignore" comment
+ python/pyspark/ml/wrapper.py:450: error: Unused "type: ignore" comment
+ python/pyspark/ml/tree.py:49: error: Unused "type: ignore" comment
+ python/pyspark/ml/tree.py:55: error: Unused "type: ignore" comment
+ python/pyspark/ml/tree.py:61: error: Unused "type: ignore" comment
+ python/pyspark/ml/tree.py:221: error: Unused "type: ignore" comment
+ python/pyspark/ml/tree.py:227: error: Unused "type: ignore" comment
+ python/pyspark/ml/tree.py:233: error: Unused "type: ignore" comment
+ python/pyspark/ml/tree.py:239: error: Unused "type: ignore" comment
+ python/pyspark/ml/tree.py:245: error: Unused "type: ignore" comment
+ python/pyspark/ml/recommendation.py:612: error: Unused "type: ignore" comment
+ python/pyspark/ml/recommendation.py:618: error: Unused "type: ignore" comment
+ python/pyspark/ml/recommendation.py:627: error: Unused "type: ignore" comment
+ python/pyspark/ml/fpm.py:127: error: Unused "type: ignore" comment
+ python/pyspark/ml/fpm.py:137: error: Unused "type: ignore" comment
+ python/pyspark/ml/feature.py:1222: error: Unused "type: ignore" comment
+ python/pyspark/ml/feature.py:1892: error: Unused "type: ignore" comment
+ python/pyspark/ml/feature.py:1900: error: Unused "type: ignore" comment
+ python/pyspark/ml/feature.py:1908: error: Unused "type: ignore" comment
+ python/pyspark/ml/feature.py:2258: error: Unused "type: ignore" comment
+ python/pyspark/ml/feature.py:2473: error: Unused "type: ignore" comment
+ python/pyspark/ml/feature.py:2823: error: Unused "type: ignore" comment
+ python/pyspark/ml/feature.py:2831: error: Unused "type: ignore" comment
+ python/pyspark/ml/feature.py:3332: error: Unused "type: ignore" comment
+ python/pyspark/ml/feature.py:4010: error: Unused "type: ignore" comment
+ python/pyspark/ml/feature.py:4018: error: Unused "type: ignore" comment
+ python/pyspark/ml/feature.py:4462: error: Unused "type: ignore" comment
+ python/pyspark/ml/feature.py:4470: error: Unused "type: ignore" comment
+ python/pyspark/ml/feature.py:4835: error: Unused "type: ignore" comment
+ python/pyspark/ml/feature.py:4846: error: Unused "type: ignore" comment
+ python/pyspark/ml/feature.py:5630: error: Unused "type: ignore" comment
+ python/pyspark/ml/feature.py:5638: error: Unused "type: ignore" comment
+ python/pyspark/ml/feature.py:6266: error: Unused "type: ignore" comment
+ python/pyspark/ml/feature.py:6275: error: Unused "type: ignore" comment
+ python/pyspark/ml/feature.py:6732: error: Unused "type: ignore" comment
+ python/pyspark/ml/feature.py:7147: error: Unused "type: ignore" comment
+ python/pyspark/ml/feature.py:7422: error: Unused "type: ignore" comment
+ python/pyspark/ml/regression.py:456: error: Unused "type: ignore" comment
+ python/pyspark/ml/regression.py:464: error: Unused "type: ignore" comment
+ python/pyspark/ml/regression.py:472: error: Unused "type: ignore" comment
+ python/pyspark/ml/regression.py:480: error: Unused "type: ignore" comment
+ python/pyspark/ml/regression.py:520: error: Unused "type: ignore" comment
+ python/pyspark/ml/regression.py:528: error: Unused "type: ignore" comment
+ python/pyspark/ml/regression.py:537: error: Unused "type: ignore" comment
+ python/pyspark/ml/regression.py:546: error: Unused "type: ignore" comment
+ python/pyspark/ml/regression.py:555: error: Unused "type: ignore" comment
+ python/pyspark/ml/regression.py:574: error: Unused "type: ignore" comment
+ python/pyspark/ml/regression.py:590: error: Unused "type: ignore" comment
+ python/pyspark/ml/regression.py:606: error: Unused "type: ignore" comment
+ python/pyspark/ml/regression.py:621: error: Unused "type: ignore" comment
+ python/pyspark/ml/regression.py:638: error: Unused "type: ignore" comment
+ python/pyspark/ml/regression.py:654: error: Unused "type: ignore" comment
+ python/pyspark/ml/regression.py:662: error: Unused "type: ignore" comment
+ python/pyspark/ml/regression.py:670: error: Unused "type: ignore" comment
+ python/pyspark/ml/regression.py:678: error: Unused "type: ignore" comment
+ python/pyspark/ml/regression.py:980: error: Unused "type: ignore" comment
+ python/pyspark/ml/regression.py:988: error: Unused "type: ignore" comment
+ python/pyspark/ml/regression.py:997: error: Unused "type: ignore" comment
+ python/pyspark/ml/regression.py:1603: error: Unused "type: ignore" comment
+ python/pyspark/ml/regression.py:1992: error: Unused "type: ignore" comment
+ python/pyspark/ml/regression.py:2311: error: Unused "type: ignore" comment
+ python/pyspark/ml/regression.py:2319: error: Unused "type: ignore" comment
+ python/pyspark/ml/regression.py:2327: error: Unused "type: ignore" comment
+ python/pyspark/ml/regression.py:2737: error: Unused "type: ignore" comment
+ python/pyspark/ml/regression.py:2745: error: Unused "type: ignore" comment
+ python/pyspark/ml/regression.py:2753: error: Unused "type: ignore" comment
+ python/pyspark/ml/regression.py:2795: error: Unused "type: ignore" comment
+ python/pyspark/ml/regression.py:2803: error: Unused "type: ignore" comment
+ python/pyspark/ml/regression.py:2812: error: Unused "type: ignore" comment
+ python/pyspark/ml/regression.py:2820: error: Unused "type: ignore" comment
+ python/pyspark/ml/regression.py:2828: error: Unused "type: ignore" comment
+ python/pyspark/ml/regression.py:2836: error: Unused "type: ignore" comment
+ python/pyspark/ml/regression.py:2844: error: Unused "type: ignore" comment
+ python/pyspark/ml/regression.py:2866: error: Unused "type: ignore" comment
+ python/pyspark/ml/regression.py:2874: error: Unused "type: ignore" comment
+ python/pyspark/ml/regression.py:2882: error: Unused "type: ignore" comment
+ python/pyspark/ml/regression.py:2893: error: Unused "type: ignore" comment
+ python/pyspark/ml/regression.py:2910: error: Unused "type: ignore" comment
+ python/pyspark/ml/regression.py:2918: error: Unused "type: ignore" comment
+ python/pyspark/ml/regression.py:2926: error: Unused "type: ignore" comment
+ python/pyspark/ml/regression.py:2937: error: Unused "type: ignore" comment
+ python/pyspark/ml/regression.py:2948: error: Unused "type: ignore" comment
+ python/pyspark/ml/regression.py:3283: error: Unused "type: ignore" comment
+ python/pyspark/ml/regression.py:3291: error: Unused "type: ignore" comment
+ python/pyspark/ml/regression.py:3299: error: Unused "type: ignore" comment
+ python/pyspark/ml/clustering.py:86: error: Unused "type: ignore" comment
+ python/pyspark/ml/clustering.py:94: error: Unused "type: ignore" comment
+ python/pyspark/ml/clustering.py:102: error: Unused "type: ignore" comment
+ python/pyspark/ml/clustering.py:110: error: Unused "type: ignore" comment
+ python/pyspark/ml/clustering.py:118: error: Unused "type: ignore" comment
+ python/pyspark/ml/clustering.py:126: error: Unused "type: ignore" comment
+ python/pyspark/ml/clustering.py:134: error: Unused "type: ignore" comment
+ python/pyspark/ml/clustering.py:213: error: Unused "type: ignore" comment
+ python/pyspark/ml/clustering.py:223: error: Unused "type: ignore" comment
+ python/pyspark/ml/clustering.py:239: error: Unused "type: ignore" comment
+ python/pyspark/ml/clustering.py:249: error: Unused "type: ignore" comment
+ python/pyspark/ml/clustering.py:532: error: Unused "type: ignore" comment
+ python/pyspark/ml/clustering.py:540: error: Unused "type: ignore" comment
+ python/pyspark/ml/clustering.py:548: error: Unused "type: ignore" comment
+ python/pyspark/ml/clustering.py:564: error: Unused "type: ignore" comment
+ python/pyspark/ml/clustering.py:686: error: Unused "type: ignore" comment
+ python/pyspark/ml/clustering.py:1024: error: Unused "type: ignore" comment
+ python/pyspark/ml/clustering.py:1248: error: Unused "type: ignore" comment
+ python/pyspark/ml/classification.py:183: error: Unused "type: ignore" comment
+ python/pyspark/ml/classification.py:287: error: Unused "type: ignore" comment
+ python/pyspark/ml/classification.py:338: error: Unused "type: ignore" comment
+ python/pyspark/ml/classification.py:346: error: Unused "type: ignore" comment
+ python/pyspark/ml/classification.py:354: error: Unused "type: ignore" comment
+ python/pyspark/ml/classification.py:363: error: Unused "type: ignore" comment
+ python/pyspark/ml/classification.py:389: error: Unused "type: ignore" comment
+ python/pyspark/ml/classification.py:397: error: Unused "type: ignore" comment
+ python/pyspark/ml/classification.py:405: error: Unused "type: ignore" comment
+ python/pyspark/ml/classification.py:413: error: Unused "type: ignore" comment
+ python/pyspark/ml/classification.py:428: error: Unused "type: ignore" comment
+ python/pyspark/ml/classification.py:438: error: Unused "type: ignore" comment
+ python/pyspark/ml/classification.py:447: error: Unused "type: ignore" comment
+ python/pyspark/ml/classification.py:455: error: Unused "type: ignore" comment
+ python/pyspark/ml/classification.py:464: error: Unused "type: ignore" comment
+ python/pyspark/ml/classification.py:488: error: Unused "type: ignore" comment
+ python/pyspark/ml/classification.py:498: error: Unused "type: ignore" comment
+ python/pyspark/ml/classification.py:515: error: Unused "type: ignore" comment
+ python/pyspark/ml/classification.py:539: error: Unused "type: ignore" comment
+ python/pyspark/ml/classification.py:548: error: Unused "type: ignore" comment
+ python/pyspark/ml/classification.py:558: error: Unused "type: ignore" comment
+ python/pyspark/ml/classification.py:567: error: Unused "type: ignore" comment
+ python/pyspark/ml/classification.py:577: error: Unused "type: ignore" comment
+ python/pyspark/ml/classification.py:860: error: Unused "type: ignore" comment
+ python/pyspark/ml/classification.py:868: error: Unused "type: ignore" comment
+ python/pyspark/ml/classification.py:1530: error: Unused "type: ignore" comment
+ python/pyspark/ml/classification.py:1539: error: Unused "type: ignore" comment
+ python/pyspark/ml/classification.py:1548: error: Unused "type: ignore" comment
+ python/pyspark/ml/classification.py:1556: error: Unused "type: ignore" comment
+ python/pyspark/ml/classification.py:1564: error: Unused "type: ignore" comment
+ python/pyspark/ml/classification.py:1612: error: Unused "type: ignore" comment
+ python/pyspark/ml/classification.py:1621: error: Unused "type: ignore" comment
+ python/pyspark/ml/classification.py:2282: error: Unused "type: ignore" comment
+ python/pyspark/ml/classification.py:2288: error: Unused "type: ignore" comment
+ python/pyspark/ml/classification.py:2770: error: Unused "type: ignore" comment
+ python/pyspark/ml/classification.py:3021: error: Unused "type: ignore" comment
+ python/pyspark/ml/classification.py:3029: error: Unused "type: ignore" comment
+ python/pyspark/ml/classification.py:3037: error: Unused "type: ignore" comment
+ python/pyspark/ml/classification.py:3313: error: Unused "type: ignore" comment
+ python/pyspark/ml/classification.py:4229: error: Unused "type: ignore" comment
+ python/pyspark/ml/classification.py:4237: error: Unused "type: ignore" comment
+ python/pyspark/ml/classification.py:4245: error: Unused "type: ignore" comment
+ python/pyspark/mllib/recommendation.py:211: error: Unused "type: ignore" comment
+ python/pyspark/mllib/feature.py:254: error: Unused "type: ignore" comment
+ python/pyspark/mllib/feature.py:262: error: Unused "type: ignore" comment
+ python/pyspark/mllib/feature.py:270: error: Unused "type: ignore" comment
+ python/pyspark/mllib/feature.py:278: error: Unused "type: ignore" comment
+ python/pyspark/mllib/evaluation.py:88: error: Unused "type: ignore" comment
+ python/pyspark/mllib/evaluation.py:97: error: Unused "type: ignore" comment
+ python/pyspark/mllib/evaluation.py:164: error: Unused "type: ignore" comment
+ python/pyspark/mllib/evaluation.py:173: error: Unused "type: ignore" comment
+ python/pyspark/mllib/evaluation.py:182: error: Unused "type: ignore" comment
+ python/pyspark/mllib/evaluation.py:191: error: Unused "type: ignore" comment
+ python/pyspark/mllib/evaluation.py:200: error: Unused "type: ignore" comment
+ python/pyspark/mllib/evaluation.py:351: error: Unused "type: ignore" comment
+ python/pyspark/mllib/evaluation.py:360: error: Unused "type: ignore" comment
+ python/pyspark/mllib/evaluation.py:369: error: Unused "type: ignore" comment
+ python/pyspark/mllib/evaluation.py:377: error: Unused "type: ignore" comment
+ python/pyspark/mllib/evaluation.py:386: error: Unused "type: ignore" comment
+ python/pyspark/mllib/evaluation.py:477: error: Unused "type: ignore" comment
+ python/pyspark/mllib/evaluation.py:609: error: Unused "type: ignore" comment
+ python/pyspark/mllib/evaluation.py:618: error: Unused "type: ignore" comment
+ python/pyspark/mllib/evaluation.py:627: error: Unused "type: ignore" comment
+ python/pyspark/mllib/evaluation.py:636: error: Unused "type: ignore" comment
+ python/pyspark/mllib/evaluation.py:644: error: Unused "type: ignore" comment
+ python/pyspark/mllib/evaluation.py:653: error: Unused "type: ignore" comment
+ python/pyspark/mllib/linalg/distributed.py:503: error: Unused "type: ignore" comment
+ python/pyspark/mllib/linalg/distributed.py:520: error: Unused "type: ignore" comment
+ python/pyspark/mllib/linalg/distributed.py:528: error: Unused "type: ignore" comment
+ python/pyspark/mllib/clustering.py:82: error: Unused "type: ignore" comment
+ python/pyspark/mllib/clustering.py:89: error: Unused "type: ignore" comment
+ python/pyspark/mllib/clustering.py:284: error: Unused "type: ignore" comment
+ python/pyspark/mllib/clustering.py:290: error: Unused "type: ignore" comment
+ python/pyspark/mllib/clustering.py:535: error: Unused "type: ignore" comment
+ python/pyspark/mllib/clustering.py:544: error: Unused "type: ignore" comment
+ python/pyspark/mllib/clustering.py:555: error: Unused "type: ignore" comment
+ python/pyspark/mllib/clustering.py:779: error: Unused "type: ignore" comment
+ python/pyspark/mllib/clustering.py:947: error: Unused "type: ignore" comment

core (https://github.com/home-assistant/core)
+ homeassistant/components/norway_air/air_quality.py:109: error: Unused "type: ignore" comment
+ homeassistant/components/norway_air/air_quality.py:115: error: Unused "type: ignore" comment
+ homeassistant/components/norway_air/air_quality.py:121: error: Unused "type: ignore" comment
+ homeassistant/components/norway_air/air_quality.py:127: error: Unused "type: ignore" comment
+ homeassistant/components/norway_air/air_quality.py:133: error: Unused "type: ignore" comment

pandas (https://github.com/pandas-dev/pandas)
+ pandas/core/indexes/base.py:5088: error: Unused "type: ignore" comment
+ pandas/core/arrays/interval.py:1432: error: Unused "type: ignore" comment
+ pandas/core/indexes/numeric.py:213: error: Unused "type: ignore" comment
+ pandas/core/indexes/period.py:192: error: Unused "type: ignore" comment
+ pandas/core/indexes/period.py:199: error: Unused "type: ignore" comment
+ pandas/core/indexes/period.py:206: error: Unused "type: ignore" comment

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Decorated property not supported
1 participant