diff --git a/src/sage/rings/function_field/jacobian_base.py b/src/sage/rings/function_field/jacobian_base.py index e4b86bf79d4..67a785fa117 100644 --- a/src/sage/rings/function_field/jacobian_base.py +++ b/src/sage/rings/function_field/jacobian_base.py @@ -297,7 +297,7 @@ def __init__(self, parent, function_field, base_div) -> None: sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2) sage: J = C.jacobian(model='hess') sage: G = J.group() - sage: TestSuite(G).run(skip=['_test_elements', '_test_pickling']) + sage: TestSuite(G).run() """ super().__init__(base=IntegerRing(), category=CommutativeAdditiveGroups()) diff --git a/src/sage/rings/function_field/jacobian_hess.py b/src/sage/rings/function_field/jacobian_hess.py index dfc3c33107f..3f95f831d5b 100644 --- a/src/sage/rings/function_field/jacobian_hess.py +++ b/src/sage/rings/function_field/jacobian_hess.py @@ -130,7 +130,7 @@ def __init__(self, parent, dS, ds) -> None: sage: G = C.jacobian(model='hess', base_div=b).group() sage: pl = C([1,8,1]).place() sage: p = G.point(pl - b) - sage: TestSuite(p).run(skip=['_test_category','_test_pickling']) + sage: TestSuite(p).run() """ super().__init__(parent) self._data = (dS, ds) @@ -570,7 +570,7 @@ def __init__(self, parent, function_field, base_div) -> None: sage: b = C([0,1,0]).place() sage: J = C.jacobian(model='hess', base_div=b) sage: G = J.group() - sage: TestSuite(G).run(skip=['_test_elements', '_test_pickling']) + sage: TestSuite(G).run() """ super().__init__(parent, function_field, base_div) @@ -876,7 +876,7 @@ def __init__(self, parent, function_field, base_div) -> None: sage: b = C([0,1,0]).place() sage: J = C.jacobian(model='hess', base_div=b) sage: G = J.group() - sage: TestSuite(G).run(skip=['_test_elements','_test_pickling']) + sage: TestSuite(G).run() """ super().__init__(parent, function_field, base_div) @@ -1023,7 +1023,7 @@ def __init__(self, function_field, base_div, **kwds) -> None: sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2) sage: b = C([0,1,0]).place() sage: J = C.jacobian(model='hess', base_div=b) - sage: TestSuite(J).run(skip=['_test_elements','_test_pickling']) + sage: TestSuite(J).run() """ super().__init__(function_field, base_div, **kwds) diff --git a/src/sage/rings/function_field/jacobian_khuri_makdisi.py b/src/sage/rings/function_field/jacobian_khuri_makdisi.py index 2fb4d3bed96..cf3f8c79ca4 100644 --- a/src/sage/rings/function_field/jacobian_khuri_makdisi.py +++ b/src/sage/rings/function_field/jacobian_khuri_makdisi.py @@ -184,7 +184,7 @@ def __init__(self, parent, w) -> None: sage: G = J.group() sage: pl = C([3,2,1]).place() sage: p = G.point(pl - b) - sage: TestSuite(p).run(skip=['_test_category','_test_pickling']) + sage: TestSuite(p).run() """ super().__init__(parent) w.set_immutable() @@ -867,7 +867,7 @@ def __init__(self, parent, function_field, base_div) -> None: sage: h = C.function(y/x).divisor_of_poles() sage: J = C.jacobian(model='km_large', base_div=h) sage: G = J.group() - sage: TestSuite(G).run(skip=['_test_elements', '_test_pickling']) + sage: TestSuite(G).run() """ super().__init__(parent, function_field, base_div) @@ -988,7 +988,7 @@ def __init__(self, function_field, base_div, model, **kwds) -> None: sage: P2. = ProjectiveSpace(GF(7), 2) sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2) sage: J = C.jacobian(model='km_large') - sage: TestSuite(J).run(skip=['_test_elements', '_test_pickling']) + sage: TestSuite(J).run() :: diff --git a/src/sage/schemes/curves/projective_curve.py b/src/sage/schemes/curves/projective_curve.py index 4c3e644145b..ccde845c104 100644 --- a/src/sage/schemes/curves/projective_curve.py +++ b/src/sage/schemes/curves/projective_curve.py @@ -139,9 +139,14 @@ from builtins import sum as add from sage.categories.fields import Fields -from sage.categories.homset import hom, Hom, End +from sage.categories.homset import End, Hom, hom from sage.categories.number_fields import NumberFields -from sage.libs.singular.function import singular_function, lib as singular_lib, get_printlevel, set_printlevel +from sage.libs.singular.function import ( + get_printlevel, + set_printlevel, + singular_function, +) +from sage.libs.singular.function import lib as singular_lib from sage.matrix.constructor import matrix from sage.misc.cachefunc import cached_method from sage.misc.lazy_attribute import lazy_attribute @@ -150,27 +155,34 @@ from sage.misc.sage_eval import sage_eval from sage.rings.integer import Integer from sage.rings.integer_ring import IntegerRing -from sage.rings.polynomial.multi_polynomial_element import degree_lowest_rational_function +from sage.rings.polynomial.multi_polynomial_element import ( + degree_lowest_rational_function, +) from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.rational_field import RationalField -from sage.schemes.projective.projective_space import ProjectiveSpace, ProjectiveSpace_ring -from sage.schemes.projective.projective_subscheme import (AlgebraicScheme_subscheme_projective, - AlgebraicScheme_subscheme_projective_field) +from sage.schemes.projective.projective_space import ( + ProjectiveSpace, + ProjectiveSpace_ring, +) +from sage.schemes.projective.projective_subscheme import ( + AlgebraicScheme_subscheme_projective, + AlgebraicScheme_subscheme_projective_field, +) lazy_import('sage.interfaces.singular', 'singular') lazy_import('sage.rings.number_field.number_field', 'NumberField') -from .curve import Curve_generic - -from .point import (ProjectiveCurvePoint_field, - ProjectivePlaneCurvePoint_field, - ProjectivePlaneCurvePoint_finite_field, - IntegralProjectiveCurvePoint, - IntegralProjectiveCurvePoint_finite_field, - IntegralProjectivePlaneCurvePoint, - IntegralProjectivePlaneCurvePoint_finite_field) - from .closed_point import IntegralProjectiveCurveClosedPoint +from .curve import Curve_generic +from .point import ( + IntegralProjectiveCurvePoint, + IntegralProjectiveCurvePoint_finite_field, + IntegralProjectivePlaneCurvePoint, + IntegralProjectivePlaneCurvePoint_finite_field, + ProjectiveCurvePoint_field, + ProjectivePlaneCurvePoint_field, + ProjectivePlaneCurvePoint_finite_field, +) class ProjectiveCurve(Curve_generic, AlgebraicScheme_subscheme_projective): @@ -1449,7 +1461,7 @@ def ordinary_model(self): + (1/16*a + 1/16)*x*y*z^2 + (3/16*a + 3/16)*y^2*z^2 + (-3/16*a - 1/4)*y*z^3 + (1/16*a + 3/32)*z^4) """ - from sage.rings.qqbar import number_field_elements_from_algebraics, QQbar + from sage.rings.qqbar import QQbar, number_field_elements_from_algebraics def extension(self): # helper function for extending the base field @@ -1459,13 +1471,12 @@ def extension(self): K = number_field_elements_from_algebraics(L)[0] if isinstance(K, RationalField): return F.embeddings(F)[0] + elif isinstance(F, RationalField): + return F.embeddings(K)[0] else: - if isinstance(F, RationalField): - return F.embeddings(K)[0] - else: - # make sure the defining polynomial variable names are the same for K, N - N = NumberField(K.defining_polynomial().parent()(F.defining_polynomial()), str(K.gen())) - return N.composite_fields(K, both_maps=True)[0][1]*F.embeddings(N)[0] + # make sure the defining polynomial variable names are the same for K, N + N = NumberField(K.defining_polynomial().parent()(F.defining_polynomial()), str(K.gen())) + return N.composite_fields(K, both_maps=True)[0][1]*F.embeddings(N)[0] if self.base_ring() not in NumberFields(): raise NotImplementedError("the base ring of this curve must be a number field") if not self.is_irreducible(): @@ -2374,8 +2385,12 @@ def random_element(self): sage: P in C True """ - from sage.schemes.elliptic_curves.ell_finite_field import EllipticCurve_finite_field - from sage.schemes.hyperelliptic_curves.hyperelliptic_finite_field import HyperellipticCurve_finite_field + from sage.schemes.elliptic_curves.ell_finite_field import ( + EllipticCurve_finite_field, + ) + from sage.schemes.hyperelliptic_curves.hyperelliptic_finite_field import ( + HyperellipticCurve_finite_field, + ) if not isinstance(self, (EllipticCurve_finite_field, HyperellipticCurve_finite_field)): raise NotImplementedError("only implemented for elliptic and hyperelliptic curves over finite fields") @@ -2417,17 +2432,57 @@ def __init__(self, A, f): True """ super().__init__(A, f) - ideal = self.defining_ideal() gs = self.ambient_space().gens() for i in range(self.ngens()): if gs[i] not in ideal: - self._open_affine = self.affine_patch(i) self._open_affine_index = i break else: raise ValueError("no projective curve defined") + @lazy_attribute + def _open_affine(self): + r""" + An affine patch of the curve. + + TESTS:: + + sage: P2. = ProjectiveSpace(GF(7), 2) + sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2) + sage: C._open_affine + Affine Plane Curve over Finite Field of size 7 defined by -y^2*z - 2*z^3 + 1 + """ + return self.affine_patch(self._open_affine_index) + + def __getstate__(self): + r""" + Remove some attributes that cause issues before pickling. + These are easily recomputed anyway. + + TESTS: + + Make sure that pickling and unpickling works after + accessing attributes. See :issue:`41265`:: + + sage: P2. = ProjectiveSpace(GF(7), 2) + sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2) + sage: C._open_affine is not None + True + sage: C._map_from_function_field is not None + True + sage: loaded = loads(dumps(C)) + sage: loaded == C + True + sage: loaded._open_affine == C._open_affine + True + """ + state = super().__getstate__() + # We don't use del in case these properties haven't been accessed and cached yet + state.pop('_open_affine', None) + state.pop('_map_from_function_field', None) + return state + def function_field(self): """ Return the function field of this curve.