Ticket #13447: trac_13447-sanitise_ring_refcount.patch

File trac_13447-sanitise_ring_refcount.patch, 28.1 KB (added by SimonKing, 7 years ago)

Combined patch

  • sage/libs/singular/function.pxd

    # HG changeset patch
    # User Nils Bruin <nbruin@sfu.ca>
    # Date 1347728520 25200
    # Node ID eb5e38623c2f31b5d0cc0fbd4d132fbec654fbb8
    # Parent  97ea48ce6d07f2457433a8bec4cf5bf4d11a401f
    #13447: Consolidate the two refcount systems implemented for libsingular rings
    * fix polynomial_zz_pex.get_cparent to return NULL on AttributeError
    * remove now unused class ring_wrapper_Py and associated functions
    
    diff --git a/sage/libs/singular/function.pxd b/sage/libs/singular/function.pxd
    a b  
    1818from sage.libs.singular.decl cimport leftv, idhdl, syStrategy, matrix, poly, ideal, intvec
    1919from sage.libs.singular.decl cimport ring as singular_ring
    2020from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomialRing_libsingular, MPolynomial_libsingular
     21from sage.libs.singular.ring cimport singular_ring_reference, singular_ring_delete
    2122
    2223cdef poly* access_singular_poly(p) except <poly*> -1
    2324cdef singular_ring* access_singular_ring(r) except <singular_ring*> -1
  • sage/libs/singular/function.pyx

    diff --git a/sage/libs/singular/function.pyx b/sage/libs/singular/function.pyx
    a b  
    146146        if not self.is_commutative():
    147147            return "<noncommutative RingWrap>"
    148148        return "<RingWrap>"
    149    
     149
    150150    def __dealloc__(self):
    151         if self._ring!=NULL:
    152             self._ring.ref -= 1
     151        singular_ring_delete(self._ring)
     152
     153    def _get_refcount(self):
     154        """
     155        Return the number of references to the wrapped ring.
     156
     157        EXAMPLES::
     158
     159            sage: from sage.libs.singular.function import singular_function
     160            sage: P.<x,y,z> = PolynomialRing(QQ)
     161            sage: ringlist = singular_function("ringlist")
     162            sage: l = ringlist(P)
     163            sage: ring = singular_function("ring")
     164            sage: W = ring(l, ring=P)
     165            sage: W._get_refcount()
     166            1
     167        """
     168        if self._ring == NULL:
     169            return 0
     170        return self._ring.ref + 1
    153171
    154172    def ngens(self):
    155173        """
     
    816834        """
    817835        Append the ring ``r`` to the list.
    818836        """
    819         cdef ring *_r =  access_singular_ring(r)
    820         _r.ref+=1
     837        cdef ring *_r =  singular_ring_reference(access_singular_ring(r))
    821838        return self._append(<void *>_r, RING_CMD)
    822839
    823840    cdef leftv *append_matrix(self, mat) except NULL:
     
    11411158            foobar (singular function)
    11421159        """
    11431160        self._name = name
    1144 
    1145         global currRingHdl
    1146         if currRingHdl == NULL:
    1147             currRingHdl = enterid("my_awesome_sage_ring", 0, RING_CMD, &IDROOT, 1)
    1148             currRingHdl.data.uring.ref += 1
     1161        self.call_handler = None
    11491162
    11501163    cdef BaseCallHandler get_call_handler(self):
    11511164        """
     
    14061419
    14071420    if si_ring != currRing: rChangeCurrRing(si_ring)
    14081421
    1409     if currRingHdl.data.uring!= currRing:
    1410         currRingHdl.data.uring.ref -= 1
    1411         currRingHdl.data.uring = currRing # ref counting?
    1412         currRingHdl.data.uring.ref += 1
     1422    if currRingHdl == NULL:
     1423        currRingHdl = rFindHdl(currRing,NULL,NULL)
     1424        if currRingHdl==NULL:
     1425            currRingHdl = enterid("my_awesome_sage_ring", 0, RING_CMD, &IDROOT, 0)
     1426            currRingHdl.data.uring = currRing
     1427
     1428    elif currRingHdl.data.uring!= currRing:
     1429        # We do not singular_ring_delete(currRingHdl.data.uring),
     1430        # since singular_ring_delete is supposed to be only called
     1431        # in __dealloc__ methods.
     1432        currRingHdl.data.uring = currRing
     1433
     1434    if self.call_handler is None:
     1435        self.call_handler = self.get_call_handler()
    14131436
    14141437    cdef Converter argument_list = Converter(args, R, attributes)
    14151438
     
    14221445    while error_messages:
    14231446        error_messages.pop()
    14241447
    1425     with opt_ctx: # we are preserving the global options state here
    1426         if signal_handler:
    1427             sig_on()
    1428             _res = self.call_handler.handle_call(argument_list, si_ring)
    1429             sig_off()
     1448    # In the Singular interpreter, we must ensure that currRing->ref > 0.
     1449    currRing.ref += 1
     1450    try:
     1451        with opt_ctx: # we are preserving the global options state here
     1452            if signal_handler:
     1453                sig_on()
     1454                _res = self.call_handler.handle_call(argument_list, si_ring)
     1455                sig_off()
     1456            else:
     1457                _res = self.call_handler.handle_call(argument_list, si_ring)
     1458
     1459        if myynest:
     1460            myynest = 0
     1461
     1462        if currentVoice:
     1463            currentVoice = NULL
     1464
     1465        if errorreported:
     1466            errorreported = 0
     1467            raise RuntimeError("Error in Singular function call '%s':\n %s"%
     1468                (self._name, "\n ".join(error_messages)))
     1469
     1470        res = argument_list.to_python(_res)
     1471
     1472        if self.call_handler.free_res():
     1473            free_leftv(_res, si_ring)
    14301474        else:
    1431             _res = self.call_handler.handle_call(argument_list, si_ring)
    1432    
    1433     if myynest:
    1434         myynest = 0
     1475            _res.CleanUp(si_ring)
    14351476
    1436     if currentVoice:
    1437         currentVoice = NULL
    1438 
    1439     if errorreported:
    1440         errorreported = 0
    1441         raise RuntimeError("Error in Singular function call '%s':\n %s"%
    1442             (self._name, "\n ".join(error_messages)))
    1443 
    1444     res = argument_list.to_python(_res)
    1445    
    1446     if self.call_handler.free_res():
    1447         free_leftv(_res, si_ring)
    1448     else:
    1449         _res.CleanUp(si_ring)
    1450    
    1451     return res
     1477        return res
     1478    finally:
     1479        currRing.ref -= 1
    14521480       
    14531481cdef class SingularLibraryFunction(SingularFunction):
    14541482    """
     
    14631491    """
    14641492    def __init__(self, name):
    14651493        """
    1466         Construct a new Singular kernel function.
     1494        Construct a new Singular library function.
    14671495
    14681496        EXAMPLES::
    14691497
     
    14751503            [y - 1, x + 1]
    14761504        """
    14771505        super(SingularLibraryFunction,self).__init__(name)
     1506        # the following will yield a NameError, if the function
     1507        # is not defined in a previously loaded library
    14781508        self.call_handler = self.get_call_handler()
    14791509
    14801510    cdef BaseCallHandler get_call_handler(self):
     
    15171547            [y - 1, x + 1]
    15181548        """
    15191549        super(SingularKernelFunction,self).__init__(name)
    1520         self.call_handler = self.get_call_handler()
     1550        # We test whether a kernel function of this name exists.
     1551        # Not that the return value of IsCmd may be zero, if currRing is NULL
     1552        # Hence, we do not create a KernelCallHandler at this point,
     1553        # unless currRing!=NULL
     1554        cdef int cmd_n = -1
     1555        arity = IsCmd(self._name, cmd_n)
     1556        if cmd_n == -1:
     1557            raise NameError("Function '%s' is not defined."%self._name)
     1558        if currRing!=NULL:
     1559            self.call_handler = KernelCallHandler(cmd_n, arity)
    15211560
    15221561    cdef BaseCallHandler get_call_handler(self):
    15231562        cdef int cmd_n = -1
     
    17901829#cdef ring*?
    17911830cdef inline RingWrap new_RingWrap(ring* r):
    17921831    cdef RingWrap ring_wrap_result = PY_NEW(RingWrap)
    1793     ring_wrap_result._ring = r
    1794     ring_wrap_result._ring.ref += 1
    1795    
     1832    ring_wrap_result._ring = singular_ring_reference(r)
    17961833    return ring_wrap_result
  • sage/libs/singular/groebner_strategy.pxd

    diff --git a/sage/libs/singular/groebner_strategy.pxd b/sage/libs/singular/groebner_strategy.pxd
    a b  
    1515
    1616cdef class NCGroebnerStrategy(SageObject):
    1717    cdef skStrategy *_strat
     18    cdef ring *_parent_ring
    1819    cdef NCPolynomialRing_plural _parent
    1920    cdef object _ideal
    2021
  • sage/libs/singular/groebner_strategy.pyx

    diff --git a/sage/libs/singular/groebner_strategy.pyx b/sage/libs/singular/groebner_strategy.pyx
    a b  
    339339
    340340        cdef NCPolynomialRing_plural R = <NCPolynomialRing_plural>L.ring()
    341341        self._parent = R
     342        self._parent_ring = singular_ring_reference(R._ring)
    342343
    343344        if not R.term_order().is_global():
    344345            raise NotImplementedError("The local case is not implemented yet.")
     
    394395            omfree(self._strat.fromQ)
    395396            id_Delete(&self._strat.Shdl, self._parent._ring)
    396397
    397             if self._parent._ring != currRing:
     398            if self._parent_ring != currRing:
    398399                oldRing = currRing
    399                 rChangeCurrRing(self._parent._ring)
     400                rChangeCurrRing(self._parent_ring)
    400401                delete_skStrategy(self._strat)
    401402                rChangeCurrRing(oldRing)
    402403            else:
    403404                delete_skStrategy(self._strat)
     405        singular_ring_delete(self._parent_ring)
    404406
    405407    def _repr_(self):
    406408        """
  • sage/libs/singular/ring.pxd

    diff --git a/sage/libs/singular/ring.pxd b/sage/libs/singular/ring.pxd
    a b  
    4848# create a new singular ring
    4949cdef ring *singular_ring_new(base_ring, n, names, term_order) except NULL
    5050
    51 # reference an existing ring
     51# incref an existing ring
    5252cdef ring *singular_ring_reference(ring *existing_ring) except NULL
    5353
    5454# carefully delete a ring once its refcount is zero
    5555cdef void singular_ring_delete(ring *doomed)
    56 
    57 # Used internally for reference counting
    58 cdef wrap_ring(ring* R)
  • sage/libs/singular/ring.pyx

    diff --git a/sage/libs/singular/ring.pyx b/sage/libs/singular/ring.pyx
    a b  
    2020from sage.libs.gmp.mpz cimport mpz_init_set_ui, mpz_init_set
    2121
    2222from sage.libs.singular.decl cimport number, lnumber, napoly, ring, currRing
    23 from sage.libs.singular.decl cimport rChangeCurrRing, rCopy0, rComplete, rDelete
     23from sage.libs.singular.decl cimport rChangeCurrRing, rCopy0, rComplete, rDelete, rKill
    2424from sage.libs.singular.decl cimport omAlloc0, omStrDup, omAlloc, omAlloc0Bin,  sip_sring_bin, rnumber_bin
    2525from sage.libs.singular.decl cimport ringorder_dp, ringorder_Dp, ringorder_lp, ringorder_rp, ringorder_ds, ringorder_Ds, ringorder_ls, ringorder_M, ringorder_C, ringorder_wp, ringorder_Wp, ringorder_ws, ringorder_Ws, ringorder_a
    2626from sage.libs.singular.decl cimport p_Copy
     
    323323    _ring.ShortOut = 0
    324324
    325325    rChangeCurrRing(_ring)
    326    
    327     wrapped_ring = wrap_ring(_ring)
    328     if wrapped_ring in ring_refcount_dict:
    329         raise ValueError('newly created ring already in dictionary??')
    330     ring_refcount_dict[wrapped_ring] = 1
     326    _ring.ref=0
    331327    return _ring
    332328
    333 
    334329#############################################################################
    335 ring_refcount_dict = {}
    336 
    337 
    338 cdef class ring_wrapper_Py(object):
    339     r"""
    340     Python object wrapping the ring pointer.
    341 
    342     This is useful to store ring pointers in Python containers.
    343 
    344     You must not construct instances of this class yourself, use
    345     :func:`wrap_ring` instead.
    346 
    347     EXAMPLES::
    348 
    349         sage: from sage.libs.singular.ring import ring_wrapper_Py
    350         sage: ring_wrapper_Py
    351         <type 'sage.libs.singular.ring.ring_wrapper_Py'>
    352     """
    353 
    354     cdef ring* _ring
    355 
    356     def __cinit__(self):
    357         """
    358         The Cython constructor.
    359        
    360         EXAMPLES::
    361        
    362             sage: from sage.libs.singular.ring import ring_wrapper_Py
    363             sage: t = ring_wrapper_Py(); t
    364             The ring pointer 0x0
    365             sage: TestSuite(t).run()
    366         """
    367         self._ring = NULL
    368 
    369     def __hash__(self):
    370         """
    371         Return a hash value so that instances can be used as dictionary keys.
    372 
    373         OUTPUT:
    374        
    375         Integer.
    376        
    377         EXAMPLES::
    378 
    379             sage: from sage.libs.singular.ring import ring_wrapper_Py
    380             sage: t = ring_wrapper_Py()
    381             sage: t.__hash__()
    382             0
    383         """
    384         return <long>(self._ring)
    385 
    386     def __repr__(self):
    387         """
    388         Return a string representation.
    389 
    390         OUTPUT:
    391 
    392         String.
    393 
    394         EXAMPLES::
    395 
    396             sage: from sage.libs.singular.ring import ring_wrapper_Py
    397             sage: t = ring_wrapper_Py()
    398             sage: t
    399             The ring pointer 0x0
    400             sage: t.__repr__()
    401             'The ring pointer 0x0'
    402         """
    403         return 'The ring pointer '+hex(self.__hash__())
    404 
    405     def __cmp__(ring_wrapper_Py left, ring_wrapper_Py right):
    406         """
    407         Compare ``left`` and ``right`` so that instances can be used as dictionary keys.
    408        
    409         INPUT:
    410 
    411         - ``right`` -- a :class:`ring_wrapper_Py`
    412        
    413         OUTPUT:
    414 
    415         -1, 0, or +1 depending on whether ``left`` and ``right`` are
    416          less than, equal, or greather than.
    417 
    418         EXAMPLES::
    419 
    420             sage: from sage.libs.singular.ring import ring_wrapper_Py
    421             sage: t = ring_wrapper_Py()
    422             sage: t.__cmp__(t)
    423             0
    424         """
    425         if left._ring < right._ring:
    426             return -1
    427         if left._ring > right._ring:
    428             return +1
    429         return 0
    430 
    431 
    432 cdef wrap_ring(ring* R):
    433     """
    434     Wrap a C ring pointer into a Python object.
    435 
    436     INPUT:
    437 
    438     - ``R`` -- a singular ring (a C datastructure).
    439 
    440     OUTPUT:
    441 
    442     A Python object :class:`ring_wrapper_Py` wrapping the C pointer.
    443     """
    444     cdef ring_wrapper_Py W = ring_wrapper_Py()
    445     W._ring = R
    446     return W
    447 
    448 
    449330cdef ring *singular_ring_reference(ring *existing_ring) except NULL:
    450331    """
    451332    Refcount the ring ``existing_ring``.
     
    466347        sage: _ = gc.collect()
    467348        sage: from sage.rings.polynomial.multi_polynomial_libsingular import MPolynomialRing_libsingular
    468349        sage: from sage.libs.singular.groebner_strategy import GroebnerStrategy
    469         sage: from sage.libs.singular.ring import ring_refcount_dict
    470         sage: n = len(ring_refcount_dict)
    471         sage: prev_rings = set(ring_refcount_dict.keys())
     350        sage: n = len([x for x in gc.get_objects() if isinstance(x,MPolynomialRing_libsingular)])
    472351        sage: P = MPolynomialRing_libsingular(GF(541), 2, ('x', 'y'), TermOrder('degrevlex', 2))
    473         sage: ring_ptr = set(ring_refcount_dict.keys()).difference(prev_rings).pop()
    474         sage: ring_ptr  # random output
    475         The ring pointer 0x7f78a646b8d0
    476         sage: ring_refcount_dict[ring_ptr]
    477         4
    478352
    479353        sage: strat = GroebnerStrategy(Ideal([P.gen(0) + P.gen(1)]))
    480         sage: ring_refcount_dict[ring_ptr]
    481         6
    482354       
    483355        sage: del strat
    484         sage: _ = gc.collect()
    485         sage: ring_refcount_dict[ring_ptr]
    486         4
    487 
    488356        sage: del P
    489357        sage: _ = gc.collect()
    490         sage: ring_ptr in ring_refcount_dict
    491         False
     358        sage: n == len([x for x in gc.get_objects() if isinstance(x,MPolynomialRing_libsingular)])
     359        True
    492360    """
    493361    if existing_ring==NULL:
    494362        raise ValueError('singular_ring_reference(ring*) called with NULL pointer.')
    495     cdef object r = wrap_ring(existing_ring)
    496     refcount = ring_refcount_dict.pop(r)
    497     ring_refcount_dict[r] = refcount+1
     363    existing_ring.ref=existing_ring.ref+1
    498364    return existing_ring
    499365
    500366
     
    530396        # this function is typically called in __deallocate__, so we can't raise an exception
    531397        import traceback
    532398        traceback.print_stack()
    533 
    534     if not ring_refcount_dict:  # arbitrary finalization order when we shut Sage down
    535399        return
    536400
    537     cdef ring_wrapper_Py r = wrap_ring(doomed)
    538     refcount = ring_refcount_dict.pop(r)
    539     if refcount > 1:
    540         ring_refcount_dict[r] = refcount-1
     401    if doomed.ref < 0:
     402        print "singular_ring_delete(ring*) called with a ring that had no references."
     403        import traceback
     404        traceback.print_stack()
    541405        return
    542 
    543     global currRing
    544     cdef ring *oldRing = currRing
    545     if currRing == doomed:
    546         rDelete(doomed)
    547         currRing = <ring*>NULL
    548     else:
    549         rChangeCurrRing(doomed)
    550         rDelete(doomed)
    551         rChangeCurrRing(oldRing)
    552    
    553 
     406    rKill(doomed)
    554407
    555408
    556409#############################################################################
     
    608461    cdef size_t addr = <size_t>currRing
    609462    print "DEBUG: currRing == "+str(hex(addr))
    610463
    611 def currRing_wrapper():
    612     """
    613     Returns a wrapper for the current ring, for use in debugging ring_refcount_dict.
    614 
    615     EXAMPLES::
    616 
    617         sage: from sage.libs.singular.ring import currRing_wrapper
    618         sage: currRing_wrapper()
    619         The ring pointer ...
    620     """
    621     return wrap_ring(currRing)
  • sage/libs/singular/singular-cdefs.pxi

    diff --git a/sage/libs/singular/singular-cdefs.pxi b/sage/libs/singular/singular-cdefs.pxi
    a b  
    426426    # ring destructor
    427427   
    428428    void rDelete(ring *r)
     429    void rKill(ring *r)
    429430
    430431    # return characteristic of r
    431432   
     
    10171018    char* rOrderingString "rOrdStr"(ring* r)
    10181019#    void rDebugPrint(ring* r)
    10191020    void pDebugPrint "p_DebugPrint" (poly*p, ring* r)
    1020    
     1021    idhdl *rFindHdl(ring *r, idhdl *n, idhdl *w)
     1022
    10211023cdef extern from "stairc.h":
    10221024    # Computes the monomial basis for R[x]/I
    10231025    ideal *scKBase(int deg, ideal *s, ideal *Q)
  • sage/modular/modsym/ambient.py

    diff --git a/sage/modular/modsym/ambient.py b/sage/modular/modsym/ambient.py
    a b  
    13411341    def boundary_space(self):
    13421342        r"""
    13431343        Return the subspace of boundary modular symbols of this modular symbols ambient space.
    1344        
     1344
    13451345        EXAMPLES::
    1346        
    1347             sage: ModularSymbols(20,2).boundary_space()
     1346
     1347            sage: M = ModularSymbols(20, 2)
     1348            sage: B = M.boundary_space(); B
    13481349            Space of Boundary Modular Symbols for Congruence Subgroup Gamma0(20) of weight 2 and over Rational Field
    1349             sage: ModularSymbols(20,2).dimension()
     1350            sage: M.cusps()
     1351            [Infinity, 0, -1/4, 1/5, -1/2, 1/10]
     1352            sage: M.dimension()
    13501353            7
    1351             sage: ModularSymbols(20,2).boundary_space().dimension()
     1354            sage: B.dimension()
    13521355            6
     1356
    13531357        """
    13541358        raise NotImplementedError
    13551359       
  • sage/rings/polynomial/multi_polynomial_libsingular.pyx

    diff --git a/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/sage/rings/polynomial/multi_polynomial_libsingular.pyx
    a b  
    392392        if self._ring != NULL:  # the constructor did not raise an exception
    393393            singular_ring_delete(self._ring)
    394394
     395    def _get_refcount(self):
     396        """
     397        Return the number of references set to this ring.
     398
     399        NOTE:
     400
     401        This is mainly for doctesting.
     402
     403        EXAMPLES::
     404
     405            sage: import gc
     406            sage: gc.collect()  # random
     407            sage: R.<x,y,z> = GF(5)[]
     408            sage: n = R._get_refcount()
     409            sage: p = x*y+z
     410            sage: R._get_refcount() == n+1
     411            True
     412            sage: del p
     413            sage: gc.collect()  # random
     414            sage: R._get_refcount() == n
     415            True
     416
     417        """
     418        if self._ring==NULL:
     419            return 0
     420        return self._ring.ref
     421   
    395422    def __copy__(self):
    396423        """
    397424        Copy ``self``.
     
    402429       
    403430            sage: import gc
    404431            sage: from sage.rings.polynomial.multi_polynomial_libsingular import MPolynomialRing_libsingular
    405             sage: from sage.libs.singular.ring import ring_refcount_dict
    406432            sage: gc.collect()  # random output
    407             sage: n = len(ring_refcount_dict)
     433            sage: n = len([x for x in gc.get_objects() if isinstance(x,MPolynomialRing_libsingular)])
    408434            sage: R = MPolynomialRing_libsingular(GF(547), 2, ('x', 'y'), TermOrder('degrevlex', 2))
    409             sage: len(ring_refcount_dict) == n + 1
     435            sage: len([x for x in gc.get_objects() if isinstance(x,MPolynomialRing_libsingular)]) == n+1
    410436            True
    411437
    412438            sage: Q = copy(R)   # indirect doctest
     
    417443            sage: del p
    418444            sage: del q
    419445            sage: gc.collect() # random output
    420             sage: len(ring_refcount_dict) == n   
     446            sage: len([x for x in gc.get_objects() if isinstance(x,MPolynomialRing_libsingular)]) == n
    421447            True
    422448        """
    423449        return self
  • sage/rings/polynomial/plural.pxd

    diff --git a/sage/rings/polynomial/plural.pxd b/sage/rings/polynomial/plural.pxd
    a b  
    44from sage.structure.element cimport RingElement, Element
    55from sage.structure.parent cimport Parent
    66from sage.libs.singular.function cimport RingWrap
     7from sage.libs.singular.ring cimport singular_ring_reference
    78from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomialRing_libsingular
    89
    910
     
    2930
    3031cdef class NCPolynomial_plural(RingElement):
    3132    cdef poly *_poly
     33    cdef ring *_parent_ring
    3234    cpdef _repr_short_(self)
    3335    cdef long _hash_c(self)
    3436    cpdef is_constant(self)
  • sage/rings/polynomial/plural.pyx

    diff --git a/sage/rings/polynomial/plural.pyx b/sage/rings/polynomial/plural.pyx
    a b  
    111111from sage.structure.parent_gens cimport ParentWithGens
    112112
    113113# singular rings
    114 from sage.libs.singular.ring cimport singular_ring_new, singular_ring_delete, wrap_ring
     114from sage.libs.singular.ring cimport singular_ring_new, singular_ring_delete
    115115import sage.libs.singular.ring
    116116
    117117from sage.rings.integer cimport Integer
     
    335335        cdef RingWrap rw = ncalgebra(self._c, self._d, ring = P)
    336336
    337337        #       rw._output()
    338         self._ring = rw._ring
     338        self._ring = singular_ring_reference(rw._ring)
    339339        self._ring.ShortOut = 0
    340340
    341341        self.__ngens = n
     
    350350       
    351351        self._one_element = new_NCP(self, p_ISet(1, self._ring))
    352352        self._zero_element = new_NCP(self, NULL)
    353        
    354353
    355354        if check:
    356355            import sage.libs.singular
     
    408407            sage: _ = gc.collect()
    409408        """
    410409        singular_ring_delete(self._ring)
    411    
     410
     411    def _get_refcount(self):
     412        """
     413        Return the number of references to the underlying c data of this ring.
     414
     415        NOTE:
     416
     417        This is mainly for doctesting.
     418
     419        EXAMPLES::
     420
     421            sage: import gc
     422            sage: gc.collect()    # random
     423            sage: from sage.libs.singular.groebner_strategy import NCGroebnerStrategy
     424            sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
     425            sage: H.<x,y,z> = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})
     426            sage: n = H._get_refcount()
     427            sage: I = H.ideal([y^2, x^2, z^2-H.one_element()])
     428            sage: strat = NCGroebnerStrategy(I)
     429
     430        We have created three elements of `H` and one Groebner strategy.
     431        Each create a reference to the underlying c data. Hence, we have::
     432
     433            sage: H._get_refcount() == n+4
     434            True
     435            sage: del strat
     436            sage: gc.collect()   # random
     437            sage: H._get_refcount() == n+3
     438            True
     439            sage: del I
     440            sage: gc.collect()   # random
     441            sage: H._get_refcount() == n
     442            True
     443            sage: p = x*y+z
     444            sage: H._get_refcount() == n+1
     445            True
     446            sage: del p
     447            sage: gc.collect()   # random
     448            sage: H._get_refcount() == n
     449            True
     450
     451        """
     452        if self._ring==NULL:
     453            return 0
     454        return self._ring.ref+1
     455
    412456    def _element_constructor_(self, element):
    413457        """
    414458        Make sure element is a valid member of self, and return the constructed element.
     
    846890           sage: Q = P._list_to_ring(rlist)
    847891           sage: Q # indirect doctest
    848892           <noncommutative RingWrap>
     893           sage: Q._get_refcount()
     894           1
     895
    849896        """
    850897
    851898        cdef ring* _ring = self._ring
     
    853900       
    854901        from sage.libs.singular.function import singular_function
    855902        ring = singular_function('ring')
    856         return ring(L, ring=self)
     903        cdef RingWrap W = ring(L, ring=self)
     904        return W
    857905
    858906# TODO: Implement this properly!
    859907#    def quotient(self, I):
     
    13571405        """
    13581406        self._poly = NULL
    13591407        self._parent = <ParentWithBase>parent
     1408        self._parent_ring = singular_ring_reference(parent._ring)
    13601409
    13611410    def __dealloc__(self):
    1362         # TODO: Warn otherwise!
    1363         # for some mysterious reason, various things may be NULL in some cases
    1364         if self._parent is not <ParentWithBase>None and (<NCPolynomialRing_plural>self._parent)._ring != NULL and self._poly != NULL:
    1365             p_Delete(&self._poly, (<NCPolynomialRing_plural>self._parent)._ring)
     1411        if self._poly != NULL:
     1412            if self._parent_ring != NULL:
     1413                p_Delete(&self._poly, self._parent_ring)
     1414        singular_ring_delete(self._parent_ring)
    13661415
    13671416#    def __call__(self, *x, **kwds): # ?
    13681417
     
    17571806            sage: f # indirect doctest
    17581807            x^3 - x*z*y + z^2 + z
    17591808        """
    1760         cdef ring *_ring = (<NCPolynomialRing_plural>self._parent)._ring
     1809        cdef ring *_ring = self._parent_ring
    17611810        s = singular_polynomial_str(self._poly, _ring)
    17621811        return s
    17631812
     
    26772726    """
    26782727    cdef NCPolynomial_plural p = PY_NEW(NCPolynomial_plural)
    26792728    p._parent = <ParentWithBase>parent
     2729    p._parent_ring = singular_ring_reference(parent._ring)
    26802730    p._poly = juice
    26812731    p_Normalize(p._poly, parent._ring)
    26822732    return p
     
    27122762
    27132763    Check that #13145 has been resolved::
    27142764
    2715         sage: h = hash(R.gen() + 1) # sets currRing
    2716         sage: from sage.libs.singular.ring import ring_refcount_dict, currRing_wrapper
    2717         sage: curcnt = ring_refcount_dict[currRing_wrapper()]
    2718         sage: newR = new_CRing(W, H.base_ring())
    2719         sage: ring_refcount_dict[currRing_wrapper()] - curcnt
    2720         1
     2765        sage: import gc
     2766        sage: gc.collect()    # random
     2767        sage: from sage.libs.singular.groebner_strategy import NCGroebnerStrategy
     2768        sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
     2769        sage: H.<x,y,z> = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})
     2770        sage: n = H._get_refcount()
     2771        sage: I = H.ideal([y^2, x^2, z^2-H.one_element()])
     2772        sage: strat = NCGroebnerStrategy(I)
     2773
     2774    We have created three elements and one Groebner strategy, and thus have
     2775    four additional references to the underlying c data::
     2776
     2777        sage: H._get_refcount() == n+4
     2778        True
     2779        sage: del strat, I
     2780        sage: gc.collect()   # random
     2781        sage: H._get_refcount() == n
     2782        True
     2783
    27212784    """
    27222785    assert( rw.is_commutative() )
    2723        
     2786
    27242787    cdef MPolynomialRing_libsingular self = <MPolynomialRing_libsingular>PY_NEW(MPolynomialRing_libsingular)
    2725        
    2726     self._ring = rw._ring
    2727 
    2728     wrapped_ring = wrap_ring(self._ring)
    2729     cur_refcnt = sage.libs.singular.ring.ring_refcount_dict.get(wrapped_ring, 0)
    2730     sage.libs.singular.ring.ring_refcount_dict[wrapped_ring] = cur_refcnt + 1
     2788
     2789    self._ring = singular_ring_reference(rw._ring)
    27312790
    27322791    self._ring.ShortOut = 0
    27332792       
     
    27902849    assert( not rw.is_commutative() )
    27912850   
    27922851    cdef NCPolynomialRing_plural self = <NCPolynomialRing_plural>PY_NEW(NCPolynomialRing_plural)
    2793     self._ring = rw._ring
    2794 
    2795     wrapped_ring = wrap_ring(self._ring)
    2796     cur_refcnt = sage.libs.singular.ring.ring_refcount_dict.get(wrapped_ring, 0)
    2797     sage.libs.singular.ring.ring_refcount_dict[wrapped_ring] = cur_refcnt + 1
     2852    self._ring = singular_ring_reference(rw._ring)
    27982853
    27992854    self._ring.ShortOut = 0
    28002855       
     
    28602915    if rw.is_commutative():
    28612916        return new_CRing(rw, base_ring)
    28622917    return new_NRing(rw, base_ring)
    2863        
    28642918
    28652919def SCA(base_ring, names, alt_vars, order='degrevlex'):
    28662920    """
     
    29082962    I = H.ideal([H.gen(i) *H.gen(i) for i in alt_vars]).twostd()
    29092963    L = H._ringlist()
    29102964    L[3] = I
    2911     W = H._list_to_ring(L)
     2965    cdef RingWrap W = H._list_to_ring(L)
    29122966    return new_NRing(W, H.base_ring())
    29132967
    29142968cdef poly *addwithcarry(poly *tempvector, poly *maxvector, int pos, ring *_ring):
  • sage/rings/polynomial/polynomial_zz_pex.pyx

    diff --git a/sage/rings/polynomial/polynomial_zz_pex.pyx b/sage/rings/polynomial/polynomial_zz_pex.pyx
    a b  
    2626    if parent is None:
    2727        return NULL
    2828    cdef ntl_ZZ_pEContext_class c
    29     c = parent._modulus
     29    try:
     30        c = parent._modulus
     31    except AttributeError:
     32        return NULL
    3033    return &(c.x)
    3134
    3235# first we include the definitions