desert icon indicating copy to clipboard operation
desert copied to clipboard

Type hinting complains on desert.field() (maybe .ib()?)

Open altendky opened this issue 5 years ago • 1 comments

https://github.com/python-desert/desert/blob/631de5f98d0f3edd3ecbab57100c5664a43bf3d5/src/desert/init.py#L55-L66

Below is my attempt to minimally recreate the issue and show some not-working options and output.

https://mypy-play.net/?mypy=latest&python=3.8&flags=strict%2Ccheck-untyped-defs&gist=7956a372fa34375077012351364a3aec

import dataclasses
import typing


T = typing.TypeVar('T')


def make_a_field_t() -> T:
    return dataclasses.field()


def make_a_field_field() -> dataclasses.Field:
    return dataclasses.field()


def make_a_field_field_any() -> dataclasses.Field[typing.Any]:
    return dataclasses.field()


def make_a_field_nothing():
    return dataclasses.field()


@dataclasses.dataclass
class C:
    a: int = dataclasses.field()
    b: int = dataclasses.Field()
    c: int = make_a_field_t()
    d: int = make_a_field_field()
    e: int = make_a_field_field_any()
    f: int = make_a_field_nothing()


reveal_type(dataclasses.field)
reveal_type(dataclasses.Field)
reveal_type(make_a_field_t)
reveal_type(make_a_field_field)
reveal_type(make_a_field_field_any)
reveal_type(make_a_field_nothing)
main.py:9: error: Returning Any from function declared to return "T"
main.py:12: error: Missing type parameters for generic type "Field"
main.py:13: error: Returning Any from function declared to return "Field[Any]"
main.py:17: error: Returning Any from function declared to return "Field[Any]"
main.py:20: error: Function is missing a return type annotation
main.py:27: error: Incompatible types in assignment (expression has type "Field[<nothing>]", variable has type "int")
main.py:29: error: Incompatible types in assignment (expression has type "Field[Any]", variable has type "int")
main.py:30: error: Incompatible types in assignment (expression has type "Field[Any]", variable has type "int")
main.py:31: error: Call to untyped function "make_a_field_nothing" in typed context
main.py:34: note: Revealed type is 'Overload(def [_T] (*, default: _T`-1, init: builtins.bool =, repr: builtins.bool =, hash: Union[builtins.bool, None] =, compare: builtins.bool =, metadata: Union[typing.Mapping[builtins.str, Any], None] =) -> _T`-1, def [_T] (*, default_factory: def () -> _T`-1, init: builtins.bool =, repr: builtins.bool =, hash: Union[builtins.bool, None] =, compare: builtins.bool =, metadata: Union[typing.Mapping[builtins.str, Any], None] =) -> _T`-1, def (*, init: builtins.bool =, repr: builtins.bool =, hash: Union[builtins.bool, None] =, compare: builtins.bool =, metadata: Union[typing.Mapping[builtins.str, Any], None] =) -> Any)'
main.py:35: note: Revealed type is 'def [_T] () -> dataclasses.Field[_T`1]'
main.py:36: note: Revealed type is 'def [T] () -> T`-1'
main.py:37: note: Revealed type is 'def () -> dataclasses.Field[Any]'
main.py:38: note: Revealed type is 'def () -> dataclasses.Field[Any]'
main.py:39: note: Revealed type is 'def () -> Any'
Found 9 errors in 1 file (checked 1 source file)

altendky avatar May 30 '20 17:05 altendky

I have also experienced this issue when running mypy on my desert code. Here is an even more minimal example:

import desert
from dataclasses import dataclass
from typing import List
from marshmallow import fields


@dataclass
class Foo:

    list_of_strings: List[str] = desert.field(
        fields.List(fields.String()), default_factory=list
    )

Running mypy gives the following error:

blah.py: note: In class "Foo":
blah.py:10:34: error: Incompatible types in assignment (expression has type "Field[Any]", variable has type "List[str]")  [assignment]
        list_of_strings: List[str] = desert.field(
                                     ^
Found 1 error in 1 file (checked 1 source file) 

Is there any way we can make the desert field return type match what we have specified?

amin-nejad avatar Nov 24 '21 11:11 amin-nejad