-
-
Notifications
You must be signed in to change notification settings - Fork 84
Implement hash for AffineScalarFunc #219
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
base: master
Are you sure you want to change the base?
Conversation
|
Last but not least, the |
I think, that is not the case, it is correct that #218 originates from #189, but it is about a different topic. Sure, if the Please let me know if I misunderstand something. |
|
Sorry @NelDav for not opening an issue to discuss further. I had wanted to, but I had not partly because discussion continued on in a few different GitHub Discussions in this repo like #218 and also just because I did not have time. I had suggested moving discussion to your fork because I thought the feedback in #189 was that it was too verbose and we should get alignment before reopening a clean PR. Here is my current understanding:
Personally, I prefer the latter option, but my impression is that the other maintainers have more reservations about treating |
Yes, @NelDav, the title of that discussion is about |
|
Yes, sorry if I have been the hold-up here. I think the various discussions here also get into the issue of what should "ideal behavior" be, and we want to do going forward, not so much about "let's fix a bug right now". I am OK with merging this, and then working to get 3.2.0 ready. That is, the more philosophical discussion for version 4.0. But, unable to resist, I would respond to @wshanks:
I think my preference would be:
But, again, that is for a future version. |
I totally agree with that. That's what I wanted to say before, but I did not find such nice words as you did.
Personally, I like this idea for the future version. It sounds like a clean solution. |
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #219 +/- ##
==========================================
- Coverage 95.59% 95.41% -0.18%
==========================================
Files 12 12
Lines 1905 1943 +38
==========================================
+ Hits 1821 1854 +33
- Misses 84 89 +5 ☔ View full report in Codecov by Sentry. |
|
See this PR on my fork where I implement a solution that allows It begins with the Next is the Finally is the *Basically I wanted a few conveniences in the API. I wanted users to be able to pass any kind of number, int, decimal, float, etc. in for the |
It is more than a week now, that I closed #189 and asked to continue discussion inside the issues of my Fork.
Nobody opened an issue. Because of that, I think that there are no further discrepancies between @wshanks, @MichaelTiemannOSC and me.
So, I want to try again and merge this changes :)
In the current master branch, there is no
__hash__function forAffineScalarFuncbut forVariable:Basics about hashes
If we just need a hash for
Variable, this would be sufficient, but it is possible to makeAffineScalarFunchashable and I think we should provide a__hash__function forAffineScalarFuncobjects as well.First, let us take a deeper look into python glossary about the term
hashable.It describes to requirements:
From this requirement, it follows that the hash must be independent from the state of the object, because otherwise the hash could change during lifetime. That means, that we can only use immutable properties of the object, to calculate the hash.
If we use the same properties, that are used to determine equality, to calculate the hash, this requirement is fulfilled.
Hashes in the uncertainties package
Let us now check how
AffinceScalarFuncbehaves in the uncertainties package.Equality of two
AffineScalarFuncobjects is relatively complicate and I do not really want to step into details here.Currently there is another issue discussing that in more detail.
However, if we use the
_linear_partproperty and the_nominal_valueproperty, we are able to calculate a hash, that compares equal, if twoAffineScalarFuncobjects compare equal.But there is still a problem, the hash equality must also be guaranteed, for comparisons, where a
AffineScalarFuncobject and aVariableobject are equal.Because of that, we cannot keep the original implementation of
__hash__inside theVariableobject.Instead, we need to use the same calculation for
Variable::__hash_as we use forAffineScalarFunc;:__hash__.Normally, removing the
__hash__function fromVariablewould do the trick, sinceAffineScalarFuncis the base class ofVariable.However, there one problem.
But before I explain this problem, let us check if the implementation of
AffineScalarFunc::__hash__fulfills the first requirement ofhashable.We note, that the
AffienScalarFuncobjects are mutable, which might be problem.But fortunately, the expanded version of
_linear_part, as well as the_nominal_valueare immutable.Because of that, also the hash is immutable and cannot change during the entire lifetime.
Now let us step into the reason, why we need to use a slightly different implementation of
__hash__forVariable.The
Variableobject has a self reference inside the_linear_part.This is a problem, when unpickling a
Variableobject. The reason for that is, that the pickle will first generate theLinearCombinationobject, before it generate theVariableobject. While doing so, it tries to calculate the hash from the self reference. But theVariableobject does not exist and the calculation will fail.For the same reason, the
__getstate__and__setstate__function must be implemented.In the end, I want to thank everybody, who contributed to this PR.