-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
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
Fix attrs.evolve with generics #15016
Conversation
👋 @JelleZijlstra you reviewed #14526 so you might have context |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
I was looking around for MRs touching I was hoping this MR resolved our issue, but it doesn't appear to do so. Our use case is below. I made a minor tweak to make things "work" albeit maybe not in a satisfactory way. I'm willing to open an issue and discuss the proper fix for it if it doesn't fit with this MR re evolve + Generics. import attr
from typing import Generic, TypeVar
from dataclasses import dataclass
C_T = TypeVar("C_T", bound="Config")
@attr.s
class Config():
name: str = attr.ib()
@dataclass
class ConfigFactory(Generic[C_T]):
_configs: list[C_T]
def create_configs(self) -> None:
for current_config in self._configs:
x = attr.evolve(current_config, name="abc")
print(x)
@dataclass
class TestCF(ConfigFactory[Config]):
pass
def test() -> None:
factory = TestCF(list())
factory._configs.extend([Config(name="test")])
factory.create_configs() Where I needed to add: diff --git a/mypy/plugins/attrs.py b/mypy/plugins/attrs.py
index 98090cbeb..668293fad 100644
--- a/mypy/plugins/attrs.py
+++ b/mypy/plugins/attrs.py
@@ -963,7 +963,10 @@ def evolve_function_sig_callback(ctx: mypy.plugin.FunctionSigContext) -> Callabl
# </hack>
inst_type = get_proper_type(inst_type)
+ if isinstance(inst_type, TypeVarType):
+ inst_type = inst_type.upper_bound
inst_type_str = format_type_bare(inst_type)
+
|
This comment has been minimized.
This comment has been minimized.
@vfazio tried addressing it in the next commits I basically did what you suggested, but added an
|
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
8ade002
to
e9f876e
Compare
This comment has been minimized.
This comment has been minimized.
Awesome, thanks! |
mypy/plugins/attrs.py
Outdated
ctx.api.fail( | ||
f'Argument 1 to "evolve" has incompatible type "{inst_type_str}"; expected an attrs class', | ||
f'Argument 1 to "evolve" has a variable type "{inst_type_str}" not bound to an attrs class' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be more friendly, e.g.
has a variable type "T" that is not necessarily an attrs class; consider adding bounds= to your TypeVar definition
I can't tell where we stand between succinct and instructive.
Split the TypeVar fix into #15022, to be merged before this. |
@hauntsaninja while I have your attention... (There's a flood of comments above but it's basically around split-out #15022 which we already merged.) |
According to mypy_primer, this change has no effect on the checked open source code. 🤖🎉 |
Closed in favor of #15050 which also addresses unions. |
Fixes
attrs.evolve
for generic attrs classes.