python-attrs / attrs

Python Classes Without Boilerplate
https://www.attrs.org/
MIT License
5.28k stars 369 forks source link

Typing issue (stubs) for converter with default #518

Open Funth0mas opened 5 years ago

Funth0mas commented 5 years ago

When using attr.ibute with both converter and default, wrong expectations is applied on default type (with mypy == 0.670). Mypy dev say it's an issue in attr stubs.

The valid code

import attr
import typing

def to_int(x: typing.Any) -> int:
    return int(x)

@attr.s
class C:
    a: int = attr.ib(converter=to_int, default="1")

results in:

main.py:9: error: Incompatible types in assignment (expression has type "str", variable has type "int")
main.py:9: error: Argument "converter" has incompatible type "Callable[[Any], int]"; expected "Optional[Callable[[Any], str]]"

The result is not right, because the converter is applied on default value as well.

Of course the hotfix is to convert the default value manually.

ljluestc commented 1 year ago

import attr import typing

def to_int(x: typing.Any) -> int: return int(x)

@attr.s class C: a: int = attr.ib(converter=to_int, default="1") # Manually specify the default as a string a: int = attr.ib(converter=to_int, default=1) # Manually specify the default as an integer

Example usage

obj1 = C() # 'a' will have a default value of 1 as an integer obj2 = C("42") # 'a' will be converted to an integer using the converter

print(obj1.a) print(obj2.a)