extern "C" {
#endif
+#define _PyObject_SIZE(typeobj) ( (typeobj)->tp_basicsize )
+
+/* _PyObject_VAR_SIZE returns the number of bytes (as size_t) allocated for a
+ vrbl-size object with nitems items, exclusive of gc overhead (if any). The
+ value is rounded up to the closest multiple of sizeof(void *), in order to
+ ensure that pointer fields at the end of the object are correctly aligned
+ for the platform (this is of special importance for subclasses of, e.g.,
+ str or int, so that pointers can be stored after the embedded data).
+
+ Note that there's no memory wastage in doing this, as malloc has to
+ return (at worst) pointer-aligned memory anyway.
+*/
+#if ((SIZEOF_VOID_P - 1) & SIZEOF_VOID_P) != 0
+# error "_PyObject_VAR_SIZE requires SIZEOF_VOID_P be a power of 2"
+#endif
+
+#define _PyObject_VAR_SIZE(typeobj, nitems) \
+ _Py_SIZE_ROUND_UP((typeobj)->tp_basicsize + \
+ (nitems)*(typeobj)->tp_itemsize, \
+ SIZEOF_VOID_P)
+
+
+/* This example code implements an object constructor with a custom
+ allocator, where PyObject_New is inlined, and shows the important
+ distinction between two steps (at least):
+ 1) the actual allocation of the object storage;
+ 2) the initialization of the Python specific fields
+ in this storage with PyObject_{Init, InitVar}.
+
+ PyObject *
+ YourObject_New(...)
+ {
+ PyObject *op;
+
+ op = (PyObject *) Your_Allocator(_PyObject_SIZE(YourTypeStruct));
+ if (op == NULL)
+ return PyErr_NoMemory();
+
+ PyObject_Init(op, &YourTypeStruct);
+
+ op->ob_field = value;
+ ...
+ return op;
+ }
+
+ Note that in C++, the use of the new operator usually implies that
+ the 1st step is performed automatically for you, so in a C++ class
+ constructor you would start directly with PyObject_Init/InitVar. */
+
+
/* Inline functions trading binary compatibility for speed:
PyObject_INIT() is the fast version of PyObject_Init(), and
PyObject_INIT_VAR() is the fast version of PyObject_InitVar().
PyAPI_FUNC(PyObject *) _PyObject_New(PyTypeObject *);
PyAPI_FUNC(PyVarObject *) _PyObject_NewVar(PyTypeObject *, Py_ssize_t);
-#define PyObject_New(type, typeobj) \
- ( (type *) _PyObject_New(typeobj) )
+#define PyObject_New(type, typeobj) ((type *)_PyObject_New(typeobj))
+
+// Alias to PyObject_New(). In Python 3.8, PyObject_NEW() called directly
+// PyObject_MALLOC() with _PyObject_SIZE().
+#define PyObject_NEW(type, typeobj) PyObject_New(type, typeobj)
+
#define PyObject_NewVar(type, typeobj, n) \
( (type *) _PyObject_NewVar((typeobj), (n)) )
-#define _PyObject_SIZE(typeobj) ( (typeobj)->tp_basicsize )
+// Alias to PyObject_New(). In Python 3.8, PyObject_NEW() called directly
+// PyObject_MALLOC() with _PyObject_VAR_SIZE().
+#define PyObject_NEW_VAR(type, typeobj, n) PyObject_NewVar(type, typeobj, n)
#ifdef Py_LIMITED_API
#endif
-/* _PyObject_VAR_SIZE returns the number of bytes (as size_t) allocated for a
- vrbl-size object with nitems items, exclusive of gc overhead (if any). The
- value is rounded up to the closest multiple of sizeof(void *), in order to
- ensure that pointer fields at the end of the object are correctly aligned
- for the platform (this is of special importance for subclasses of, e.g.,
- str or int, so that pointers can be stored after the embedded data).
-
- Note that there's no memory wastage in doing this, as malloc has to
- return (at worst) pointer-aligned memory anyway.
-*/
-#if ((SIZEOF_VOID_P - 1) & SIZEOF_VOID_P) != 0
-# error "_PyObject_VAR_SIZE requires SIZEOF_VOID_P be a power of 2"
-#endif
-
-#define _PyObject_VAR_SIZE(typeobj, nitems) \
- _Py_SIZE_ROUND_UP((typeobj)->tp_basicsize + \
- (nitems)*(typeobj)->tp_itemsize, \
- SIZEOF_VOID_P)
-
-#define PyObject_NEW(type, typeobj) \
-( (type *) PyObject_Init( \
- (PyObject *) PyObject_MALLOC( _PyObject_SIZE(typeobj) ), (typeobj)) )
-
-#define PyObject_NEW_VAR(type, typeobj, n) \
-( (type *) PyObject_InitVar( \
- (PyVarObject *) PyObject_MALLOC(_PyObject_VAR_SIZE((typeobj),(n)) ),\
- (typeobj), (n)) )
-
-/* This example code implements an object constructor with a custom
- allocator, where PyObject_New is inlined, and shows the important
- distinction between two steps (at least):
- 1) the actual allocation of the object storage;
- 2) the initialization of the Python specific fields
- in this storage with PyObject_{Init, InitVar}.
-
- PyObject *
- YourObject_New(...)
- {
- PyObject *op;
-
- op = (PyObject *) Your_Allocator(_PyObject_SIZE(YourTypeStruct));
- if (op == NULL)
- return PyErr_NoMemory();
-
- PyObject_Init(op, &YourTypeStruct);
-
- op->ob_field = value;
- ...
- return op;
- }
-
- Note that in C++, the use of the new operator usually implies that
- the 1st step is performed automatically for you, so in a C++ class
- constructor you would start directly with PyObject_Init/InitVar
-*/
-
-
-
/*
* Garbage Collection Support
* ==========================
--- /dev/null
+The :c:func:`PyObject_NEW` macro becomes an alias to the :c:func:`PyObject_New`
+macro, and the :c:func:`PyObject_NEW_VAR` macro becomes an alias to the
+:c:func:`PyObject_NewVar` macro, to hide implementation details. They no longer
+access directly the :c:member:`PyTypeObject.tp_basicsize` member.
{
PyCursesPanelObject *po;
- po = PyObject_NEW(PyCursesPanelObject,
+ po = PyObject_New(PyCursesPanelObject,
(PyTypeObject *)(_curses_panelstate_global)->PyCursesPanel_Type);
if (po == NULL) return NULL;
po->pan = pan;
encoding = "utf-8";
}
- wo = PyObject_NEW(PyCursesWindowObject, &PyCursesWindow_Type);
+ wo = PyObject_New(PyCursesWindowObject, &PyCursesWindow_Type);
if (wo == NULL) return NULL;
wo->win = win;
wo->encoding = _PyMem_Strdup(encoding);
n = PyList_GET_SIZE(code);
/* coverity[ampersand_in_size] */
- self = PyObject_NEW_VAR(PatternObject, &Pattern_Type, n);
+ self = PyObject_NewVar(PatternObject, &Pattern_Type, n);
if (!self)
return NULL;
self->weakreflist = NULL;
/* create match object (with room for extra group marks) */
/* coverity[ampersand_in_size] */
- match = PyObject_NEW_VAR(MatchObject, &Match_Type,
- 2*(pattern->groups+1));
+ match = PyObject_NewVar(MatchObject, &Match_Type,
+ 2*(pattern->groups+1));
if (!match)
return NULL;
ScannerObject* scanner;
/* create scanner object */
- scanner = PyObject_NEW(ScannerObject, &Scanner_Type);
+ scanner = PyObject_New(ScannerObject, &Scanner_Type);
if (!scanner)
return NULL;
scanner->pattern = NULL;
return NULL;
}
- capsule = PyObject_NEW(PyCapsule, &PyCapsule_Type);
+ capsule = PyObject_New(PyCapsule, &PyCapsule_Type);
if (capsule == NULL) {
return NULL;
}
cell2arg = NULL;
}
}
- co = PyObject_NEW(PyCodeObject, &PyCode_Type);
+ co = PyObject_New(PyCodeObject, &PyCode_Type);
if (co == NULL) {
if (cell2arg)
PyMem_FREE(cell2arg);
PyObject *
_PyObject_New(PyTypeObject *tp)
{
- PyObject *op;
- op = (PyObject *) PyObject_MALLOC(_PyObject_SIZE(tp));
- if (op == NULL)
+ PyObject *op = (PyObject *) PyObject_MALLOC(_PyObject_SIZE(tp));
+ if (op == NULL) {
return PyErr_NoMemory();
- return PyObject_INIT(op, tp);
+ }
+ PyObject_INIT(op, tp);
+ return op;
}
PyVarObject *
static PyObject*
record_new(MSIHANDLE h)
{
- msiobj *result = PyObject_NEW(struct msiobj, &record_Type);
+ msiobj *result = PyObject_New(struct msiobj, &record_Type);
if (!result) {
MsiCloseHandle(h);
if ((status = MsiDatabaseOpenView(msidb->h, sql, &hView)) != ERROR_SUCCESS)
return msierror(status);
- result = PyObject_NEW(struct msiobj, &msiview_Type);
+ result = PyObject_New(struct msiobj, &msiview_Type);
if (!result) {
MsiCloseHandle(hView);
return NULL;
if (status != ERROR_SUCCESS)
return msierror(status);
- oresult = PyObject_NEW(struct msiobj, &summary_Type);
+ oresult = PyObject_New(struct msiobj, &summary_Type);
if (!oresult) {
MsiCloseHandle(result);
return NULL;
if (status != ERROR_SUCCESS)
return msierror(status);
- result = PyObject_NEW(struct msiobj, &msidb_Type);
+ result = PyObject_New(struct msiobj, &msidb_Type);
if (!result) {
MsiCloseHandle(h);
return NULL;
PyObject *
PyHKEY_New(HKEY hInit)
{
- PyHKEYObject *key = PyObject_NEW(PyHKEYObject, &PyHKEY_Type);
+ PyHKEYObject *key = PyObject_New(PyHKEYObject, &PyHKEY_Type);
if (key)
key->hkey = hInit;
return (PyObject *)key;