Exempt base-dictated Any positions in @override methods from explicit-any - #4798
Open
nitishagar wants to merge 1 commit into
Open
Exempt base-dictated Any positions in @override methods from explicit-any#4798nitishagar wants to merge 1 commit into
nitishagar wants to merge 1 commit into
Conversation
…-any A method decorated with @typing.override cannot narrow or drop an `Any` that the base signature already declares — repeating it is required to keep the override compatible — yet explicit-any fired on exactly those annotations, pointing at code that cannot be changed (issue facebook#4548; ruff reached the same conclusion for ANN401). The override context is known at binding time (where the name-only is_override check already exists), so the method's annotations now carry the method name when they belong to an @OverRide method. The solver, which can resolve the base signature, consumes it: parameter and return annotations report explicit-any from solve_annotation instead of expr_untype, exempting a position only when both the annotation is exactly Any and the corresponding base position (param by name, *args, **kwargs, or return — unwrapping Coroutine for async bases, considering every overload) is explicitly annotated Any. Everything else still reports: undictated positions, missing @OverRide, missing base member, unannotated base positions, and nested Any like list[Any]. Fixes facebook#4548
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #4548
Problem
With
explicit-any = "error", a@typing.overridemethod whose base signature is annotated withAnymust repeat thatAny— narrowing or dropping it would break the override — yet the rule fired on exactly those annotations:The signature is fixed by typeshed's
json.JSONEncoder.default((self, o: Any) -> Any), so the diagnostic points at code that cannot be changed. Ruff exempts@overridemethods in its equivalent lint (ANN401) for the same reason.Change
is_override(name-only decorator check) when it registers method annotations; those annotations now carry the method's name when they belong to an@overridemethod.explicit-anyfromsolve_annotation(which has the class context) instead ofexpr_untype; a position is exempt only when the annotation is exactlyAnyand the corresponding base position is explicitly annotatedAny:*args/**kwargsand return positions included),Coroutine[Any, Any, T],@override,@overridewith no base member (bad-override still fires), base positions that merely lack annotations, and nestedAnylikelist[Any].The base's own explicit
Anys still report when the base is user code in the checked project (in the issue's case the base is in typeshed and not checked) — only the dictated override positions are exempt.Test plan
testcase!s inpyrefly/lib/test/inference.rscovering: exemption (plain/args-kwargs/overload/typing_extensions/async), still-reporting (undictated positions, no decorator, no base member, unannotated base param, nestedAny, per-position granularity)explicit-any = "error"cargo test -p pyrefly --lib -- --skip test::lspgreen (the twomissing-sourceLSP interaction failures are pre-existing onmain)