43
43
#******************************************************************************
44
44
from sage .misc .cachefunc import cached_function , cached_method
45
45
from sage .misc .lazy_attribute import lazy_class_attribute
46
+ from sage .misc .lazy_import import LazyImport
46
47
from sage .categories .category import Category
47
48
from sage .structure .sage_object import SageObject
48
49
from sage .structure .unique_representation import UniqueRepresentation
@@ -317,22 +318,37 @@ def __classget__(cls, base_category, base_category_class):
317
318
``Category``, even if it has been overriden by a
318
319
``Subquotients`` class.
319
320
320
- TESTS ::
321
+ EXAMPLES ::
321
322
322
323
sage: Sets.Subquotients
323
324
<class 'sage.categories.sets_cat.Sets.Subquotients'>
324
325
sage: Sets().Subquotients
325
326
Cached version of <function Subquotients at ...>
326
327
328
+ This method also initializes the attribute
329
+ ``_base_category_class`` if not already set::
330
+
331
+ sage: Sets.Subquotients._base_category_class
332
+ (<class 'sage.categories.sets_cat.Sets'>,)
333
+
334
+ It also forces the resolution of lazy imports (see :trac:`15648`)::
335
+
336
+ sage: type(Algebras.__dict__["Graded"])
337
+ <type 'sage.misc.lazy_import.LazyImport'>
338
+ sage: Algebras.Graded
339
+ <class 'sage.categories.graded_algebras.GradedAlgebras'>
340
+ sage: type(Algebras.__dict__["Graded"])
341
+ <type 'sage.misc.classcall_metaclass.ClasscallMetaclass'>
342
+
327
343
.. TODO::
328
344
329
345
The logic is very similar to that implemented in
330
346
:class:`CategoryWithAxiom.__classget__`. Find a way to
331
347
refactor this to avoid the duplication.
332
348
"""
333
- if base_category is None :
334
- return cls
335
-
349
+ if base_category is not None :
350
+ assert base_category . __class__ is base_category_class
351
+ assert isinstance ( base_category_class , DynamicMetaclass )
336
352
if isinstance (base_category_class , DynamicMetaclass ):
337
353
base_category_class = base_category_class .__base__
338
354
if "_base_category_class" not in cls .__dict__ :
@@ -342,6 +358,13 @@ def __classget__(cls, base_category, base_category_class):
342
358
"base category class for {} mismatch; expected {}, got {}" .format (
343
359
cls , cls ._base_category_class [0 ], base_category_class )
344
360
361
+ # Workaround #15648: if Sets.Subquotients is a LazyImport object,
362
+ # this forces the substitution of the object back into Sets
363
+ # to avoid resolving the lazy import over and over
364
+ if isinstance (base_category_class .__dict__ [cls ._functor_category ], LazyImport ):
365
+ setattr (base_category_class , cls ._functor_category , cls )
366
+ if base_category is None :
367
+ return cls
345
368
return getattr (super (base_category .__class__ .__base__ , base_category ),
346
369
cls ._functor_category )
347
370
0 commit comments