Ticket #13447: trac_13447-sanitise_ring_refcount.patch
File trac_13447-sanitise_ring_refcount.patch, 28.1 KB (added by , 10 years ago) |
---|
-
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 18 18 from sage.libs.singular.decl cimport leftv, idhdl, syStrategy, matrix, poly, ideal, intvec 19 19 from sage.libs.singular.decl cimport ring as singular_ring 20 20 from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomialRing_libsingular, MPolynomial_libsingular 21 from sage.libs.singular.ring cimport singular_ring_reference, singular_ring_delete 21 22 22 23 cdef poly* access_singular_poly(p) except <poly*> -1 23 24 cdef 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 146 146 if not self.is_commutative(): 147 147 return "<noncommutative RingWrap>" 148 148 return "<RingWrap>" 149 149 150 150 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 153 171 154 172 def ngens(self): 155 173 """ … … 816 834 """ 817 835 Append the ring ``r`` to the list. 818 836 """ 819 cdef ring *_r = access_singular_ring(r) 820 _r.ref+=1 837 cdef ring *_r = singular_ring_reference(access_singular_ring(r)) 821 838 return self._append(<void *>_r, RING_CMD) 822 839 823 840 cdef leftv *append_matrix(self, mat) except NULL: … … 1141 1158 foobar (singular function) 1142 1159 """ 1143 1160 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 1149 1162 1150 1163 cdef BaseCallHandler get_call_handler(self): 1151 1164 """ … … 1406 1419 1407 1420 if si_ring != currRing: rChangeCurrRing(si_ring) 1408 1421 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() 1413 1436 1414 1437 cdef Converter argument_list = Converter(args, R, attributes) 1415 1438 … … 1422 1445 while error_messages: 1423 1446 error_messages.pop() 1424 1447 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) 1430 1474 else: 1431 _res = self.call_handler.handle_call(argument_list, si_ring) 1432 1433 if myynest: 1434 myynest = 0 1475 _res.CleanUp(si_ring) 1435 1476 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 1452 1480 1453 1481 cdef class SingularLibraryFunction(SingularFunction): 1454 1482 """ … … 1463 1491 """ 1464 1492 def __init__(self, name): 1465 1493 """ 1466 Construct a new Singular kernelfunction.1494 Construct a new Singular library function. 1467 1495 1468 1496 EXAMPLES:: 1469 1497 … … 1475 1503 [y - 1, x + 1] 1476 1504 """ 1477 1505 super(SingularLibraryFunction,self).__init__(name) 1506 # the following will yield a NameError, if the function 1507 # is not defined in a previously loaded library 1478 1508 self.call_handler = self.get_call_handler() 1479 1509 1480 1510 cdef BaseCallHandler get_call_handler(self): … … 1517 1547 [y - 1, x + 1] 1518 1548 """ 1519 1549 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) 1521 1560 1522 1561 cdef BaseCallHandler get_call_handler(self): 1523 1562 cdef int cmd_n = -1 … … 1790 1829 #cdef ring*? 1791 1830 cdef inline RingWrap new_RingWrap(ring* r): 1792 1831 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) 1796 1833 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 15 15 16 16 cdef class NCGroebnerStrategy(SageObject): 17 17 cdef skStrategy *_strat 18 cdef ring *_parent_ring 18 19 cdef NCPolynomialRing_plural _parent 19 20 cdef object _ideal 20 21 -
sage/libs/singular/groebner_strategy.pyx
diff --git a/sage/libs/singular/groebner_strategy.pyx b/sage/libs/singular/groebner_strategy.pyx
a b 339 339 340 340 cdef NCPolynomialRing_plural R = <NCPolynomialRing_plural>L.ring() 341 341 self._parent = R 342 self._parent_ring = singular_ring_reference(R._ring) 342 343 343 344 if not R.term_order().is_global(): 344 345 raise NotImplementedError("The local case is not implemented yet.") … … 394 395 omfree(self._strat.fromQ) 395 396 id_Delete(&self._strat.Shdl, self._parent._ring) 396 397 397 if self._parent ._ring != currRing:398 if self._parent_ring != currRing: 398 399 oldRing = currRing 399 rChangeCurrRing(self._parent ._ring)400 rChangeCurrRing(self._parent_ring) 400 401 delete_skStrategy(self._strat) 401 402 rChangeCurrRing(oldRing) 402 403 else: 403 404 delete_skStrategy(self._strat) 405 singular_ring_delete(self._parent_ring) 404 406 405 407 def _repr_(self): 406 408 """ -
sage/libs/singular/ring.pxd
diff --git a/sage/libs/singular/ring.pxd b/sage/libs/singular/ring.pxd
a b 48 48 # create a new singular ring 49 49 cdef ring *singular_ring_new(base_ring, n, names, term_order) except NULL 50 50 51 # referencean existing ring51 # incref an existing ring 52 52 cdef ring *singular_ring_reference(ring *existing_ring) except NULL 53 53 54 54 # carefully delete a ring once its refcount is zero 55 55 cdef void singular_ring_delete(ring *doomed) 56 57 # Used internally for reference counting58 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 20 20 from sage.libs.gmp.mpz cimport mpz_init_set_ui, mpz_init_set 21 21 22 22 from sage.libs.singular.decl cimport number, lnumber, napoly, ring, currRing 23 from sage.libs.singular.decl cimport rChangeCurrRing, rCopy0, rComplete, rDelete 23 from sage.libs.singular.decl cimport rChangeCurrRing, rCopy0, rComplete, rDelete, rKill 24 24 from sage.libs.singular.decl cimport omAlloc0, omStrDup, omAlloc, omAlloc0Bin, sip_sring_bin, rnumber_bin 25 25 from 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 26 26 from sage.libs.singular.decl cimport p_Copy … … 323 323 _ring.ShortOut = 0 324 324 325 325 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 331 327 return _ring 332 328 333 334 329 ############################################################################# 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, use345 :func:`wrap_ring` instead.346 347 EXAMPLES::348 349 sage: from sage.libs.singular.ring import ring_wrapper_Py350 sage: ring_wrapper_Py351 <type 'sage.libs.singular.ring.ring_wrapper_Py'>352 """353 354 cdef ring* _ring355 356 def __cinit__(self):357 """358 The Cython constructor.359 360 EXAMPLES::361 362 sage: from sage.libs.singular.ring import ring_wrapper_Py363 sage: t = ring_wrapper_Py(); t364 The ring pointer 0x0365 sage: TestSuite(t).run()366 """367 self._ring = NULL368 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_Py380 sage: t = ring_wrapper_Py()381 sage: t.__hash__()382 0383 """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_Py397 sage: t = ring_wrapper_Py()398 sage: t399 The ring pointer 0x0400 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`` are416 less than, equal, or greather than.417 418 EXAMPLES::419 420 sage: from sage.libs.singular.ring import ring_wrapper_Py421 sage: t = ring_wrapper_Py()422 sage: t.__cmp__(t)423 0424 """425 if left._ring < right._ring:426 return -1427 if left._ring > right._ring:428 return +1429 return 0430 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 = R446 return W447 448 449 330 cdef ring *singular_ring_reference(ring *existing_ring) except NULL: 450 331 """ 451 332 Refcount the ring ``existing_ring``. … … 466 347 sage: _ = gc.collect() 467 348 sage: from sage.rings.polynomial.multi_polynomial_libsingular import MPolynomialRing_libsingular 468 349 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)]) 472 351 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 output475 The ring pointer 0x7f78a646b8d0476 sage: ring_refcount_dict[ring_ptr]477 4478 352 479 353 sage: strat = GroebnerStrategy(Ideal([P.gen(0) + P.gen(1)])) 480 sage: ring_refcount_dict[ring_ptr]481 6482 354 483 355 sage: del strat 484 sage: _ = gc.collect()485 sage: ring_refcount_dict[ring_ptr]486 4487 488 356 sage: del P 489 357 sage: _ = gc.collect() 490 sage: ring_ptr in ring_refcount_dict491 False358 sage: n == len([x for x in gc.get_objects() if isinstance(x,MPolynomialRing_libsingular)]) 359 True 492 360 """ 493 361 if existing_ring==NULL: 494 362 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 498 364 return existing_ring 499 365 500 366 … … 530 396 # this function is typically called in __deallocate__, so we can't raise an exception 531 397 import traceback 532 398 traceback.print_stack() 533 534 if not ring_refcount_dict: # arbitrary finalization order when we shut Sage down535 399 return 536 400 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-1401 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() 541 405 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) 554 407 555 408 556 409 ############################################################################# … … 608 461 cdef size_t addr = <size_t>currRing 609 462 print "DEBUG: currRing == "+str(hex(addr)) 610 463 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_wrapper618 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 426 426 # ring destructor 427 427 428 428 void rDelete(ring *r) 429 void rKill(ring *r) 429 430 430 431 # return characteristic of r 431 432 … … 1017 1018 char* rOrderingString "rOrdStr"(ring* r) 1018 1019 # void rDebugPrint(ring* r) 1019 1020 void pDebugPrint "p_DebugPrint" (poly*p, ring* r) 1020 1021 idhdl *rFindHdl(ring *r, idhdl *n, idhdl *w) 1022 1021 1023 cdef extern from "stairc.h": 1022 1024 # Computes the monomial basis for R[x]/I 1023 1025 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 1341 1341 def boundary_space(self): 1342 1342 r""" 1343 1343 Return the subspace of boundary modular symbols of this modular symbols ambient space. 1344 1344 1345 1345 EXAMPLES:: 1346 1347 sage: ModularSymbols(20,2).boundary_space() 1346 1347 sage: M = ModularSymbols(20, 2) 1348 sage: B = M.boundary_space(); B 1348 1349 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() 1350 1353 7 1351 sage: ModularSymbols(20,2).boundary_space().dimension()1354 sage: B.dimension() 1352 1355 6 1356 1353 1357 """ 1354 1358 raise NotImplementedError 1355 1359 -
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 392 392 if self._ring != NULL: # the constructor did not raise an exception 393 393 singular_ring_delete(self._ring) 394 394 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 395 422 def __copy__(self): 396 423 """ 397 424 Copy ``self``. … … 402 429 403 430 sage: import gc 404 431 sage: from sage.rings.polynomial.multi_polynomial_libsingular import MPolynomialRing_libsingular 405 sage: from sage.libs.singular.ring import ring_refcount_dict406 432 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)]) 408 434 sage: R = MPolynomialRing_libsingular(GF(547), 2, ('x', 'y'), TermOrder('degrevlex', 2)) 409 sage: len( ring_refcount_dict) == n +1435 sage: len([x for x in gc.get_objects() if isinstance(x,MPolynomialRing_libsingular)]) == n+1 410 436 True 411 437 412 438 sage: Q = copy(R) # indirect doctest … … 417 443 sage: del p 418 444 sage: del q 419 445 sage: gc.collect() # random output 420 sage: len( ring_refcount_dict) == n446 sage: len([x for x in gc.get_objects() if isinstance(x,MPolynomialRing_libsingular)]) == n 421 447 True 422 448 """ 423 449 return self -
sage/rings/polynomial/plural.pxd
diff --git a/sage/rings/polynomial/plural.pxd b/sage/rings/polynomial/plural.pxd
a b 4 4 from sage.structure.element cimport RingElement, Element 5 5 from sage.structure.parent cimport Parent 6 6 from sage.libs.singular.function cimport RingWrap 7 from sage.libs.singular.ring cimport singular_ring_reference 7 8 from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomialRing_libsingular 8 9 9 10 … … 29 30 30 31 cdef class NCPolynomial_plural(RingElement): 31 32 cdef poly *_poly 33 cdef ring *_parent_ring 32 34 cpdef _repr_short_(self) 33 35 cdef long _hash_c(self) 34 36 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 111 111 from sage.structure.parent_gens cimport ParentWithGens 112 112 113 113 # singular rings 114 from sage.libs.singular.ring cimport singular_ring_new, singular_ring_delete , wrap_ring114 from sage.libs.singular.ring cimport singular_ring_new, singular_ring_delete 115 115 import sage.libs.singular.ring 116 116 117 117 from sage.rings.integer cimport Integer … … 335 335 cdef RingWrap rw = ncalgebra(self._c, self._d, ring = P) 336 336 337 337 # rw._output() 338 self._ring = rw._ring338 self._ring = singular_ring_reference(rw._ring) 339 339 self._ring.ShortOut = 0 340 340 341 341 self.__ngens = n … … 350 350 351 351 self._one_element = new_NCP(self, p_ISet(1, self._ring)) 352 352 self._zero_element = new_NCP(self, NULL) 353 354 353 355 354 if check: 356 355 import sage.libs.singular … … 408 407 sage: _ = gc.collect() 409 408 """ 410 409 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 412 456 def _element_constructor_(self, element): 413 457 """ 414 458 Make sure element is a valid member of self, and return the constructed element. … … 846 890 sage: Q = P._list_to_ring(rlist) 847 891 sage: Q # indirect doctest 848 892 <noncommutative RingWrap> 893 sage: Q._get_refcount() 894 1 895 849 896 """ 850 897 851 898 cdef ring* _ring = self._ring … … 853 900 854 901 from sage.libs.singular.function import singular_function 855 902 ring = singular_function('ring') 856 return ring(L, ring=self) 903 cdef RingWrap W = ring(L, ring=self) 904 return W 857 905 858 906 # TODO: Implement this properly! 859 907 # def quotient(self, I): … … 1357 1405 """ 1358 1406 self._poly = NULL 1359 1407 self._parent = <ParentWithBase>parent 1408 self._parent_ring = singular_ring_reference(parent._ring) 1360 1409 1361 1410 def __dealloc__(self): 1362 # TODO: Warn otherwise!1363 # for some mysterious reason, various things may be NULL in some cases1364 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) 1366 1415 1367 1416 # def __call__(self, *x, **kwds): # ? 1368 1417 … … 1757 1806 sage: f # indirect doctest 1758 1807 x^3 - x*z*y + z^2 + z 1759 1808 """ 1760 cdef ring *_ring = (<NCPolynomialRing_plural>self._parent)._ring1809 cdef ring *_ring = self._parent_ring 1761 1810 s = singular_polynomial_str(self._poly, _ring) 1762 1811 return s 1763 1812 … … 2677 2726 """ 2678 2727 cdef NCPolynomial_plural p = PY_NEW(NCPolynomial_plural) 2679 2728 p._parent = <ParentWithBase>parent 2729 p._parent_ring = singular_ring_reference(parent._ring) 2680 2730 p._poly = juice 2681 2731 p_Normalize(p._poly, parent._ring) 2682 2732 return p … … 2712 2762 2713 2763 Check that #13145 has been resolved:: 2714 2764 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 2721 2784 """ 2722 2785 assert( rw.is_commutative() ) 2723 2786 2724 2787 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) 2731 2790 2732 2791 self._ring.ShortOut = 0 2733 2792 … … 2790 2849 assert( not rw.is_commutative() ) 2791 2850 2792 2851 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) 2798 2853 2799 2854 self._ring.ShortOut = 0 2800 2855 … … 2860 2915 if rw.is_commutative(): 2861 2916 return new_CRing(rw, base_ring) 2862 2917 return new_NRing(rw, base_ring) 2863 2864 2918 2865 2919 def SCA(base_ring, names, alt_vars, order='degrevlex'): 2866 2920 """ … … 2908 2962 I = H.ideal([H.gen(i) *H.gen(i) for i in alt_vars]).twostd() 2909 2963 L = H._ringlist() 2910 2964 L[3] = I 2911 W = H._list_to_ring(L)2965 cdef RingWrap W = H._list_to_ring(L) 2912 2966 return new_NRing(W, H.base_ring()) 2913 2967 2914 2968 cdef 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 26 26 if parent is None: 27 27 return NULL 28 28 cdef ntl_ZZ_pEContext_class c 29 c = parent._modulus 29 try: 30 c = parent._modulus 31 except AttributeError: 32 return NULL 30 33 return &(c.x) 31 34 32 35 # first we include the definitions