Description
Feature
Version 20.1 of attrs introduced support for running a field's converter whenever the field is set. Here's an example of it in action:
import re
import attr
@attr.s(auto_attribs=True)
class GHRepo:
owner: str
name: str
def parse_ghrepo(s: str) -> GHRepo:
if (m := re.fullmatch(r'([^/]+)/([^/]+)', s)) is not None:
return GHRepo(owner=m[1], name=m[2])
else:
raise ValueError(s)
@attr.s
class Foo:
repo: GHRepo = attr.ib(converter=parse_ghrepo, on_setattr=attr.setters.convert)
f = Foo("owner/name")
f.repo = "python/mypy" # mypy errors on this line
print(f)
This prints out Foo(repo=GHRepo(owner='python', name='mypy'))
, as the "python/mypy"
assigned to f.repo
is converted to a GHRepo
with parse_ghrepo()
.
Unfortunately, mypy as of both version 0.812 and commit 28034cc does not recognize the typing implications of on_setattr=attr.setters.convert
, as running it on the above code with the default settings gives the error Incompatible types in assignment (expression has type "str", variable has type "GHRepo")
on the marked line. I would like to request that mypy recognize the setting's typing implications and allow thus-configured fields to be set to the input types of their converters.
Pitch
This feature would provide greater support for attrs and allow for defining fields that are initialized & set by converting from other types.