I thank all of you for your answers. And sorry for taking a bit long to reply!
After many trys and errors, here is something that works for me: ``` from sage.structure.sage_object import SageObject from sage.structure.unique_representation import CachedRepresentation class MyInteger(CachedRepresentation, SageObject): @staticmethod def __classcall_private__(cls, n): if n % 2 == 0: return MyInteger_even(n) else: return cls.__classcall__(cls, n) def __init__(self, n): self.n = n class MyInteger_even(MyInteger): def __init__(self, n): self.n = n self.half = n // 2 ``` However, this has a major drawback, as all instances that have same data are references to one another. And I don't find any way to bypass that: ``` sage: from copy import deepcopy sage: s1 = MyInteger(2) sage: s2 = MyInteger(2) sage: s3 = deepcopy(s2) sage: s1 == s2 True sage: s1 is s2 True sage: s1 == s3 True sage: s1 is s3 True sage: s1.n 2 sage: s3.n = 5 sage: s1.n 5 sage: ``` I appreciate that this may not be a problem for classes representing sets and categories (like `EuclideanSpace`). But for classes representing children elements, this may cause problems. And this is the case for me, as I need this for `FiniteDrinfeldModule` and `FiniteDrinfeldModule_rank_two` (https://trac.sagemath.org/ticket/33713). Is there a way to avoid this? Kindest regards, Antoine On Sat, 2022-05-14 at 21:07 -0700, Nils Bruin wrote: > It's probably worth pointing out that __classcall_private__ is not a standard > python facility. It looks like you need > > class Foo(metaclass=ClasscallMetaclass): > > to make it work on Foo. > > On Saturday, 14 May 2022 at 20:21:48 UTC-7 Travis Scrimshaw wrote: > > For this you want to use __classcall_private__ as otherwise you would likely > > end up in an infinite loop when you try to construct the subclass. There are > > lots of examples of this in the Sage library code. > > > > Best, > > Travis > > > > > > On Sunday, May 15, 2022 at 5:42:49 AM UTC+9 Eric Gourgoulhon wrote: > > > Hi, > > > > > > Le samedi 14 mai 2022 à 00:07:02 UTC+2, David Roe a écrit : > > > > I think the following should work: > > > > > > > > class MyObject: > > > > def __classcall__(cls, arg): > > > > if isinstance(arg, special): > > > > return typecall(MyObject_specific_case, arg) > > > > else: > > > > return typecall(MyObject, arg) > > > > > > > > plus the same __init__ you had before. I haven't checked it though.... > > > > David > > > > > > > > > > > > > > > > > An alternative is to use __classcall_private__ > > > For an example, see the class EuclideanSpace in > > > src/sage/manifolds/differentiable/examples/euclidean.py > > > > > > EuclideanSpace(n) actually returns an instance of the subclass > > > EuclideanPlane if n = 2 or of the subclass Euclidean3dimSpace if n = 3. > > > > > > Best wishes, > > > > > > Eric. > -- > You received this message because you are subscribed to a topic in the Google > Groups "sage-devel" group. > To unsubscribe from this topic, visit > https://groups.google.com/d/topic/sage-devel/PaUReuoxEXI/unsubscribe. > To unsubscribe from this group and all its topics, send an email to > sage-devel+unsubscr...@googlegroups.com. > To view this discussion on the web visit > https://groups.google.com/d/msgid/sage-devel/a8bc696f-7887-41b2-8fe9-af3ac055eb71n%40googlegroups.com > . -- You received this message because you are subscribed to the Google Groups "sage-devel" group. To unsubscribe from this group and stop receiving emails from it, send an email to sage-devel+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/sage-devel/e17a059b1fb7b120b08b088ca17d6a3df5b72d5f.camel%40gmail.com.