-
Notifications
You must be signed in to change notification settings - Fork 2
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
QoL improvements for IDEs and LSPs #41
Conversation
Inheriting from a generic type without specifying the generic fixes the generic to `Any`. This breaks strict type checking and prevents users from specifying the type that a Quantity is wrapping.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like defining __all__
(I'd ban star imports if I could and it rapidly goes out of sync) but not enough stand in the way of making an IDE happy.
Could you explain _MagnitudeType
, perhaps in other language or a with an example? I'm hung up on what "magnitude type" means - is this int
vs. float
vs numpy.ndarray
, etc.? I see bracketed Quantity
s and think of the length: FloatQuantity["nanometer"] = Field(..)
annotations we have in most of our Pydantic models. IME the data wrapped with units are typically ducky so I have not given this much thought or seen the utility.
I guess the intent here is that you can distinguish Quantity[int]
from Quantity[numpy.ndarray]
? If so, I see the value in at least distinguishing scalar and matrix values ... would a type checker actually pick up on disobeying the original annotation?
Agree with you on star imports. I think the way to think about how
Yeah exactly, the magnitude type is the data type wrapped by the quantity, the type you get when you call box_vectors: Quantity[ArrayLike]
formal_charge: Quantity[float]
I would love this feature (though I'd want to specify dimensions and not units. Or both/either I guess), and there is an open issue for it on Pint, but it hasn't seen much attention recently. One day I want to specify types like
It does for Pint quantities, but doesn't seem happy with OpenFF Quantities. This appears to be a problem with the status quo, at least in PyRight. So I guess I jumped the gun on this PR and I need to figure out what's happening there! I'll take another look after I've finished the toolkit showcase PR. Pint quantities work as expected in both pyright and mypy: from openff.units import unit
from pint import Quantity as PintQuantity
from openff.units import Quantity as OpenFFQuantity
from numpy.typing import NDArray
import numpy as np
# Create pint quantities of ints and arrays
pint_quant_int = PintQuantity(1, unit.nanometer)
pint_quant_ary = PintQuantity(np.array([1]), unit.nanometer)
# Assign the above to annotated variables
pint_quant_int_annotated_ary: PintQuantity[NDArray] = pint_quant_int # Should not typecheck
pint_quant_int_annotated_int: PintQuantity[int] = pint_quant_int # Should typecheck
pint_quant_ary_annotated_ary: PintQuantity[NDArray] = pint_quant_ary # Should not typecheck
pint_quant_ary_annotated_int: PintQuantity[int] = pint_quant_ary # should typecheck MyPy:
PyRight:
But I'm glad you brought this up explicitly because it seems MyPy and PyRight both seem not to like the way type annotations are inherited here: from openff.units import unit
from pint import Quantity as PintQuantity
from openff.units import Quantity as OpenFFQuantity
from numpy.typing import NDArray
import numpy as np
# Same for OpenFF
openff_quant_int = OpenFFQuantity(1, unit.nanometer)
openff_quant_ary = OpenFFQuantity(np.array([1]), unit.nanometer)
openff_quant_int_annotated_ary: OpenFFQuantity[NDArray] = openff_quant_int
openff_quant_int_annotated_int: OpenFFQuantity[int] = openff_quant_int
openff_quant_ary_annotated_ary: OpenFFQuantity[NDArray] = openff_quant_ary
openff_quant_ary_annotated_int: OpenFFQuantity[int] = openff_quant_ary
# Try leaving off the generic
openff_quant_int_annotated_quant: OpenFFQuantity = openff_quant_int MyPy can't seem to find the type annotation on the parent type:
PyRight finds the type annotation, but seems not to accept OpenFFQuantity as an instance of PintQuantity, leading to confusing messages (it's also unhappy with the status quo):
|
Description
I ran into a few minor barbs working with units in the Toolkit using the PyRight LSP. PyRight includes a type checker that is generally stricter than MyPy and less pedantic than
MyPy --strict
, so I love it. This PR fixes those barbs.Todos
Notable points that this PR has either accomplished or will accomplish.
__all__
to the exceptions module.Quantity
generic over its magnitude type.Quantity
was always aQuantity[Any]
.Status