python-attrs / python-attrs/attrs

Mypy error "Cannot determine __init__ type from converter" when using type checking, overloads and converters

Open
#897 3 comments 0 reactions 1 assignee View on GitHub

@Tinche is already working on this.

Since Jan 9, 2022.

Typing
Dominant language
Python
Stars
5.8k
Forks
480
Avg merge
2h 15m
Merged PRs (30d)
2

Description

Hello,

I'm not sure how to explain this properly but I'll do my best. Imagine a project with the following layout:

test
├── __init__.py
├── py.typed
├── test.py
└── test_functions.py

The __init__.py and py.typed files are both empty. The other two files contain the following test code:

test.py

from datetime import datetime
from typing import Optional
from attrs import define, field

from .test_functions import to_datetime

@define
class Test:
    test_string: str
    test_date: Optional[datetime] = field(converter=to_datetime, repr=str)

test_functions.py

from datetime import datetime
from typing import overload
from typing import Optional


@overload
def to_datetime(value: None) -> None:
    pass


@overload
def to_datetime(value: str) -> datetime:
    pass


def to_datetime(value: Optional[str]) -> Optional[datetime]:
    if value is None:
        return None

    retval = datetime.strptime(value, "%Y-%m-%dT%H:%M:%S%z")
    return retval

This all fine and passes mypy checks:

(.venv) vscode ➜ /workspaces/test $ mypy test
Success: no issues found in 3 source files
(.venv) vscode ➜ /workspaces/test $ 

However, if I move the functions from the test_functions.py file over to the test.py like so:

test.py

from datetime import datetime
from typing import Optional, overload
from attrs import define, field

# from .test_functions import to_datetime


@overload
def to_datetime(value: None) -> None:
    pass


@overload
def to_datetime(value: str) -> datetime:
    pass


def to_datetime(value: Optional[str]) -> Optional[datetime]:
    if value is None:
        return None

    retval = datetime.strptime(value, "%Y-%m-%dT%H:%M:%S%z")
    return retval


@define
class Test:
    test_string: str
    test_date: Optional[datetime] = field(converter=to_datetime, repr=str)

mypy will fail with the following error: test/test.py:29: error: Cannot determine __init__ type from converter

(.venv) vscode ➜ /workspaces/test $ mypy test
test/test.py:29: error: Cannot determine __init__ type from converter
Found 1 error in 1 file (checked 3 source files)
(.venv) vscode ➜ /workspaces/test $ 

I've been scratching my head for hours about this, but I cannot seem to find a valid reason for it. I really don't want some functions in a seperate file as that will cause an even harder to solve import loop :).

Is this a bug or something I'm not properly understanding / doing wrong?

Thanks!

PS: attrs version 21.3.0, python version 3.7.12.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.