Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor 'NewType' as it no longer conforms to the typing spec #256

Open
mvanderlee opened this issue Mar 9, 2024 · 2 comments · May be fixed by #257
Open

Refactor 'NewType' as it no longer conforms to the typing spec #256

mvanderlee opened this issue Mar 9, 2024 · 2 comments · May be fixed by #257

Comments

@mvanderlee
Copy link
Contributor

mvanderlee commented Mar 9, 2024

Python is updating the Typing spec which causes Variable not allowed in type expression for types created with marshmallow_dataclass's NewType

microsoft/pyright#7268

The modern way is to use typing.Annotated. (Python >=3.9)

I propose deprecating NewType and adding Annotated support.

Example:

from typing import Annotated
import marshmallow.fields as mf
import marshmallow.validate as mv
from marshmallow_dataclass import dataclass

Url = Annotated[str, mf.Url]
Email = Annotated[str, mf.Email]

@dataclass
class ContactInfo:
    mail: Email

@dataclass
class Network:
    ipv4: Annotated[str, mf.String(validate=mv.Regexp(r'^([0-9]{1,3}\\.){3}[0-9]{1,3}$'))]
@mvanderlee mvanderlee linked a pull request Mar 9, 2024 that will close this issue
@dairiki
Copy link
Collaborator

dairiki commented Apr 29, 2024

Not a problem, but something to be aware of:

The proposed use of Annotated types is not equivalent to the old custom NewType with regards to static type checking. (NewType introduces a new type, while Annotated adds annotations to an existing type.)

Consider:

from typing import Annotated
from marshmallow import fields
from marshmallow_dataclass import dataclass, NewType

Email1 = NewType("Email", str, field=fields.Email)
Email2 = Annotated[str, fields.Email]

@dataclass
class Record:
    email1: Email1
    email2: Email2

r = Record(email1="joe@example.org", email2="jane@example.net")

Mypy will complain that Argument "email1" to "Record" has incompatible type "str"; expected "Email1". Passing the str for email2 is fine.

@dairiki
Copy link
Collaborator

dairiki commented Apr 29, 2024

Python is updating the Typing spec which causes Variable not allowed in type expression for types created with marshmallow_dataclass's NewType

FWIW: For mypy, at least, use of the marshmallow_dataclass.mypy mypy plugin fixes this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants