diff --git a/.coverage b/.coverage index cad90cb..ede9937 100644 Binary files a/.coverage and b/.coverage differ diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 795cc66..ebb390d 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -17,10 +17,14 @@ jobs: uses: actions/setup-python@v5.2.0 with: python-version: "3.13" - cache: 'pip' - - run: | - python -m pip install --upgrade pip - pip install ruff + + - name: Install uv + uses: astral-sh/setup-uv@v6 + with: + enable-cache: true + + - name: Install ruff + run: uv pip install ruff - name: Run Ruff run: | ruff check json2xml @@ -37,8 +41,14 @@ jobs: uses: actions/setup-python@v5.2.0 with: python-version: '3.13' - cache: 'pip' - - run: pip install --upgrade mypy types-requests types-urllib3 + + - name: Install uv + uses: astral-sh/setup-uv@v6 + with: + enable-cache: true + + - name: Install mypy and types + run: uv pip install mypy types-requests types-urllib3 - name: mypy uses: liskin/gh-problem-matcher-wrap@v2 with: diff --git a/.github/workflows/publish-to-live-pypi.yml b/.github/workflows/publish-to-live-pypi.yml index 290e260..20ca8da 100644 --- a/.github/workflows/publish-to-live-pypi.yml +++ b/.github/workflows/publish-to-live-pypi.yml @@ -12,16 +12,17 @@ jobs: steps: - uses: actions/checkout@v4.1.7 - name: Set up Python 3.12 - uses: actions/setup-python@v3 + uses: actions/setup-python@v5.2.0 with: python-version: '3.12' - - name: Install pypa/build - run: >- - python -m - pip install - build - --user + - name: Install uv + uses: astral-sh/setup-uv@v6 + with: + enable-cache: true + + - name: Install build dependencies + run: uv pip install build - name: Build a binary wheel and a source tarball run: >- python -m diff --git a/.github/workflows/publish-to-test-pypi.yml b/.github/workflows/publish-to-test-pypi.yml index e5e0401..16aa02f 100644 --- a/.github/workflows/publish-to-test-pypi.yml +++ b/.github/workflows/publish-to-test-pypi.yml @@ -13,16 +13,17 @@ jobs: steps: - uses: actions/checkout@v4.1.7 - name: Set up Python 3.12 - uses: actions/setup-python@v3 + uses: actions/setup-python@v5.2.0 with: python-version: '3.12' - - name: Install pypa/build - run: >- - python -m - pip install - build - --user + - name: Install uv + uses: astral-sh/setup-uv@v6 + with: + enable-cache: true + + - name: Install build dependencies + run: uv pip install build - name: Build a binary wheel and a source tarball run: >- python -m diff --git a/.github/workflows/pythonpackage.yml b/.github/workflows/pythonpackage.yml index 3a96c70..c75774d 100644 --- a/.github/workflows/pythonpackage.yml +++ b/.github/workflows/pythonpackage.yml @@ -28,11 +28,11 @@ jobs: strategy: fail-fast: false matrix: - python-version: [pypy-3.10, pypy-3.11, '3.10', '3.11', '3.12', '3.13', '3.14'] + python-version: [pypy-3.10, pypy-3.11, '3.10', '3.11', '3.12', '3.13', '3.14.0'] os: [ - ubuntu-latest, - windows-latest, - macos-latest, + ubuntu-22.04, + windows-2022, + macos-14, ] steps: - uses: actions/checkout@v4 @@ -142,3 +142,72 @@ jobs: - name: Run mypy run: mypy json2xml tests + test-freethreaded: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - os: ubuntu-22.04 + python-version: '3.14.0' + - os: windows-2022 + python-version: '3.14.0' + - os: macos-14 + python-version: '3.14.0' + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: false + + - name: Set up Python ${{ matrix.python-version }} (freethreaded) + uses: actions/setup-python@v5.2.0 + with: + python-version: '3.14t' + allow-prereleases: true + + - name: Verify freethreaded Python + shell: bash + run: | + python -c "import sys; print(f'Python {sys.version}'); print(f'GIL enabled: {sys._is_gil_enabled()}' if hasattr(sys, '_is_gil_enabled') else 'GIL check not available')" + + - name: Install uv + uses: astral-sh/setup-uv@v6 + with: + enable-cache: true + cache-dependency-glob: | + requirements*.txt + requirements-dev.in + pyproject.toml + + - name: Install dependencies + run: | + uv pip install --system -e . + uv pip install --system pytest pytest-xdist pytest-cov + + - name: Create coverage directory + shell: bash + run: mkdir -p coverage/reports + + - name: Run tests with freethreaded Python + run: | + pytest --cov=json2xml --cov-report=xml:coverage/reports/coverage.xml --cov-report=term -xvs tests -n auto + env: + PYTHONPATH: ${{ github.workspace }} + PYTHON_FREETHREADED: 1 + + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v5 + if: success() + with: + directory: ./coverage/reports/ + env_vars: OS,PYTHON + fail_ci_if_error: false + files: ./coverage/reports/coverage.xml + flags: freethreaded + token: ${{ secrets.CODECOV_TOKEN }} + name: codecov-freethreaded + verbose: true + env: + OS: ${{ matrix.os }} + PYTHON: ${{ matrix.python-version }}-freethreaded + diff --git a/README.rst b/README.rst index f2bcc0e..1e007f6 100644 --- a/README.rst +++ b/README.rst @@ -8,6 +8,7 @@ json2xml .. image:: https://github.com/vinitkumar/json2xml/actions/workflows/pythonpackage.yml/badge.svg .. image:: https://img.shields.io/pypi/pyversions/json2xml.svg +.. image:: https://img.shields.io/badge/python-3.14%20freethreaded-blue .. image:: https://readthedocs.org/projects/json2xml/badge/?version=latest :target: https://json2xml.readthedocs.io/en/latest/?badge=latest :alt: Documentation Status @@ -36,6 +37,7 @@ json2xml supports the following features: * Conversion from a `json` string to XML * Conversion from a `json` file to XML * Conversion from an API that emits `json` data to XML +* Full compatibility with Python 3.14 freethreaded (GIL-free) builds Usage ^^^^^ @@ -194,7 +196,7 @@ in case any of the input(file, string or API URL) returns invalid JSON. Development ^^^^^^^^^^^ -This project uses modern Python development practices. Here's how to set up a development environment: +This project uses modern Python development practices and supports both regular and freethreaded Python 3.14. Here's how to set up a development environment: .. code-block:: console diff --git a/pyproject.toml b/pyproject.toml index 19ab880..d4cd2c8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -24,6 +24,7 @@ classifiers = [ "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.14", "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: CPython :: 3.14", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: Software Development :: Libraries :: Python Modules" ]