-
-
Notifications
You must be signed in to change notification settings - Fork 480
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
Fix hyperelliptic curve dynamic class construction to allow proper method inheritance #37613
Fix hyperelliptic curve dynamic class construction to allow proper method inheritance #37613
Conversation
Of course another idea would be something like... base_cls = None
if len(superclass) == 0:
base_cls = HyperellipticCurve_generic
class_name = "_".join(cls_name)
cls = dynamic_class(class_name,
tuple(superclass),
cls=base_cls,
doccls=HyperellipticCurve) Being changed to if not superclass:
superclass.append(HyperellipticCurve_generic)
class_name = "_".join(cls_name)
cls = dynamic_class(class_name,
tuple(superclass),
doccls=HyperellipticCurve) and simply ensure that if no children of this parent have been used we use this instead? |
After thinking about it a little more, I will write what I think is happening. When we call dynamic_class(name_of_class: str, base_classes: tuple[Class], cls: Class, ...) I believe we take the class supplied in For the current code, this then means we take
As the super class and make something which looks like...
So new_class_name has all the methods of So the question now is what's the right thing to do? As
But this will fail when no special classes have been found. I therefore think if not superclass:
superclass.append(HyperellipticCurve_generic)
class_name = "_".join(cls_name)
cls = dynamic_class(class_name,
tuple(superclass),
doccls=HyperellipticCurve) Is a reasonable fix. We will either have a tuple of classes whose parent is |
Hi @kwankyu, I hope it's OK to ask for a review on this. I saw you had previously done great work with class refactoring and that you might be a good person to check whether what I did was satisfactory for the long term usage of these constructors. |
Thank you for the comments. |
Would you rebase to the latest develop? |
Updated and merged. |
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. LGTM.
Documentation preview for this PR (built with commit 02aad62; changes) is ready! 🎉 |
While working on some hyperelliptic code, I realised the dynamic class construction had an issue with inheritance for the genus two classes and certain methods which should have been available were not.
This is discussed in more detail in the issue #37612
I do not know a good fix for this, but I have found a fix which at least allows the functions supposed to be accessed to be accessed.
I have added a small doctest to ensure that the method called for genus two curves is bound to the correct class.
Overview of the fix
The original class was constructed as:
Where
superclass
is either an empty list, a list with a single child from:HyperellipticCurve_finite_field
HyperellipticCurve_rational_field
HyperellipticCurve_padic_field
HyperellipticCurve_g2
Notice that all four of these classes are children of
HyperellipticCurve_generic
.Or, in the case of the base field being one of the above AND the curve being genus two this list is of the form:
In this case, I found that the dynamic class insertion into
cls
meant that the methods shared by one of the "superclass
" (probably should be called base classes?) andcls
itself would call the method fromcls
rather than the superclass and so all specialised functions were unavailable, making the genus two optimisations redundant.In my new fix, if
superclass
has a length of zero, I setcls
to beHyperellipticCurve_generic
, otherwisecls
isNone
.This seems to work, but I don't know if this is good practice.
Fixes #37612