codekingpro/portable-devtools
114k
1#ifndef GREENLET_REFS_HPP
2#define GREENLET_REFS_HPP
3
4#define PY_SSIZE_T_CLEAN
5#include <Python.h>
6
7#include <string>
8
9//#include "greenlet_internal.hpp"
10#include "greenlet_compiler_compat.hpp"
11#include "greenlet_cpython_compat.hpp"
12#include "greenlet_exceptions.hpp"
13
14struct _greenlet;
15struct _PyMainGreenlet;
16
17typedef struct _greenlet PyGreenlet;
18extern PyTypeObject PyGreenlet_Type;
19
20
21#ifdef GREENLET_USE_STDIO
22#include <iostream>
23using std::cerr;
24using std::endl;
25#endif
26
27namespace greenlet
28{
29 class Greenlet;
30
31 static inline bool
32 IsShuttingDown()
33 {
34 // This used to check a flag set by an ``atexit`` callback.
35 // This was wrong: the interpreter is still fully functional
36 // while *all* atexit callbacks are run, and it is perfectly
37 // valid for an atexit callback that runs after our atexit
38 // callback (i.e., registered first/before ours) to want to
39 // make use of greenlet services --- this comes up easily with
40 // gevent monkey-patching. Almost immediately after atexit callbacks,
41 // and before any destructive action is taken, Python arranges
42 // for Py_IsFinalizing to become true.
43
44 // It may see me could potentially tighten this check even more (and
45 // eliminate a function call) by setting a flag in a
46 // destructor function for our PyCapsule object (_C_API) to
47 // determine when we're shutting down. ``Py_IsFinalizing``
48 // becomes true relatively early in the shutdown process,
49 // while Capsule destructor functions only run when the module
50 // has actually been torn down --- well, when all of its dicts are
51 // cleared and collected; recall that because we use
52 // single-phase init, there is a "hidden" copy of the module
53 // dict kept by CPython internals used to re-populate a module
54 // if greenlet is imported twice, so Python code can't trigger
55 // C_API to get GC'd early without seriously poking at CPython
56 // internals, e.g., by using `gc.get_referrers` to find the
57 // hidden dict. However, C extensions could have INCREF the
58 // capsule object and prevent it from *ever* getting torn
59 // down, so this isn't reliable.
60
61 // We could probably be even "smarter" and replace values in
62 // _PyGreenlet_API with different values at destruction time.
63 // For the PyObject* returning APIs, we could replace them
64 // with versions that set an exception and return null --- the
65 // benefit being that we don't have to include a
66 // Py_IsFinalizing() call in the normal path; int returning
67 // APIs would be handled on a case-by-case basis; unclear what
68 // to do with the types. This is of questionable benefit
69 // though because by the time our destructor is called, our
70 // module is about to be destroyed which may take our
71 // allocated storage with it (if CPython ever dynamically
72 // unloads loaded shared libraries, which as of 3.14 it never
73 // does).
74
75 return Py_IsFinalizing();
76 }
77
78 namespace refs
79 {
80 // Type checkers throw a TypeError if the argument is not
81 // null, and isn't of the required Python type.
82 // (We can't use most of the defined type checkers
83 // like PyList_Check, etc, directly, because they are
84 // implemented as macros.)
85 typedef void (*TypeChecker)(void*);
86
87 void
88 NoOpChecker(void*)
89 {
90 return;
91 }
92
93 void
94 GreenletChecker(void *p)
95 {
96 if (!p) {
97 return;
98 }
99 if (IsShuttingDown()) {
100 return;
101 }
102
103 PyTypeObject* typ = Py_TYPE(p);
104 // fast, common path. (PyObject_TypeCheck is a macro or
105 // static inline function, and it also does a
106 // direct comparison of the type pointers, but its fast
107 // path only handles one type)
108 if (typ == &PyGreenlet_Type) {
109 return;
110 }
111
112 if (!PyObject_TypeCheck(p, &PyGreenlet_Type)) {
113 std::string err("GreenletChecker: Expected any type of greenlet, not ");
114 err += Py_TYPE(p)->tp_name;
115 throw TypeError(err);
116 }
117 }
118
119 void
120 MainGreenletExactChecker(void *p);
121
122 template <typename T, TypeChecker>
123 class PyObjectPointer;
124
125 template<typename T, TypeChecker>
126 class OwnedReference;
127
128
129 template<typename T, TypeChecker>
130 class BorrowedReference;
131
132 typedef BorrowedReference<PyObject, NoOpChecker> BorrowedObject;
133 typedef OwnedReference<PyObject, NoOpChecker> OwnedObject;
134
135 class ImmortalObject;
136 class ImmortalString;
137
138 template<typename T, TypeChecker TC>
139 class _OwnedGreenlet;
140
141 typedef _OwnedGreenlet<PyGreenlet, GreenletChecker> OwnedGreenlet;
142 typedef _OwnedGreenlet<PyGreenlet, MainGreenletExactChecker> OwnedMainGreenlet;
143
144 template<typename T, TypeChecker TC>
145 class _BorrowedGreenlet;
146
147 typedef _BorrowedGreenlet<PyGreenlet, GreenletChecker> BorrowedGreenlet;
148
149 void
150 ContextExactChecker(void *p)
151 {
152 if (!p) {
153 return;
154 }
155 if (IsShuttingDown()) {
156 return;
157 }
158 if (!PyContext_CheckExact(p)) {
159 throw TypeError(
160 "greenlet context must be a contextvars.Context or None"
161 );
162 }
163 }
164
165 typedef OwnedReference<PyObject, ContextExactChecker> OwnedContext;
166 }
167}
168
169namespace greenlet {
170
171
172 namespace refs {
173 // A set of classes to make reference counting rules in python
174 // code explicit.
175 //
176 // Rules of use:
177 // (1) Functions returning a new reference that the caller of the
178 // function is expected to dispose of should return a
179 // ``OwnedObject`` object. This object automatically releases its
180 // reference when it goes out of scope. It works like a ``std::shared_ptr``
181 // and can be copied or used as a function parameter (but don't do
182 // that). Note that constructing a ``OwnedObject`` from a
183 // PyObject* steals the reference.
184 // (2) Parameters to functions should be either a
185 // ``OwnedObject&``, or, more generally, a ``PyObjectPointer&``.
186 // If the function needs to create its own new reference, it can
187 // do so by copying to a local ``OwnedObject``.
188 // (3) Functions returning an existing pointer that is NOT
189 // incref'd, and which the caller MUST NOT decref,
190 // should return a ``BorrowedObject``.
191
192 // XXX: The following two paragraphs do not hold for all platforms.
193 // Notably, 32-bit PPC Linux passes structs by reference, not by
194 // value, so this actually doesn't work. (Although that's the only
195 // platform that doesn't work on.) DO NOT ATTEMPT IT. The
196 // unfortunate consequence of that is that the slots which we
197 // *know* are already type safe will wind up calling the type
198 // checker function (when we had the slots accepting
199 // BorrowedGreenlet, this was bypassed), so this slows us down.
200 // TODO: Optimize this again.
201
202 // For a class with a single pointer member, whose constructor
203 // does nothing but copy a pointer parameter into the member, and
204 // which can then be converted back to the pointer type, compilers
205 // generate code that's the same as just passing the pointer.
206 // That is, func(BorrowedObject x) called like ``PyObject* p =
207 // ...; f(p)`` has 0 overhead. Similarly, they "unpack" to the
208 // pointer type with 0 overhead.
209 //
210 // If there are no virtual functions, no complex inheritance (maybe?) and
211 // no destructor, these can be directly used as parameters in
212 // Python callbacks like tp_init: the layout is the same as a
213 // single pointer. Only subclasses with trivial constructors that
214 // do nothing but set the single pointer member are safe to use
215 // that way.
216
217
218 // This is the base class for things that can be done with a
219 // PyObject pointer. It assumes nothing about memory management.
220 // NOTE: Nothing is virtual, so subclasses shouldn't add new
221 // storage fields or try to override these methods.
222 template <typename T=PyObject, TypeChecker TC=NoOpChecker>
223 class PyObjectPointer
224 {
225 public:
226 typedef T PyType;
227 protected:
228 T* p;
229 public:
230 PyObjectPointer(T* it=nullptr) : p(it)
231 {
232 TC(p);
233 }
234
235 // We don't allow automatic casting to PyObject* at this
236 // level, because then we could be passed to Py_DECREF/INCREF,
237 // but we want nothing to do with memory management. If you
238 // know better, then you can use the get() method, like on a
239 // std::shared_ptr. Except we name it borrow() to clarify that
240 // if this is a reference-tracked object, the pointer you get
241 // back will go away when the object does.
242 // TODO: This should probably not exist here, but be moved
243 // down to relevant sub-types.
244
245 T* borrow() const noexcept
246 {
247 return this->p;
248 }
249
250 PyObject* borrow_o() const noexcept
251 {
252 return reinterpret_cast<PyObject*>(this->p);
253 }
254
255 T* operator->() const noexcept
256 {
257 return this->p;
258 }
259
260 bool is_None() const noexcept
261 {
262 return this->p == Py_None;
263 }
264
265 PyObject* acquire_or_None() const noexcept
266 {
267 PyObject* result = this->p ? reinterpret_cast<PyObject*>(this->p) : Py_None;
268 Py_INCREF(result);
269 return result;
270 }
271
272 explicit operator bool() const noexcept
273 {
274 return this->p != nullptr;
275 }
276
277 bool operator!() const noexcept
278 {
279 return this->p == nullptr;
280 }
281
282 Py_ssize_t REFCNT() const noexcept
283 {
284 return p ? Py_REFCNT(p) : -42;
285 }
286
287 PyTypeObject* TYPE() const noexcept
288 {
289 return p ? Py_TYPE(p) : nullptr;
290 }
291
292 inline OwnedObject PyStr() const noexcept;
293 inline const std::string as_str() const noexcept;
294 inline OwnedObject PyGetAttr(const ImmortalObject& name) const noexcept;
295 inline OwnedObject PyRequireAttr(const char* const name) const;
296 inline OwnedObject PyRequireAttr(const ImmortalString& name) const;
297 inline OwnedObject PyCall(const BorrowedObject& arg) const;
298 inline OwnedObject PyCall(PyGreenlet* arg) const ;
299 inline OwnedObject PyCall(PyObject* arg) const ;
300 // PyObject_Call(this, args, kwargs);
301 inline OwnedObject PyCall(const BorrowedObject args,
302 const BorrowedObject kwargs) const;
303 inline OwnedObject PyCall(const OwnedObject& args,
304 const OwnedObject& kwargs) const;
305
306 protected:
307 void _set_raw_pointer(void* t)
308 {
309 TC(t);
310 p = reinterpret_cast<T*>(t);
311 }
312 void* _get_raw_pointer() const
313 {
314 return p;
315 }
316 };
317
318#ifdef GREENLET_USE_STDIO
319 template<typename T, TypeChecker TC>
320 std::ostream& operator<<(std::ostream& os, const PyObjectPointer<T, TC>& s)
321 {
322 const std::type_info& t = typeid(s);
323 os << t.name()
324 << "(addr=" << s.borrow()
325 << ", refcnt=" << s.REFCNT()
326 << ", value=" << s.as_str()
327 << ")";
328
329 return os;
330 }
331#endif
332
333 template<typename T, TypeChecker TC>
334 inline bool operator==(const PyObjectPointer<T, TC>& lhs, const PyObject* const rhs) noexcept
335 {
336 return static_cast<const void*>(lhs.borrow_o()) == static_cast<const void*>(rhs);
337 }
338
339 template<typename T, TypeChecker TC, typename X, TypeChecker XC>
340 inline bool operator==(const PyObjectPointer<T, TC>& lhs, const PyObjectPointer<X, XC>& rhs) noexcept
341 {
342 return lhs.borrow_o() == rhs.borrow_o();
343 }
344
345 template<typename T, TypeChecker TC, typename X, TypeChecker XC>
346 inline bool operator!=(const PyObjectPointer<T, TC>& lhs,
347 const PyObjectPointer<X, XC>& rhs) noexcept
348 {
349 return lhs.borrow_o() != rhs.borrow_o();
350 }
351
352 template<typename T=PyObject, TypeChecker TC=NoOpChecker>
353 class OwnedReference : public PyObjectPointer<T, TC>
354 {
355 private:
356 friend class OwnedList;
357
358 protected:
359 explicit OwnedReference(T* it) : PyObjectPointer<T, TC>(it)
360 {
361 }
362
363 public:
364
365 // Constructors
366
367 static OwnedReference<T, TC> consuming(PyObject* p)
368 {
369 return OwnedReference<T, TC>(reinterpret_cast<T*>(p));
370 }
371
372 static OwnedReference<T, TC> owning(T* p)
373 {
374 OwnedReference<T, TC> result(p);
375 Py_XINCREF(result.p);
376 return result;
377 }
378
379 OwnedReference() : PyObjectPointer<T, TC>(nullptr)
380 {}
381
382 explicit OwnedReference(const PyObjectPointer<>& other)
383 : PyObjectPointer<T, TC>(nullptr)
384 {
385 T* op = other.borrow();
386 TC(op);
387 this->p = other.borrow();
388 Py_XINCREF(this->p);
389 }
390
391 // It would be good to make use of the C++11 distinction
392 // between move and copy operations, e.g., constructing from a
393 // pointer should be a move operation.
394 // In the common case of ``OwnedObject x = Py_SomeFunction()``,
395 // the call to the copy constructor will be elided completely.
396 OwnedReference(const OwnedReference<T, TC>& other)
397 : PyObjectPointer<T, TC>(other.p)
398 {
399 Py_XINCREF(this->p);
400 }
401
402 static OwnedReference<PyObject> None()
403 {
404 Py_INCREF(Py_None);
405 return OwnedReference<PyObject>(Py_None);
406 }
407
408 // We can assign from exactly our type without any extra checking
409 OwnedReference<T, TC>& operator=(const OwnedReference<T, TC>& other)
410 {
411 Py_XINCREF(other.p);
412 const T* tmp = this->p;
413 this->p = other.p;
414 Py_XDECREF(tmp);
415 return *this;
416 }
417
418 OwnedReference<T, TC>& operator=(const BorrowedReference<T, TC> other)
419 {
420 return this->operator=(other.borrow());
421 }
422
423 OwnedReference<T, TC>& operator=(T* const other)
424 {
425 TC(other);
426 Py_XINCREF(other);
427 T* tmp = this->p;
428 this->p = other;
429 Py_XDECREF(tmp);
430 return *this;
431 }
432
433 // We can assign from an arbitrary reference type
434 // if it passes our check.
435 template<typename X, TypeChecker XC>
436 OwnedReference<T, TC>& operator=(const OwnedReference<X, XC>& other)
437 {
438 X* op = other.borrow();
439 TC(op);
440 return this->operator=(reinterpret_cast<T*>(op));
441 }
442
443 inline void steal(T* other)
444 {
445 assert(this->p == nullptr);
446 TC(other);
447 this->p = other;
448 }
449
450 T* relinquish_ownership()
451 {
452 T* result = this->p;
453 this->p = nullptr;
454 return result;
455 }
456
457 T* acquire() const
458 {
459 // Return a new reference.
460 // TODO: This may go away when we have reference objects
461 // throughout the code.
462 Py_XINCREF(this->p);
463 return this->p;
464 }
465
466 // Nothing else declares a destructor, we're the leaf, so we
467 // should be able to get away without virtual.
468 ~OwnedReference()
469 {
470 Py_CLEAR(this->p);
471 }
472
473 void CLEAR()
474 {
475 Py_CLEAR(this->p);
476 assert(this->p == nullptr);
477 }
478 };
479
480 static inline
481 void operator<<=(PyObject*& target, OwnedObject& o)
482 {
483 target = o.relinquish_ownership();
484 }
485
486
487 class NewReference : public OwnedObject
488 {
489 private:
490 G_NO_COPIES_OF_CLS(NewReference);
491 public:
492 // Consumes the reference. Only use this
493 // for API return values.
494 NewReference(PyObject* it) : OwnedObject(it)
495 {
496 }
497 };
498
499 class NewDictReference : public NewReference
500 {
501 private:
502 G_NO_COPIES_OF_CLS(NewDictReference);
503 public:
504 NewDictReference() : NewReference(PyDict_New())
505 {
506 if (!this->p) {
507 throw PyErrOccurred();
508 }
509 }
510
511 void SetItem(const char* const key, PyObject* value)
512 {
513 Require(PyDict_SetItemString(this->p, key, value));
514 }
515
516 void SetItem(const PyObjectPointer<>& key, PyObject* value)
517 {
518 Require(PyDict_SetItem(this->p, key.borrow_o(), value));
519 }
520 };
521
522 template<typename T=PyGreenlet, TypeChecker TC=GreenletChecker>
523 class _OwnedGreenlet: public OwnedReference<T, TC>
524 {
525 private:
526 protected:
527 _OwnedGreenlet(T* it) : OwnedReference<T, TC>(it)
528 {}
529
530 public:
531 _OwnedGreenlet() : OwnedReference<T, TC>()
532 {}
533
534 _OwnedGreenlet(const _OwnedGreenlet<T, TC>& other) : OwnedReference<T, TC>(other)
535 {
536 }
537 _OwnedGreenlet(OwnedMainGreenlet& other) :
538 OwnedReference<T, TC>(reinterpret_cast<T*>(other.acquire()))
539 {
540 }
541 _OwnedGreenlet(const BorrowedGreenlet& other);
542 // Steals a reference.
543 static _OwnedGreenlet<T, TC> consuming(PyGreenlet* it)
544 {
545 return _OwnedGreenlet<T, TC>(reinterpret_cast<T*>(it));
546 }
547
548 inline _OwnedGreenlet<T, TC>& operator=(const OwnedGreenlet& other)
549 {
550 return this->operator=(other.borrow());
551 }
552
553 inline _OwnedGreenlet<T, TC>& operator=(const BorrowedGreenlet& other);
554
555 _OwnedGreenlet<T, TC>& operator=(const OwnedMainGreenlet& other)
556 {
557 PyGreenlet* owned = other.acquire();
558 Py_XDECREF(this->p);
559 this->p = reinterpret_cast<T*>(owned);
560 return *this;
561 }
562
563 _OwnedGreenlet<T, TC>& operator=(T* const other)
564 {
565 OwnedReference<T, TC>::operator=(other);
566 return *this;
567 }
568
569 T* relinquish_ownership()
570 {
571 T* result = this->p;
572 this->p = nullptr;
573 return result;
574 }
575
576 PyObject* relinquish_ownership_o()
577 {
578 return reinterpret_cast<PyObject*>(relinquish_ownership());
579 }
580
581 inline Greenlet* operator->() const noexcept;
582 inline operator Greenlet*() const noexcept;
583 };
584
585 template <typename T=PyObject, TypeChecker TC=NoOpChecker>
586 class BorrowedReference : public PyObjectPointer<T, TC>
587 {
588 public:
589 // Allow implicit creation from PyObject* pointers as we
590 // transition to using these classes. Also allow automatic
591 // conversion to PyObject* for passing to C API calls and even
592 // for Py_INCREF/DECREF, because we ourselves do no memory management.
593 BorrowedReference(T* it) : PyObjectPointer<T, TC>(it)
594 {}
595
596 BorrowedReference(const PyObjectPointer<T>& ref) : PyObjectPointer<T, TC>(ref.borrow())
597 {}
598
599 BorrowedReference() : PyObjectPointer<T, TC>(nullptr)
600 {}
601
602 operator T*() const
603 {
604 return this->p;
605 }
606 };
607
608 typedef BorrowedReference<PyObject> BorrowedObject;
609 //typedef BorrowedReference<PyGreenlet> BorrowedGreenlet;
610
611 template<typename T=PyGreenlet, TypeChecker TC=GreenletChecker>
612 class _BorrowedGreenlet : public BorrowedReference<T, TC>
613 {
614 public:
615 _BorrowedGreenlet() :
616 BorrowedReference<T, TC>(nullptr)
617 {}
618
619 _BorrowedGreenlet(T* it) :
620 BorrowedReference<T, TC>(it)
621 {}
622
623 _BorrowedGreenlet(const BorrowedObject& it);
624
625 _BorrowedGreenlet(const OwnedGreenlet& it) :
626 BorrowedReference<T, TC>(it.borrow())
627 {}
628
629 _BorrowedGreenlet<T, TC>& operator=(const BorrowedObject& other);
630
631 // We get one of these for PyGreenlet, but one for PyObject
632 // is handy as well
633 operator PyObject*() const
634 {
635 return reinterpret_cast<PyObject*>(this->p);
636 }
637 Greenlet* operator->() const noexcept;
638 operator Greenlet*() const noexcept;
639 };
640
641 typedef _BorrowedGreenlet<PyGreenlet> BorrowedGreenlet;
642
643 template<typename T, TypeChecker TC>
644 _OwnedGreenlet<T, TC>::_OwnedGreenlet(const BorrowedGreenlet& other)
645 : OwnedReference<T, TC>(reinterpret_cast<T*>(other.borrow()))
646 {
647 Py_XINCREF(this->p);
648 }
649
650
651 class BorrowedMainGreenlet
652 : public _BorrowedGreenlet<PyGreenlet, MainGreenletExactChecker>
653 {
654 public:
655 BorrowedMainGreenlet(const OwnedMainGreenlet& it) :
656 _BorrowedGreenlet<PyGreenlet, MainGreenletExactChecker>(it.borrow())
657 {}
658 BorrowedMainGreenlet(PyGreenlet* it=nullptr)
659 : _BorrowedGreenlet<PyGreenlet, MainGreenletExactChecker>(it)
660 {}
661 };
662
663 template<typename T, TypeChecker TC>
664 _OwnedGreenlet<T, TC>& _OwnedGreenlet<T, TC>::operator=(const BorrowedGreenlet& other)
665 {
666 return this->operator=(other.borrow());
667 }
668
669
670 class ImmortalObject : public PyObjectPointer<>
671 {
672 private:
673 G_NO_ASSIGNMENT_OF_CLS(ImmortalObject);
674 public:
675 explicit ImmortalObject(PyObject* it) : PyObjectPointer<>(it)
676 {
677 }
678
679 ImmortalObject(const ImmortalObject& other)
680 : PyObjectPointer<>(other.p)
681 {
682
683 }
684
685 /**
686 * Become the new owner of the object. Does not change the
687 * reference count.
688 */
689 ImmortalObject& operator=(PyObject* it)
690 {
691 assert(this->p == nullptr);
692 this->p = it;
693 return *this;
694 }
695
696 static ImmortalObject consuming(PyObject* it)
697 {
698 return ImmortalObject(it);
699 }
700
701 inline operator PyObject*() const
702 {
703 return this->p;
704 }
705 };
706
707 class ImmortalString : public ImmortalObject
708 {
709 private:
710 G_NO_COPIES_OF_CLS(ImmortalString);
711 const char* str;
712 public:
713 ImmortalString(const char* const str) :
714 ImmortalObject(str ? Require(PyUnicode_InternFromString(str)) : nullptr)
715 {
716 this->str = str;
717 }
718
719 inline ImmortalString& operator=(const char* const str)
720 {
721 if (!this->p) {
722 this->p = Require(PyUnicode_InternFromString(str));
723 this->str = str;
724 }
725 else {
726 assert(this->str == str);
727 }
728 return *this;
729 }
730
731 inline operator std::string() const
732 {
733 return this->str;
734 }
735
736 };
737
738 class ImmortalEventName : public ImmortalString
739 {
740 private:
741 G_NO_COPIES_OF_CLS(ImmortalEventName);
742 public:
743 ImmortalEventName(const char* const str) : ImmortalString(str)
744 {}
745 };
746
747 class ImmortalException : public ImmortalObject
748 {
749 private:
750 G_NO_COPIES_OF_CLS(ImmortalException);
751 public:
752 ImmortalException(const char* const name, PyObject* base=nullptr) :
753 ImmortalObject(name
754 // Python 2.7 isn't const correct
755 ? Require(PyErr_NewException((char*)name, base, nullptr))
756 : nullptr)
757 {}
758
759 inline bool PyExceptionMatches() const
760 {
761 return PyErr_ExceptionMatches(this->p) > 0;
762 }
763
764 };
765
766 template<typename T, TypeChecker TC>
767 inline OwnedObject PyObjectPointer<T, TC>::PyStr() const noexcept
768 {
769 if (!this->p) {
770 return OwnedObject();
771 }
772 return OwnedObject::consuming(PyObject_Str(reinterpret_cast<PyObject*>(this->p)));
773 }
774
775 template<typename T, TypeChecker TC>
776 inline const std::string PyObjectPointer<T, TC>::as_str() const noexcept
777 {
778 // NOTE: This is not Python exception safe.
779 if (this->p) {
780 // The Python APIs return a cached char* value that's only valid
781 // as long as the original object stays around, and we're
782 // about to (probably) toss it. Hence the copy to std::string.
783 OwnedObject py_str = this->PyStr();
784 if (!py_str) {
785 return "(nil)";
786 }
787 return PyUnicode_AsUTF8(py_str.borrow());
788 }
789 return "(nil)";
790 }
791
792 template<typename T, TypeChecker TC>
793 inline OwnedObject PyObjectPointer<T, TC>::PyGetAttr(const ImmortalObject& name) const noexcept
794 {
795 assert(this->p);
796 return OwnedObject::consuming(PyObject_GetAttr(reinterpret_cast<PyObject*>(this->p), name));
797 }
798
799 template<typename T, TypeChecker TC>
800 inline OwnedObject PyObjectPointer<T, TC>::PyRequireAttr(const char* const name) const
801 {
802 assert(this->p);
803 return OwnedObject::consuming(Require(PyObject_GetAttrString(this->p, name), name));
804 }
805
806 template<typename T, TypeChecker TC>
807 inline OwnedObject PyObjectPointer<T, TC>::PyRequireAttr(const ImmortalString& name) const
808 {
809 assert(this->p);
810 return OwnedObject::consuming(Require(
811 PyObject_GetAttr(
812 reinterpret_cast<PyObject*>(this->p),
813 name
814 ),
815 name
816 ));
817 }
818
819 template<typename T, TypeChecker TC>
820 inline OwnedObject PyObjectPointer<T, TC>::PyCall(const BorrowedObject& arg) const
821 {
822 return this->PyCall(arg.borrow());
823 }
824
825 template<typename T, TypeChecker TC>
826 inline OwnedObject PyObjectPointer<T, TC>::PyCall(PyGreenlet* arg) const
827 {
828 return this->PyCall(reinterpret_cast<PyObject*>(arg));
829 }
830
831 template<typename T, TypeChecker TC>
832 inline OwnedObject PyObjectPointer<T, TC>::PyCall(PyObject* arg) const
833 {
834 assert(this->p);
835 return OwnedObject::consuming(PyObject_CallFunctionObjArgs(this->p, arg, NULL));
836 }
837
838 template<typename T, TypeChecker TC>
839 inline OwnedObject PyObjectPointer<T, TC>::PyCall(const BorrowedObject args,
840 const BorrowedObject kwargs) const
841 {
842 assert(this->p);
843 return OwnedObject::consuming(PyObject_Call(this->p, args, kwargs));
844 }
845
846 template<typename T, TypeChecker TC>
847 inline OwnedObject PyObjectPointer<T, TC>::PyCall(const OwnedObject& args,
848 const OwnedObject& kwargs) const
849 {
850 assert(this->p);
851 return OwnedObject::consuming(PyObject_Call(this->p, args.borrow(), kwargs.borrow()));
852 }
853
854 inline void
855 ListChecker(void * p)
856 {
857 if (!p) {
858 return;
859 }
860 if (!PyList_Check(p)) {
861 throw TypeError("Expected a list");
862 }
863 }
864
865 class OwnedList : public OwnedReference<PyObject, ListChecker>
866 {
867 private:
868 G_NO_ASSIGNMENT_OF_CLS(OwnedList);
869 public:
870 // TODO: Would like to use move.
871 explicit OwnedList(const OwnedObject& other)
872 : OwnedReference<PyObject, ListChecker>(other)
873 {
874 }
875
876 OwnedList& operator=(const OwnedObject& other)
877 {
878 if (other && PyList_Check(other.p)) {
879 // Valid list. Own a new reference to it, discard the
880 // reference to what we did own.
881 PyObject* new_ptr = other.p;
882 Py_INCREF(new_ptr);
883 Py_XDECREF(this->p);
884 this->p = new_ptr;
885 }
886 else {
887 // Either the other object was NULL (an error) or it
888 // wasn't a list. Either way, we're now invalidated.
889 Py_XDECREF(this->p);
890 this->p = nullptr;
891 }
892 return *this;
893 }
894
895 inline bool empty() const
896 {
897 return PyList_GET_SIZE(p) == 0;
898 }
899
900 inline Py_ssize_t size() const
901 {
902 return PyList_GET_SIZE(p);
903 }
904
905 inline BorrowedObject at(const Py_ssize_t index) const
906 {
907 return PyList_GET_ITEM(p, index);
908 }
909
910 inline void clear()
911 {
912 PyList_SetSlice(p, 0, PyList_GET_SIZE(p), NULL);
913 }
914 };
915
916 // Use this to represent the module object used at module init
917 // time.
918 // This could either be a borrowed (Py2) or new (Py3) reference;
919 // either way, we don't want to do any memory management
920 // on it here, Python itself will handle that.
921 // XXX: Actually, that's not quite right. On Python 3, if an
922 // exception occurs before we return to the interpreter, this will
923 // leak; but all previous versions also had that problem.
924 class CreatedModule : public PyObjectPointer<>
925 {
926 private:
927 G_NO_COPIES_OF_CLS(CreatedModule);
928 public:
929 CreatedModule(PyModuleDef& mod_def) : PyObjectPointer<>(
930 Require(PyModule_Create(&mod_def)))
931 {
932 }
933
934 // PyAddObject(): Add a new reference to the object to the module.
935 void PyAddObject(const char* name, const long new_bool)
936 {
937 Require(PyModule_AddIntConstant(this->p, name, new_bool));
938 }
939
940 // It is safe to pass a null value to this API because we use
941 // PyModule_AddObjectRef under the covers which allows null.
942 void PyAddObject(const char* name, const OwnedObject& new_object)
943 {
944 // The caller already owns a reference they will decref
945 // when their variable goes out of scope, we still need to
946 // incref/decref.
947 this->PyAddObject(name, new_object.borrow());
948 }
949
950 void PyAddObject(const char* name, const ImmortalObject& new_object)
951 {
952 this->PyAddObject(name, new_object.borrow());
953 }
954
955 void PyAddObject(const char* name, PyTypeObject& type)
956 {
957 this->PyAddObject(name, reinterpret_cast<PyObject*>(&type));
958 }
959
960 private:
961
962 void PyAddObject(const char* name, PyObject* new_object)
963 {
964 Require(PyModule_AddObjectRef(this->p, name, new_object));
965 }
966 };
967
968 class PyErrFetchParam : public PyObjectPointer<>
969 {
970 // Not an owned object, because we can't be initialized with
971 // one, and we only sometimes acquire ownership.
972 private:
973 G_NO_COPIES_OF_CLS(PyErrFetchParam);
974 public:
975 // To allow declaring these and passing them to
976 // PyErr_Fetch we implement the empty constructor,
977 // and the address operator.
978 PyErrFetchParam() : PyObjectPointer<>(nullptr)
979 {
980 }
981
982 PyObject** operator&()
983 {
984 return &this->p;
985 }
986
987 // This allows us to pass one directly without the &,
988 // BUT it has higher precedence than the bool operator
989 // if it's not explicit.
990 operator PyObject**()
991 {
992 return &this->p;
993 }
994
995 // We don't want to be able to pass these to Py_DECREF and
996 // such so we don't have the implicit PyObject* conversion.
997
998 inline PyObject* relinquish_ownership()
999 {
1000 PyObject* result = this->p;
1001 this->p = nullptr;
1002 return result;
1003 }
1004
1005 ~PyErrFetchParam()
1006 {
1007 Py_XDECREF(p);
1008 }
1009 };
1010
1011 class OwnedErrPiece : public OwnedObject
1012 {
1013 private:
1014
1015 public:
1016 // Unlike OwnedObject, this increments the refcount.
1017 OwnedErrPiece(PyObject* p=nullptr) : OwnedObject(p)
1018 {
1019 this->acquire();
1020 }
1021
1022 PyObject** operator&()
1023 {
1024 return &this->p;
1025 }
1026
1027 inline operator PyObject*() const
1028 {
1029 return this->p;
1030 }
1031
1032 operator PyTypeObject*() const
1033 {
1034 return reinterpret_cast<PyTypeObject*>(this->p);
1035 }
1036 };
1037
1038 // TODO: When we run on 3.12+ only (GREENLET_312), switch to the
1039 // ``PyErr_GetRaisedException`` family of functions. The
1040 // ``PyErr_Fetch`` family is deprecated on 3.12+, but is part
1041 // of the stable ABI so it's not going anywhere.
1042 class PyErrPieces
1043 {
1044 private:
1045 OwnedErrPiece type;
1046 OwnedErrPiece instance;
1047 OwnedErrPiece traceback;
1048 bool restored;
1049 public:
1050 // Takes new references; if we're destroyed before
1051 // restoring the error, we drop the references.
1052 PyErrPieces(PyObject* t, PyObject* v, PyObject* tb) :
1053 type(t),
1054 instance(v),
1055 traceback(tb),
1056 restored(0)
1057 {
1058 this->normalize();
1059 }
1060
1061 PyErrPieces() :
1062 restored(0)
1063 {
1064 // PyErr_Fetch transfers ownership to us, so
1065 // we don't actually need to INCREF; but we *do*
1066 // need to DECREF if we're not restored.
1067 PyErrFetchParam t, v, tb;
1068 PyErr_Fetch(&t, &v, &tb);
1069 type.steal(t.relinquish_ownership());
1070 instance.steal(v.relinquish_ownership());
1071 traceback.steal(tb.relinquish_ownership());
1072 }
1073
1074 void PyErrRestore()
1075 {
1076 // can only do this once
1077 assert(!this->restored);
1078 this->restored = true;
1079 PyErr_Restore(
1080 this->type.relinquish_ownership(),
1081 this->instance.relinquish_ownership(),
1082 this->traceback.relinquish_ownership());
1083 assert(!this->type && !this->instance && !this->traceback);
1084 }
1085
1086 private:
1087 void normalize()
1088 {
1089 // First, check the traceback argument, replacing None,
1090 // with NULL
1091 if (traceback.is_None()) {
1092 traceback = nullptr;
1093 }
1094
1095 if (traceback && !PyTraceBack_Check(traceback.borrow())) {
1096 throw PyErrOccurred(PyExc_TypeError,
1097 "throw() third argument must be a traceback object");
1098 }
1099
1100 if (PyExceptionClass_Check(type)) {
1101 // If we just had a type, we'll now have a type and
1102 // instance.
1103 // The type's refcount will have gone up by one
1104 // because of the instance and the instance will have
1105 // a refcount of one. Either way, we owned, and still
1106 // do own, exactly one reference.
1107 PyErr_NormalizeException(&type, &instance, &traceback);
1108
1109 }
1110 else if (PyExceptionInstance_Check(type)) {
1111 /* Raising an instance --- usually that means an
1112 object that is a subclass of BaseException, but on
1113 Python 2, that can also mean an arbitrary old-style
1114 object. The value should be a dummy. */
1115 if (instance && !instance.is_None()) {
1116 throw PyErrOccurred(
1117 PyExc_TypeError,
1118 "instance exception may not have a separate value");
1119 }
1120 /* Normalize to raise <class>, <instance> */
1121 this->instance = this->type;
1122 this->type = PyExceptionInstance_Class(instance.borrow());
1123
1124 /*
1125 It would be tempting to do this:
1126
1127 Py_ssize_t type_count = Py_REFCNT(Py_TYPE(instance.borrow()));
1128 this->type = PyExceptionInstance_Class(instance.borrow());
1129 assert(this->type.REFCNT() == type_count + 1);
1130
1131 But that doesn't work on Python 2 in the case of
1132 old-style instances: The result of Py_TYPE is going to
1133 be the global shared <type instance> that all
1134 old-style classes have, while the return of Instance_Class()
1135 will be the Python-level class object. The two are unrelated.
1136 */
1137 }
1138 else {
1139 /* Not something you can raise. throw() fails. */
1140 PyErr_Format(PyExc_TypeError,
1141 "exceptions must be classes, or instances, not %s",
1142 Py_TYPE(type.borrow())->tp_name);
1143 throw PyErrOccurred();
1144 }
1145 }
1146 };
1147
1148 // PyArg_Parse's O argument returns a borrowed reference.
1149 class PyArgParseParam : public BorrowedObject
1150 {
1151 private:
1152 G_NO_COPIES_OF_CLS(PyArgParseParam);
1153 public:
1154 explicit PyArgParseParam(PyObject* p=nullptr) : BorrowedObject(p)
1155 {
1156 }
1157
1158 inline PyObject** operator&()
1159 {
1160 return &this->p;
1161 }
1162 };
1163
1164#ifdef Py_GIL_DISABLED
1165 // building on 3.13 or newer, free-threaded
1166 class PyCriticalObjectSection {
1167 private:
1168 G_NO_COPIES_OF_CLS(PyCriticalObjectSection);
1169 PyCriticalSection _py_cs;
1170 public:
1171 explicit PyCriticalObjectSection(PyObject* p)
1172 {
1173 PyCriticalSection_Begin(&this->_py_cs, p);
1174 }
1175 explicit PyCriticalObjectSection(const PyGreenlet* p)
1176 : PyCriticalObjectSection(
1177 reinterpret_cast<PyObject*>(
1178 const_cast<PyGreenlet*>(p)))
1179 {}
1180 ~PyCriticalObjectSection()
1181 {
1182 PyCriticalSection_End(&this->_py_cs);
1183 }
1184 };
1185#else
1186 class PyCriticalObjectSection {
1187 public:
1188 explicit PyCriticalObjectSection(PyObject* UNUSED(p))
1189 {}
1190 explicit PyCriticalObjectSection(const PyGreenlet* UNUSED(p))
1191 {}
1192 };
1193
1194#endif
1195
1196
1197};};
1198
1199#endif
1200 