Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Remove trailing commas in _PyObject_HEAD_INIT and _PyVarObject_HEAD_INIT
Removing the trailing comma allows the macros to be used in more places,
which means fewer `#ifdef Py_NOGIL` checks.

Note that the public API macros `PyObject_HEAD_INIT` and
`PyVarObject_HEAD_INIT` are not changed.
  • Loading branch information
colesbury authored and corona10 committed Oct 30, 2023
commit 94bfbdee82c421656db8e75250e7d8605e79fa36
2 changes: 1 addition & 1 deletion Include/internal/pycore_long.h
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ _PyLong_FlipSign(PyLongObject *op) {

#define _PyLong_DIGIT_INIT(val) \
{ \
.ob_base = _PyObject_HEAD_INIT(&PyLong_Type) \
.ob_base = _PyObject_HEAD_INIT(&PyLong_Type), \
.long_value = { \
.lv_tag = TAG_FROM_SIGN_AND_SIZE( \
(val) == 0 ? 0 : ((val) < 0 ? -1 : 1), \
Expand Down
6 changes: 3 additions & 3 deletions Include/internal/pycore_object.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,12 @@ PyAPI_FUNC(int) _PyObject_IsFreed(PyObject *);
{ \
.ob_refcnt = _Py_IMMORTAL_REFCNT, \
.ob_type = (type) \
},
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Loosing the trailing comma is definitely better style, but is bound to break some third party code.
I think you need to leave the comma.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is in an internal-only header (Include/internal/pycore_object.h), not used by third party code.

There's a similarly named public macro used by third party code that is not changed.

#define _PyVarObject_HEAD_INIT(type, size) \
{ \
.ob_base = _PyObject_HEAD_INIT(type) \
.ob_base = _PyObject_HEAD_INIT(type), \
.ob_size = size \
},
}
Comment thread
corona10 marked this conversation as resolved.

extern void _Py_NO_RETURN _Py_FatalRefcountErrorFunc(
const char *func,
Expand Down
14 changes: 7 additions & 7 deletions Include/internal/pycore_runtime_init.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,13 +129,13 @@ extern PyTypeObject _PyExc_MemoryError;
.latin1 = _Py_str_latin1_INIT, \
}, \
.tuple_empty = { \
.ob_base = _PyVarObject_HEAD_INIT(&PyTuple_Type, 0) \
.ob_base = _PyVarObject_HEAD_INIT(&PyTuple_Type, 0), \
}, \
.hamt_bitmap_node_empty = { \
.ob_base = _PyVarObject_HEAD_INIT(&_PyHamt_BitmapNode_Type, 0) \
.ob_base = _PyVarObject_HEAD_INIT(&_PyHamt_BitmapNode_Type, 0), \
}, \
.context_token_missing = { \
.ob_base = _PyObject_HEAD_INIT(&_PyContextTokenMissing_Type) \
.ob_base = _PyObject_HEAD_INIT(&_PyContextTokenMissing_Type), \
}, \
}, \
}, \
Expand Down Expand Up @@ -172,11 +172,11 @@ extern PyTypeObject _PyExc_MemoryError;
.singletons = { \
._not_used = 1, \
.hamt_empty = { \
.ob_base = _PyObject_HEAD_INIT(&_PyHamt_Type) \
.ob_base = _PyObject_HEAD_INIT(&_PyHamt_Type), \
.h_root = (PyHamtNode*)&_Py_SINGLETON(hamt_bitmap_node_empty), \
}, \
.last_resort_memory_error = { \
_PyObject_HEAD_INIT(&_PyExc_MemoryError) \
_PyObject_HEAD_INIT(&_PyExc_MemoryError), \
.args = (PyObject*)&_Py_SINGLETON(tuple_empty) \
}, \
}, \
Expand Down Expand Up @@ -206,7 +206,7 @@ extern PyTypeObject _PyExc_MemoryError;

#define _PyBytes_SIMPLE_INIT(CH, LEN) \
{ \
_PyVarObject_HEAD_INIT(&PyBytes_Type, (LEN)) \
_PyVarObject_HEAD_INIT(&PyBytes_Type, (LEN)), \
.ob_shash = -1, \
.ob_sval = { (CH) }, \
}
Expand All @@ -217,7 +217,7 @@ extern PyTypeObject _PyExc_MemoryError;

#define _PyUnicode_ASCII_BASE_INIT(LITERAL, ASCII) \
{ \
.ob_base = _PyObject_HEAD_INIT(&PyUnicode_Type) \
.ob_base = _PyObject_HEAD_INIT(&PyUnicode_Type), \
.length = sizeof(LITERAL) - 1, \
.hash = -1, \
.state = { \
Expand Down
10 changes: 2 additions & 8 deletions Objects/object.c
Original file line number Diff line number Diff line change
Expand Up @@ -1926,10 +1926,7 @@ PyTypeObject _PyNone_Type = {
none_new, /*tp_new */
};

PyObject _Py_NoneStruct = {
{ _Py_IMMORTAL_REFCNT },
&_PyNone_Type
};
PyObject _Py_NoneStruct = _PyObject_HEAD_INIT(&_PyNone_Type);

/* NotImplemented is an object that can be used to signal that an
operation is not implemented for the given type combination. */
Expand Down Expand Up @@ -2028,10 +2025,7 @@ PyTypeObject _PyNotImplemented_Type = {
notimplemented_new, /*tp_new */
};

PyObject _Py_NotImplementedStruct = {
{ _Py_IMMORTAL_REFCNT },
&_PyNotImplemented_Type
};
PyObject _Py_NotImplementedStruct = _PyObject_HEAD_INIT(&_PyNotImplemented_Type);


PyStatus
Expand Down
5 changes: 1 addition & 4 deletions Objects/setobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -2394,7 +2394,4 @@ static PyTypeObject _PySetDummy_Type = {
Py_TPFLAGS_DEFAULT, /*tp_flags */
};

static PyObject _dummy_struct = {
{ _Py_IMMORTAL_REFCNT },
&_PySetDummy_Type
};
static PyObject _dummy_struct = _PyObject_HEAD_INIT(&_PySetDummy_Type);
5 changes: 1 addition & 4 deletions Objects/sliceobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,7 @@ PyTypeObject PyEllipsis_Type = {
ellipsis_new, /* tp_new */
};

PyObject _Py_EllipsisObject = {
{ _Py_IMMORTAL_REFCNT },
&PyEllipsis_Type
};
PyObject _Py_EllipsisObject = _PyObject_HEAD_INIT(&PyEllipsis_Type);


/* Slice object implementation */
Expand Down
12 changes: 2 additions & 10 deletions Python/instrumentation.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,9 @@
/* Uncomment this to dump debugging output when assertions fail */
// #define INSTRUMENT_DEBUG 1

PyObject _PyInstrumentation_DISABLE =
{
.ob_refcnt = _Py_IMMORTAL_REFCNT,
.ob_type = &PyBaseObject_Type
};
PyObject _PyInstrumentation_DISABLE = _PyObject_HEAD_INIT(&PyBaseObject_Type);

PyObject _PyInstrumentation_MISSING =
{
.ob_refcnt = _Py_IMMORTAL_REFCNT,
.ob_type = &PyBaseObject_Type
};
PyObject _PyInstrumentation_MISSING = _PyObject_HEAD_INIT(&PyBaseObject_Type);

static const int8_t EVENT_FOR_OPCODE[256] = {
[RETURN_CONST] = PY_MONITORING_EVENT_PY_RETURN,
Expand Down
2 changes: 1 addition & 1 deletion Python/specialize.c
Original file line number Diff line number Diff line change
Expand Up @@ -2525,7 +2525,7 @@ static const PyBytesObject no_location = {
};

const struct _PyCode_DEF(8) _Py_InitCleanup = {
_PyVarObject_HEAD_INIT(&PyCode_Type, 3)
_PyVarObject_HEAD_INIT(&PyCode_Type, 3),
.co_consts = (PyObject *)&_Py_SINGLETON(tuple_empty),
.co_names = (PyObject *)&_Py_SINGLETON(tuple_empty),
.co_exceptiontable = (PyObject *)&_Py_SINGLETON(bytes_empty),
Expand Down
9 changes: 3 additions & 6 deletions Tools/build/deepfreeze.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ def __init__(self, file: TextIO) -> None:
self.inits: list[str] = []
self.identifiers, self.strings = self.get_identifiers_and_strings()
self.write('#include "Python.h"')
self.write('#include "internal/pycore_object.h"')
self.write('#include "internal/pycore_gc.h"')
self.write('#include "internal/pycore_code.h"')
self.write('#include "internal/pycore_frame.h"')
Expand Down Expand Up @@ -154,14 +155,10 @@ def block(self, prefix: str, suffix: str = "") -> None:
self.write("}" + suffix)

def object_head(self, typename: str) -> None:
with self.block(".ob_base =", ","):
self.write(f".ob_refcnt = _Py_IMMORTAL_REFCNT,")
self.write(f".ob_type = &{typename},")
self.write(f".ob_base = _PyObject_HEAD_INIT(&{typename}),")

def object_var_head(self, typename: str, size: int) -> None:
with self.block(".ob_base =", ","):
self.object_head(typename)
self.write(f".ob_size = {size},")
self.write(f".ob_base = _PyVarObject_HEAD_INIT(&{typename}, {size}),")

def field(self, obj: object, name: str) -> None:
self.write(f".{name} = {getattr(obj, name)},")
Expand Down