Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-regex for openSUSE:Factory checked in at 2026-03-30 18:30:02 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-regex (Old) and /work/SRC/openSUSE:Factory/.python-regex.new.1999 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-regex" Mon Mar 30 18:30:02 2026 rev:32 rq:1343499 version:2026.3.32 Changes: -------- --- /work/SRC/openSUSE:Factory/python-regex/python-regex.changes 2026-03-11 20:49:47.428320997 +0100 +++ /work/SRC/openSUSE:Factory/.python-regex.new.1999/python-regex.changes 2026-03-30 18:30:24.984868592 +0200 @@ -1,0 +2,8 @@ +Sun Mar 29 18:23:36 UTC 2026 - Dirk Müller <[email protected]> + +- update to 2026.3.32: + * Fixed segfault. + * Various fixes, including ones to improve free-threading + support. + +------------------------------------------------------------------- Old: ---- regex-2026.2.28.tar.gz New: ---- regex-2026.3.32.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-regex.spec ++++++ --- /var/tmp/diff_new_pack.2NaUyp/_old 2026-03-30 18:30:26.960950721 +0200 +++ /var/tmp/diff_new_pack.2NaUyp/_new 2026-03-30 18:30:26.976951386 +0200 @@ -18,7 +18,7 @@ %{?sle15_python_module_pythons} Name: python-regex -Version: 2026.2.28 +Version: 2026.3.32 Release: 0 Summary: Alternative regular expression module for Python License: Apache-2.0 ++++++ regex-2026.2.28.tar.gz -> regex-2026.3.32.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/regex-2026.2.28/PKG-INFO new/regex-2026.3.32/PKG-INFO --- old/regex-2026.2.28/PKG-INFO 2026-02-28 02:12:31.823559800 +0100 +++ new/regex-2026.3.32/PKG-INFO 2026-03-28 21:45:50.057209300 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.4 Name: regex -Version: 2026.2.28 +Version: 2026.3.32 Summary: Alternative regular expression module, to replace re. Author-email: Matthew Barnett <[email protected]> License-Expression: Apache-2.0 AND CNRI-Python diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/regex-2026.2.28/changelog.txt new/regex-2026.3.32/changelog.txt --- old/regex-2026.2.28/changelog.txt 2026-02-28 02:12:26.000000000 +0100 +++ new/regex-2026.3.32/changelog.txt 2026-03-28 21:45:46.000000000 +0100 @@ -1,3 +1,23 @@ +Version: 2026.3.32 + + Fixed segfault. + +Version: 2026.3.31 + + Fixed bug again. + +Version: 2026.3.30 + + Fixed bug. + +Version: 2026.3.28 + + Fixed version. + +Version: 2026.3.27 + + Various fixes, including ones to improve free-threading support. + Version: 2026.2.28 Replaced atomic operations with mutex on pattern object for free-threaded Python. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/regex-2026.2.28/pyproject.toml new/regex-2026.3.32/pyproject.toml --- old/regex-2026.2.28/pyproject.toml 2026-02-28 02:12:26.000000000 +0100 +++ new/regex-2026.3.32/pyproject.toml 2026-03-28 21:45:46.000000000 +0100 @@ -4,7 +4,7 @@ [project] name = "regex" -version = "2026.2.28" +version = "2026.3.32" description = "Alternative regular expression module, to replace re." readme = "README.rst" authors = [ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/regex-2026.2.28/regex/_main.py new/regex-2026.3.32/regex/_main.py --- old/regex-2026.2.28/regex/_main.py 2026-02-28 02:12:26.000000000 +0100 +++ new/regex-2026.3.32/regex/_main.py 2026-03-28 21:45:46.000000000 +0100 @@ -244,7 +244,7 @@ "VERSION1", "X", "VERBOSE", "W", "WORD", "error", "Regex", "__version__", "__doc__", "RegexFlag"] -__version__ = "2026.2.28" +__version__ = "2026.3.32" # -------------------------------------------------------------------- # Public interface. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/regex-2026.2.28/regex.egg-info/PKG-INFO new/regex-2026.3.32/regex.egg-info/PKG-INFO --- old/regex-2026.2.28/regex.egg-info/PKG-INFO 2026-02-28 02:12:31.000000000 +0100 +++ new/regex-2026.3.32/regex.egg-info/PKG-INFO 2026-03-28 21:45:50.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.4 Name: regex -Version: 2026.2.28 +Version: 2026.3.32 Summary: Alternative regular expression module, to replace re. Author-email: Matthew Barnett <[email protected]> License-Expression: Apache-2.0 AND CNRI-Python diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/regex-2026.2.28/setup.py new/regex-2026.3.32/setup.py --- old/regex-2026.2.28/setup.py 2026-02-28 02:12:26.000000000 +0100 +++ new/regex-2026.3.32/setup.py 2026-03-28 21:45:46.000000000 +0100 @@ -12,6 +12,5 @@ setup( ext_modules=[Extension('regex._regex', ['src/_regex.c', - 'src/_regex_unicode.c'])], - define_macros=macros, + 'src/_regex_unicode.c'], define_macros=macros)], ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/regex-2026.2.28/src/_regex.c new/regex-2026.3.32/src/_regex.c --- old/regex-2026.2.28/src/_regex.c 2026-02-28 02:12:26.000000000 +0100 +++ new/regex-2026.3.32/src/_regex.c 2026-03-28 21:45:46.000000000 +0100 @@ -119,6 +119,7 @@ #define RE_ERROR_NOT_BYTES -14 /* Not a bytestring. */ #define RE_ERROR_BAD_TIMEOUT -15 /* "timeout" invalid. */ #define RE_ERROR_TIMED_OUT -16 /* Matching has timed out. */ +#define RE_ERROR_INVALID_BYTESTRING -17 /* Invalid bytestring. */ /* Node bitflags. */ #define RE_POSITIVE_OP 0x1 @@ -214,7 +215,7 @@ static PyObject* error_exception; /* The dictionary of Unicode properties. */ -static PyObject* property_dict; +static PyObject* property_dict = NULL; typedef struct RE_State* RE_StatePtr; @@ -2074,7 +2075,7 @@ PyErr_SetString(PyExc_ValueError, "timeout not float or None"); break; case RE_ERROR_CANCELLED: - /* An exception has already been raised, so let it fly. */ + PyErr_SetString(PyExc_KeyboardInterrupt, "operation cancelled"); break; case RE_ERROR_CONCURRENT: PyErr_SetString(PyExc_ValueError, "concurrent not int or None"); @@ -2095,8 +2096,13 @@ PyErr_SetString(PyExc_TypeError, "string indices must be integers"); break; case RE_ERROR_INVALID_GROUP_REF: - if (!error_exception) + if (!error_exception) { error_exception = get_object("regex._regex_core", "error"); + if (!error_exception) { + PyErr_SetString(PyExc_RuntimeError, "cannot import regex._regex_core.error"); + break; + } + } PyErr_SetString(error_exception, "invalid group reference"); break; @@ -2120,14 +2126,22 @@ PyErr_SetString(PyExc_IndexError, "no such group"); break; case RE_ERROR_REPLACEMENT: - if (!error_exception) + if (!error_exception) { error_exception = get_object("regex._regex_core", "error"); + if (!error_exception) { + PyErr_SetString(PyExc_RuntimeError, "cannot import regex._regex_core.error"); + break; + } + } PyErr_SetString(error_exception, "invalid replacement"); break; case RE_ERROR_TIMED_OUT: PyErr_SetString(PyExc_TimeoutError, "regex timed out"); break; + case RE_ERROR_INVALID_BYTESTRING: + PyErr_SetString(PyExc_ValueError, "invalid bytestring"); + break; default: /* Other error codes indicate compiler/engine bugs. */ PyErr_SetString(PyExc_RuntimeError, @@ -6546,6 +6560,9 @@ * Internally, however, it isn't. For safety we need to hold the GIL. */ acquire_GIL(state); + #if defined(Py_GIL_DISABLED) + PyMutex_Lock(&state->pattern->mutex); + #endif /* Double-check because of multithreading. */ if (!(node->status & RE_STATUS_FAST_INIT)) { @@ -6553,6 +6570,9 @@ node->status |= RE_STATUS_FAST_INIT; } + #if defined(Py_GIL_DISABLED) + PyMutex_Unlock(&state->pattern->mutex); + #endif release_GIL(state); } @@ -6734,6 +6754,9 @@ * Internally, however, it isn't. For safety we need to hold the GIL. */ acquire_GIL(state); + #if defined(Py_GIL_DISABLED) + PyMutex_Lock(&state->pattern->mutex); + #endif /* Double-check because of multithreading. */ if (!(node->status & RE_STATUS_FAST_INIT)) { @@ -6741,6 +6764,9 @@ node->status |= RE_STATUS_FAST_INIT; } + #if defined(Py_GIL_DISABLED) + PyMutex_Unlock(&state->pattern->mutex); + #endif release_GIL(state); } @@ -6776,6 +6802,9 @@ * Internally, however, it isn't. For safety we need to hold the GIL. */ acquire_GIL(state); + #if defined(Py_GIL_DISABLED) + PyMutex_Lock(&state->pattern->mutex); + #endif /* Double-check because of multithreading. */ if (!(node->status & RE_STATUS_FAST_INIT)) { @@ -6783,6 +6812,9 @@ node->status |= RE_STATUS_FAST_INIT; } + #if defined(Py_GIL_DISABLED) + PyMutex_Unlock(&state->pattern->mutex); + #endif release_GIL(state); } @@ -6817,6 +6849,9 @@ * Internally, however, it isn't. For safety we need to hold the GIL. */ acquire_GIL(state); + #if defined(Py_GIL_DISABLED) + PyMutex_Lock(&state->pattern->mutex); + #endif /* Double-check because of multithreading. */ if (!(node->status & RE_STATUS_FAST_INIT)) { @@ -6825,6 +6860,9 @@ } release_GIL(state); + #if defined(Py_GIL_DISABLED) + PyMutex_Unlock(&state->pattern->mutex); + #endif } if (try_fast && node->string.bad_character_offset) { @@ -9575,7 +9613,7 @@ too_wide: re_dealloc(byte_buffer); - + set_error(RE_ERROR_INVALID_BYTESTRING, NULL); return NULL; } @@ -18710,6 +18748,9 @@ Py_LOCAL_INLINE(PyObject*) ensure_immutable(PyObject* string) { PyObject* new_string; + if (!string) + return NULL; + if (PyUnicode_CheckExact(string) || PyBytes_CheckExact(string)) return string; @@ -19195,7 +19236,7 @@ PyObject* result; Py_ssize_t i; - size = PyTuple_GET_SIZE(args); + size = PyTuple_Size(args); switch (size) { case 0: @@ -19203,33 +19244,44 @@ result = match_get_group_by_index(self, 0, Py_None); break; case 1: - /* group(x). PyTuple_GET_ITEM borrows the reference. */ - result = match_get_group(self, PyTuple_GET_ITEM(args, 0), Py_None, + /* group(x). PyTuple_GetItem borrows the reference. */ + result = match_get_group(self, PyTuple_GetItem(args, 0), Py_None, FALSE); break; default: + { + PyObject* list; + int status; + /* group(x, y, z, ...) */ /* Fetch multiple items. */ - result = PyTuple_New(size); - if (!result) + list = PyList_New(0); + if (!list) return NULL; for (i = 0; i < size; i++) { PyObject* item; - /* PyTuple_GET_ITEM borrows the reference. */ - item = match_get_group(self, PyTuple_GET_ITEM(args, i), Py_None, + item = match_get_group(self, PyTuple_GetItem(args, i), Py_None, FALSE); if (!item) { - Py_DECREF(result); + Py_DECREF(list); return NULL; } - /* PyTuple_SET_ITEM borrows the reference. */ - PyTuple_SET_ITEM(result, i, item); + status = PyList_Append(list, item); + Py_DECREF(item); + if (status != 0) { + Py_DECREF(list); + return NULL; + } } + + result = PyList_AsTuple(list); + Py_DECREF(list); break; } + } return result; } @@ -19241,7 +19293,7 @@ PyObject* result; Py_ssize_t i; - size = PyTuple_GET_SIZE(args); + size = PyTuple_Size(args); switch (size) { case 0: @@ -19249,8 +19301,8 @@ result = get_by_index(self, 0); break; case 1: - /* get(x). PyTuple_GET_ITEM borrows the reference. */ - result = get_by_arg(self, PyTuple_GET_ITEM(args, 0), get_by_index); + /* get(x). PyTuple_GetItem borrows the reference. */ + result = get_by_arg(self, PyTuple_GetItem(args, 0), get_by_index); break; default: /* get(x, y, z, ...) */ @@ -19262,8 +19314,8 @@ for (i = 0; i < size; i++) { PyObject* item; - /* PyTuple_GET_ITEM borrows the reference. */ - item = get_by_arg(self, PyTuple_GET_ITEM(args, i), get_by_index); + /* PyTuple_GetItem borrows the reference. */ + item = get_by_arg(self, PyTuple_GetItem(args, i), get_by_index); if (!item) { Py_DECREF(result); return NULL; @@ -19883,7 +19935,7 @@ static PyTypeObject Capture_Type = { PyVarObject_HEAD_INIT(NULL,0) "_regex.Capture", - sizeof(MatchObject) + sizeof(CaptureObject) }; /* Creates a new CaptureObject. */ @@ -19966,23 +20018,38 @@ /* MatchObject's 'expandf' method. */ static PyObject* match_expandf(MatchObject* self, PyObject* str_template) { PyObject* format_func; + PyObject* list; PyObject* args = NULL; size_t g; - PyObject* kwargs = NULL; + PyObject* kwargs; PyObject* result; format_func = PyObject_GetAttrString(str_template, "format"); if (!format_func) return NULL; - args = PyTuple_New((Py_ssize_t)self->group_count + 1); - if (!args) + list = PyList_New(0); + if (!list) goto error; - for (g = 0; g < self->group_count + 1; g++) - /* PyTuple_SetItem borrows the reference. */ - PyTuple_SetItem(args, (Py_ssize_t)g, make_capture_object(&self, - (Py_ssize_t)g)); + for (g = 0; g < self->group_count + 1; g++) { + PyObject* item; + int status; + + item = make_capture_object(&self, (Py_ssize_t)g); + if (!item) + goto error; + + status = PyList_Append(list, item); + Py_DECREF(item); + if (status != 0) + goto error; + } + + args = PyList_AsTuple(list); + Py_CLEAR(list); + if (!args) + goto error; kwargs = make_capture_dict(self, &self); if (!kwargs) @@ -19998,6 +20065,7 @@ error: Py_XDECREF(args); + Py_XDECREF(list); Py_DECREF(format_func); return NULL; } @@ -20083,22 +20151,39 @@ if (slice_length <= 0) return PyTuple_New(0); else { - PyObject* result; + PyObject* list; Py_ssize_t cur; Py_ssize_t i; + PyObject* result; - result = PyTuple_New(slice_length); - if (!result) + list = PyList_New(0); + if (!list) return NULL; cur = start; + for (i = 0; i < slice_length; i++) { - /* PyTuple_SetItem borrows the reference. */ - PyTuple_SetItem(result, i, match_get_group_by_index(self, cur, - Py_None)); + PyObject* item; + int status; + + item = match_get_group_by_index(self, cur, Py_None); + if (!item) { + Py_DECREF(list); + return NULL; + } + + status = PyList_Append(list, item); + Py_DECREF(item); + if (status != 0) { + Py_DECREF(list); + return NULL; + } + cur += step; } + result = PyList_AsTuple(list); + Py_DECREF(list); return result; } } @@ -20348,7 +20433,6 @@ Py_INCREF(result); return result; } - PyErr_Clear(); } Py_RETURN_NONE; @@ -21422,23 +21506,23 @@ */ Py_ssize_t arg_count; if (args && !kwargs && PyTuple_CheckExact(args)) - arg_count = PyTuple_GET_SIZE(args); + arg_count = PyTuple_Size(args); else arg_count = -1; if (1 <= arg_count && arg_count <= 5) { - /* PyTuple_GET_ITEM borrows the reference. */ - string = PyTuple_GET_ITEM(args, 0); + /* PyTuple_GetItem borrows the reference. */ + string = PyTuple_GetItem(args, 0); if (arg_count >= 2) - pos = PyTuple_GET_ITEM(args, 1); + pos = PyTuple_GetItem(args, 1); if (arg_count >= 3) - endpos = PyTuple_GET_ITEM(args, 2); + endpos = PyTuple_GetItem(args, 2); if (arg_count >= 4) - concurrent = PyTuple_GET_ITEM(args, 3); + concurrent = PyTuple_GetItem(args, 3); if (arg_count >= 5) - partial = PyTuple_GET_ITEM(args, 4); + partial = PyTuple_GetItem(args, 4); if (arg_count >= 6) - timeout = PyTuple_GET_ITEM(args, 5); + timeout = PyTuple_GetItem(args, 5); } else if (!PyArg_ParseTupleAndKeywords(args, kwargs, args_desc, kwlist, &string, &pos, &endpos, &concurrent, &partial, &timeout)) return NULL; @@ -21782,17 +21866,40 @@ * objects. */ if (!built_capture) { - /* The args are a tuple of the capture group matches. */ - args = PyTuple_New((Py_ssize_t)match->group_count + 1); - if (!args) { + PyObject* list; + + list = PyList_New(0); + if (!list) { Py_DECREF(match); goto error; } - for (g = 0; g < match->group_count + 1; g++) - /* PyTuple_SetItem borrows the reference. */ - PyTuple_SetItem(args, (Py_ssize_t)g, - make_capture_object(&match, (Py_ssize_t)g)); + for (g = 0; g < match->group_count + 1; g++) { + PyObject* capture; + int status; + + capture = make_capture_object(&match, (Py_ssize_t)g); + if (!capture) { + Py_DECREF(list); + Py_DECREF(match); + goto error; + } + + status = PyList_Append(list, capture); + Py_DECREF(capture); + if (status != 0) { + Py_DECREF(list); + Py_DECREF(match); + goto error; + } + } + + args = PyList_AsTuple(list); + Py_DECREF(list); + if (!args) { + Py_DECREF(match); + goto error; + } /* The kwargs are a dict of the named capture group matches. */ kwargs = make_capture_dict(match, &match); @@ -22646,6 +22753,9 @@ max_size = code_len * 5 + (Py_ssize_t)((sizeof(Py_ssize_t) * 8) + 6) / 7; packed = (RE_UINT8*)re_alloc((size_t)max_size); + if (!packed) + return NULL; + count = 0; /* Store the length of the code list. */ @@ -22690,6 +22800,9 @@ return NULL; packed_data = (RE_UINT8*)PyBytes_AsString(packed); + if (!packed_data) + goto error; + index = 0; /* Unpack the length of the code list. */ @@ -25610,7 +25723,7 @@ *req_chars = NULL; *req_length = 0; - len = PyTuple_GET_SIZE(required_chars); + len = PyTuple_Size(required_chars); if (len < 1 || PyErr_Occurred()) { PyErr_Clear(); return; @@ -25625,7 +25738,7 @@ size_t value; /* PyTuple_SET_ITEM borrows the reference. */ - o = PyTuple_GET_ITEM(required_chars, i); + o = PyTuple_GetItem(required_chars, i); value = PyLong_AsUnsignedLong(o); if ((Py_ssize_t)value == -1 && PyErr_Occurred()) @@ -26132,20 +26245,22 @@ */ static PyObject* get_expand_on_folding(PyObject* self, PyObject* unused) { int count; - PyObject* result; + PyObject* list; int i; + PyObject* result; /* How many characters are there? */ count = sizeof(re_expand_on_folding) / sizeof(re_expand_on_folding[0]); /* Put all the characters in a tuple. */ - result = PyTuple_New(count); - if (!result) + list = PyList_New(0); + if (!list) return NULL; for (i = 0; i < count; i++) { Py_UCS4 codepoint; PyObject* item; + int status; codepoint = re_expand_on_folding[i]; @@ -26153,14 +26268,19 @@ if (!item) goto error; - /* PyTuple_SetItem borrows the reference. */ - PyTuple_SetItem(result, i, item); + status = PyList_Append(list, item); + Py_DECREF(item); + if (status != 0) + goto error; } + result = PyList_AsTuple(list); + Py_DECREF(list); + return result; error: - Py_DECREF(result); + Py_DECREF(list); return NULL; } @@ -26277,7 +26397,8 @@ PyObject** value_dicts; char munged[256]; - property_dict = NULL; + if (property_dict) + return TRUE; /* How many value sets are there? */ value_set_count = 0; @@ -26358,7 +26479,7 @@ return TRUE; error: - Py_XDECREF(property_dict); + Py_CLEAR(property_dict); /* DECREF the value sets. */ for (i = 0; i < value_set_count; i++) @@ -26463,28 +26584,33 @@ d = PyModule_GetDict(m); x = PyLong_FromLong(RE_MAGIC); - if (x) { - PyDict_SetItemString(d, "MAGIC", x); - Py_DECREF(x); - } + if (!x) + goto error; + + PyDict_SetItemString(d, "MAGIC", x); + Py_DECREF(x); x = PyLong_FromLong(sizeof(RE_CODE)); - if (x) { - PyDict_SetItemString(d, "CODE_SIZE", x); - Py_DECREF(x); - } + if (!x) + goto error; + + PyDict_SetItemString(d, "CODE_SIZE", x); + Py_DECREF(x); x = PyUnicode_FromString(copyright); - if (x) { - PyDict_SetItemString(d, "copyright", x); - Py_DECREF(x); - } + if (!x) + goto error; + + PyDict_SetItemString(d, "copyright", x); + Py_DECREF(x); /* Initialise the property dictionary. */ - if (!init_property_dict()) { - Py_DECREF(m); - return NULL; - } + if (!init_property_dict()) + goto error; return m; + +error: + Py_DECREF(m); + return NULL; }
