From c72ea530c3d7cffebc6497ea3c9d54f1055a3059 Mon Sep 17 00:00:00 2001 From: Jiseok CHOI Date: Fri, 14 Aug 2026 15:25:38 +0900 Subject: [PATCH 1/5] gh-150449: Support negative steps in sqlite3.Blob slices (GH-150450) Reading or writing a slice with a negative step computed a negative length for sqlite3_blob_read() and sqlite3_blob_write(), so it failed instead of returning or storing the selected bytes. Compute the contiguous region which covers all selected bytes, and index it with a size_t cursor, so that a step of any sign and magnitude works. Co-authored-by: Serhiy Storchaka --- Doc/library/sqlite3.rst | 4 ++ Doc/whatsnew/3.16.rst | 7 +++ Lib/test/test_sqlite3/test_dbapi.py | 50 +++++++++++++++++ ...-05-26-15-53-50.gh-issue-150449.GfDWxl.rst | 3 + Modules/_sqlite/blob.c | 56 +++++++++++-------- 5 files changed, 98 insertions(+), 22 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-05-26-15-53-50.gh-issue-150449.GfDWxl.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 3a75d44f3f7d21..5aa3d2b0adcbf6 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -1760,6 +1760,10 @@ Blob objects .. versionadded:: 3.11 + .. versionchanged:: next + :class:`Blob` now supports negative-step slices + (e.g. ``blob[9:0:-2]``) for both reading and writing. + A :class:`Blob` instance is a :term:`file-like object` that can read and write data in an SQLite :abbr:`BLOB (Binary Large OBject)`. Call :func:`len(blob) ` to get the size (number of bytes) of the blob. diff --git a/Doc/whatsnew/3.16.rst b/Doc/whatsnew/3.16.rst index fc09afc96b1676..9d3bdd21509a9e 100644 --- a/Doc/whatsnew/3.16.rst +++ b/Doc/whatsnew/3.16.rst @@ -466,6 +466,13 @@ shlex a string, even if it is already safe for a shell without being quoted. (Contributed by Jay Berry in :gh:`148846`.) +sqlite3 +------- + +* :class:`sqlite3.Blob` now supports negative-step slices for reading and + writing (e.g. ``blob[9:0:-2]``). Previously, such slices would raise + :exc:`SystemError` or :exc:`ValueError`. + (Contributed by Jiseok CHOI in :gh:`150449`.) symtable -------- diff --git a/Lib/test/test_sqlite3/test_dbapi.py b/Lib/test/test_sqlite3/test_dbapi.py index 2cf3556f66d963..c21448a92361d7 100644 --- a/Lib/test/test_sqlite3/test_dbapi.py +++ b/Lib/test/test_sqlite3/test_dbapi.py @@ -1390,6 +1390,19 @@ def test_blob_get_slice_negative_index(self): def test_blob_get_slice_with_skip(self): self.assertEqual(self.blob[0:10:2], b"ti lb") + def test_blob_get_slice_with_negative_step(self): + # gh-150449: negative-step slices must not crash + self.assertEqual(self.blob[9:0:-2], self.data[9:0:-2]) + self.assertEqual(self.blob[9::-2], self.data[9::-2]) + self.assertEqual(self.blob[::-1], self.data[::-1]) + # When start <= stop with a negative step the slice is empty; this + # must return b"" rather than crashing or raising an exception. + self.assertEqual(self.blob[3:8:-1], self.data[3:8:-1]) # b"" + self.assertEqual(self.blob[5:5:-1], self.data[5:5:-1]) # b"" + # Extreme step values: cur += (size_t)step must not overflow. + self.assertEqual(self.blob[5::sys.maxsize], self.data[5::sys.maxsize]) + self.assertEqual(self.blob[::-sys.maxsize - 1], self.data[::-sys.maxsize - 1]) + def test_blob_set_slice(self): self.blob[0:5] = b"12345" expected = b"12345" + self.data[5:] @@ -1430,6 +1443,43 @@ def test_blob_set_slice_with_skip(self): expected = b"1h2s3b4o5 " + self.data[10:] self.assertEqual(actual, expected) + def test_blob_set_slice_with_negative_step(self): + # gh-150449: negative-step slice assignment must not crash + expected = bytearray(self.data) + expected[9:0:-2] = b"12345" + self.blob[9:0:-2] = b"12345" + actual = self.cx.execute("select b from test").fetchone()[0] + self.assertEqual(actual, bytes(expected)) + + # Also verify a slice that includes index 0 + expected2 = bytearray(self.data) + expected2[9::-2] = b"12345" + self.blob[9::-2] = b"12345" + actual2 = self.cx.execute("select b from test").fetchone()[0] + self.assertEqual(actual2, bytes(expected2)) + + # When start <= stop with a negative step the slice is empty; + # assigning b"" to it must be a no-op (blob contents unchanged). + state_before = bytes(self.blob[:]) + self.blob[3:8:-1] = b"" + self.assertEqual(bytes(self.blob[:]), state_before) + + def test_blob_set_slice_with_extreme_positive_step(self): + expected = bytearray(self.data) + expected[5::sys.maxsize] = b"\xab" + self.blob[5::sys.maxsize] = b"\xab" + actual = self.cx.execute("select b from test").fetchone()[0] + self.assertEqual(actual, bytes(expected)) + self.assertEqual(actual[5], 0xab) + + def test_blob_set_slice_with_extreme_negative_step(self): + expected = bytearray(self.data) + expected[::-sys.maxsize - 1] = b"\xcd" + self.blob[::-sys.maxsize - 1] = b"\xcd" + actual = self.cx.execute("select b from test").fetchone()[0] + self.assertEqual(actual, bytes(expected)) + self.assertEqual(actual[-1], 0xcd) + def test_blob_mapping_invalid_index_type(self): msg = "indices must be integers" with self.assertRaisesRegex(TypeError, msg): diff --git a/Misc/NEWS.d/next/Library/2026-05-26-15-53-50.gh-issue-150449.GfDWxl.rst b/Misc/NEWS.d/next/Library/2026-05-26-15-53-50.gh-issue-150449.GfDWxl.rst new file mode 100644 index 00000000000000..f849fe791356a1 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-05-26-15-53-50.gh-issue-150449.GfDWxl.rst @@ -0,0 +1,3 @@ +:class:`sqlite3.Blob` now supports negative-step slices for reading and +writing (e.g. ``blob[9:0:-2]``). Previously, such slices would raise +:exc:`SystemError` or :exc:`ValueError`. diff --git a/Modules/_sqlite/blob.c b/Modules/_sqlite/blob.c index 53d28a06181a9c..a9a98b40bf60b8 100644 --- a/Modules/_sqlite/blob.c +++ b/Modules/_sqlite/blob.c @@ -454,7 +454,14 @@ subscript_slice(pysqlite_Blob *self, PyObject *item) return read_multiple(self, len, start); } - PyObject *blob = read_multiple(self, stop - start, start); + // Compute the contiguous blob region covering all slice elements, then + // copy each element using the standard size_t-cursor pattern that handles + // both positive and negative steps via unsigned arithmetic. + Py_ssize_t last = start + (len - 1) * step; + Py_ssize_t read_offset = Py_MIN(start, last); + Py_ssize_t read_length = Py_ABS(start - last) + 1; + + PyObject *blob = read_multiple(self, read_length, read_offset); if (blob == NULL) { return NULL; } @@ -465,10 +472,12 @@ subscript_slice(pysqlite_Blob *self, PyObject *item) return NULL; } char *res_buf = PyBytesWriter_GetData(writer); - char *blob_buf = PyBytes_AS_STRING(blob); - for (Py_ssize_t i = 0, j = 0; i < len; i++, j += step) { - res_buf[i] = blob_buf[j]; + + size_t cur; + Py_ssize_t i; + for (cur = (size_t)start, i = 0; i < len; cur += (size_t)step, i++) { + res_buf[i] = blob_buf[(Py_ssize_t)cur - read_offset]; } Py_DECREF(blob); return PyBytesWriter_Finish(writer); @@ -562,28 +571,31 @@ ass_subscript_slice(pysqlite_Blob *self, PyObject *item, PyObject *value) rc = inner_write(self, vbuf.buf, len, start); } else { - /* Read the affected region, patch it and write it back. The - object returned by read_multiple() cannot be used as the buffer, - because for a single byte it is an immortal singleton. */ - Py_ssize_t length = stop - start; - if (length <= 0) { - /* start > stop for a negative step; see gh-150449. */ - PyErr_SetString(PyExc_ValueError, "size must be >= 0"); + /* Compute the contiguous blob region covering all slice elements, + read it, patch each element and write it back. The object + returned by read_multiple() cannot be used as the buffer, because + for a single byte it is an immortal singleton. */ + Py_ssize_t last = start + (len - 1) * step; + Py_ssize_t write_offset = Py_MIN(start, last); + Py_ssize_t write_length = Py_ABS(start - last) + 1; + char *buf = PyMem_Malloc(write_length); + if (buf == NULL) { + PyErr_NoMemory(); } else { - char *buf = PyMem_Malloc(length); - if (buf == NULL) { - PyErr_NoMemory(); - } - else { - if (inner_read(self, buf, length, start) == 0) { - for (Py_ssize_t i = 0, j = 0; i < len; i++, j += step) { - buf[j] = ((char *)vbuf.buf)[i]; - } - rc = inner_write(self, buf, length, start); + if (inner_read(self, buf, write_length, write_offset) == 0) { + /* The size_t cursor handles both positive and negative steps + via unsigned arithmetic. */ + size_t cur; + Py_ssize_t i; + for (cur = (size_t)start, i = 0; i < len; + cur += (size_t)step, i++) { + buf[(Py_ssize_t)cur - write_offset] = + ((char *)vbuf.buf)[i]; } - PyMem_Free(buf); + rc = inner_write(self, buf, write_length, write_offset); } + PyMem_Free(buf); } } PyBuffer_Release(&vbuf); From 58a620ae485c967f976fa6ea9082396aa5411389 Mon Sep 17 00:00:00 2001 From: Bhuvansh Date: Fri, 14 Aug 2026 08:22:51 +0000 Subject: [PATCH 2/5] gh-154753: Update references to moved files in the docs (#155553) Co-authored-by: Stan Ulbrych --- Doc/extending/extending.rst | 2 +- Doc/library/sys.rst | 2 +- Doc/using/android.rst | 10 +++++----- Doc/using/configure.rst | 2 +- Doc/using/ios.rst | 10 +++++----- InternalDocs/code_objects.md | 2 +- InternalDocs/jit.md | 2 +- 7 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Doc/extending/extending.rst b/Doc/extending/extending.rst index 110dfea8cb98ab..6a807085cc328f 100644 --- a/Doc/extending/extending.rst +++ b/Doc/extending/extending.rst @@ -1106,7 +1106,7 @@ Finally it should be mentioned that Capsules offer additional functionality, which is especially useful for memory allocation and deallocation of the pointer stored in a Capsule. The details are described in the Python/C API Reference Manual in the section :ref:`capsules` and in the implementation of Capsules (files -:file:`Include/pycapsule.h` and :file:`Objects/pycapsule.c` in the Python source +:file:`Include/pycapsule.h` and :file:`Objects/capsule.c` in the Python source code distribution). .. rubric:: Footnotes diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst index a2668a38c6b4a2..b9781de77860bb 100644 --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -1941,7 +1941,7 @@ always available. Unless explicitly noted otherwise, all variables are read-only The interpreter is about to execute a new line of code or re-execute the condition of a loop. The local trace function is called; *arg* is ``None``; the return value specifies the new local trace function. See - :file:`Objects/lnotab_notes.txt` for a detailed explanation of how this + :source:`InternalDocs/code_objects.md` for a detailed explanation of how this works. Per-line events may be disabled for a frame by setting :attr:`~frame.f_trace_lines` to :const:`False` on that diff --git a/Doc/using/android.rst b/Doc/using/android.rst index 60a13569318141..36d82c11d95307 100644 --- a/Doc/using/android.rst +++ b/Doc/using/android.rst @@ -37,7 +37,7 @@ much easier experience: * `Termux `__ If you're sure you want to do all of this manually, read on. You can use the -:source:`testbed app ` as a guide; each step below contains a +:source:`testbed app ` as a guide; each step below contains a link to the relevant file. * First, acquire a build of Python for Android: @@ -47,10 +47,10 @@ link to the relevant file. mentioned below is at the top level of the package. * Or if you want to build it yourself, follow the instructions in - :source:`Android/README.md`. The ``prefix`` directory will be created under + :source:`Platforms/Android/README.md`. The ``prefix`` directory will be created under :samp:`cross-build/{HOST}`. -* Add code to your :source:`build.gradle ` +* Add code to your :source:`build.gradle ` file to copy the following items into your project. All except your own Python code can be copied from ``prefix/lib``: @@ -65,10 +65,10 @@ link to the relevant file. * ``python*.*/site-packages`` (your own Python code) * Add code to your app to :source:`extract the assets to the filesystem - `. + `. * Add code to your app to :source:`start Python in embedded mode - `. This will need to be C code + `. This will need to be C code called via JNI. Building a Python package for Android diff --git a/Doc/using/configure.rst b/Doc/using/configure.rst index fd20ff2cb89810..28edf0408fd36e 100644 --- a/Doc/using/configure.rst +++ b/Doc/using/configure.rst @@ -1275,7 +1275,7 @@ See :source:`Mac/README.rst`. iOS Options ----------- -See :source:`iOS/README.rst`. +See :source:`Platforms/Apple/iOS/README.md`. .. option:: --enable-framework=INSTALLDIR diff --git a/Doc/using/ios.rst b/Doc/using/ios.rst index 5e4033fb6cec7a..31d9e2f2c816e7 100644 --- a/Doc/using/ios.rst +++ b/Doc/using/ios.rst @@ -170,7 +170,7 @@ helpful. To add Python to an iOS Xcode project: 1. Build or obtain a Python ``XCFramework``. See the instructions in - :source:`Apple/iOS/README.md` (in the CPython source distribution) for details on + :source:`Platforms/Apple/iOS/README.md` (in the CPython source distribution) for details on how to build a Python ``XCFramework``. At a minimum, you will need a build that supports ``arm64-apple-ios``, plus one of either ``arm64-apple-ios-simulator`` or ``x86_64-apple-ios-simulator``. @@ -266,13 +266,13 @@ modules in your app, some additional steps will be required: Testing a Python package ------------------------ -The CPython source tree contains :source:`a testbed project ` that +The CPython source tree contains :source:`a testbed project ` that is used to run the CPython test suite on the iOS simulator. This testbed can also be used as a testbed project for running your Python library's test suite on iOS. -After building or obtaining an iOS XCFramework (see :source:`Apple/iOS/README.md` +After building or obtaining an iOS XCFramework (see :source:`Platforms/Apple/iOS/README.md` for details), create a clone of the Python iOS testbed project. If you used the -``Apple`` build script to build the XCframework, you can run: +``Platforms/Apple`` build script to build the XCframework, you can run: .. code-block:: bash @@ -282,7 +282,7 @@ Or, if you've sourced your own XCframework, by running: .. code-block:: bash - $ python Apple/testbed clone --platform iOS --framework --app --app app-testbed + $ python Platforms/Apple/testbed clone --platform iOS --framework --app --app app-testbed Any folders specified with the ``--app`` flag will be copied into the cloned testbed project. The resulting testbed will be created in the ``app-testbed`` diff --git a/InternalDocs/code_objects.md b/InternalDocs/code_objects.md index cccbe71588622c..98fa22d66a923c 100644 --- a/InternalDocs/code_objects.md +++ b/InternalDocs/code_objects.md @@ -48,7 +48,7 @@ Note that traceback objects don't store all this information -- they store the s number, for backward compatibility, and the "last instruction" value. The rest can be computed from the last instruction (`tb_lasti`) with the help of the locations table. For Python code, there is a convenience method -(`codeobject.co_positions`)[https://docs.python.org/dev/reference/datamodel.html#codeobject.co_positions] +[`codeobject.co_positions`](https://docs.python.org/dev/reference/datamodel.html#codeobject.co_positions) which returns an iterator of `({line}, {endline}, {column}, {endcolumn})` tuples, one per instruction. There is also `co_lines()` which returns an iterator of `({start}, {end}, {line})` tuples, diff --git a/InternalDocs/jit.md b/InternalDocs/jit.md index 1345f2db8b34db..8db5ba3c85ddda 100644 --- a/InternalDocs/jit.md +++ b/InternalDocs/jit.md @@ -140,7 +140,7 @@ template file [`Tools/jit/template.c`](../Tools/jit/template.c). Each of the `.c` files is compiled by LLVM, to produce an object file that contains a function that executes the opcode. These compiled functions are used to generate the file -[`jit_stencils.h`](../jit_stencils.h), which contains the functions +`jit_stencils.h`, which contains the functions that the JIT can use to emit code for each of the bytecodes. For Python maintainers this means that changes to the bytecodes and From 5d91cf6487eb5aa37107598c792573f61ebe310f Mon Sep 17 00:00:00 2001 From: Stan Ulbrych Date: Fri, 14 Aug 2026 10:06:14 +0100 Subject: [PATCH 3/5] gh-139314: Add support for linking against `zlib-rs` and `libbzip2-rs` (#155119) --- Doc/using/configure.rst | 82 ++++- Doc/whatsnew/3.16.rst | 12 + ...-09-25-01-33-12.gh-issue-139314._m9BUl.rst | 9 + configure | 328 +++++++++++++----- configure.ac | 85 ++++- 5 files changed, 416 insertions(+), 100 deletions(-) create mode 100644 Misc/NEWS.d/next/Build/2025-09-25-01-33-12.gh-issue-139314._m9BUl.rst diff --git a/Doc/using/configure.rst b/Doc/using/configure.rst index 28edf0408fd36e..8b4940ceb9521a 100644 --- a/Doc/using/configure.rst +++ b/Doc/using/configure.rst @@ -71,7 +71,8 @@ Dependencies to build optional modules are: * - Dependency - Minimum version - Python module - * - `libbz2 `_ + * - `libbz2 `_ or + `libbzip2-rs `_ [1]_ - - :mod:`bz2` * - `libffi `_ @@ -82,47 +83,54 @@ Dependencies to build optional modules are: - :mod:`lzma` * - `libmpdec `_ - 2.5.0 - - :mod:`decimal` [1]_ + - :mod:`decimal` [2]_ * - `libreadline `_ or - `libedit `_ [2]_ + `libedit `_ [3]_ - - :mod:`readline` * - `libuuid `_ - - - ``_uuid`` [3]_ - * - `ncurses `_ [4]_ + - ``_uuid`` [4]_ + * - `ncurses `_ [5]_ - - :mod:`curses` * - `OpenSSL `_ - | 3.0.18 recommended | (1.1.1 minimum) - - :mod:`ssl`, :mod:`hashlib` [5]_ + - :mod:`ssl`, :mod:`hashlib` [6]_ * - `SQLite `_ - 3.15.2 - :mod:`sqlite3` * - `Tcl/Tk `_ - 8.5.12 - :mod:`tkinter`, :ref:`IDLE `, :mod:`turtle` - * - `zlib `_ - - 1.2.2.1 + * - `zlib `_, + `zlib-ng `_, or + `zlib-rs `_ [7]_ + - | 1.2.2.1 (zlib, zlib-ng) + | 0.6.0 (zlib-rs) - :mod:`zlib`, :mod:`gzip`, :mod:`ensurepip` * - `zstd `_ - 1.4.5 - :mod:`compression.zstd` -.. [1] If *libmpdec* is not available, the :mod:`decimal` module will use +.. [1] See :option:`--with-bzip2` for choosing the backend for the + :mod:`bz2` module. +.. [2] If *libmpdec* is not available, the :mod:`decimal` module will use a pure-Python implementation. -.. [2] See :option:`--with-readline` for choosing the backend for the +.. [3] See :option:`--with-readline` for choosing the backend for the :mod:`readline` module. -.. [3] The :mod:`uuid` module uses ``_uuid`` to generate "safe" UUIDs. +.. [4] The :mod:`uuid` module uses ``_uuid`` to generate "safe" UUIDs. See the module documentation for details. -.. [4] The :mod:`curses` module requires the ``libncurses`` or ``libncursesw`` +.. [5] The :mod:`curses` module requires the ``libncurses`` or ``libncursesw`` library. The :mod:`curses.panel` module additionally requires the ``libpanel`` or ``libpanelw`` library. -.. [5] If OpenSSL is not available, the :mod:`hashlib` module will use +.. [6] If OpenSSL is not available, the :mod:`hashlib` module will use bundled implementations of several hash functions. See :option:`--with-builtin-hashlib-hashes` for *forcing* usage of OpenSSL. +.. [7] See :option:`--with-zlib` for choosing the backend for the + :mod:`zlib` module. Note that the table does not include all optional modules; in particular, platform-specific modules like :mod:`winreg` are not listed here. @@ -1113,6 +1121,54 @@ Libraries options .. versionadded:: next +.. option:: --with-zlib=zlib|zlib-ng|zlib-rs + + Designate the zlib implementation to build the :mod:`zlib` module against. + + * ``zlib``: Use the system zlib library, found via ``pkg-config`` or as + ``libz``. + * ``zlib-ng``: Same detection as ``zlib``, but fail unless the detected + library is `zlib-ng `__. + * ``zlib-rs``: Use `zlib-rs + `__, found via + ``pkg-config`` as ``libz_rs``. + + Without this option (or with ``--with-zlib=auto``, the default), the system + zlib is used when found; configure only fails when an implementation was + requested explicitly but cannot be found. + + .. versionadded:: next + +.. option:: --without-zlib + + Don't build the :mod:`zlib` module, even when a zlib library is present + (built by default when one is found). + + .. versionadded:: next + +.. option:: --with-bzip2=bzip2|bzip2-rs + + Designate the bzip2 implementation to build the :mod:`bz2` module against. + + * ``bzip2``: Use the system bzip2 library, found via ``pkg-config`` or as + ``libbz2``. + * ``bzip2-rs``: Use `libbzip2-rs + `__, found via + ``pkg-config`` as ``libbz2_rs``. + + Without this option (or with ``--with-bzip2=auto``, the default), the + system bzip2 is used when found; configure only fails when an + implementation was requested explicitly but cannot be found. + + .. versionadded:: next + +.. option:: --without-bzip2 + + Don't build the :mod:`bz2` module, even when a bzip2 library is present + (built by default when one is found). + + .. versionadded:: next + .. option:: --with-libm=STRING Override ``libm`` math library to *STRING* (default is system-dependent). diff --git a/Doc/whatsnew/3.16.rst b/Doc/whatsnew/3.16.rst index 9d3bdd21509a9e..063755e1eadcb5 100644 --- a/Doc/whatsnew/3.16.rst +++ b/Doc/whatsnew/3.16.rst @@ -877,6 +877,18 @@ Build changes (Contributed by Serhiy Storchaka in :gh:`136687`.) +* Add the :option:`--with-zlib` and :option:`--with-bzip2` :program:`configure` + options to select the zlib and bzip2 implementations used to build the + :mod:`zlib` and :mod:`bz2` modules. In addition to the default system + libraries, they can build against `zlib-rs + `__ and `libbzip2-rs + `__, and + ``--with-zlib=zlib-ng`` verifies that the detected zlib is `zlib-ng + `__. :option:`--without-zlib` and + :option:`--without-bzip2` exclude the modules from the build. + + (Contributed by Stan Ulbrych in :gh:`139314`.) + C API changes ============= diff --git a/Misc/NEWS.d/next/Build/2025-09-25-01-33-12.gh-issue-139314._m9BUl.rst b/Misc/NEWS.d/next/Build/2025-09-25-01-33-12.gh-issue-139314._m9BUl.rst new file mode 100644 index 00000000000000..afc78af0d28fc7 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2025-09-25-01-33-12.gh-issue-139314._m9BUl.rst @@ -0,0 +1,9 @@ +Add the :option:`--with-zlib` and :option:`--with-bzip2` :program:`configure` +options to select the zlib and bzip2 implementations used to build the +:mod:`zlib` and :mod:`bz2` modules. In addition to the default system +libraries, they can build against `zlib-rs +`__ and `libbzip2-rs +`__, and +``--with-zlib=zlib-ng`` verifies that the detected zlib is `zlib-ng +`__. :option:`--without-zlib` and +:option:`--without-bzip2` exclude the modules from the build. diff --git a/configure b/configure index 598a21fb31f750..ea560d60072259 100755 --- a/configure +++ b/configure @@ -1142,6 +1142,8 @@ with_c_locale_coercion with_valgrind with_dtrace enable_epoll +with_zlib +with_bzip2 with_libm with_libc enable_big_digits @@ -1964,6 +1966,12 @@ Optional Packages: (default is yes) --with-valgrind enable Valgrind support (default is no) --with-dtrace enable DTrace support (default is no) + --with(out)-zlib[=zlib|zlib-ng|zlib-rs|no] + select the zlib implementation to link against, or + disable zlib support (default: auto) + --with(out)-bzip2[=bzip2|bzip2-rs|no] + select the bzip2 implementation to link against, or + disable bzip2 support (default: auto) --with-libm=STRING override libm math library to STRING (default is system-dependent) --with-libc=STRING override libc C library to STRING (default is @@ -22837,6 +22845,30 @@ fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-zlib" >&5 +printf %s "checking for --with-zlib... " >&6; } + +# Check whether --with-zlib was given. +if test ${with_zlib+y} +then : + withval=$with_zlib; case $with_zlib in #( + yes|auto) : + with_zlib=auto ;; #( + zlib|zlib-ng|zlib-rs|no) : + ;; #( + *) : + as_fn_error $? "proper usage is --with(out)-zlib[=zlib|zlib-ng|zlib-rs|no]" "$LINENO" 5 ;; +esac +else case e in #( + e) with_zlib=auto ;; +esac +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_zlib" >&5 +printf "%s\n" "$with_zlib" >&6; } + +case $with_zlib in #( + auto|zlib) : @@ -22849,23 +22881,47 @@ then : fi + ;; #( + *) : + ;; +esac + +if test "x$with_zlib" = xzlib-rs +then : + + zlib_name="libz_rs" + zlib_version="0.6.0" + zlib_libname="z_rs" +else case e in #( + e) + zlib_name="zlib" + zlib_version="1.2.2.1" + zlib_libname="z" + ;; +esac +fi +if test "x$with_zlib" = xno +then : + have_zlib=no +else case e in #( + e) pkg_failed=no -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for zlib >= 1.2.2.1" >&5 -printf %s "checking for zlib >= 1.2.2.1... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $zlib_name >= $zlib_version" >&5 +printf %s "checking for $zlib_name >= $zlib_version... " >&6; } if test -n "$ZLIB_CFLAGS"; then pkg_cv_ZLIB_CFLAGS="$ZLIB_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"zlib >= 1.2.2.1\""; } >&5 - ($PKG_CONFIG --exists --print-errors "zlib >= 1.2.2.1") 2>&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$zlib_name >= \$zlib_version\""; } >&5 + ($PKG_CONFIG --exists --print-errors "$zlib_name >= $zlib_version") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_ZLIB_CFLAGS=`$PKG_CONFIG --cflags "zlib >= 1.2.2.1" 2>/dev/null` + pkg_cv_ZLIB_CFLAGS=`$PKG_CONFIG --cflags "$zlib_name >= $zlib_version" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes @@ -22877,12 +22933,12 @@ if test -n "$ZLIB_LIBS"; then pkg_cv_ZLIB_LIBS="$ZLIB_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"zlib >= 1.2.2.1\""; } >&5 - ($PKG_CONFIG --exists --print-errors "zlib >= 1.2.2.1") 2>&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$zlib_name >= \$zlib_version\""; } >&5 + ($PKG_CONFIG --exists --print-errors "$zlib_name >= $zlib_version") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_ZLIB_LIBS=`$PKG_CONFIG --libs "zlib >= 1.2.2.1" 2>/dev/null` + pkg_cv_ZLIB_LIBS=`$PKG_CONFIG --libs "$zlib_name >= $zlib_version" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes @@ -22903,9 +22959,9 @@ else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - ZLIB_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "zlib >= 1.2.2.1" 2>&1` + ZLIB_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$zlib_name >= $zlib_version" 2>&1` else - ZLIB_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "zlib >= 1.2.2.1" 2>&1` + ZLIB_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$zlib_name >= $zlib_version" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$ZLIB_PKG_ERRORS" >&5 @@ -22927,14 +22983,15 @@ then : printf "%s\n" "#define HAVE_ZLIB_H 1" >>confdefs.h py_check_lib_save_LIBS=$LIBS -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gzread in -lz" >&5 -printf %s "checking for gzread in -lz... " >&6; } -if test ${ac_cv_lib_z_gzread+y} +as_ac_Lib=`printf "%s\n" "ac_cv_lib_$zlib_libname""_gzread" | sed "$as_sed_sh"` +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gzread in -l$zlib_libname" >&5 +printf %s "checking for gzread in -l$zlib_libname... " >&6; } +if eval test \${$as_ac_Lib+y} then : printf %s "(cached) " >&6 else case e in #( e) ac_check_lib_save_LIBS=$LIBS -LIBS="-lz $LIBS" +LIBS="-l$zlib_libname $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -22958,9 +23015,9 @@ return gzread (); _ACEOF if ac_fn_c_try_link "$LINENO" then : - ac_cv_lib_z_gzread=yes + eval "$as_ac_Lib=yes" else case e in #( - e) ac_cv_lib_z_gzread=no ;; + e) eval "$as_ac_Lib=no" ;; esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ @@ -22968,9 +23025,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \ LIBS=$ac_check_lib_save_LIBS ;; esac fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_gzread" >&5 -printf "%s\n" "$ac_cv_lib_z_gzread" >&6; } -if test "x$ac_cv_lib_z_gzread" = xyes +eval ac_res=\$$as_ac_Lib + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } +if eval test \"x\$"$as_ac_Lib"\" = x"yes" then : have_zlib=yes else case e in #( @@ -22991,16 +23049,17 @@ done then : ZLIB_CFLAGS=${ZLIB_CFLAGS-""} - ZLIB_LIBS=${ZLIB_LIBS-"-lz"} + ZLIB_LIBS=${ZLIB_LIBS-"-l$zlib_libname"} py_check_lib_save_LIBS=$LIBS -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for inflateCopy in -lz" >&5 -printf %s "checking for inflateCopy in -lz... " >&6; } -if test ${ac_cv_lib_z_inflateCopy+y} +as_ac_Lib=`printf "%s\n" "ac_cv_lib_$zlib_libname""_inflateCopy" | sed "$as_sed_sh"` +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for inflateCopy in -l$zlib_libname" >&5 +printf %s "checking for inflateCopy in -l$zlib_libname... " >&6; } +if eval test \${$as_ac_Lib+y} then : printf %s "(cached) " >&6 else case e in #( e) ac_check_lib_save_LIBS=$LIBS -LIBS="-lz $LIBS" +LIBS="-l$zlib_libname $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -23024,9 +23083,9 @@ return inflateCopy (); _ACEOF if ac_fn_c_try_link "$LINENO" then : - ac_cv_lib_z_inflateCopy=yes + eval "$as_ac_Lib=yes" else case e in #( - e) ac_cv_lib_z_inflateCopy=no ;; + e) eval "$as_ac_Lib=no" ;; esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ @@ -23034,9 +23093,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \ LIBS=$ac_check_lib_save_LIBS ;; esac fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_inflateCopy" >&5 -printf "%s\n" "$ac_cv_lib_z_inflateCopy" >&6; } -if test "x$ac_cv_lib_z_inflateCopy" = xyes +eval ac_res=\$$as_ac_Lib + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } +if eval test \"x\$"$as_ac_Lib"\" = x"yes" then : printf "%s\n" "#define HAVE_ZLIB_COPY 1" >>confdefs.h @@ -23074,14 +23134,15 @@ then : printf "%s\n" "#define HAVE_ZLIB_H 1" >>confdefs.h py_check_lib_save_LIBS=$LIBS -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gzread in -lz" >&5 -printf %s "checking for gzread in -lz... " >&6; } -if test ${ac_cv_lib_z_gzread+y} +as_ac_Lib=`printf "%s\n" "ac_cv_lib_$zlib_libname""_gzread" | sed "$as_sed_sh"` +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gzread in -l$zlib_libname" >&5 +printf %s "checking for gzread in -l$zlib_libname... " >&6; } +if eval test \${$as_ac_Lib+y} then : printf %s "(cached) " >&6 else case e in #( e) ac_check_lib_save_LIBS=$LIBS -LIBS="-lz $LIBS" +LIBS="-l$zlib_libname $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -23105,9 +23166,9 @@ return gzread (); _ACEOF if ac_fn_c_try_link "$LINENO" then : - ac_cv_lib_z_gzread=yes + eval "$as_ac_Lib=yes" else case e in #( - e) ac_cv_lib_z_gzread=no ;; + e) eval "$as_ac_Lib=no" ;; esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ @@ -23115,9 +23176,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \ LIBS=$ac_check_lib_save_LIBS ;; esac fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_gzread" >&5 -printf "%s\n" "$ac_cv_lib_z_gzread" >&6; } -if test "x$ac_cv_lib_z_gzread" = xyes +eval ac_res=\$$as_ac_Lib + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } +if eval test \"x\$"$as_ac_Lib"\" = x"yes" then : have_zlib=yes else case e in #( @@ -23138,16 +23200,17 @@ done then : ZLIB_CFLAGS=${ZLIB_CFLAGS-""} - ZLIB_LIBS=${ZLIB_LIBS-"-lz"} + ZLIB_LIBS=${ZLIB_LIBS-"-l$zlib_libname"} py_check_lib_save_LIBS=$LIBS -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for inflateCopy in -lz" >&5 -printf %s "checking for inflateCopy in -lz... " >&6; } -if test ${ac_cv_lib_z_inflateCopy+y} +as_ac_Lib=`printf "%s\n" "ac_cv_lib_$zlib_libname""_inflateCopy" | sed "$as_sed_sh"` +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for inflateCopy in -l$zlib_libname" >&5 +printf %s "checking for inflateCopy in -l$zlib_libname... " >&6; } +if eval test \${$as_ac_Lib+y} then : printf %s "(cached) " >&6 else case e in #( e) ac_check_lib_save_LIBS=$LIBS -LIBS="-lz $LIBS" +LIBS="-l$zlib_libname $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -23171,9 +23234,9 @@ return inflateCopy (); _ACEOF if ac_fn_c_try_link "$LINENO" then : - ac_cv_lib_z_inflateCopy=yes + eval "$as_ac_Lib=yes" else case e in #( - e) ac_cv_lib_z_inflateCopy=no ;; + e) eval "$as_ac_Lib=no" ;; esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ @@ -23181,9 +23244,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \ LIBS=$ac_check_lib_save_LIBS ;; esac fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_inflateCopy" >&5 -printf "%s\n" "$ac_cv_lib_z_inflateCopy" >&6; } -if test "x$ac_cv_lib_z_inflateCopy" = xyes +eval ac_res=\$$as_ac_Lib + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } +if eval test \"x\$"$as_ac_Lib"\" = x"yes" then : printf "%s\n" "#define HAVE_ZLIB_COPY 1" >>confdefs.h @@ -23211,8 +23275,53 @@ printf "%s\n" "yes" >&6; } printf "%s\n" "#define HAVE_ZLIB_COPY 1" >>confdefs.h +fi + ;; +esac fi +if test "x$with_zlib" = xzlib-ng +then : + if test "x$have_zlib" = xyes +then : + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $ZLIB_CFLAGS" + ac_fn_check_decl "$LINENO" "ZLIBNG_VERSION" "ac_cv_have_decl_ZLIBNG_VERSION" "#include +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_ZLIBNG_VERSION" = xyes +then : + +else case e in #( + e) as_fn_error $? "--with-zlib=zlib-ng: the detected zlib library is not zlib-ng" "$LINENO" 5 ;; +esac +fi + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +fi +fi + +case $with_zlib in #( + auto|no) : + ;; #( + *) : + if test "x$have_zlib" = xno +then : + as_fn_error $? "--with-zlib=$with_zlib requested but $zlib_name was not found" "$LINENO" 5 +fi ;; +esac + if test "x$have_zlib" = xyes then : @@ -23221,6 +23330,30 @@ then : fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-bzip2" >&5 +printf %s "checking for --with-bzip2... " >&6; } + +# Check whether --with-bzip2 was given. +if test ${with_bzip2+y} +then : + withval=$with_bzip2; case $with_bzip2 in #( + yes|auto) : + with_bzip2=auto ;; #( + bzip2|bzip2-rs|no) : + ;; #( + *) : + as_fn_error $? "proper usage is --with(out)-bzip2[=bzip2|bzip2-rs|no]" "$LINENO" 5 ;; +esac +else case e in #( + e) with_bzip2=auto ;; +esac +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_bzip2" >&5 +printf "%s\n" "$with_bzip2" >&6; } + +case $with_bzip2 in #( + auto|bzip2) : @@ -23233,23 +23366,45 @@ then : fi + ;; #( + *) : + ;; +esac + +if test "x$with_bzip2" = xbzip2-rs +then : + + bzip2_name="libbz2_rs" + bzip2_libname="bz2_rs" +else case e in #( + e) + bzip2_name="bzip2" + bzip2_libname="bz2" + ;; +esac +fi +if test "x$with_bzip2" = xno +then : + have_bzip2=no +else case e in #( + e) pkg_failed=no -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for bzip2" >&5 -printf %s "checking for bzip2... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $bzip2_name" >&5 +printf %s "checking for $bzip2_name... " >&6; } if test -n "$BZIP2_CFLAGS"; then pkg_cv_BZIP2_CFLAGS="$BZIP2_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"bzip2\""; } >&5 - ($PKG_CONFIG --exists --print-errors "bzip2") 2>&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$bzip2_name\""; } >&5 + ($PKG_CONFIG --exists --print-errors "$bzip2_name") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_BZIP2_CFLAGS=`$PKG_CONFIG --cflags "bzip2" 2>/dev/null` + pkg_cv_BZIP2_CFLAGS=`$PKG_CONFIG --cflags "$bzip2_name" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes @@ -23261,12 +23416,12 @@ if test -n "$BZIP2_LIBS"; then pkg_cv_BZIP2_LIBS="$BZIP2_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"bzip2\""; } >&5 - ($PKG_CONFIG --exists --print-errors "bzip2") 2>&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$bzip2_name\""; } >&5 + ($PKG_CONFIG --exists --print-errors "$bzip2_name") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_BZIP2_LIBS=`$PKG_CONFIG --libs "bzip2" 2>/dev/null` + pkg_cv_BZIP2_LIBS=`$PKG_CONFIG --libs "$bzip2_name" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes @@ -23287,9 +23442,9 @@ else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - BZIP2_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "bzip2" 2>&1` + BZIP2_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$bzip2_name" 2>&1` else - BZIP2_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "bzip2" 2>&1` + BZIP2_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$bzip2_name" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$BZIP2_PKG_ERRORS" >&5 @@ -23310,14 +23465,15 @@ if test "x$ac_cv_header_bzlib_h" = xyes then : printf "%s\n" "#define HAVE_BZLIB_H 1" >>confdefs.h - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for BZ2_bzCompress in -lbz2" >&5 -printf %s "checking for BZ2_bzCompress in -lbz2... " >&6; } -if test ${ac_cv_lib_bz2_BZ2_bzCompress+y} + as_ac_Lib=`printf "%s\n" "ac_cv_lib_$bzip2_libname""_BZ2_bzCompress" | sed "$as_sed_sh"` +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for BZ2_bzCompress in -l$bzip2_libname" >&5 +printf %s "checking for BZ2_bzCompress in -l$bzip2_libname... " >&6; } +if eval test \${$as_ac_Lib+y} then : printf %s "(cached) " >&6 else case e in #( e) ac_check_lib_save_LIBS=$LIBS -LIBS="-lbz2 $LIBS" +LIBS="-l$bzip2_libname $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -23341,9 +23497,9 @@ return BZ2_bzCompress (); _ACEOF if ac_fn_c_try_link "$LINENO" then : - ac_cv_lib_bz2_BZ2_bzCompress=yes + eval "$as_ac_Lib=yes" else case e in #( - e) ac_cv_lib_bz2_BZ2_bzCompress=no ;; + e) eval "$as_ac_Lib=no" ;; esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ @@ -23351,9 +23507,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \ LIBS=$ac_check_lib_save_LIBS ;; esac fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bz2_BZ2_bzCompress" >&5 -printf "%s\n" "$ac_cv_lib_bz2_BZ2_bzCompress" >&6; } -if test "x$ac_cv_lib_bz2_BZ2_bzCompress" = xyes +eval ac_res=\$$as_ac_Lib + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } +if eval test \"x\$"$as_ac_Lib"\" = x"yes" then : have_bzip2=yes else case e in #( @@ -23372,7 +23529,7 @@ done then : BZIP2_CFLAGS=${BZIP2_CFLAGS-""} - BZIP2_LIBS=${BZIP2_LIBS-"-lbz2"} + BZIP2_LIBS=${BZIP2_LIBS-"-l$bzip2_libname"} fi @@ -23402,14 +23559,15 @@ if test "x$ac_cv_header_bzlib_h" = xyes then : printf "%s\n" "#define HAVE_BZLIB_H 1" >>confdefs.h - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for BZ2_bzCompress in -lbz2" >&5 -printf %s "checking for BZ2_bzCompress in -lbz2... " >&6; } -if test ${ac_cv_lib_bz2_BZ2_bzCompress+y} + as_ac_Lib=`printf "%s\n" "ac_cv_lib_$bzip2_libname""_BZ2_bzCompress" | sed "$as_sed_sh"` +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for BZ2_bzCompress in -l$bzip2_libname" >&5 +printf %s "checking for BZ2_bzCompress in -l$bzip2_libname... " >&6; } +if eval test \${$as_ac_Lib+y} then : printf %s "(cached) " >&6 else case e in #( e) ac_check_lib_save_LIBS=$LIBS -LIBS="-lbz2 $LIBS" +LIBS="-l$bzip2_libname $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -23433,9 +23591,9 @@ return BZ2_bzCompress (); _ACEOF if ac_fn_c_try_link "$LINENO" then : - ac_cv_lib_bz2_BZ2_bzCompress=yes + eval "$as_ac_Lib=yes" else case e in #( - e) ac_cv_lib_bz2_BZ2_bzCompress=no ;; + e) eval "$as_ac_Lib=no" ;; esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ @@ -23443,9 +23601,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \ LIBS=$ac_check_lib_save_LIBS ;; esac fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bz2_BZ2_bzCompress" >&5 -printf "%s\n" "$ac_cv_lib_bz2_BZ2_bzCompress" >&6; } -if test "x$ac_cv_lib_bz2_BZ2_bzCompress" = xyes +eval ac_res=\$$as_ac_Lib + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } +if eval test \"x\$"$as_ac_Lib"\" = x"yes" then : have_bzip2=yes else case e in #( @@ -23464,7 +23623,7 @@ done then : BZIP2_CFLAGS=${BZIP2_CFLAGS-""} - BZIP2_LIBS=${BZIP2_LIBS-"-lbz2"} + BZIP2_LIBS=${BZIP2_LIBS-"-l$bzip2_libname"} fi @@ -23482,6 +23641,19 @@ else printf "%s\n" "yes" >&6; } have_bzip2=yes fi + ;; +esac +fi + +case $with_bzip2 in #( + auto|no) : + ;; #( + *) : + if test "x$have_bzip2" = xno +then : + as_fn_error $? "--with-bzip2=$with_bzip2 requested but $bzip2_name was not found" "$LINENO" 5 +fi ;; +esac pkg_failed=no diff --git a/configure.ac b/configure.ac index 47c5f7e49422a5..7dfc6ca29297a8 100644 --- a/configure.ac +++ b/configure.ac @@ -5706,10 +5706,34 @@ fi dnl Check for compression libraries AH_TEMPLATE([HAVE_ZLIB_COPY], [Define if the zlib library has inflateCopy]) +AC_MSG_CHECKING([for --with-zlib]) +AC_ARG_WITH( + [zlib], + [AS_HELP_STRING([--with(out)-zlib@<:@=zlib|zlib-ng|zlib-rs|no@:>@], + [select the zlib implementation to link against, or disable + zlib support (default: auto)])], + [AS_CASE([$with_zlib], + [yes|auto], [with_zlib=auto], + [zlib|zlib-ng|zlib-rs|no], [], + [AC_MSG_ERROR([proper usage is --with(out)-zlib@<:@=zlib|zlib-ng|zlib-rs|no@:>@])])], + [with_zlib=auto]) +AC_MSG_RESULT([$with_zlib]) + dnl detect zlib from Emscripten emport -PY_CHECK_EMSCRIPTEN_PORT([ZLIB], [-sUSE_ZLIB]) +AS_CASE([$with_zlib], [auto|zlib], [PY_CHECK_EMSCRIPTEN_PORT([ZLIB], [-sUSE_ZLIB])]) + +AS_VAR_IF([with_zlib], [zlib-rs], [ + AS_VAR_SET([zlib_name], ["libz_rs"]) + AS_VAR_SET([zlib_version], ["0.6.0"]) + AS_VAR_SET([zlib_libname], ["z_rs"]) +], [ + AS_VAR_SET([zlib_name], ["zlib"]) + AS_VAR_SET([zlib_version], ["1.2.2.1"]) + AS_VAR_SET([zlib_libname], ["z"]) +]) -PKG_CHECK_MODULES([ZLIB], [zlib >= 1.2.2.1], [ +AS_VAR_IF([with_zlib], [no], [have_zlib=no], [ +PKG_CHECK_MODULES([ZLIB], [$zlib_name >= $zlib_version], [ have_zlib=yes dnl zlib 1.2.0 (2003) added inflateCopy AC_DEFINE([HAVE_ZLIB_COPY], [1]) @@ -5718,15 +5742,30 @@ PKG_CHECK_MODULES([ZLIB], [zlib >= 1.2.2.1], [ CPPFLAGS="$CPPFLAGS $ZLIB_CFLAGS" LIBS="$LIBS $ZLIB_LIBS" AC_CHECK_HEADERS([zlib.h], [ - PY_CHECK_LIB([z], [gzread], [have_zlib=yes], [have_zlib=no]) + PY_CHECK_LIB([$zlib_libname], [gzread], [have_zlib=yes], [have_zlib=no]) ], [have_zlib=no]) AS_VAR_IF([have_zlib], [yes], [ ZLIB_CFLAGS=${ZLIB_CFLAGS-""} - ZLIB_LIBS=${ZLIB_LIBS-"-lz"} - PY_CHECK_LIB([z], [inflateCopy], [AC_DEFINE([HAVE_ZLIB_COPY], [1])]) + ZLIB_LIBS=${ZLIB_LIBS-"-l$zlib_libname"} + PY_CHECK_LIB([$zlib_libname], [inflateCopy], [AC_DEFINE([HAVE_ZLIB_COPY], [1])]) ]) ]) ]) +]) + +AS_VAR_IF([with_zlib], [zlib-ng], [AS_VAR_IF([have_zlib], [yes], [ + WITH_SAVE_ENV([ + CPPFLAGS="$CPPFLAGS $ZLIB_CFLAGS" + AC_CHECK_DECL([ZLIBNG_VERSION], [], + [AC_MSG_ERROR([--with-zlib=zlib-ng: the detected zlib library is not zlib-ng])], + [@%:@include ]) + ]) +])]) + +AS_CASE([$with_zlib], + [auto|no], [], + [AS_VAR_IF([have_zlib], [no], + [AC_MSG_ERROR([--with-zlib=$with_zlib requested but $zlib_name was not found])])]) dnl binascii can use zlib for optimized crc32. AS_VAR_IF([have_zlib], [yes], [ @@ -5734,22 +5773,50 @@ AS_VAR_IF([have_zlib], [yes], [ BINASCII_LIBS="$ZLIB_LIBS" ]) +AC_MSG_CHECKING([for --with-bzip2]) +AC_ARG_WITH( + [bzip2], + [AS_HELP_STRING([--with(out)-bzip2@<:@=bzip2|bzip2-rs|no@:>@], + [select the bzip2 implementation to link against, or disable + bzip2 support (default: auto)])], + [AS_CASE([$with_bzip2], + [yes|auto], [with_bzip2=auto], + [bzip2|bzip2-rs|no], [], + [AC_MSG_ERROR([proper usage is --with(out)-bzip2@<:@=bzip2|bzip2-rs|no@:>@])])], + [with_bzip2=auto]) +AC_MSG_RESULT([$with_bzip2]) + dnl detect bzip2 from Emscripten emport -PY_CHECK_EMSCRIPTEN_PORT([BZIP2], [-sUSE_BZIP2]) +AS_CASE([$with_bzip2], [auto|bzip2], [PY_CHECK_EMSCRIPTEN_PORT([BZIP2], [-sUSE_BZIP2])]) -PKG_CHECK_MODULES([BZIP2], [bzip2], [have_bzip2=yes], [ +AS_VAR_IF([with_bzip2], [bzip2-rs], [ + AS_VAR_SET([bzip2_name], ["libbz2_rs"]) + AS_VAR_SET([bzip2_libname], ["bz2_rs"]) +], [ + AS_VAR_SET([bzip2_name], ["bzip2"]) + AS_VAR_SET([bzip2_libname], ["bz2"]) +]) + +AS_VAR_IF([with_bzip2], [no], [have_bzip2=no], [ +PKG_CHECK_MODULES([BZIP2], [$bzip2_name], [have_bzip2=yes], [ WITH_SAVE_ENV([ CPPFLAGS="$CPPFLAGS $BZIP2_CFLAGS" LIBS="$LIBS $BZIP2_LIBS" AC_CHECK_HEADERS([bzlib.h], [ - AC_CHECK_LIB([bz2], [BZ2_bzCompress], [have_bzip2=yes], [have_bzip2=no]) + AC_CHECK_LIB([$bzip2_libname], [BZ2_bzCompress], [have_bzip2=yes], [have_bzip2=no]) ], [have_bzip2=no]) AS_VAR_IF([have_bzip2], [yes], [ BZIP2_CFLAGS=${BZIP2_CFLAGS-""} - BZIP2_LIBS=${BZIP2_LIBS-"-lbz2"} + BZIP2_LIBS=${BZIP2_LIBS-"-l$bzip2_libname"} ]) ]) ]) +]) + +AS_CASE([$with_bzip2], + [auto|no], [], + [AS_VAR_IF([have_bzip2], [no], + [AC_MSG_ERROR([--with-bzip2=$with_bzip2 requested but $bzip2_name was not found])])]) PKG_CHECK_MODULES([LIBLZMA], [liblzma], [have_liblzma=yes], [ WITH_SAVE_ENV([ From 0d87a0b635475fd311d350c20f8cf70893681a83 Mon Sep 17 00:00:00 2001 From: cui fliter Date: Fri, 14 Aug 2026 19:02:53 +0800 Subject: [PATCH 4/5] gh-153521: Preserve bytes message sets in imaplib (GH-153907) Signed-off-by: cuishuang --- Lib/imaplib.py | 2 ++ Lib/test/test_imaplib.py | 13 +++++++++++++ 2 files changed, 15 insertions(+) diff --git a/Lib/imaplib.py b/Lib/imaplib.py index 139da1d3bb6fb8..24d3a27f21d2d1 100644 --- a/Lib/imaplib.py +++ b/Lib/imaplib.py @@ -168,6 +168,8 @@ def _seq_range(item): def _format_sequence_set(arg): + if isinstance(arg, (bytes, bytearray)): + return str(arg, 'ascii') if isinstance(arg, (int, str)): return str(arg) # A sequence of message numbers and ranges. diff --git a/Lib/test/test_imaplib.py b/Lib/test/test_imaplib.py index 100791a9c3eb2c..d97da398803681 100644 --- a/Lib/test/test_imaplib.py +++ b/Lib/test/test_imaplib.py @@ -292,6 +292,8 @@ def test_sequence_set(self): # A scalar is passed through as a string. self.assertEqual(m._sequence_set(5), '5') self.assertEqual(m._sequence_set('1:3,7'), '1:3,7') + self.assertEqual(m._sequence_set(b'1:3,7'), '1:3,7') + self.assertEqual(m._sequence_set(bytearray(b'1:3,7')), '1:3,7') # A sequence of numbers and ranges is formatted as a sequence set. self.assertEqual(m._sequence_set([1, 2, 5]), '1,2,5') self.assertEqual(m._sequence_set([1, (3, 5), (8, '*')]), '1,3:5,8:*') @@ -333,6 +335,7 @@ def test_substitute(self): r'(\Seen \Answered)') # '?s' formats a message sequence set. self.assertEqual(sub('?s', [[1, (3, 5), (8, '*')]]), '1,3:5,8:*') + self.assertEqual(sub('?s', [b'1:3,7']), '1:3,7') # '??' is a literal '?'. self.assertEqual(sub('a?? b', []), 'a? b') @@ -1574,6 +1577,16 @@ def cmd_FETCH(self, tag, args): ]) self.assertEqual(server.args, ['2:4', '(FLAGS)']) + # A preformatted message set may be passed as bytes. + typ, data = client.fetch(b'2:4', '(FLAGS)') + self.assertEqual(typ, 'OK') + self.assertEqual(data, [ + br'2 (FLAGS (\Seen))', + br'3 (FLAGS (\Seen))', + br'4 (FLAGS (\Seen))', + ]) + self.assertEqual(server.args, ['2:4', '(FLAGS)']) + # A comma-separated set with an open range up to '*'. typ, data = client.fetch('1,3:*', '(FLAGS)') self.assertEqual(typ, 'OK') From a0e77f20cbd479c128cb425d5dcadd1584c0d571 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 14 Aug 2026 13:08:40 +0200 Subject: [PATCH 5/5] gh-155742: Use PyBytesWriter in _zstd.train_dict() (#155745) Replace soft deprecated PyBytes_FromStringAndSize() with PyBytesWriter. --- Modules/_zstd/_zstdmodule.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/Modules/_zstd/_zstdmodule.c b/Modules/_zstd/_zstdmodule.c index 94246dd93b17de..c9ed1ff22bdbd7 100644 --- a/Modules/_zstd/_zstdmodule.c +++ b/Modules/_zstd/_zstdmodule.c @@ -274,7 +274,7 @@ _zstd_train_dict_impl(PyObject *module, PyBytesObject *samples_bytes, PyObject *samples_sizes, Py_ssize_t dict_size) /*[clinic end generated code: output=8e87fe43935e8f77 input=d20dedb21c72cb62]*/ { - PyObject *dst_dict_bytes = NULL; + PyBytesWriter *dst_dict_bytes = NULL; size_t *chunk_sizes = NULL; Py_ssize_t chunks_number; size_t zstd_ret; @@ -294,13 +294,13 @@ _zstd_train_dict_impl(PyObject *module, PyBytesObject *samples_bytes, } /* Allocate dict buffer */ - dst_dict_bytes = PyBytes_FromStringAndSize(NULL, dict_size); + dst_dict_bytes = PyBytesWriter_Create(dict_size); if (dst_dict_bytes == NULL) { goto error; } /* Train the dictionary */ - char *dst_dict_buffer = PyBytes_AS_STRING(dst_dict_bytes); + char *dst_dict_buffer = PyBytesWriter_GetData(dst_dict_bytes); const char *samples_buffer = PyBytes_AS_STRING(samples_bytes); Py_BEGIN_ALLOW_THREADS zstd_ret = ZDICT_trainFromBuffer(dst_dict_buffer, dict_size, @@ -315,19 +315,15 @@ _zstd_train_dict_impl(PyObject *module, PyBytesObject *samples_bytes, goto error; } - /* Resize dict_buffer */ - if (_PyBytes_Resize(&dst_dict_bytes, zstd_ret) < 0) { - goto error; - } + PyMem_Free(chunk_sizes); - goto success; + /* Resize dict_buffer */ + return PyBytesWriter_FinishWithSize(dst_dict_bytes, zstd_ret); error: - Py_CLEAR(dst_dict_bytes); - -success: + PyBytesWriter_Discard(dst_dict_bytes); PyMem_Free(chunk_sizes); - return dst_dict_bytes; + return NULL; } /*[clinic input]