Skip to content

Commit

Permalink
gh-89188: Implement PyUnicode_KIND() as a function (#129412)
Browse files Browse the repository at this point in the history
Implement PyUnicode_KIND() and PyUnicode_DATA() as function, in
addition to the macros with the same names. The macros rely on C bit
fields which have compiler-specific layout.
  • Loading branch information
vstinner authored Jan 30, 2025
1 parent e1c4ba9 commit a810cb8
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 2 deletions.
8 changes: 6 additions & 2 deletions Include/cpython/unicodeobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,8 @@ enum PyUnicode_Kind {
PyUnicode_4BYTE_KIND = 4
};

PyAPI_FUNC(int) PyUnicode_KIND(PyObject *op);

// PyUnicode_KIND(): Return one of the PyUnicode_*_KIND values defined above.
//
// gh-89653: Converting this macro to a static inline function would introduce
Expand All @@ -264,13 +266,15 @@ static inline void* _PyUnicode_NONCOMPACT_DATA(PyObject *op) {
return data;
}

static inline void* PyUnicode_DATA(PyObject *op) {
PyAPI_FUNC(void*) PyUnicode_DATA(PyObject *op);

static inline void* _PyUnicode_DATA(PyObject *op) {
if (PyUnicode_IS_COMPACT(op)) {
return _PyUnicode_COMPACT_DATA(op);
}
return _PyUnicode_NONCOMPACT_DATA(op);
}
#define PyUnicode_DATA(op) PyUnicode_DATA(_PyObject_CAST(op))
#define PyUnicode_DATA(op) _PyUnicode_DATA(_PyObject_CAST(op))

/* Return pointers to the canonical representation cast to unsigned char,
Py_UCS2, or Py_UCS4 for direct character access.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Implement :c:func:`PyUnicode_KIND` and :c:func:`PyUnicode_DATA` as function,
in addition to the macros with the same names. The macros rely on C bit
fields which have compiler-specific layout. Patch by Victor Stinner.
21 changes: 21 additions & 0 deletions Objects/unicodeobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -16486,3 +16486,24 @@ PyInit__string(void)
{
return PyModuleDef_Init(&_string_module);
}


#undef PyUnicode_KIND
int PyUnicode_KIND(PyObject *op)
{
if (!PyUnicode_Check(op)) {
PyErr_Format(PyExc_TypeError, "expect str, got %T", op);
return -1;
}
return _PyASCIIObject_CAST(op)->state.kind;
}

#undef PyUnicode_DATA
void* PyUnicode_DATA(PyObject *op)
{
if (!PyUnicode_Check(op)) {
PyErr_Format(PyExc_TypeError, "expect str, got %T", op);
return NULL;
}
return _PyUnicode_DATA(op);
}

0 comments on commit a810cb8

Please sign in to comment.