Repository navigation
fix deprecated - false negative on usage of deprecated class #5170 - #5175
asukaminato0721 wants to merge 11 commits into
Conversation
|
This pull request has been imported. If you are a Meta employee, you can view this in D124324453. (Because this pull request was imported automatically, there will not be any future comments.) |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
Hey @asukaminato0721, thanks for picking this up! It looks like there are some CI errors right now. I think we may need to add a filter to skip these errors on typeshed, since it looks like they're showing up in the scrut tests. |
This comment has been minimized.
This comment has been minimized.
connernilsen
left a comment
There was a problem hiding this comment.
Thanks for fixing the test! I have a few more requests. Sorry, my previous comment was a little misguided on how to fix the test
c885903 to
4c4a4a6
Compare
This comment has been minimized.
This comment has been minimized.
connernilsen
left a comment
There was a problem hiding this comment.
Just a few more requests :)
| if let Type::ClassDef(cls) = ty | ||
| && cls.module_path() == self.module().path() | ||
| && let Some(class_idx) = self.bindings().enclosing_class(range) | ||
| && let BindingClass::ClassDef(binding) = self.bindings().get(class_idx) | ||
| && binding.def_index == cls.index() | ||
| { | ||
| // References inside the defining class are part of its implementation. |
There was a problem hiding this comment.
This logic only records exemptions for this error inside the class body, but bases, decorators, and type params are outside of the body, so they'll error on the class definition.
Can we add tests to make sure this doesn't happen, and if it does, fix it?
Example:
@deprecated("x")
class Old(Base["Old"]): ...
class Old[T: "Old"]: ...
| pub def_index: ClassDefIndex, | ||
| pub parent: NestingContext, | ||
| pub is_protocol: bool, | ||
| pub deprecation: Option<Deprecation>, |
There was a problem hiding this comment.
nit: can we change this to an Option<Box<Deprecation>> instead? This should bring it down from 13 words to 11
| instance = OldClass() # E: Use NewClass instead | ||
| instance.method() | ||
| alias = OldClass # E: `OldClass` is deprecated | ||
| alias() # E: `OldClass` is deprecated |
There was a problem hiding this comment.
Alias is already flagged on the previous line. Is this intended? I think this is reasonable, but what about
(x := OldClass) # might warn twice
class X:
def foo(self) -> OldClass:
...
X().foo() # this would likely warn
I think we'd at least want to guard against the walrus case, but whether or not we want to handle all of them is up to you
| "#, | ||
| ); | ||
|
|
||
| testcase!( |
There was a problem hiding this comment.
It might be worth adding these tests:
(note, test_deprecated_class_and_init might have a second error)
testcase!(
test_deprecated_class_header_and_nested,
r#"
from warnings import deprecated
class Base[T]: ...
@deprecated("x")
class Old(Base["Old"]): # no error: the class's own header
class Inner:
def f(self) -> "Old": ... # no error: nested inside Old
@deprecated("x")
class Bounded[T: "Bounded"]: ... # no error: its own type parameter bound
"#,
);
testcase!(
test_deprecated_class_annotation_forms,
r#"
from warnings import deprecated
@deprecated("x")
class Old: ...
def f(a: Old | None, b: type[Old], c: object) -> None: # E: `Old` is deprecated # E: `Old` is deprecated
if isinstance(c, Old): # E: `Old` is deprecated
pass
try:
pass
except Exception as e:
pass
"#,
);
testcase!(
test_deprecated_class_and_init,
r#"
from warnings import deprecated
@deprecated("class")
class Old:
@deprecated("init")
def __init__(self) -> None: ...
Old() # E: `Old` is deprecated
"#,
);
testcase!(
test_deprecated_class_qualified_decorator,
r#"
import typing_extensions
import dataclasses, enum, typing
@typing_extensions.deprecated("x")
class A: ...
@typing_extensions.deprecated("x")
@dataclasses.dataclass
class D:
x: int
@typing_extensions.deprecated("x")
class E(enum.Enum):
X = 1
@typing_extensions.deprecated("x")
class P(typing.Protocol): ...
A() # E: `A` is deprecated
D(1) # E: `D` is deprecated
E.X # E: `E` is deprecated
def g(p: P) -> None: ... # E: `P` is deprecated
"#,
);
|
Diff from mypy_primer, showing the effect of this PR on open source code: ============================================================
SUMMARY
============================================================
Total: +100 new errors, -2 fixed errors
By preset: +100/-0 (default), +100/-0 (strict)
Projects with changes (17):
openlibrary: +1 -0
mitmproxy: +6 -0
scipy-stubs: +5 -0
spark: +3 -0
scikit-learn: +29 -0
scikit-build-core: +1 -0
manticore: +2 -0
mongo-python-driver: +2 -0
strawberry: +3 -0
Tanjun: +5 -0
static-frame: +3 -0
mypy: +28 -2
meson: +1 -0
pyodide: +2 -0
parso: +2 -0
pydantic: +4 -0
PyGithub: +3 -0
============================================================
FULL DIFF DETAILS
------------------------------------------------------------
openlibrary (https://github.com/internetarchive/openlibrary)
+ ERROR openlibrary/tests/fastapi/test_account_loans.py:123:31-64: `openlibrary.plugins.upstream.account.account_loans_json` is deprecated [deprecated]
mitmproxy (https://github.com/mitmproxy/mitmproxy)
+ ERROR docs/src/examples/contrib/check_ssl_pinning.py:57:14-42: `OpenSSL.crypto.X509Extension` is deprecated [deprecated]
+ ERROR examples/contrib/check_ssl_pinning.py:57:14-42: `OpenSSL.crypto.X509Extension` is deprecated [deprecated]
+ ERROR mitmproxy/contentviews/__init__.py:168:32-36: `mitmproxy.contentviews.base.View` is deprecated [deprecated]
+ ERROR mitmproxy/contentviews/_compat.py:60:37-41: `mitmproxy.contentviews.base.View` is deprecated [deprecated]
+ ERROR mitmproxy/contentviews/_compat.py:73:18-22: `mitmproxy.contentviews.base.View` is deprecated [deprecated]
+ ERROR test/mitmproxy/contentviews/test__compat.py:10:20-24: `mitmproxy.contentviews.base.View` is deprecated [deprecated]
scipy-stubs (https://github.com/scipy/scipy-stubs)
+ ERROR scipy-stubs/interpolate/interpolate.pyi:51:16-37: `scipy.interpolate._interpolate.interp2d` is deprecated [deprecated]
+ ERROR scipy-stubs/io/arff/arffread.pyi:16:22-31: `ArffError` is deprecated [deprecated]
+ ERROR scipy-stubs/io/matlab/mio5.pyi:24:22-34: `MatlabObject` is deprecated [deprecated]
+ ERROR scipy-stubs/optimize/minpack.pyi:40:6-20: `OptimizeResult` is deprecated [deprecated]
+ ERROR tests/interpolate/test_interpolate.pyi:97:22-30: `scipy.interpolate._interpolate.interp2d` is deprecated [deprecated]
spark (https://github.com/apache/spark)
+ ERROR python/pyspark/cloudpickle/cloudpickle.py:1249:21-44: `abc.abstractclassmethod` is deprecated [deprecated]
+ ERROR python/pyspark/cloudpickle/cloudpickle.py:1250:21-45: `abc.abstractstaticmethod` is deprecated [deprecated]
+ ERROR python/pyspark/cloudpickle/cloudpickle.py:1251:21-41: `abc.abstractproperty` is deprecated [deprecated]
scikit-learn (https://github.com/scikit-learn/scikit-learn)
+ ERROR sklearn/linear_model/tests/test_common.py:191:9-35: `sklearn.linear_model._passive_aggressive.PassiveAggressiveRegressor` is deprecated [deprecated]
+ ERROR sklearn/linear_model/tests/test_common.py:231:10-37: `sklearn.linear_model._passive_aggressive.PassiveAggressiveClassifier` is deprecated [deprecated]
+ ERROR sklearn/linear_model/tests/test_passive_aggressive.py:93:11-38: `sklearn.linear_model._passive_aggressive.PassiveAggressiveClassifier` is deprecated [deprecated]
+ ERROR sklearn/linear_model/tests/test_passive_aggressive.py:117:11-38: `sklearn.linear_model._passive_aggressive.PassiveAggressiveClassifier` is deprecated [deprecated]
+ ERROR sklearn/linear_model/tests/test_passive_aggressive.py:132:11-38: `sklearn.linear_model._passive_aggressive.PassiveAggressiveClassifier` is deprecated [deprecated]
+ ERROR sklearn/linear_model/tests/test_passive_aggressive.py:151:12-39: `sklearn.linear_model._passive_aggressive.PassiveAggressiveClassifier` is deprecated [deprecated]
+ ERROR sklearn/linear_model/tests/test_passive_aggressive.py:162:11-38: `sklearn.linear_model._passive_aggressive.PassiveAggressiveClassifier` is deprecated [deprecated]
+ ERROR sklearn/linear_model/tests/test_passive_aggressive.py:173:11-38: `sklearn.linear_model._passive_aggressive.PassiveAggressiveClassifier` is deprecated [deprecated]
+ ERROR sklearn/linear_model/tests/test_passive_aggressive.py:180:11-38: `sklearn.linear_model._passive_aggressive.PassiveAggressiveClassifier` is deprecated [deprecated]
+ ERROR sklearn/linear_model/tests/test_passive_aggressive.py:193:11-38: `sklearn.linear_model._passive_aggressive.PassiveAggressiveClassifier` is deprecated [deprecated]
+ ERROR sklearn/linear_model/tests/test_passive_aggressive.py:202:11-38: `sklearn.linear_model._passive_aggressive.PassiveAggressiveClassifier` is deprecated [deprecated]
+ ERROR sklearn/linear_model/tests/test_passive_aggressive.py:206:20-47: `sklearn.linear_model._passive_aggressive.PassiveAggressiveClassifier` is deprecated [deprecated]
+ ERROR sklearn/linear_model/tests/test_passive_aggressive.py:209:20-47: `sklearn.linear_model._passive_aggressive.PassiveAggressiveClassifier` is deprecated [deprecated]
+ ERROR sklearn/linear_model/tests/test_passive_aggressive.py:225:11-38: `sklearn.linear_model._passive_aggressive.PassiveAggressiveClassifier` is deprecated [deprecated]
+ ERROR sklearn/linear_model/tests/test_passive_aggressive.py:239:11-37: `sklearn.linear_model._passive_aggressive.PassiveAggressiveRegressor` is deprecated [deprecated]
+ ERROR sklearn/linear_model/tests/test_passive_aggressive.py:264:11-37: `sklearn.linear_model._passive_aggressive.PassiveAggressiveRegressor` is deprecated [deprecated]
+ ERROR sklearn/linear_model/tests/test_passive_aggressive.py:288:12-38: `sklearn.linear_model._passive_aggressive.PassiveAggressiveRegressor` is deprecated [deprecated]
+ ERROR sklearn/linear_model/tests/test_passive_aggressive.py:296:11-37: `sklearn.linear_model._passive_aggressive.PassiveAggressiveRegressor` is deprecated [deprecated]
+ ERROR sklearn/linear_model/tests/test_passive_aggressive.py:303:19-46: `sklearn.linear_model._passive_aggressive.PassiveAggressiveClassifier` is deprecated [deprecated]
+ ERROR sklearn/linear_model/tests/test_passive_aggressive.py:303:48-74: `sklearn.linear_model._passive_aggressive.PassiveAggressiveRegressor` is deprecated [deprecated]
+ ERROR sklearn/linear_model/tests/test_passive_aggressive.py:318:10-37: `sklearn.linear_model._passive_aggressive.PassiveAggressiveClassifier` is deprecated [deprecated]
+ ERROR sklearn/linear_model/tests/test_passive_aggressive.py:334:10-36: `sklearn.linear_model._passive_aggressive.PassiveAggressiveRegressor` is deprecated [deprecated]
+ ERROR sklearn/utils/_test_common/instance_generator.py:402:5-32: `sklearn.linear_model._passive_aggressive.PassiveAggressiveClassifier` is deprecated [deprecated]
+ ERROR sklearn/utils/_test_common/instance_generator.py:403:5-31: `sklearn.linear_model._passive_aggressive.PassiveAggressiveRegressor` is deprecated [deprecated]
+ ERROR sklearn/utils/tests/test_deprecation.py:40:18-28: `MockClass1` is deprecated [deprecated]
+ ERROR sklearn/utils/tests/test_deprecation.py:63:9-19: `MockClass1` is deprecated [deprecated]
+ ERROR sklearn/utils/tests/test_deprecation.py:71:9-19: `MockClass6` is deprecated [deprecated]
+ ERROR sklearn/utils/tests/test_deprecation.py:80:27-37: `MockClass1` is deprecated [deprecated]
+ ERROR sklearn/utils/tests/test_deprecation.py:98:27-36: `test_deprecated_class_signature.MockClass` is deprecated [deprecated]
scikit-build-core (https://github.com/scikit-build/scikit-build-core)
+ ERROR src/scikit_build_core/_compat/importlib/metadata.py:29:31-47: `importlib.metadata.SelectableGroups` is deprecated [deprecated]
manticore (https://github.com/trailofbits/manticore)
+ ERROR tests/wasm/json2mc.py:8:38-55: `argparse.FileType` is deprecated [deprecated]
+ ERROR tests/wasm_sym/json2smc.py:8:38-55: `argparse.FileType` is deprecated [deprecated]
mongo-python-driver (https://github.com/mongodb/mongo-python-driver)
+ ERROR bson/codec_options.py:65:6-26: `abc.abstractproperty` is deprecated [deprecated]
+ ERROR bson/codec_options.py:84:6-26: `abc.abstractproperty` is deprecated [deprecated]
strawberry (https://github.com/strawberry-graphql/strawberry)
+ ERROR strawberry/utils/typing.py:231:61-70: `ast.Index` is deprecated [deprecated]
+ ERROR strawberry/utils/typing.py:249:61-70: `ast.Index` is deprecated [deprecated]
+ ERROR strawberry/utils/typing.py:275:61-70: `ast.Index` is deprecated [deprecated]
Tanjun (https://github.com/FasterSpeeding/Tanjun)
+ ERROR tanjun/context/autocomplete.py:56:27-46: `alluka._context.BasicContext` is deprecated [deprecated]
+ ERROR tanjun/context/base.py:47:19-38: `alluka._context.BasicContext` is deprecated [deprecated]
+ ERROR tanjun/injecting.py:74:22-47: `alluka._self_injecting.AsyncSelfInjecting` is deprecated [deprecated]
+ ERROR tanjun/injecting.py:104:10-35: `alluka._self_injecting.AsyncSelfInjecting` is deprecated [deprecated]
+ ERROR tanjun/injecting.py:105:16-41: `alluka._self_injecting.AsyncSelfInjecting` is deprecated [deprecated]
static-frame (https://github.com/static-frame/static-frame)
+ ERROR static_frame/core/type_clinic.py:1753:28-36: `numpy._typing._nbit_base.NBitBase` is deprecated [deprecated]
+ ERROR static_frame/test/unit/test_type_clinic.py:41:1-9: `numpy._typing._nbit_base.NBitBase` is deprecated [deprecated]
+ ERROR static_frame/test/unit/test_type_clinic.py:42:9-17: `numpy._typing._nbit_base.NBitBase` is deprecated [deprecated]
mypy (https://github.com/python/mypy)
+ ERROR mypy/typeshed/stdlib/argparse.pyi:33:49-57: `FileType` is deprecated [deprecated]
+ ERROR mypy/typeshed/stdlib/argparse.pyi:411:41-49: `FileType` is deprecated [deprecated]
+ ERROR mypy/typeshed/stdlib/argparse.pyi:469:45-53: `FileType` is deprecated [deprecated]
- ERROR mypy/typeshed/stdlib/ast.pyi:1223:96-116: Unused `# type: ignore` comment [unused-type-ignore]
+ ERROR mypy/typeshed/stdlib/ast.pyi:1222:16-21: `slice` is deprecated [deprecated]
+ ERROR mypy/typeshed/stdlib/ast.pyi:1226:13-18: `slice` is deprecated [deprecated]
+ ERROR mypy/typeshed/stdlib/ast.pyi:2168:36-44: `ExtSlice` is deprecated [deprecated]
+ ERROR mypy/typeshed/stdlib/ast.pyi:2169:33-38: `Index` is deprecated [deprecated]
+ ERROR mypy/typeshed/stdlib/ast.pyi:2170:33-38: `Suite` is deprecated [deprecated]
+ ERROR mypy/typeshed/stdlib/ast.pyi:2171:35-42: `AugLoad` is deprecated [deprecated]
+ ERROR mypy/typeshed/stdlib/ast.pyi:2172:36-44: `AugStore` is deprecated [deprecated]
+ ERROR mypy/typeshed/stdlib/ast.pyi:2173:33-38: `Param` is deprecated [deprecated]
+ ERROR mypy/typeshed/stdlib/asyncio/events.pyi:769:40-60: `mypy.typeshed.stdlib.asyncio.unix_events.AbstractChildWatcher` is deprecated [deprecated]
+ ERROR mypy/typeshed/stdlib/asyncio/events.pyi:772:46-66: `mypy.typeshed.stdlib.asyncio.unix_events.AbstractChildWatcher` is deprecated [deprecated]
+ ERROR mypy/typeshed/stdlib/asyncio/events.pyi:801:32-52: `mypy.typeshed.stdlib.asyncio.unix_events.AbstractChildWatcher` is deprecated [deprecated]
+ ERROR mypy/typeshed/stdlib/asyncio/events.pyi:803:36-56: `mypy.typeshed.stdlib.asyncio.unix_events.AbstractChildWatcher` is deprecated [deprecated]
+ ERROR mypy/typeshed/stdlib/asyncio/unix_events.pyi:99:36-56: `AbstractChildWatcher` is deprecated [deprecated]
+ ERROR mypy/typeshed/stdlib/asyncio/unix_events.pyi:105:36-52: `BaseChildWatcher` is deprecated [deprecated]
+ ERROR mypy/typeshed/stdlib/asyncio/unix_events.pyi:116:36-52: `BaseChildWatcher` is deprecated [deprecated]
+ ERROR mypy/typeshed/stdlib/asyncio/unix_events.pyi:176:48-68: `AbstractChildWatcher` is deprecated [deprecated]
+ ERROR mypy/typeshed/stdlib/asyncio/unix_events.pyi:178:54-74: `AbstractChildWatcher` is deprecated [deprecated]
+ ERROR mypy/typeshed/stdlib/asyncio/unix_events.pyi:196:41-61: `AbstractChildWatcher` is deprecated [deprecated]
+ ERROR mypy/typeshed/stdlib/asyncio/unix_events.pyi:210:40-60: `AbstractChildWatcher` is deprecated [deprecated]
+ ERROR mypy/typeshed/stdlib/asyncio/unix_events.pyi:225:37-57: `AbstractChildWatcher` is deprecated [deprecated]
+ ERROR mypy/typeshed/stdlib/distutils/cygwinccompiler.pyi:19:29-41: `setuptools._distutils.version.LooseVersion` is deprecated [deprecated]
- ERROR mypy/typeshed/stdlib/importlib/abc.pyi:62:108-130: Unused `# type: ignore` comment [unused-type-ignore]
+ ERROR mypy/typeshed/stdlib/importlib/abc.pyi:96:50-64: `ResourceLoader` is deprecated [deprecated]
+ ERROR mypy/typeshed/stdlib/importlib/resources/_common.pyi:36:59-73: `importlib.resources.abc.ResourceReader` is deprecated [deprecated]
+ ERROR mypy/typeshed/stdlib/importlib/resources/abc.pyi:56:32-46: `ResourceReader` is deprecated [deprecated]
+ ERROR mypy/typeshed/stdlib/urllib/request.pyi:390:26-35: `URLopener` is deprecated [deprecated]
meson (https://github.com/mesonbuild/meson)
+ ERROR mesonbuild/linkers/linkers.py:139:6-26: `abc.abstractproperty` is deprecated [deprecated]
pyodide (https://github.com/pyodide/pyodide)
+ ERROR src/tests/test_python.py:159:18-30: `setuptools._distutils.version.LooseVersion` is deprecated [deprecated]
+ ERROR src/tests/test_python.py:160:25-37: `setuptools._distutils.version.LooseVersion` is deprecated [deprecated]
parso (https://github.com/davidhalter/parso)
+ ERROR parso/tree.py:131:6-22: `abc.abstractproperty` is deprecated [deprecated]
+ ERROR parso/tree.py:140:6-22: `abc.abstractproperty` is deprecated [deprecated]
pydantic (https://github.com/pydantic/pydantic)
+ ERROR pydantic/deprecated/json.py:57:5-10: `pydantic.color.Color` is deprecated [deprecated]
+ ERROR pydantic/v1/_hypothesis_plugin.py:105:5-25: `pydantic.color.Color` is deprecated [deprecated]
+ ERROR pydantic/v1/_hypothesis_plugin.py:126:13-39: `pydantic.types.PaymentCardNumber` is deprecated [deprecated]
+ ERROR pydantic/v1/_hypothesis_plugin.py:139:5-31: `pydantic.types.PaymentCardNumber` is deprecated [deprecated]
PyGithub (https://github.com/PyGithub/PyGithub)
+ ERROR github/MainClass.py:198:19-36: `github.AppAuthentication.AppAuthentication` is deprecated [deprecated]
+ ERROR github/Requester.py:287:17-34: `github.AppAuthentication.AppAuthentication` is deprecated [deprecated]
+ ERROR tests/Authentication.py:97:24-48: `github.AppAuthentication.AppAuthentication` is deprecated [deprecated] |
Summary
Fixes #5170
add deprecated class support.
Test Plan
add teset