Skip to content

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

Open

Description

@altendky

def field(marshmallow_field: marshmallow.fields.Field, **kw) -> dataclasses.Field:
"""Specify a marshmallow field in the metadata for a ``dataclasses.dataclass``.
.. code-block:: python
@dataclasses.dataclass
class A:
x: int = desert.field(marshmallow.fields.Int())
"""
meta = metadata(marshmallow_field)
meta.update(kw.pop("metadata", {}))
return dataclasses.field(**kw, metadata=meta)

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)

Activity

  1. amin-nejad commented on Nov 24, 2021

    @amin-nejad

    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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions