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

Added [prop-decorator] code for unsupported property decorators (#14461) #16571

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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions docs/source/error_code_list.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1171,6 +1171,29 @@ annotations in an unchecked function:
Note that mypy will still exit with return code ``0``, since such behaviour is
specified by :pep:`484`.

.. _code-prop-decorator:

Decorator preceding property not supported [prop-decorator]
-----------------------------------------------------------

Mypy does not yet support analysis of decorators that precede the property
decorator. If the decorator does not preserve the declared type of the property,
mypy will not infer the correct type for the declaration. If the decorator cannot
be moved after the ``@property`` decorator, then you must use a type ignore
comment:

.. code-block:: python

class MyClass
@special # type: ignore[prop-decorator]
@property
def magic(self) -> str:
return "xyzzy"

.. note::

For backward compatibility, this error code is a subcode of the generic ``[misc]`` code.

.. _code-syntax:

Report syntax errors [syntax]
Expand Down
8 changes: 7 additions & 1 deletion mypy/errorcodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,6 @@ def __hash__(self) -> int:
default_enabled=False,
)


# Syntax errors are often blocking.
SYNTAX: Final[ErrorCode] = ErrorCode("syntax", "Report syntax errors", "General")

Expand All @@ -281,6 +280,13 @@ def __hash__(self) -> int:
sub_code_of=MISC,
)

PROPERTY_DECORATOR = ErrorCode(
"prop-decorator",
"Decorators on top of @property are not supported",
"General",
sub_code_of=MISC,
)

NARROWED_TYPE_NOT_SUBTYPE: Final[ErrorCode] = ErrorCode(
"narrowed-type-not-subtype",
"Warn if a TypeIs function's narrowed type is not a subtype of the original type",
Expand Down
6 changes: 4 additions & 2 deletions mypy/semanal.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@

from mypy import errorcodes as codes, message_registry
from mypy.constant_fold import constant_fold_expr
from mypy.errorcodes import ErrorCode
from mypy.errorcodes import PROPERTY_DECORATOR, ErrorCode
from mypy.errors import Errors, report_internal_error
from mypy.exprtotype import TypeTranslationError, expr_to_unanalyzed_type
from mypy.messages import (
Expand Down Expand Up @@ -1620,7 +1620,9 @@ def visit_decorator(self, dec: Decorator) -> None:
if not no_type_check and self.recurse_into_functions:
dec.func.accept(self)
if could_be_decorated_property and dec.decorators and dec.var.is_property:
self.fail("Decorators on top of @property are not supported", dec)
self.fail(
"Decorators on top of @property are not supported", dec, code=PROPERTY_DECORATOR
)
if (dec.func.is_static or dec.func.is_class) and dec.var.is_property:
self.fail("Only instance methods can be decorated with @property", dec)
if dec.func.abstract_status == IS_ABSTRACT and dec.func.is_final:
Expand Down
6 changes: 6 additions & 0 deletions test-data/unit/semanal-errors.test
Original file line number Diff line number Diff line change
Expand Up @@ -1241,6 +1241,12 @@ class A:
@property # OK
@dec
def g(self) -> int: pass
@dec # type: ignore[misc]
@property
def h(self) -> int: pass
@dec # type: ignore[prop-decorator]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused ignores aren't caught here. You're missing @property.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doh!

@property
def i(self) -> int: pass
[builtins fixtures/property.pyi]
[out]

Expand Down
Loading