Tell Pyright to ignore Decimal to float conversion

88 views Asked by At

In this contrived example, I want pyright to accept that using a Decimal instead of a float is fine (I am aware of the limitations, but this is what is needed and I am fine with the consequences).

from decimal import Decimal
d = Decimal(1.0)
f: float = d

Pyright will say on the line f: float = d:

Expression of type "Decimal" cannot be assigned to declared type "float"

"Decimal" is incompatible with "float" Pylance(reportGeneralTypeIssues)

The options I know of are:

  • ignore reportGeneralTypeIssues completely (that would remove a lot of the power of Pyright, even inside one file)
  • ignore reportGeneralTypeIssues on each line where I have the Decimal/float conversion (visually very very polluting in my codebase)

Is there a way to tell "Ignore reportGeneralTypeIssues errors related to Decimal -> float conversions"?

Edit:

I know that there will be conversion happening down the line in my code (I am basically working with 2 types of pydantic models: one with Decimal, one with float), so I am basically looking for a no boilerplate option (yes, I could convert all Decimals to float manually, but that's not what I am looking for).

1

There are 1 answers

4
Mark On

There are several approaches to this, so I'll list a couple below:

1. Convert the type

This is the most straight-forward, we simply convert the object to a float prior to use. I would recommend this because then the types actually reflect the objects used. The entire point of using types is so that objects you use have the properties you expect.

from decimal import Decimal
d = float(Decimal(1.0))
f: float = d

2. Masking the type

This way is not ideal, but you can (for no runtime cost) mask what type is really being used behind a "cast".

from decimal import Decimal
from typing import cast
d = cast(float, Decimal(1.0))
f: float = d

This just overrides the type of the item effectively.

Syntax

You could wrap either of these in a function for brevity e.g.:

from decimal import Decimal
from typing import cast

def MyDecimal(num: float) -> float:
    return cast(float, Decimal(num))

f: float = MyDecimal(1.0)

With the above syntax you can also make use almost exactly the same, with a change to the import line:

new_decimal.py

from decimal import Decimal as DecOld
from typing import cast

def Decimal(num: float) -> float:
    return cast(float, DecOld(num))

used_file.py

from .new_decimal import Decimal
d = Decimal(1.0)
f: float = d

Hope this helps!