Description: PROBLEM DESCRIPTION: The pyuno bridge on Windows is currently compiled against a specific version of Python (e.g., Python 3.11). This creates a hard binary dependency, preventing external Python scripts running on any other version (e.g., 3.12, 3.13) from importing "uno". This creates a "Version Lock" that hinders professional automation and Data Science integration. BENEFITS OF FIXING THIS: 1. Decoupling: Users can upgrade their external Python environment (e.g., to use modern AI/ML libraries) without breaking LibreOffice automation. 2. Enterprise Deployment: IT departments can deploy standard Python versions without conflict. 3. Longevity: Automation scripts won't break every time LibreOffice updates its bundled Python version. Steps to Reproduce: 1. Install LibreOffice (which currently bundles Python 3.11). 2. Install an external Python 3.12 (or newer) environment (e.g., via Anaconda or python.org). 3. In the external Python 3.12 environment, append the LibreOffice "program" directory to sys.path. 4. Attempt to run: "import uno" Actual Results: The import fails with a DLL conflict error: "ImportError: Module use of python311.dll conflicts with this version of Python." Expected Results: The "uno" module should import successfully. If pyuno were compiled with the Python Stable ABI (Limited API), the bridge would be able to load into Python 3.11, 3.12, or 3.13 processes seamlessly without binary conflicts. Reproducible: Always User Profile Reset: No Additional Info: TECHNICAL IMPLEMENTATION PROPOSAL: To support this, the Windows build process for the PyUNO bridge needs to be updated to target the Python Stable ABI. 1. Compiler Flags: Define `Py_LIMITED_API` (e.g., 0x03080000 for Python 3.8+ compatibility) in the pyuno makefiles. 2. Linker: Link against `python3.lib` (the stable ABI library) instead of the version-specific `python311.lib`. 3. Source Refactoring: Refactor `pyuno` C++ source files to replace direct access to Python internal structures (e.g., ob_refcnt, ob_type) with the equivalent Stable API macros/functions (Py_REFCNT, Py_TYPE), as direct structure access is forbidden in the Limited API.
Neil, what's your opinion for this one?
Created attachment 207478 [details] pyuno: build pyuno against Python Stable ABI Subject: pyuno: build pyuno against Python Stable ABI This patch is a concrete first pass at removing pyuno's CPython-minor-version lock by moving the pyuno C extension surface toward Python's Stable ABI. Problem: pyuno currently depends on CPython-version-specific ABI details. On Windows this shows up directly as a pyuno.pyd built for a specific pythonXY.dll, so Python automation clients must match LibreOffice's bundled CPython minor version. Approach: - Add a pyuno-specific `python_abi3` external that defines `Py_LIMITED_API=0x030A0000`. - Link pyuno through a pyuno-specific ABI3 external while leaving other LibreOffice Python consumers on the existing Python external. On POSIX builds, prefer the non-embed `python3` pkg-config module and allow pyuno's Python API symbols to resolve from the loading interpreter instead of adding a minor-versioned `libpython3.x` dependency. - Convert pyuno's static `PyTypeObject` definitions to heap types created with `PyType_FromSpec`. - Replace direct CPython struct access such as `PyThreadState_Get()->interp`, `Py_TYPE(obj)->tp_dict`, and `tp_free` with public API usage. - Replace APIs/macros not available at the Python 3.10 Limited API floor, such as `PyUnicode_AsUTF8` and `PyUnicode_FromKindAndData`. Validation done here: - Confirmed MSVC Build Tools and Windows SDK are installed and usable. - Compiled, linked, and ran a small Windows C++ smoke test with `cl.exe`. - Applied this patch to a full LibreOffice core checkout at commit `ea59b2284`. - Configured a WSL Ubuntu 24.04 build with system Python 3.12 and a minimized headless build profile. - Ran `make fetch`, `PARALLELISM=2 make Library_pyuno`, and `PARALLELISM=2 make Pyuno` successfully. - Verified `instdir/program/libpyuno.so` does not have a `libpython3.12` `DT_NEEDED` entry. - Smoke-loaded `instdir/program/libpyuno.so` from Python 3.12 with `ctypes.CDLL(...)` and `LD_LIBRARY_PATH` pointed at `instdir/program`. - Scanned the patched pyuno module for remaining static type objects, CPython-version conditionals, direct type-field access, and removed Unicode APIs. - Checked the used `PyType_Slot` constants and main APIs against CPython 3.10 headers, matching the `Py_LIMITED_API=0x030A0000` floor. Still needed upstream: - Review whether POSIX pyuno should explicitly opt out of `-z defs` as done here or use a gbuild-level Python-extension abstraction. - Run the full pyuno Python tests, including Writer/Calc UNO import and bridge smoke tests from more than one Python 3 minor version. - Run Windows and macOS builds, especially the Windows `python3.lib`/`python3.dll` Stable ABI path that motivated this change. # Validation Notes LibreOffice core checkout: - Source: `https://github.com/LibreOffice/core.git` - Commit tested: `ea59b2284` - Build host: Ubuntu 24.04 in WSL - Python: system Python 3.12 Configure/build commands: ```sh ./autogen.sh --enable-python=system --disable-gui --without-x --without-java \ --disable-gtk3 --disable-gtk4 --disable-dbus --disable-cups \ --disable-gstreamer-1-0 --disable-sdremote --disable-sdremote-bluetooth \ --disable-pdfimport --disable-skia --disable-lpsolve --disable-coinmp \ --disable-firebird-sdbc --disable-postgresql-sdbc --disable-report-builder \ --disable-extension-integration --without-help --without-myspell-dicts \ --disable-ccache --disable-dependency-tracking --disable-werror make fetch PARALLELISM=2 make Library_pyuno PARALLELISM=2 make Pyuno ``` Results: - `Library_pyuno` built successfully. - `Pyuno` built successfully. - `config_host.mk` generated `PYTHON_ABI3_LIBS=$(gb_SPACE) -ldl`. - `config_host.mk` still generated legacy `PYTHON_LIBS=$(gb_SPACE) -lpython3.12 -ldl`. - `instdir/program/libpyuno.so` was produced. - `readelf -d instdir/program/libpyuno.so` did not show any `libpython3.12` `DT_NEEDED` entry. - This smoke load succeeded: ```sh LD_LIBRARY_PATH=$PWD/instdir/program python3 - <<'PY' import ctypes ctypes.CDLL('instdir/program/libpyuno.so') print('loaded libpyuno.so') PY ``` Remaining upstream work: - Run full pyuno Python tests and UNO bridge smoke tests. - Build on Windows to validate the intended `python3.lib` / `python3.dll` Stable ABI path. - Build on macOS and review platform-specific Python Stable ABI policy.