-
Notifications
You must be signed in to change notification settings - Fork 3
MetrologyNamespace (initial PR) #9
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
Conversation
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.
Looks really good!
Minor comments about the docstring formatting.
Co-authored-by: Nathaniel Starkman <nstarman@users.noreply.github.com>
Co-authored-by: Nathaniel Starkman <nstarman@users.noreply.github.com>
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 notice that there are several type parameters with generic upper bounds (basically everything that uses TypeVar
). As I mentioned previously, this is unfortunately not supported in Python.
I'd recommend adding type-checkers to the CI, so that you can avoid this in the future.
@jorenham yes, we have them, you can observe in CI the errors I pointed out at #9 (comment). My question is how to address those errors. |
In other words, do we have to use just |
Ah nice. I must've missed it because I did not expect type-checkers to run under the "lint" label, but it's of course true that type-checking is a form of linting.
Basedmypy is indeed the only one that supports it. But it requires that you use all off the type-parameters in the upper bound on the right-hand-side. Put differently; it doesn't accept free type-parameters. That's because free type-parameters don't do anything, so you might as well leave them out (and use However, by relying on this exclusive basedmypy feature, you're effectively requiring all of your users to only use basedmypy. Because, after all, the other type-checkers don't support these parametrized upper bounds of type-parameter. The typing-spec compliant alternative is precisely like you said — using |
Okay, thanks! How does b70a68b look? |
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.
maybe I'm missing something, but I see only two type parameters here:
class Quantity[V, U: Unit](Protocol): |
Nitpick: Since you're using Quantity[Any, Any(, Any)?]
a couple of times now, you could consider defining a type _AnyQuantity = ...
for the the sake of DRY.
I think you're looking at a different commit to the tip of this branch |
Further to the above, maybe some relevant points (though likely for v2!):
|
one of the key requirements for the library was to support power systems units, which look like per-unit MW or per-unit V. These are essentially dimensionless units but it is necessary to track the original unit as well so to know what it can legitimately be converted back to. In the computation this allows transformers to be mostly ignored in some computations. But we need a mechanism to get back to the original values as well. Hence the use of dedicated per-unit flag in the unit definition. I wouldn't really suggest trying to make this mechanism more broadly applicable as it is a rather niche use case, though we do also use for other things like strain for example and other types of ratio measurements. For C to F and R and a few other temperature units there is a separate chunk of code that knows about those and do the appropriate conversion. There is also an equation flag and overloaded bit codes that know of different types of operations and inverse operations for things like dB and bel, and a few other logarithmic type operations that are inherent in some units. There isn't a general datum shift mechanism though. |
Interesting. That sounds not dissimilar to our logarithmic units, where we also have to keep track of the reference unit (e.g., |
Namespace collision isn't just between namespaces, it's within! If we implement Quantity Kinds then it will be necessary to support conversion between kinds.
I think this is an important discussion. Function or method?
Yes. This is definitely something to discuss. Even at the level of which functions should have **kwargs in their signatures? There are other functions, like |
I think we should follow the array API standard's lead https://data-apis.org/array-api/draft/purpose_and_scope.html#conformance:
thus |
I have mixed feelings on their stance. It makes for easier-to-read docs, but it's actually less correct from a static typing perspective. The Array API doesn't actually have statically typed reference code, only the docs, so our situation is a bit different. |
We've hit an impasse. This feels close to merging - should we leave the unit conversion to another PR? |
I think so! Things that seem to need further discussion:
|
Co-authored-by: Joren Hammudoglu <jhammudoglu@gmail.com>
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.
one question @andrewgsavage !
any idea why the lint CI is falling over now? |
prefix-dev/pixi-build-backends#130 I can push a workaround if they don't respond today |
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.
thanks all, looks good from my side!
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'm OK with getting this in, but note that much seems implicitly defined by typing. I'm not at all an expert on this, but there are oddities:
- What does
Quantity[V, U, D]
mean? Is it now required forQuantity
to be (partially) defined by a Dimension? Or is that still optional. I can see the point ofDimension
, but astropy'sQuantity
makes clear one can get a nice working system without it. - I don't understand the typing for the operators: the typing suggests that
other
is required to be aQuantity
, but surely that is incorrect. At least, I'd assume we wantq * 5
to work, and probablydimensionless_q + 10.
as well).
I guess the second option brings up an overall worry with most PRs so far: we've jumped straight into abstractions, but I at least work by far the best with concrete examples. Comments and docstrings would seem appropriate!
Yes, perhaps we want to expand self: "Quantity[V, U, D]", other: "Quantity[op.CanRMul[V, R], U, D]" to self: "Quantity[V, U, D]", other: "Quantity[op.CanRMul[V, R], U, D] | op.CanRMul[V, R]" |
To clarify, what this means is that class Q[V, U[D]]: ... In which case the "D" can be "hidden" / more easily left unspecified. |
@lucascolley - seems sensible for multiplication. What about the example I gave for addition? Here, unfortunately, it does depend on the unit instance, not the type... I guess the question boils down to whether, generically, any Note that in astropy there is an exception to this: we special-case zero as equivalent to 0 with any unit, so that Note that perhaps both the above should be restricted - I've been arguing elsewhere for not pre-allowing flexibility or baking in complexity. So, if some other unit libraries do not support adding non-quantities to dimensionless ones, or do not allow comparing with 0, then that's fine. Ideally, though, the documents that we produce explicitly state that support for examples like the ones above is not required. p.s. Perhaps, though, we should merge this and just open an issue about details like these... |
Agreed. Generalizing non-Quantities to Quantities is challenging and may be best left as a choice for implementing libraries. The common API of course is for Q2Q ops to work! |
alright, merging this then we can move the last comments to their own issues. |
transferred from quantity-dev/quantity-api#5