From f51090d053874aed0f3bfdb354e42f641296eaac Mon Sep 17 00:00:00 2001 From: Valentin Stanciu <250871+svalentin@users.noreply.github.com> Date: Wed, 4 Dec 2024 10:49:35 +0000 Subject: [PATCH] Make "deprecated" Note a standard Error, disabled by default (#18192) While working on the relase of mypy 1.14 we noticed a large number of notes for deprecated. Speaking with Jukka, he suggested we make this disabled by default. And if it's disabled by default, having it as a note is not as useful. We also don't have many stand alone notes. Most notes are "attached" with an error. This PR makes the deprecated error disabled by default and by default reports it as error when enabled. `--report-deprecated-as-note` can be used to report them as notes instead. --- docs/source/command_line.rst | 10 +- docs/source/error_code_list2.rst | 10 +- mypy/checker.py | 2 +- mypy/errorcodes.py | 1 + mypy/main.py | 4 +- mypy/options.py | 2 +- mypy/typeanal.py | 2 +- test-data/unit/check-deprecated.test | 226 ++++++++++++++------------- test-data/unit/fine-grained.test | 145 +++++++++-------- 9 files changed, 216 insertions(+), 186 deletions(-) diff --git a/docs/source/command_line.rst b/docs/source/command_line.rst index e65317331d55..1d91625084fd 100644 --- a/docs/source/command_line.rst +++ b/docs/source/command_line.rst @@ -541,12 +541,12 @@ potentially problematic or redundant in some way. This limitation will be removed in future releases of mypy. -.. option:: --report-deprecated-as-error +.. option:: --report-deprecated-as-note - By default, mypy emits notes if your code imports or uses deprecated - features. This flag converts such notes to errors, causing mypy to - eventually finish with a non-zero exit code. Features are considered - deprecated when decorated with ``warnings.deprecated``. + If error code ``deprecated`` is enabled, mypy emits errors if your code + imports or uses deprecated features. This flag converts such errors to + notes, causing mypy to eventually finish with a zero exit code. Features + are considered deprecated when decorated with ``warnings.deprecated``. .. _miscellaneous-strictness-flags: diff --git a/docs/source/error_code_list2.rst b/docs/source/error_code_list2.rst index eb18d76e2f2f..df8b696745fc 100644 --- a/docs/source/error_code_list2.rst +++ b/docs/source/error_code_list2.rst @@ -236,13 +236,13 @@ incorrect control flow or conditional checks that are accidentally always true o Check that imported or used feature is deprecated [deprecated] -------------------------------------------------------------- -By default, mypy generates a note if your code imports a deprecated feature explicitly with a +If you use :option:`--enable-error-code deprecated `, +mypy generates an error if your code imports a deprecated feature explicitly with a ``from mod import depr`` statement or uses a deprecated feature imported otherwise or defined locally. Features are considered deprecated when decorated with ``warnings.deprecated``, as -specified in `PEP 702 `_. You can silence single notes via -``# type: ignore[deprecated]`` or turn off this check completely via ``--disable-error-code=deprecated``. -Use the :option:`--report-deprecated-as-error ` option for -more strictness, which turns all such notes into errors. +specified in `PEP 702 `_. +Use the :option:`--report-deprecated-as-note ` option to +turn all such errors into notes. .. note:: diff --git a/mypy/checker.py b/mypy/checker.py index 1b11caf01f18..379da3f1c0da 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -7696,7 +7696,7 @@ def warn_deprecated(self, node: SymbolNode | None, context: Context) -> None: and ((deprecated := node.deprecated) is not None) and not self.is_typeshed_stub ): - warn = self.msg.fail if self.options.report_deprecated_as_error else self.msg.note + warn = self.msg.note if self.options.report_deprecated_as_note else self.msg.fail warn(deprecated, context, code=codes.DEPRECATED) diff --git a/mypy/errorcodes.py b/mypy/errorcodes.py index b835f27bbad9..5736be5c143e 100644 --- a/mypy/errorcodes.py +++ b/mypy/errorcodes.py @@ -308,6 +308,7 @@ def __hash__(self) -> int: "deprecated", "Warn when importing or using deprecated (overloaded) functions, methods or classes", "General", + default_enabled=False, ) # This copy will not include any error codes defined later in the plugins. diff --git a/mypy/main.py b/mypy/main.py index fb4a1f61a01d..7032682c9fd0 100644 --- a/mypy/main.py +++ b/mypy/main.py @@ -810,10 +810,10 @@ def add_invertible_flag( group=lint_group, ) add_invertible_flag( - "--report-deprecated-as-error", + "--report-deprecated-as-note", default=False, strict_flag=False, - help="Report importing or using deprecated features as errors instead of notes", + help="Report importing or using deprecated features as notes instead of errors", group=lint_group, ) diff --git a/mypy/options.py b/mypy/options.py index 561b23fec7d0..33a2c75d164e 100644 --- a/mypy/options.py +++ b/mypy/options.py @@ -177,7 +177,7 @@ def __init__(self) -> None: self.warn_return_any = False # Report importing or using deprecated features as errors instead of notes. - self.report_deprecated_as_error = False + self.report_deprecated_as_note = False # Warn about unused '# type: ignore' comments self.warn_unused_ignores = False diff --git a/mypy/typeanal.py b/mypy/typeanal.py index b7e7da17e209..2f85e83bb3c3 100644 --- a/mypy/typeanal.py +++ b/mypy/typeanal.py @@ -790,7 +790,7 @@ def check_and_warn_deprecated(self, info: TypeInfo, ctx: Context) -> None: if isinstance(imp, ImportFrom) and any(info.name == n[0] for n in imp.names): break else: - warn = self.fail if self.options.report_deprecated_as_error else self.note + warn = self.note if self.options.report_deprecated_as_note else self.fail warn(deprecated, ctx, code=codes.DEPRECATED) def analyze_type_with_type_info( diff --git a/test-data/unit/check-deprecated.test b/test-data/unit/check-deprecated.test index fbfdfcce5a14..8bbb887d4567 100644 --- a/test-data/unit/check-deprecated.test +++ b/test-data/unit/check-deprecated.test @@ -1,8 +1,7 @@ -- Type checker test cases for reporting deprecations. -[case testDeprecatedDisableNotes] -# flags: --disable-error-code=deprecated +[case testDeprecatedDisabled] from typing_extensions import deprecated @@ -15,7 +14,7 @@ f() [case testDeprecatedAsNoteWithErrorCode] -# flags: --show-error-codes +# flags: --enable-error-code=deprecated --show-error-codes --report-deprecated-as-note from typing_extensions import deprecated @@ -29,7 +28,7 @@ f() # N: function __main__.f is deprecated: use f2 instead [deprecated] [case testDeprecatedAsErrorWithErrorCode] -# flags: --report-deprecated-as-error --show-error-codes +# flags: --enable-error-code=deprecated --show-error-codes from typing_extensions import deprecated @@ -43,41 +42,43 @@ f() # E: function __main__.f is deprecated: use f2 instead [deprecated] [case testDeprecatedFunction] +# flags: --enable-error-code=deprecated from typing_extensions import deprecated @deprecated("use f2 instead") def f() -> None: ... -f # N: function __main__.f is deprecated: use f2 instead # type: ignore[deprecated] -f(1) # N: function __main__.f is deprecated: use f2 instead \ +f # E: function __main__.f is deprecated: use f2 instead # type: ignore[deprecated] +f(1) # E: function __main__.f is deprecated: use f2 instead \ # E: Too many arguments for "f" -f[1] # N: function __main__.f is deprecated: use f2 instead \ +f[1] # E: function __main__.f is deprecated: use f2 instead \ # E: Value of type "Callable[[], None]" is not indexable -g = f # N: function __main__.f is deprecated: use f2 instead +g = f # E: function __main__.f is deprecated: use f2 instead g() -t = (f, f, g) # N: function __main__.f is deprecated: use f2 instead +t = (f, f, g) # E: function __main__.f is deprecated: use f2 instead [builtins fixtures/tuple.pyi] [case testDeprecatedFunctionDifferentModule] +# flags: --enable-error-code=deprecated import m import p.s import m as n import p.s as ps -from m import f # N: function m.f is deprecated: use f2 instead -from p.s import g # N: function p.s.g is deprecated: use g2 instead +from m import f # E: function m.f is deprecated: use f2 instead +from p.s import g # E: function p.s.g is deprecated: use g2 instead from k import * -m.f() # N: function m.f is deprecated: use f2 instead -p.s.g() # N: function p.s.g is deprecated: use g2 instead -n.f() # N: function m.f is deprecated: use f2 instead -ps.g() # N: function p.s.g is deprecated: use g2 instead +m.f() # E: function m.f is deprecated: use f2 instead +p.s.g() # E: function p.s.g is deprecated: use g2 instead +n.f() # E: function m.f is deprecated: use f2 instead +ps.g() # E: function p.s.g is deprecated: use g2 instead f() g() -h() # N: function k.h is deprecated: use h2 instead +h() # E: function k.h is deprecated: use h2 instead [file m.py] from typing_extensions import deprecated @@ -101,6 +102,7 @@ def h() -> None: ... [case testDeprecatedClass] +# flags: --enable-error-code=deprecated from typing import Callable, List, Optional, Tuple, Union from typing_extensions import deprecated, TypeAlias, TypeVar @@ -108,65 +110,67 @@ from typing_extensions import deprecated, TypeAlias, TypeVar @deprecated("use C2 instead") class C: ... -c: C # N: class __main__.C is deprecated: use C2 instead -C() # N: class __main__.C is deprecated: use C2 instead -C.missing() # N: class __main__.C is deprecated: use C2 instead \ +c: C # E: class __main__.C is deprecated: use C2 instead +C() # E: class __main__.C is deprecated: use C2 instead +C.missing() # E: class __main__.C is deprecated: use C2 instead \ # E: "Type[C]" has no attribute "missing" -C.__init__(c) # N: class __main__.C is deprecated: use C2 instead -C(1) # N: class __main__.C is deprecated: use C2 instead \ +C.__init__(c) # E: class __main__.C is deprecated: use C2 instead +C(1) # E: class __main__.C is deprecated: use C2 instead \ # E: Too many arguments for "C" -D = C # N: class __main__.C is deprecated: use C2 instead +D = C # E: class __main__.C is deprecated: use C2 instead D() -t = (C, C, D) # N: class __main__.C is deprecated: use C2 instead +t = (C, C, D) # E: class __main__.C is deprecated: use C2 instead -u1: Union[C, int] = 1 # N: class __main__.C is deprecated: use C2 instead +u1: Union[C, int] = 1 # E: class __main__.C is deprecated: use C2 instead u1 = 1 -u2 = 1 # type: Union[C, int] # N: class __main__.C is deprecated: use C2 instead +u2 = 1 # type: Union[C, int] # E: class __main__.C is deprecated: use C2 instead u2 = 1 -c1 = c2 = C() # N: class __main__.C is deprecated: use C2 instead -i, c3 = 1, C() # N: class __main__.C is deprecated: use C2 instead +c1 = c2 = C() # E: class __main__.C is deprecated: use C2 instead +i, c3 = 1, C() # E: class __main__.C is deprecated: use C2 instead class E: ... -x1: Optional[C] # N: class __main__.C is deprecated: use C2 instead -x2: Union[D, C, E] # N: class __main__.C is deprecated: use C2 instead -x3: Union[D, Optional[C], E] # N: class __main__.C is deprecated: use C2 instead -x4: Tuple[D, C, E] # N: class __main__.C is deprecated: use C2 instead -x5: Tuple[Tuple[D, C], E] # N: class __main__.C is deprecated: use C2 instead -x6: List[C] # N: class __main__.C is deprecated: use C2 instead -x7: List[List[C]] # N: class __main__.C is deprecated: use C2 instead -x8: List[Optional[Tuple[Union[List[C], int]]]] # N: class __main__.C is deprecated: use C2 instead -x9: Callable[[int], C] # N: class __main__.C is deprecated: use C2 instead -x10: Callable[[int, C, int], int] # N: class __main__.C is deprecated: use C2 instead +x1: Optional[C] # E: class __main__.C is deprecated: use C2 instead +x2: Union[D, C, E] # E: class __main__.C is deprecated: use C2 instead +x3: Union[D, Optional[C], E] # E: class __main__.C is deprecated: use C2 instead +x4: Tuple[D, C, E] # E: class __main__.C is deprecated: use C2 instead +x5: Tuple[Tuple[D, C], E] # E: class __main__.C is deprecated: use C2 instead +x6: List[C] # E: class __main__.C is deprecated: use C2 instead +x7: List[List[C]] # E: class __main__.C is deprecated: use C2 instead +x8: List[Optional[Tuple[Union[List[C], int]]]] # E: class __main__.C is deprecated: use C2 instead +x9: Callable[[int], C] # E: class __main__.C is deprecated: use C2 instead +x10: Callable[[int, C, int], int] # E: class __main__.C is deprecated: use C2 instead T = TypeVar("T") -A1: TypeAlias = Optional[C] # N: class __main__.C is deprecated: use C2 instead +A1: TypeAlias = Optional[C] # E: class __main__.C is deprecated: use C2 instead x11: A1 -A2: TypeAlias = List[Union[A2, C]] # N: class __main__.C is deprecated: use C2 instead +A2: TypeAlias = List[Union[A2, C]] # E: class __main__.C is deprecated: use C2 instead x12: A2 A3: TypeAlias = List[Optional[T]] -x13: A3[C] # N: class __main__.C is deprecated: use C2 instead +x13: A3[C] # E: class __main__.C is deprecated: use C2 instead [builtins fixtures/tuple.pyi] [case testDeprecatedBaseClass] +# flags: --enable-error-code=deprecated from typing_extensions import deprecated @deprecated("use C2 instead") class C: ... -class D(C): ... # N: class __main__.C is deprecated: use C2 instead +class D(C): ... # E: class __main__.C is deprecated: use C2 instead class E(D): ... -class F(D, C): ... # N: class __main__.C is deprecated: use C2 instead +class F(D, C): ... # E: class __main__.C is deprecated: use C2 instead [builtins fixtures/tuple.pyi] [case testDeprecatedClassInTypeVar] +# flags: --enable-error-code=deprecated from typing import Generic, TypeVar from typing_extensions import deprecated @@ -175,11 +179,11 @@ class B: ... @deprecated("use C2 instead") class C: ... -T = TypeVar("T", bound=C) # N: class __main__.C is deprecated: use C2 instead +T = TypeVar("T", bound=C) # E: class __main__.C is deprecated: use C2 instead def f(x: T) -> T: ... class D(Generic[T]): ... -V = TypeVar("V", B, C) # N: class __main__.C is deprecated: use C2 instead +V = TypeVar("V", B, C) # E: class __main__.C is deprecated: use C2 instead def g(x: V) -> V: ... class E(Generic[V]): ... @@ -187,6 +191,7 @@ class E(Generic[V]): ... [case testDeprecatedClassInCast] +# flags: --enable-error-code=deprecated from typing import cast, Generic from typing_extensions import deprecated @@ -195,13 +200,14 @@ class B: ... @deprecated("use C2 instead") class C: ... -c = C() # N: class __main__.C is deprecated: use C2 instead +c = C() # E: class __main__.C is deprecated: use C2 instead b = cast(B, c) [builtins fixtures/tuple.pyi] [case testDeprecatedInstanceInFunctionDefinition] +# flags: --enable-error-code=deprecated from typing import Generic, List, Optional, TypeVar from typing_extensions import deprecated @@ -209,75 +215,76 @@ from typing_extensions import deprecated @deprecated("use C2 instead") class C: ... -def f1(c: C) -> None: # N: class __main__.C is deprecated: use C2 instead +def f1(c: C) -> None: # E: class __main__.C is deprecated: use C2 instead def g1() -> None: ... -def f2(c: List[Optional[C]]) -> None: # N: class __main__.C is deprecated: use C2 instead +def f2(c: List[Optional[C]]) -> None: # E: class __main__.C is deprecated: use C2 instead def g2() -> None: ... -def f3() -> C: # N: class __main__.C is deprecated: use C2 instead +def f3() -> C: # E: class __main__.C is deprecated: use C2 instead def g3() -> None: ... - return C() # N: class __main__.C is deprecated: use C2 instead + return C() # E: class __main__.C is deprecated: use C2 instead -def f4() -> List[Optional[C]]: # N: class __main__.C is deprecated: use C2 instead +def f4() -> List[Optional[C]]: # E: class __main__.C is deprecated: use C2 instead def g4() -> None: ... return [] def f5() -> None: - def g5(c: C) -> None: ... # N: class __main__.C is deprecated: use C2 instead + def g5(c: C) -> None: ... # E: class __main__.C is deprecated: use C2 instead def f6() -> None: - def g6() -> C: ... # N: class __main__.C is deprecated: use C2 instead + def g6() -> C: ... # E: class __main__.C is deprecated: use C2 instead @deprecated("use D2 instead") class D: - def f1(self, c: C) -> None: # N: class __main__.C is deprecated: use C2 instead + def f1(self, c: C) -> None: # E: class __main__.C is deprecated: use C2 instead def g1() -> None: ... - def f2(self, c: List[Optional[C]]) -> None: # N: class __main__.C is deprecated: use C2 instead + def f2(self, c: List[Optional[C]]) -> None: # E: class __main__.C is deprecated: use C2 instead def g2() -> None: ... def f3(self) -> None: - def g3(c: C) -> None: ... # N: class __main__.C is deprecated: use C2 instead + def g3(c: C) -> None: ... # E: class __main__.C is deprecated: use C2 instead def f4(self) -> None: - def g4() -> C: ... # N: class __main__.C is deprecated: use C2 instead + def g4() -> C: ... # E: class __main__.C is deprecated: use C2 instead T = TypeVar("T") @deprecated("use E2 instead") class E(Generic[T]): - def f1(self: E[C]) -> None: ... # N: class __main__.C is deprecated: use C2 instead - def f2(self, e: E[C]) -> None: ... # N: class __main__.C is deprecated: use C2 instead - def f3(self) -> E[C]: ... # N: class __main__.C is deprecated: use C2 instead + def f1(self: E[C]) -> None: ... # E: class __main__.C is deprecated: use C2 instead + def f2(self, e: E[C]) -> None: ... # E: class __main__.C is deprecated: use C2 instead + def f3(self) -> E[C]: ... # E: class __main__.C is deprecated: use C2 instead [builtins fixtures/tuple.pyi] [case testDeprecatedClassDifferentModule] +# flags: --enable-error-code=deprecated import m import p.s import m as n import p.s as ps -from m import B, C # N: class m.B is deprecated: use B2 instead \ - # N: class m.C is deprecated: use C2 instead -from p.s import D # N: class p.s.D is deprecated: use D2 instead +from m import B, C # E: class m.B is deprecated: use B2 instead \ + # E: class m.C is deprecated: use C2 instead +from p.s import D # E: class p.s.D is deprecated: use D2 instead from k import * -m.C() # N: class m.C is deprecated: use C2 instead -p.s.D() # N: class p.s.D is deprecated: use D2 instead -n.C() # N: class m.C is deprecated: use C2 instead -ps.D() # N: class p.s.D is deprecated: use D2 instead +m.C() # E: class m.C is deprecated: use C2 instead +p.s.D() # E: class p.s.D is deprecated: use D2 instead +n.C() # E: class m.C is deprecated: use C2 instead +ps.D() # E: class p.s.D is deprecated: use D2 instead C() D() -E() # N: class k.E is deprecated: use E2 instead +E() # E: class k.E is deprecated: use E2 instead -x1: m.A # N: class m.A is deprecated: use A2 instead -x2: m.A = m.A() # N: class m.A is deprecated: use A2 instead +x1: m.A # E: class m.A is deprecated: use A2 instead +x2: m.A = m.A() # E: class m.A is deprecated: use A2 instead y1: B y2: B = B() @@ -309,6 +316,7 @@ class E: ... [case testDeprecatedClassInitMethod] +# flags: --enable-error-code=deprecated from typing_extensions import deprecated @@ -316,14 +324,15 @@ from typing_extensions import deprecated class C: def __init__(self) -> None: ... -c: C # N: class __main__.C is deprecated: use C2 instead -C() # N: class __main__.C is deprecated: use C2 instead -C.__init__(c) # N: class __main__.C is deprecated: use C2 instead +c: C # E: class __main__.C is deprecated: use C2 instead +C() # E: class __main__.C is deprecated: use C2 instead +C.__init__(c) # E: class __main__.C is deprecated: use C2 instead [builtins fixtures/tuple.pyi] [case testDeprecatedSpecialMethods] +# flags: --enable-error-code=deprecated from typing import Iterator from typing_extensions import deprecated @@ -356,19 +365,20 @@ class B: a = A() b = B() -a + 1 # N: function __main__.A.__add__ is deprecated: no A + int -1 + a # N: function __main__.A.__radd__ is deprecated: no int + A -a += 1 # N: function __main__.A.__iadd__ is deprecated: no A = A + int -for i in a: # N: function __main__.A.__iter__ is deprecated: no iteration +a + 1 # E: function __main__.A.__add__ is deprecated: no A + int +1 + a # E: function __main__.A.__radd__ is deprecated: no int + A +a += 1 # E: function __main__.A.__iadd__ is deprecated: no A = A + int +for i in a: # E: function __main__.A.__iter__ is deprecated: no iteration reveal_type(i) # N: Revealed type is "builtins.int" -1 in a # N: function __main__.A.__contains__ is deprecated: no in -1 in b # N: function __main__.B.__contains__ is deprecated: still no in -~a # N: function __main__.A.__invert__ is deprecated: no inversion +1 in a # E: function __main__.A.__contains__ is deprecated: no in +1 in b # E: function __main__.B.__contains__ is deprecated: still no in +~a # E: function __main__.A.__invert__ is deprecated: no inversion [builtins fixtures/tuple.pyi] [case testDeprecatedOverloadedSpecialMethods] +# flags: --enable-error-code=deprecated from typing import Iterator, Union from typing_extensions import deprecated, overload @@ -396,17 +406,18 @@ class A: def __iadd__(self, v: Union[int, str]) -> A: ... a = A() -a + 1 # N: overload def (__main__.A, builtins.int) of function __main__.A.__add__ is deprecated: no A + int +a + 1 # E: overload def (__main__.A, builtins.int) of function __main__.A.__add__ is deprecated: no A + int a + "x" 1 + a -"x" + a # N: overload def (__main__.A, builtins.str) of function __main__.A.__radd__ is deprecated: no str + A -a += 1 # N: function __main__.A.__iadd__ is deprecated: no A += Any -a += "x" # N: function __main__.A.__iadd__ is deprecated: no A += Any +"x" + a # E: overload def (__main__.A, builtins.str) of function __main__.A.__radd__ is deprecated: no str + A +a += 1 # E: function __main__.A.__iadd__ is deprecated: no A += Any +a += "x" # E: function __main__.A.__iadd__ is deprecated: no A += Any [builtins fixtures/tuple.pyi] [case testDeprecatedMethod] +# flags: --enable-error-code=deprecated from typing_extensions import deprecated @@ -424,23 +435,24 @@ class C: @staticmethod def k() -> None: ... -C.f # N: function __main__.C.f is deprecated: use g instead -C().f # N: function __main__.C.f is deprecated: use g instead -C().f() # N: function __main__.C.f is deprecated: use g instead -C().f(1) # N: function __main__.C.f is deprecated: use g instead \ +C.f # E: function __main__.C.f is deprecated: use g instead +C().f # E: function __main__.C.f is deprecated: use g instead +C().f() # E: function __main__.C.f is deprecated: use g instead +C().f(1) # E: function __main__.C.f is deprecated: use g instead \ # E: Too many arguments for "f" of "C" -f = C().f # N: function __main__.C.f is deprecated: use g instead +f = C().f # E: function __main__.C.f is deprecated: use g instead f() -t = (C.f, C.f, C.g) # N: function __main__.C.f is deprecated: use g instead +t = (C.f, C.f, C.g) # E: function __main__.C.f is deprecated: use g instead C().g() -C().h() # N: function __main__.C.h is deprecated: use g instead -C().k() # N: function __main__.C.k is deprecated: use g instead +C().h() # E: function __main__.C.h is deprecated: use g instead +C().k() # E: function __main__.C.k is deprecated: use g instead [builtins fixtures/callable.pyi] [case testDeprecatedClassWithDeprecatedMethod] +# flags: --enable-error-code=deprecated from typing_extensions import deprecated @@ -450,14 +462,15 @@ class C: def f(self) -> None: ... def g(self) -> None: ... -C().f() # N: class __main__.C is deprecated: use D instead \ - # N: function __main__.C.f is deprecated: use g instead -C().g() # N: class __main__.C is deprecated: use D instead +C().f() # E: class __main__.C is deprecated: use D instead \ + # E: function __main__.C.f is deprecated: use g instead +C().g() # E: class __main__.C is deprecated: use D instead [builtins fixtures/callable.pyi] [case testDeprecatedProperty] +# flags: --enable-error-code=deprecated from typing_extensions import deprecated @@ -473,24 +486,25 @@ class C: def g(self, v: int) -> None: ... -C.f # N: function __main__.C.f is deprecated: use f2 instead -C().f # N: function __main__.C.f is deprecated: use f2 instead -C().f() # N: function __main__.C.f is deprecated: use f2 instead \ +C.f # E: function __main__.C.f is deprecated: use f2 instead +C().f # E: function __main__.C.f is deprecated: use f2 instead +C().f() # E: function __main__.C.f is deprecated: use f2 instead \ # E: "int" not callable -C().f = 1 # N: function __main__.C.f is deprecated: use f2 instead \ +C().f = 1 # E: function __main__.C.f is deprecated: use f2 instead \ # E: Property "f" defined in "C" is read-only C.g C().g -C().g = 1 # N: function __main__.C.g is deprecated: use g2 instead -C().g = "x" # N: function __main__.C.g is deprecated: use g2 instead \ +C().g = 1 # E: function __main__.C.g is deprecated: use g2 instead +C().g = "x" # E: function __main__.C.g is deprecated: use g2 instead \ # E: Incompatible types in assignment (expression has type "str", variable has type "int") [builtins fixtures/property.pyi] [case testDeprecatedOverloadedFunction] +# flags: --enable-error-code=deprecated from typing import Union from typing_extensions import deprecated, overload @@ -502,10 +516,10 @@ def f(x: str) -> str: ... @deprecated("use f2 instead") def f(x: Union[int, str]) -> Union[int, str]: ... -f # N: function __main__.f is deprecated: use f2 instead -f(1) # N: function __main__.f is deprecated: use f2 instead -f("x") # N: function __main__.f is deprecated: use f2 instead -f(1.0) # N: function __main__.f is deprecated: use f2 instead \ +f # E: function __main__.f is deprecated: use f2 instead +f(1) # E: function __main__.f is deprecated: use f2 instead +f("x") # E: function __main__.f is deprecated: use f2 instead +f(1.0) # E: function __main__.f is deprecated: use f2 instead \ # E: No overload variant of "f" matches argument type "float" \ # N: Possible overload variants: \ # N: def f(x: int) -> int \ @@ -519,7 +533,7 @@ def g(x: str) -> str: ... def g(x: Union[int, str]) -> Union[int, str]: ... g -g(1) # N: overload def (x: builtins.int) -> builtins.int of function __main__.g is deprecated: work with str instead +g(1) # E: overload def (x: builtins.int) -> builtins.int of function __main__.g is deprecated: work with str instead g("x") g(1.0) # E: No overload variant of "g" matches argument type "float" \ # N: Possible overload variants: \ @@ -535,7 +549,7 @@ def h(x: Union[int, str]) -> Union[int, str]: ... h h(1) -h("x") # N: overload def (x: builtins.str) -> builtins.str of function __main__.h is deprecated: work with int instead +h("x") # E: overload def (x: builtins.str) -> builtins.str of function __main__.h is deprecated: work with int instead h(1.0) # E: No overload variant of "h" matches argument type "float" \ # N: Possible overload variants: \ # N: def h(x: int) -> int \ diff --git a/test-data/unit/fine-grained.test b/test-data/unit/fine-grained.test index f30f1e232364..9ff8a37ae9ae 100644 --- a/test-data/unit/fine-grained.test +++ b/test-data/unit/fine-grained.test @@ -10682,6 +10682,8 @@ main:4: error: Incompatible types in assignment (expression has type "f", variab [case testDeprecatedAddKeepChangeAndRemoveFunctionDeprecation] +# flags: --enable-error-code=deprecated + from a import f f() import a @@ -10711,18 +10713,19 @@ def f() -> None: ... [builtins fixtures/tuple.pyi] [out] == -main:1: note: function a.f is deprecated: use f2 instead -main:4: note: function a.f is deprecated: use f2 instead +main:3: error: function a.f is deprecated: use f2 instead +main:6: error: function a.f is deprecated: use f2 instead == -main:1: note: function a.f is deprecated: use f2 instead -main:4: note: function a.f is deprecated: use f2 instead +main:3: error: function a.f is deprecated: use f2 instead +main:6: error: function a.f is deprecated: use f2 instead == -main:1: note: function a.f is deprecated: use f3 instead -main:4: note: function a.f is deprecated: use f3 instead +main:3: error: function a.f is deprecated: use f3 instead +main:6: error: function a.f is deprecated: use f3 instead == [case testDeprecatedRemoveFunctionDeprecation] +# flags: --enable-error-code=deprecated from a import f f() import a @@ -10738,11 +10741,12 @@ def f() -> None: ... [builtins fixtures/tuple.pyi] [out] -main:1: note: function a.f is deprecated: use f2 instead -main:4: note: function a.f is deprecated: use f2 instead +main:2: error: function a.f is deprecated: use f2 instead +main:5: error: function a.f is deprecated: use f2 instead == [case testDeprecatedKeepFunctionDeprecation] +# flags: --enable-error-code=deprecated from a import f f() import a @@ -10760,14 +10764,15 @@ def f() -> None: ... [builtins fixtures/tuple.pyi] [out] -main:1: note: function a.f is deprecated: use f2 instead -main:4: note: function a.f is deprecated: use f2 instead +main:2: error: function a.f is deprecated: use f2 instead +main:5: error: function a.f is deprecated: use f2 instead == -main:1: note: function a.f is deprecated: use f2 instead -main:4: note: function a.f is deprecated: use f2 instead +main:2: error: function a.f is deprecated: use f2 instead +main:5: error: function a.f is deprecated: use f2 instead [case testDeprecatedAddFunctionDeprecationIndirectImport] +# flags: --enable-error-code=deprecated from b import f f() import b @@ -10787,12 +10792,13 @@ def f() -> int: ... [builtins fixtures/tuple.pyi] [out] == -b.py:1: note: function a.f is deprecated: use f2 instead -main:1: note: function a.f is deprecated: use f2 instead -main:4: note: function a.f is deprecated: use f2 instead +b.py:1: error: function a.f is deprecated: use f2 instead +main:2: error: function a.f is deprecated: use f2 instead +main:5: error: function a.f is deprecated: use f2 instead [case testDeprecatedChangeFunctionDeprecationIndirectImport] +# flags: --enable-error-code=deprecated from b import f f() import b @@ -10813,15 +10819,16 @@ def f() -> int: ... [builtins fixtures/tuple.pyi] [out] -b.py:1: note: function a.f is deprecated: use f1 instead -main:1: note: function a.f is deprecated: use f1 instead -main:4: note: function a.f is deprecated: use f1 instead +b.py:1: error: function a.f is deprecated: use f1 instead +main:2: error: function a.f is deprecated: use f1 instead +main:5: error: function a.f is deprecated: use f1 instead == -b.py:1: note: function a.f is deprecated: use f2 instead -main:1: note: function a.f is deprecated: use f2 instead -main:4: note: function a.f is deprecated: use f2 instead +b.py:1: error: function a.f is deprecated: use f2 instead +main:2: error: function a.f is deprecated: use f2 instead +main:5: error: function a.f is deprecated: use f2 instead [case testDeprecatedRemoveFunctionDeprecationIndirectImport] +# flags: --enable-error-code=deprecated from b import f f() import b @@ -10840,13 +10847,14 @@ def f() -> int: ... [builtins fixtures/tuple.pyi] [out] -b.py:1: note: function a.f is deprecated: use f1 instead -main:1: note: function a.f is deprecated: use f1 instead -main:4: note: function a.f is deprecated: use f1 instead +b.py:1: error: function a.f is deprecated: use f1 instead +main:2: error: function a.f is deprecated: use f1 instead +main:5: error: function a.f is deprecated: use f1 instead == [case testDeprecatedFunctionAlreadyDecorated1-only_when_cache] +# flags: --enable-error-code=deprecated from b import f x: str = f() import b @@ -10876,12 +10884,13 @@ def f() -> str: ... [builtins fixtures/tuple.pyi] [out] == -b.py:1: note: function a.f is deprecated: deprecated decorated function -main:1: note: function a.f is deprecated: deprecated decorated function -main:4: note: function a.f is deprecated: deprecated decorated function +b.py:1: error: function a.f is deprecated: deprecated decorated function +main:2: error: function a.f is deprecated: deprecated decorated function +main:5: error: function a.f is deprecated: deprecated decorated function [case testDeprecatedFunctionAlreadyDecorated2-only_when_nocache] +# flags: --enable-error-code=deprecated from b import f x: str = f() import b @@ -10911,12 +10920,13 @@ def f() -> str: ... [builtins fixtures/tuple.pyi] [out] == -main:1: note: function a.f is deprecated: deprecated decorated function -main:4: note: function a.f is deprecated: deprecated decorated function -b.py:1: note: function a.f is deprecated: deprecated decorated function +main:2: error: function a.f is deprecated: deprecated decorated function +main:5: error: function a.f is deprecated: deprecated decorated function +b.py:1: error: function a.f is deprecated: deprecated decorated function [case testDeprecatedAddClassDeprecationIndirectImport1-only_when_cache] +# flags: --enable-error-code=deprecated from b import C x: C C() @@ -10944,14 +10954,15 @@ class D: ... [builtins fixtures/tuple.pyi] [out] == -b.py:1: note: class a.C is deprecated: use C2 instead -b.py:2: note: class a.D is deprecated: use D2 instead -main:1: note: class a.C is deprecated: use C2 instead -main:5: note: class a.D is deprecated: use D2 instead -main:6: note: class a.D is deprecated: use D2 instead +b.py:1: error: class a.C is deprecated: use C2 instead +b.py:2: error: class a.D is deprecated: use D2 instead +main:2: error: class a.C is deprecated: use C2 instead +main:6: error: class a.D is deprecated: use D2 instead +main:7: error: class a.D is deprecated: use D2 instead [case testDeprecatedAddClassDeprecationIndirectImport2-only_when_nocache] +# flags: --enable-error-code=deprecated from b import C x: C C() @@ -10979,14 +10990,15 @@ class D: ... [builtins fixtures/tuple.pyi] [out] == -main:1: note: class a.C is deprecated: use C2 instead -main:5: note: class a.D is deprecated: use D2 instead -main:6: note: class a.D is deprecated: use D2 instead -b.py:1: note: class a.C is deprecated: use C2 instead -b.py:2: note: class a.D is deprecated: use D2 instead +main:2: error: class a.C is deprecated: use C2 instead +main:6: error: class a.D is deprecated: use D2 instead +main:7: error: class a.D is deprecated: use D2 instead +b.py:1: error: class a.C is deprecated: use C2 instead +b.py:2: error: class a.D is deprecated: use D2 instead [case testDeprecatedChangeClassDeprecationIndirectImport] +# flags: --enable-error-code=deprecated from b import C x: C C() @@ -11017,20 +11029,21 @@ class D: ... [builtins fixtures/tuple.pyi] [out] -b.py:1: note: class a.C is deprecated: use C1 instead -b.py:2: note: class a.D is deprecated: use D1 instead -main:1: note: class a.C is deprecated: use C1 instead -main:5: note: class a.D is deprecated: use D1 instead -main:6: note: class a.D is deprecated: use D1 instead +b.py:1: error: class a.C is deprecated: use C1 instead +b.py:2: error: class a.D is deprecated: use D1 instead +main:2: error: class a.C is deprecated: use C1 instead +main:6: error: class a.D is deprecated: use D1 instead +main:7: error: class a.D is deprecated: use D1 instead == -b.py:1: note: class a.C is deprecated: use C2 instead -b.py:2: note: class a.D is deprecated: use D2 instead -main:1: note: class a.C is deprecated: use C2 instead -main:5: note: class a.D is deprecated: use D2 instead -main:6: note: class a.D is deprecated: use D2 instead +b.py:1: error: class a.C is deprecated: use C2 instead +b.py:2: error: class a.D is deprecated: use D2 instead +main:2: error: class a.C is deprecated: use C2 instead +main:6: error: class a.D is deprecated: use D2 instead +main:7: error: class a.D is deprecated: use D2 instead [case testDeprecatedRemoveClassDeprecationIndirectImport] +# flags: --enable-error-code=deprecated from b import C x: C C() @@ -11056,15 +11069,16 @@ class D: ... [builtins fixtures/tuple.pyi] [out] -b.py:1: note: class a.C is deprecated: use C1 instead -b.py:2: note: class a.D is deprecated: use D1 instead -main:1: note: class a.C is deprecated: use C1 instead -main:5: note: class a.D is deprecated: use D1 instead -main:6: note: class a.D is deprecated: use D1 instead +b.py:1: error: class a.C is deprecated: use C1 instead +b.py:2: error: class a.D is deprecated: use D1 instead +main:2: error: class a.C is deprecated: use C1 instead +main:6: error: class a.D is deprecated: use D1 instead +main:7: error: class a.D is deprecated: use D1 instead == [case testDeprecatedAddClassDeprecationIndirectImportAlreadyDecorated1-only_when_cache] +# flags: --enable-error-code=deprecated from b import C x: C C() @@ -11099,14 +11113,15 @@ class D: ... [builtins fixtures/tuple.pyi] [out] == -b.py:1: note: class a.C is deprecated: use C2 instead -b.py:2: note: class a.D is deprecated: use D2 instead -main:1: note: class a.C is deprecated: use C2 instead -main:5: note: class a.D is deprecated: use D2 instead -main:6: note: class a.D is deprecated: use D2 instead +b.py:1: error: class a.C is deprecated: use C2 instead +b.py:2: error: class a.D is deprecated: use D2 instead +main:2: error: class a.C is deprecated: use C2 instead +main:6: error: class a.D is deprecated: use D2 instead +main:7: error: class a.D is deprecated: use D2 instead [case testDeprecatedAddClassDeprecationIndirectImportAlreadyDecorated2-only_when_nocache] +# flags: --enable-error-code=deprecated from b import C x: C C() @@ -11141,8 +11156,8 @@ class D: ... [builtins fixtures/tuple.pyi] [out] == -main:1: note: class a.C is deprecated: use C2 instead -main:5: note: class a.D is deprecated: use D2 instead -main:6: note: class a.D is deprecated: use D2 instead -b.py:1: note: class a.C is deprecated: use C2 instead -b.py:2: note: class a.D is deprecated: use D2 instead +main:2: error: class a.C is deprecated: use C2 instead +main:6: error: class a.D is deprecated: use D2 instead +main:7: error: class a.D is deprecated: use D2 instead +b.py:1: error: class a.C is deprecated: use C2 instead +b.py:2: error: class a.D is deprecated: use D2 instead