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