Skip to content

Docs: condecimal gives type error "Illegal type annotation: call expression not allowed" #354

Closed
@cassieopea

Description

@cassieopea

First Check

  • I added a very descriptive title to this issue.
  • I used the GitHub search to find a similar issue and didn't find it.
  • I searched the SQLModel documentation, with the integrated search.
  • I already searched in Google "How to X in SQLModel" and didn't find any information.
  • I already read and followed all the tutorial in the docs and didn't find an answer.
  • I already checked if it is not related to SQLModel but to Pydantic.
  • I already checked if it is not related to SQLModel but to SQLAlchemy.

Commit to Help

  • I commit to help with one of those options 👆

Example Code

from pydantic import condecimal
from sqlmodel import Field, SQLModel


class Lineitem(SQLModel, table=True):
    price: condecimal(max_digits=5, decimal_places=2) = Field(default=0)

Description

The above code yields a Pylance error in VsCode:

Illegal type annotation: call expression not allowed Pylance(reportGeneralTypeIssues)

And with mypy:

$ mypy code/example.py
code/example.py:6: error: Invalid type comment or annotation
code/example.py:6: note: Suggestion: use condecimal[...] instead of condecimal(...)
Found 1 error in 1 file (checked 1 source file)

This is definitely a Pydantic issue: pydantic/pydantic#156.

However, I thought it might be a good idea to add to the docs for decimals that this error can occur. There's a comment on the pydantic issue that gives an ugly workaround, which in my case would look something like:

from decimal import Decimal
from typing import TYPE_CHECKING
from typing_extensions import reveal_type
from pydantic import condecimal
from sqlmodel import Field, SQLModel


class Lineitem(SQLModel, table=True):
    if TYPE_CHECKING:
        price: Decimal = Field(default=0)
    else:
        price: condecimal(max_digits=5, decimal_places=2) = Field(default=0)


item = Lineitem(price=Decimal(1))
if TYPE_CHECKING:
    reveal_type(item.price) # result: Type of "item.price" is "Decimal"

item = Lineitem(price=Decimal(9.999)) # should throw a validation error

The mypy result is:

$ mypy code/example_fixed.py
code/example_fixed.py:17: note: Revealed type is "_decimal.Decimal"
Success: no issues found in 1 source file

I don't think this workaround should be added to the docs: nobody would go this far to make a type checker happy. I was thinking the docs could say something like:

Warning (or Tip?)
Type checkers will complain about the type of condecimal being the result of a callable, or be confused by it. There is no fix for this, so to silence the error add # type: ignore:

class Lineitem(SQLModel, table=True):
    price: condecimal(max_digits=5, decimal_places=2) = Field(default=0)  # type: ignore

Operating System

macOS

Operating System Details

$ sw_vers
ProductName: macOS
ProductVersion: 12.4
BuildVersion: 21F79

SQLModel Version

0.0.6

Python Version

Python 3.10.2

Additional Context

Screenshot of Pylance error:

image

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionFurther information is requested

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions