infer Self when constructing a class using cls()#2557
infer Self when constructing a class using cls()#2557yangdanny97 wants to merge 3 commits intofacebook:mainfrom
Self when constructing a class using cls()#2557Conversation
Summary: If we're star-unpacking a list/tuple/set literal that only has 1 element, we should consume 1 parameter, not more. fixes facebook#2467 Differential Revision: D94409371
…args Summary: We usually don't know how many parameters a star-unpacked arg consumes, so currently we consume all positional parameters. However, positional parameters can be passed arguments by name, so this diff makes it s.t. we look ahead at which arguments are passed by name & stop consuming positional parameters if we see one. The current behavior leads to quite a few false positives, because if you pass any non-kw-only argument by name after a star unpacking it will always give a "duplicate value provided" error. This is unsound, since the thing being unpacked could be long enough to actually consume all positional params, but we have no way of telling so we sould err on the side of false negatives here IMO. Ideally we might want some sort of backtracking to figure this out, but for now this fix should reduce false positives. fixes facebook#2468 Differential Revision: D94411643
Summary: fixes facebook#2528 Differential Revision: D94416719
|
@yangdanny97 has exported this pull request. If you are a Meta employee, you can view the originating Diff in D94416719. |
stroxler
left a comment
There was a problem hiding this comment.
Review automatically exported from Phabricator review in Meta.
|
Diff from mypy_primer, showing the effect of this PR on open source code: trio (https://github.com/python-trio/trio)
- ERROR src/trio/_tests/test_repl.py:270:18-73: Unpacked argument `tuple[str, ...]` is not assignable to parameter `*args` with type `tuple[StrOrBytesPath, *tuple[StrOrBytesPath, ...]]` in function `os.execlp` [bad-argument-type]
- ERROR src/trio/testing/_raises_group.py:69:16-25: Returned type `_ExceptionInfo[BaseException]` is not assignable to declared return type `_ExceptionInfo[MatchE]` [bad-return]
+ ERROR src/trio/testing/_raises_group.py:69:16-25: Returned type `Self@_ExceptionInfo` is not assignable to declared return type `_ExceptionInfo[MatchE]` [bad-return]
hydpy (https://github.com/hydpy-dev/hydpy)
- ERROR hydpy/core/testtools.py:1348:14-33: Cannot use `TestIO` as a context manager [bad-context-manager]
+ ERROR hydpy/core/testtools.py:1348:14-33: Cannot use `Self@TestIO` as a context manager [bad-context-manager]
apprise (https://github.com/caronc/apprise)
- ERROR apprise/plugins/telegram.py:433:69-80: Multiple values for argument `fmt` in function `apprise.utils.parse.validate_regex` [bad-keyword-argument]
- ERROR tests/test_api.py:237:18-71: Argument `str` is not assignable to parameter `asset` with type `AppriseAsset | None` in function `apprise.apprise.Apprise.add` [bad-argument-type]
operator (https://github.com/canonical/operator)
- ERROR ops/pebble.py:625:16-636:10: Returned type `ops.pebble.Warning` is not assignable to declared return type `builtins.Warning` [bad-return]
+ ERROR ops/pebble.py:625:16-636:10: Returned type `Self@ops.pebble.Warning` is not assignable to declared return type `builtins.Warning` [bad-return]
pandera (https://github.com/pandera-dev/pandera)
- ERROR pandera/api/checks.py:246:16-252:10: Returned type `BaseCheck` is not assignable to declared return type `Check` [bad-return]
- ERROR pandera/api/checks.py:260:16-266:10: Returned type `BaseCheck` is not assignable to declared return type `Check` [bad-return]
- ERROR pandera/api/checks.py:280:16-286:10: Returned type `BaseCheck` is not assignable to declared return type `Check` [bad-return]
- ERROR pandera/api/checks.py:298:16-304:10: Returned type `BaseCheck` is not assignable to declared return type `Check` [bad-return]
- ERROR pandera/api/checks.py:316:16-322:10: Returned type `BaseCheck` is not assignable to declared return type `Check` [bad-return]
- ERROR pandera/api/checks.py:334:16-340:10: Returned type `BaseCheck` is not assignable to declared return type `Check` [bad-return]
- ERROR pandera/api/checks.py:440:16-449:10: Returned type `BaseCheck` is not assignable to declared return type `Check` [bad-return]
- ERROR pandera/api/checks.py:499:16-506:10: Returned type `BaseCheck` is not assignable to declared return type `Check` [bad-return]
- ERROR pandera/api/checks.py:555:16-562:10: Returned type `BaseCheck` is not assignable to declared return type `Check` [bad-return]
- ERROR pandera/api/checks.py:577:16-584:10: Returned type `BaseCheck` is not assignable to declared return type `Check` [bad-return]
- ERROR pandera/api/checks.py:601:16-608:10: Returned type `BaseCheck` is not assignable to declared return type `Check` [bad-return]
- ERROR pandera/api/checks.py:618:16-624:10: Returned type `BaseCheck` is not assignable to declared return type `Check` [bad-return]
- ERROR pandera/api/checks.py:633:16-639:10: Returned type `BaseCheck` is not assignable to declared return type `Check` [bad-return]
- ERROR pandera/api/checks.py:684:20-690:14: Returned type `BaseCheck` is not assignable to declared return type `Check` [bad-return]
- ERROR pandera/api/checks.py:697:16-705:10: Returned type `BaseCheck` is not assignable to declared return type `Check` [bad-return]
- ERROR pandera/api/checks.py:723:16-730:10: Returned type `BaseCheck` is not assignable to declared return type `Check` [bad-return]
- ERROR pandera/api/hypotheses.py:282:16-290:10: Returned type `BaseCheck` is not assignable to declared return type `Hypothesis` [bad-return]
- ERROR pandera/api/hypotheses.py:375:16-381:10: Returned type `BaseCheck` is not assignable to declared return type `Hypothesis` [bad-return]
dd-trace-py (https://github.com/DataDog/dd-trace-py)
- ERROR tests/debugging/probe/test_remoteconfig.py:104:67-94: Multiple values for argument `status_logger` in function `ProbeRCAdapter.__init__` [bad-keyword-argument]
- ERROR tests/profiling/collector/pprof_utils.py:136:26-58: Multiple values for argument `event_type` in function `LockEvent.__init__` [bad-keyword-argument]
- ERROR tests/profiling/collector/pprof_utils.py:141:26-58: Multiple values for argument `event_type` in function `LockEvent.__init__` [bad-keyword-argument]
vision (https://github.com/pytorch/vision)
- ERROR references/segmentation/train.py:20:54-73: Multiple values for argument `mode` in function `torchvision.datasets.sbd.SBDataset.__init__` [bad-keyword-argument]
- ERROR test/test_backbone_utils.py:107:58-85: Multiple values for argument `tracer_kwargs` in function `torchvision.models.feature_extraction.create_feature_extractor` [bad-keyword-argument]
- ERROR test/test_backbone_utils.py:107:87-113: Multiple values for argument `suppress_diff_warning` in function `torchvision.models.feature_extraction.create_feature_extractor` [bad-keyword-argument]
- ERROR torchvision/models/quantization/googlenet.py:78:20-98: Multiple values for argument `blocks` in function `torchvision.models.googlenet.GoogLeNet.__init__` [bad-keyword-argument]
- ERROR torchvision/models/quantization/inception.py:129:13-137:14: Multiple values for argument `inception_blocks` in function `torchvision.models.inception.Inception3.__init__` [bad-keyword-argument]
discord.py (https://github.com/Rapptz/discord.py)
- ERROR discord/ext/commands/core.py:1552:29-66: No matching overload found for function `command` called with arguments: (*tuple[Any, ...], name=str, cls=type[Command[Any, Ellipsis, Any]], **_CommandDecoratorKwargs) [no-matching-overload]
- ERROR discord/ext/commands/core.py:1609:27-64: No matching overload found for function `group` called with arguments: (*tuple[Any, ...], name=str, cls=type[Group[Any, Ellipsis, Any]], **_GroupDecoratorKwargs) [no-matching-overload]
- ERROR discord/gateway.py:142:48-57: Multiple values for argument `name` in function `threading.Thread.__init__` [bad-keyword-argument]
static-frame (https://github.com/static-frame/static-frame)
- ERROR static_frame/core/frame.py:6911:20-65: Returned type `Frame[Any, Any, *tuple[Any, ...]] | Self@Frame` is not assignable to declared return type `Frame[Any, Any, *tuple[Any, ...]]` [bad-return]
+ ERROR static_frame/core/frame.py:6911:20-65: Returned type `Self@Frame` is not assignable to declared return type `Frame[Any, Any, *tuple[Any, ...]]` [bad-return]
- ERROR static_frame/core/frame.py:7165:20-65: Returned type `Frame[Any, Any, *tuple[Any, ...]] | Self@Frame` is not assignable to declared return type `Frame[Any, Any, *tuple[Any, ...]]` [bad-return]
+ ERROR static_frame/core/frame.py:7165:20-65: Returned type `Self@Frame` is not assignable to declared return type `Frame[Any, Any, *tuple[Any, ...]]` [bad-return]
prefect (https://github.com/PrefectHQ/prefect)
- ERROR src/prefect/_internal/concurrency/services.py:333:60-74: Argument `(self: _QueueServiceBase[Unknown]) -> None` is not assignable to parameter with type `() -> Awaitable[Awaitable[Unknown] | Unknown] | Awaitable[Unknown] | Unknown` in function `prefect._internal.concurrency.api.create_call` [bad-argument-type]
+ ERROR src/prefect/_internal/concurrency/services.py:333:60-74: Argument `(self: Self@_QueueServiceBase) -> None` is not assignable to parameter with type `() -> Awaitable[Awaitable[Unknown] | Unknown] | Awaitable[Unknown] | Unknown` in function `prefect._internal.concurrency.api.create_call` [bad-argument-type]
- ERROR src/prefect/_waiters.py:252:60-74: Argument `(self: FlowRunWaiter) -> None` is not assignable to parameter with type `() -> Awaitable[Awaitable[Unknown] | Unknown] | Awaitable[Unknown] | Unknown` in function `prefect._internal.concurrency.api.create_call` [bad-argument-type]
+ ERROR src/prefect/_waiters.py:252:60-74: Argument `(self: Self@FlowRunWaiter) -> None` is not assignable to parameter with type `() -> Awaitable[Awaitable[Unknown] | Unknown] | Awaitable[Unknown] | Unknown` in function `prefect._internal.concurrency.api.create_call` [bad-argument-type]
- ERROR src/prefect/task_runs.py:267:60-74: Argument `(self: TaskRunWaiter) -> None` is not assignable to parameter with type `() -> Awaitable[Awaitable[Unknown] | Unknown] | Awaitable[Unknown] | Unknown` in function `prefect._internal.concurrency.api.create_call` [bad-argument-type]
+ ERROR src/prefect/task_runs.py:267:60-74: Argument `(self: Self@TaskRunWaiter) -> None` is not assignable to parameter with type `() -> Awaitable[Awaitable[Unknown] | Unknown] | Awaitable[Unknown] | Unknown` in function `prefect._internal.concurrency.api.create_call` [bad-argument-type]
- ERROR src/prefect/workers/base.py:1035:52-65: Argument `BaseJobConfiguration` is not assignable to parameter `configuration` with type `C` in function `BaseWorker._initiate_run` [bad-argument-type]
- ERROR src/prefect/workers/base.py:1037:51-64: Argument `BaseJobConfiguration` is not assignable to parameter `configuration` with type `C` in function `BaseWorker.run` [bad-argument-type]
- ERROR src/prefect/workers/base.py:1592:16-29: Returned type `BaseJobConfiguration` is not assignable to declared return type `C` [bad-return]
pip (https://github.com/pypa/pip)
- ERROR src/pip/_vendor/pkg_resources/__init__.py:3415:18-53: No matching overload found for function `_warnings.warn` called with arguments: (*tuple[Unknown, ...], stacklevel=int, **dict[str, Unknown]) [no-matching-overload]
jax (https://github.com/google/jax)
- ERROR jax/_src/random.py:1411:40-59: Multiple values for argument `log_space` in function `_gamma_one` [bad-keyword-argument]
- ERROR jax/experimental/array_serialization/serialization_test.py:68:43-70: Multiple values for argument `shardings` in function `jax.experimental.array_serialization.pytree_serialization.load` [bad-keyword-argument]
- ERROR jax/experimental/sparse/bcoo.py:1044:78-113: Multiple values for argument `dimension_numbers` in function `jax._src.lax.lax.dot_general` [bad-keyword-argument]
scrapy (https://github.com/scrapy/scrapy)
- ERROR scrapy/core/downloader/contextfactory.py:88:13-26: Multiple values for argument `method` in function `ScrapyClientContextFactory.__init__` [bad-keyword-argument]
- ERROR scrapy/core/downloader/contextfactory.py:89:13-52: Multiple values for argument `tls_verbose_logging` in function `ScrapyClientContextFactory.__init__` [bad-keyword-argument]
- ERROR scrapy/core/downloader/contextfactory.py:90:13-36: Multiple values for argument `tls_ciphers` in function `ScrapyClientContextFactory.__init__` [bad-keyword-argument]
|
|
This pull request has been merged in 5684831. |
Primer Diff Classification❌ 1 regression(s) | ✅ 9 improvement(s) | ➖ 3 neutral | 13 project(s) total 1 regression(s) across prefect. error kinds:
Detailed analysis❌ Regression (1)prefect (+3, -6)
✅ Improvement (9)trio (+1, -2)
apprise (-2)
pandera (-18)
dd-trace-py (-3)
The PR changes improved pyrefly's handling of starred arguments combined with keyword arguments, correctly recognizing that these patterns don't create argument conflicts. The new logic stops consuming positional parameters when it encounters a parameter that has a corresponding keyword argument, preventing the false 'multiple values' errors.
vision (-5)
discord.py (-3)
pip (-1)
jax (-3)
The PR diff shows that pyrefly improved its handling of starred arguments by adding logic to stop consuming positional parameters when reaching one that has a corresponding keyword argument. This prevents false positive 'multiple values' errors for valid code patterns where starred unpacking is used alongside explicit keyword arguments. The change makes pyrefly's behavior align with Python's actual argument resolution rules and with other type checkers like mypy/pyright.
scrapy (-3)
➖ Neutral (3)hydpy (+1, -1)
operator (+1, -1)
static-frame (+2, -2)
Suggested FixSummary: The PR introduced a regression in Self type resolution where type[Self] constructor calls produce malformed Self@_ types instead of proper Self types. 1. In
Classification by primer-classifier (3 heuristic, 10 LLM) · Was this helpful? React with 👍 or 👎 |
|
@migeed-z this suggested fix is pretty wrong
this is not true, the rest of the analysis is based on this mistaken premise |
Summary: fixes #2528
Differential Revision: D94416719