From 572241ffa6e5fed55c480da694cda49aaee7a867 Mon Sep 17 00:00:00 2001 From: Matheus Mendes Date: Fri, 27 Feb 2026 02:02:08 -0300 Subject: [PATCH 1/9] chore(ci): modernize GitHub Actions pipeline for test-gated wheels and trusted publishing --- .github/workflows/CI.yml | 148 ++++++++++++++++----------------------- 1 file changed, 60 insertions(+), 88 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 9d87a7d..6b23225 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -4,9 +4,8 @@ on: push: branches: - main - - master tags: - - '*' + - "*" pull_request: workflow_dispatch: @@ -15,143 +14,127 @@ permissions: jobs: test: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: update - run: | - rustup update - rustup component add clippy - rustup install nightly - - name: lint - run: | - cargo fmt -- --check - cargo clippy -- -D warnings - - name: test - run: | - cargo check - cargo test --all + name: Test + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + with: + components: rustfmt, clippy + - name: Cargo fmt + run: cargo fmt --all -- --check + - name: Cargo clippy + run: cargo clippy --all-targets -- -D warnings + - name: Cargo test + run: cargo test + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + - name: Install dev dependencies + run: pip install maturin pytest + - name: Build & install (dev) + run: maturin develop + - name: Pytest + run: pytest tests/ + linux: - runs-on: ${{ matrix.platform.runner }} + runs-on: ubuntu-latest + needs: [test] strategy: matrix: - platform: - - runner: ubuntu-22.04 - target: x86_64 - - runner: ubuntu-22.04 - target: x86 - - runner: ubuntu-22.04 - target: aarch64 - - runner: ubuntu-22.04 - target: armv7 - - runner: ubuntu-22.04 - target: s390x - - runner: ubuntu-22.04 - target: ppc64le + target: [x86_64, x86, aarch64, armv7, s390x, ppc64le] steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: - python-version: 3.x + python-version: "3.x" - name: Build wheels uses: PyO3/maturin-action@v1 with: - target: ${{ matrix.platform.target }} + target: ${{ matrix.target }} args: --release --out dist --find-interpreter - sccache: ${{ !startsWith(github.ref, 'refs/tags/') }} + sccache: "true" manylinux: auto - name: Upload wheels uses: actions/upload-artifact@v4 with: - name: wheels-linux-${{ matrix.platform.target }} + name: wheels-linux-${{ matrix.target }} path: dist musllinux: - runs-on: ${{ matrix.platform.runner }} + runs-on: ubuntu-latest + needs: [test] strategy: matrix: - platform: - - runner: ubuntu-22.04 - target: x86_64 - - runner: ubuntu-22.04 - target: x86 - - runner: ubuntu-22.04 - target: aarch64 - - runner: ubuntu-22.04 - target: armv7 + target: [x86_64, aarch64, armv7] steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: - python-version: 3.x + python-version: "3.x" - name: Build wheels uses: PyO3/maturin-action@v1 with: - target: ${{ matrix.platform.target }} + target: ${{ matrix.target }} args: --release --out dist --find-interpreter - sccache: ${{ !startsWith(github.ref, 'refs/tags/') }} + sccache: "true" manylinux: musllinux_1_2 - name: Upload wheels uses: actions/upload-artifact@v4 with: - name: wheels-musllinux-${{ matrix.platform.target }} + name: wheels-musllinux-${{ matrix.target }} path: dist windows: - runs-on: ${{ matrix.platform.runner }} + runs-on: windows-latest + needs: [test] strategy: matrix: - platform: - - runner: windows-latest - target: x64 - - runner: windows-latest - target: x86 + target: [x64, x86] steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: - python-version: 3.x - architecture: ${{ matrix.platform.target }} + python-version: "3.x" + architecture: ${{ matrix.target }} - name: Build wheels uses: PyO3/maturin-action@v1 with: - target: ${{ matrix.platform.target }} + target: ${{ matrix.target }} args: --release --out dist --find-interpreter - sccache: ${{ !startsWith(github.ref, 'refs/tags/') }} + sccache: "true" - name: Upload wheels uses: actions/upload-artifact@v4 with: - name: wheels-windows-${{ matrix.platform.target }} + name: wheels-windows-${{ matrix.target }} path: dist macos: - runs-on: ${{ matrix.platform.runner }} + runs-on: macos-latest + needs: [test] strategy: matrix: - platform: - - runner: macos-13 - target: x86_64 - - runner: macos-14 - target: aarch64 + target: [x86_64, aarch64] steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: - python-version: 3.x + python-version: "3.x" - name: Build wheels uses: PyO3/maturin-action@v1 with: - target: ${{ matrix.platform.target }} + target: ${{ matrix.target }} args: --release --out dist --find-interpreter - sccache: ${{ !startsWith(github.ref, 'refs/tags/') }} + sccache: "true" - name: Upload wheels uses: actions/upload-artifact@v4 with: - name: wheels-macos-${{ matrix.platform.target }} + name: wheels-macos-${{ matrix.target }} path: dist sdist: runs-on: ubuntu-latest + needs: [test] steps: - uses: actions/checkout@v4 - name: Build sdist @@ -168,26 +151,15 @@ jobs: release: name: Release runs-on: ubuntu-latest - if: ${{ startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch' }} + if: startsWith(github.ref, 'refs/tags/') needs: [linux, musllinux, windows, macos, sdist] permissions: - # Use to sign the release artifacts - id-token: write - # Used to upload release artifacts - contents: write - # Used to generate artifact attestation - attestations: write + id-token: write # for trusted publishing steps: - uses: actions/download-artifact@v4 - - name: Generate artifact attestation - uses: actions/attest-build-provenance@v2 with: - subject-path: 'wheels-*/*' + pattern: wheels-* + merge-multiple: true + path: dist - name: Publish to PyPI - if: ${{ startsWith(github.ref, 'refs/tags/') }} - uses: PyO3/maturin-action@v1 - env: - MATURIN_PYPI_TOKEN: ${{ secrets.PYPI_API_TOKEN }} - with: - command: upload - args: --non-interactive --skip-existing wheels-*/* + uses: pypa/gh-action-pypi-publish@release/v1 From 08bcf3ec7ca5d934352247e9ec8ab737bc900115 Mon Sep 17 00:00:00 2001 From: Matheus Mendes Date: Fri, 27 Feb 2026 02:04:38 -0300 Subject: [PATCH 2/9] chore(github): add issue and pull request templates --- .github/ISSUE_TEMPLATE/bug_report.yml | 57 ++++++++++++++++++++++ .github/ISSUE_TEMPLATE/feature_request.yml | 28 +++++++++++ .github/PULL_REQUEST_TEMPLATE.md | 17 +++++++ 3 files changed, 102 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yml create mode 100644 .github/ISSUE_TEMPLATE/feature_request.yml create mode 100644 .github/PULL_REQUEST_TEMPLATE.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..bda23e1 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,57 @@ +name: Bug Report +description: Report a bug in rxml +labels: ["bug"] +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to report a bug! Please fill in the details below. + + - type: textarea + id: description + attributes: + label: Description + description: A clear description of the bug. + validations: + required: true + + - type: textarea + id: reproduction + attributes: + label: Steps to Reproduce + description: Minimal code or steps to reproduce the issue. + placeholder: | + ```python + from rxml import read_file + # ... + ``` + + - type: textarea + id: expected + attributes: + label: Expected Behavior + description: What you expected to happen. + + - type: textarea + id: actual + attributes: + label: Actual Behavior + description: What actually happened (include tracebacks if applicable). + + - type: input + id: python-version + attributes: + label: Python Version + placeholder: "3.12.0" + + - type: input + id: rxml-version + attributes: + label: rxml Version + placeholder: "2.3.6" + + - type: input + id: os + attributes: + label: Operating System + placeholder: "Ubuntu 24.04 / macOS 15 / Windows 11" diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000..d341946 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,28 @@ +name: Feature Request +description: Suggest a new feature for rxml +labels: ["enhancement"] +body: + - type: markdown + attributes: + value: | + Have an idea to improve rxml? We'd love to hear it. + + - type: textarea + id: description + attributes: + label: Description + description: A clear description of the feature you'd like. + validations: + required: true + + - type: textarea + id: use-case + attributes: + label: Use Case + description: What problem does this solve? How would you use it? + + - type: textarea + id: alternatives + attributes: + label: Alternatives Considered + description: Have you considered any alternative approaches or workarounds? diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..e310a85 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,17 @@ +# Description + + + +## Changes + + + +- + +## Checklist + +- [ ] Tests pass (`pytest tests/` and `cargo test`) +- [ ] Code is formatted (`cargo fmt` and `ruff format`) +- [ ] Lints pass (`cargo clippy`) +- [ ] Updated documentation (if applicable) +- [ ] Added/updated tests (if applicable) From ec62bae8b6bd4684a4a0558a2bc915d4500e68d3 Mon Sep 17 00:00:00 2001 From: Matheus Mendes Date: Fri, 27 Feb 2026 02:06:15 -0300 Subject: [PATCH 3/9] build(packaging): refresh project metadata and distribution config --- .gitignore | 91 ++++++++++++----------------------------- .pre-commit-config.yaml | 24 +++++++++++ py.typed | 0 pyproject.toml | 48 +++++++++++++++------- 4 files changed, 85 insertions(+), 78 deletions(-) create mode 100644 .pre-commit-config.yaml create mode 100644 py.typed diff --git a/.gitignore b/.gitignore index 1e352a5..1e338d4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,76 +1,39 @@ -/target +# Rust +/target/ +**/*.rs.bk +Cargo.lock +!Cargo.lock -# Byte-compiled / optimized / DLL files +# Python __pycache__/ -.pytest_cache/ *.py[cod] - -# C extensions +*$py.class *.so +*.pyd +*.egg-info/ +dist/ +build/ +*.egg +.eggs/ -# Distribution / packaging -.Python +# Virtual environments .venv/ -env/ -bin/ -build/ -develop-eggs/ -dist/ -eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -include/ -man/ venv/ -*.egg-info/ -.installed.cfg -*.egg +ENV/ -# Installer logs -pip-log.txt -pip-delete-this-directory.txt -pip-selfcheck.json +# IDE +.vscode/ +.idea/ +*.swp +*.swo +*~ +.DS_Store -# Unit test / coverage reports +# Testing +.pytest_cache/ +.coverage htmlcov/ .tox/ -.coverage -.cache -nosetests.xml -coverage.xml - -# Translations -*.mo - -# Mr Developer -.mr.developer.cfg -.project -.pydevproject - -# Rope -.ropeproject - -# Django stuff: -*.log -*.pot - -.DS_Store - -# Sphinx documentation -docs/_build/ - -# PyCharm -.idea/ - -# VSCode -.vscode/ - -# Pyenv -.python-version -# Test files -/tests/* -!/tests/.gitkeep \ No newline at end of file +# Maturin +*.whl diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..166f5f8 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,24 @@ +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v6.0.0 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-yaml + - id: check-toml + - id: check-merge-conflict + - id: check-added-large-files + + - repo: https://github.com/doublify/pre-commit-rust + rev: v1.0 + hooks: + - id: fmt + - id: clippy + args: ["--all-targets", "--", "-D", "warnings"] + + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.15.4 + hooks: + - id: ruff + args: ["--fix"] + - id: ruff-format diff --git a/py.typed b/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/pyproject.toml b/pyproject.toml index bbf3937..b6a71a9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,33 +1,53 @@ [build-system] -requires = ["maturin>=1.9.6"] +requires = ["maturin>=1.0,<2.0"] build-backend = "maturin" [project] name = "rxml" -description = "RXML is a python library to read and write xml files up to 2 times faster than python's xml included library." +description = "A fast Python library for reading and writing XML files, powered by Rust." readme = "README.md" -requires-python = ">=3.10" -license = "MIT" +license = { text = "MIT" } +requires-python = ">=3.8" authors = [ - { name = "Matheus Mendes", email = "mattheus2015@yahoo.com.br" }, + { name = "nephi-dev" }, ] +keywords = ["xml", "parser", "rust", "pyo3", "fast"] classifiers = [ - "Programming Language :: Rust", - "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy", + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "License :: OSI Approved :: MIT License", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", - "Programming Language :: Python :: 3.14", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy", + "Programming Language :: Rust", + "Topic :: Text Processing :: Markup :: XML", "Typing :: Typed", - "License :: OSI Approved :: MIT License", ] -version = "2.3.6" +dynamic = ["version"] + +[project.urls] +Homepage = "https://github.com/nephi-dev/rxml" +Repository = "https://github.com/nephi-dev/rxml" +Issues = "https://github.com/nephi-dev/rxml/issues" +Changelog = "https://github.com/nephi-dev/rxml/releases" +[project.optional-dependencies] +dev = [ + "pytest>=7.0", + "maturin>=1.0,<2.0", +] [tool.maturin] features = ["pyo3/extension-module"] - -[project.urls] -Repository = "https://github.com/nephi-dev/rxml" \ No newline at end of file +include = [ + { path = "py.typed", format = "wheel" }, + { path = "rxml.pyi", format = "wheel" }, +] From d793c77bdfffd29d0c844d05d9a26b4aa646033f Mon Sep 17 00:00:00 2001 From: Matheus Mendes Date: Fri, 27 Feb 2026 02:07:07 -0300 Subject: [PATCH 4/9] docs: rewrite project docs and add contribution/changelog guides --- CHANGELOG.md | 166 ++++++++++++++++++++++++++++++++++++++++++++++++ CONTRIBUTING.md | 94 +++++++++++++++++++++++++++ README.md | 118 ++++++++++++++++++++++------------ 3 files changed, 337 insertions(+), 41 deletions(-) create mode 100644 CHANGELOG.md create mode 100644 CONTRIBUTING.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..e3cb815 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,166 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +### Changed (Unreleased) + +- No unreleased changes yet. + +## [2.4.0] - 2026-02-27 + +### Added (2.4.0) + +- Added community health templates: bug report and feature request issue forms. +- Added a pull request template with required validation checklist. +- Added a contributor guide (`CONTRIBUTING.md`) with setup, workflow, and submission steps. +- Added pre-commit configuration with Rust and Python quality hooks. +- Added package typing marker distribution support via `py.typed` inclusion. + +### Changed (2.4.0) + +- Overhauled project metadata in `pyproject.toml` (description, authorship, classifiers, URLs, optional dev dependencies, dynamic versioning, and wheel include rules). +- Reworked GitHub Actions CI/CD for a clearer multi-stage flow (test gating, wheel matrix builds, sdist, and trusted-publishing release step). +- Modernized `.gitignore` to align Rust/Python build artifacts and common local tooling outputs. +- Rewrote README into a complete open-source landing page with features, quick start, development, contribution, license, and support sections. + +### Removed (2.4.0) + +- Removed legacy and redundant CI workflow logic (nightly bootstrap/update steps, mixed upload strategy, and manual token-based publish path). +- Removed outdated metadata and wording from project definition files and documentation. + +## [2.3.6] - 2025-10-08 + +### Changed (2.3.6) + +- Updated dependencies and internal linting fixes. + +## [2.3.5] - 2025-06-11 + +### Fixed (2.3.5) + +- Corrected the `indent` argument handling in `write_string`. + +## [2.3.4] - 2025-06-09 + +### Changed (2.3.4) + +- Updated Maturin build CI configuration. + +## [2.3.3] - 2025-06-09 + +### Changed (2.3.3) + +- Version bump release. + +## [2.3.2] - 2025-03-05 + +### Changed (2.3.2) + +- Performance branch merged with parser/read-path speed improvements. + +## [2.3.1] - 2025-03-05 + +### Changed (2.3.1) + +- Additional speed-focused refactors merged. + +## [2.3.0] - 2025-03-03 + +### Added (2.3.0) + +- Added `Node` dictionary conversion helpers (`from_dict`/`to_dict`) and related typing updates. + +### Changed (2.3.0) + +- Updated CI/actions and modernized dependency/tooling configuration. + +## [2.2.0] - 2024-12-18 + +### Changed (2.2.0) + +- Updated project packages and Maturin configuration. + +## [2.1.2] - 2024-12-18 + +### Fixed (2.1.2) + +- Fixed `.pyi` search function typing and `SearchType` definition. + +## [2.1.1] - 2024-11-19 + +### Added (2.1.1) + +- Improved node reader behavior for empty-tag XML elements. + +## [2.1.0] - 2024-10-30 + +### Changed (2.1.0) + +- Updated core libraries to newer versions. + +## [2.0.0] - 2024-07-12 + +### Fixed (2.0.0) + +- Stabilized tests by creating/removing files only during test execution. + +## [1.1.0] - 2024-04-08 + +### Changed (1.1.0) + +- Updated PyO3 to a newer version. + +## [1.0.1] - 2023-12-15 + +### Changed (1.0.1) + +- Version bump release. + +## [1.0.0] - 2023-11-24 + +### Fixed (1.0.0) + +- Rolled back minimum supported Python version. + +## [0.4.0] - 2023-05-01 + +### Fixed (0.4.0) + +- Allowed constructor text values to be null/empty safely. + +## [0.2.0] - 2023-04-26 + +### Added (0.2.0) + +- Expanded installation/help documentation and project description. + +## [0.1.0] - 2023-04-26 + +### Changed (0.1.0) + +- Early refactor and initial rename to `rxml`. + +[Unreleased]: https://github.com/nephi-dev/rxml/compare/2.3.6...HEAD +[2.3.6]: https://github.com/nephi-dev/rxml/compare/2.3.5...2.3.6 +[2.3.5]: https://github.com/nephi-dev/rxml/compare/2.3.4...2.3.5 +[2.3.4]: https://github.com/nephi-dev/rxml/compare/2.3.3...2.3.4 +[2.3.3]: https://github.com/nephi-dev/rxml/compare/2.3.2...2.3.3 +[2.3.2]: https://github.com/nephi-dev/rxml/compare/2.3.1...2.3.2 +[2.3.1]: https://github.com/nephi-dev/rxml/compare/2.3.0...2.3.1 +[2.3.0]: https://github.com/nephi-dev/rxml/compare/2.2.0...2.3.0 +[2.2.0]: https://github.com/nephi-dev/rxml/compare/2.1.2...2.2.0 +[2.1.2]: https://github.com/nephi-dev/rxml/compare/2.1.1...2.1.2 +[2.1.1]: https://github.com/nephi-dev/rxml/compare/2.1.0...2.1.1 +[2.1.0]: https://github.com/nephi-dev/rxml/compare/2.0.0...2.1.0 +[2.0.0]: https://github.com/nephi-dev/rxml/compare/1.1.0...2.0.0 +[1.1.0]: https://github.com/nephi-dev/rxml/compare/1.0.1...1.1.0 +[1.0.1]: https://github.com/nephi-dev/rxml/compare/1.0.0...1.0.1 +[1.0.0]: https://github.com/nephi-dev/rxml/compare/0.4.0...1.0.0 +[0.4.0]: https://github.com/nephi-dev/rxml/compare/0.2.0...0.4.0 +[0.2.0]: https://github.com/nephi-dev/rxml/compare/0.1.0...0.2.0 +[0.1.0]: https://github.com/nephi-dev/rxml/releases/tag/0.1.0 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..2cb2174 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,94 @@ +# Contributing to rxml + +Thanks for your interest in contributing to rxml! This document provides guidelines and instructions for contributing. + +## Getting Started + +### Prerequisites + +- Python 3.8+ +- A stable [Rust toolchain](https://rustup.rs/) +- [Maturin](https://www.maturin.rs/) (`pip install maturin`) + +### Development Setup + +1. Fork and clone the repository: + + ```bash + git clone https://github.com//rxml.git + cd rxml + ``` + +2. Create and activate a virtual environment: + + ```bash + python -m venv .venv + source .venv/bin/activate # Linux/macOS + .venv\Scripts\activate # Windows + ``` + +3. Install development dependencies: + + ```bash + pip install maturin pytest + ``` + +4. Build the project in development mode: + + ```bash + maturin develop + ``` + +5. Run the tests: + + ```bash + pytest tests/ + ``` + +## Making Changes + +1. Create a new branch for your feature or fix: + + ```bash + git checkout -b feature/your-feature-name + ``` + +2. Make your changes. If you're modifying Rust code, rebuild with `maturin develop` before testing. + +3. Ensure all tests pass: + + ```bash + pytest tests/ + cargo test + ``` + +4. Format your code: + + ```bash + cargo fmt + ``` + +5. Run the Rust linter: + + ```bash + cargo clippy + ``` + +## Submitting a Pull Request + +1. Push your branch to your fork. +2. Open a pull request against the `main` branch. +3. Provide a clear description of your changes and the motivation behind them. +4. Ensure CI checks pass. + +## Reporting Issues + +If you encounter a bug or have a feature request, please [open an issue](https://github.com/nephi-dev/rxml/issues/new) with as much detail as possible, including: + +- Your Python and Rust versions +- Your operating system +- A minimal reproducible example (if applicable) + +## Code of Conduct + +Please be respectful and constructive in all interactions. We are committed to providing a welcoming and inclusive experience for everyone. diff --git a/README.md b/README.md index 52d4553..8e6941b 100644 --- a/README.md +++ b/README.md @@ -1,86 +1,122 @@ -

Like my work? consider supporting it!

+# rxml -[![BuyMeACoffee](https://img.shields.io/badge/Buy%20Me%20a%20Coffee-ffdd00?style=for-the-badge&logo=buy-me-a-coffee&logoColor=black)](https://buymeacoffee.com/nephilim) +[![PyPI version](https://img.shields.io/pypi/v/rxml?color=%2334D058&label=pypi%20package)](https://pypi.org/project/rxml) +[![Python versions](https://img.shields.io/pypi/pyversions/rxml.svg?color=%2334D058)](https://pypi.org/project/rxml) +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) -

RXML

+A fast, lightweight Python library for reading and writing XML files, powered by Rust. -

rxml is a simple python library to read xml files up to 2 times faster than python's xml(ElementTree) library.

+`rxml` provides up to **2× faster** XML parsing compared to Python's built-in `xml.etree.ElementTree`, with a simple and intuitive API. -

- - Package version - - - Supported Python versions - -

+--- -## Installation +## Features + +- **Fast** — Rust-powered XML parsing, up to 2× faster than the standard library. +- **Simple API** — Read, traverse, and write XML with minimal boilerplate. +- **Type-safe** — Ships with a `.pyi` stub file for full editor autocompletion and type checking. +- **Cross-platform** — Supports CPython and PyPy on Windows, macOS, and Linux. -To install `rxml` you can use `pip`: +## Installation ```bash pip install rxml ``` -Simply as that! +## Quick Start -## Example usage +### Reading XML -To a given xml with `test.xml` as name: +Given an XML file `note.xml`: ```xml - Example Name + Example Name - Example Name + Example Name An Example Heading An Example Body! ``` -We write the following python code: +Parse it with `rxml`: ```python from rxml import read_file -root_node = read_file("test.xml", "note") -``` +root = read_file("note.xml", "note") -where `"test.xml"` is the `file_name` and `"note"` is the `root_tag`. - -After that we can simply iter through the children with: - -```python -for node in root_node.children: - # do something with the node here +for child in root.children: + print(child.name, child.text) ``` -You can also write it to a file or string(refer to the `.pyi` file for the args). +### Writing XML ```python from rxml import Node, write_file -example_node = Node( - name="hello_world", - attrs={"example_attr": "example"}, - text="Hello World!" +node = Node( + name="greeting", + attrs={"lang": "en"}, + text="Hello, World!", ) -write_file(example_node, "test_ex.xml") +write_file(node, "greeting.xml") ``` -## Node attributes +### The `Node` Object -This is how the `Node` looks like: +Every parsed element is represented as a `Node`: ```python class Node: - name: str - attrs: dict[str, str] - children: list[Node] - text: str + name: str # Tag name + attrs: dict[str, str] # Element attributes + children: list[Node] # Child nodes + text: str # Text content ``` + +Refer to the [`rxml.pyi`](rxml.pyi) stub file for the complete API surface, including `read_string`, `write_string`, and additional utilities. + +## Development + +`rxml` is built with [PyO3](https://pyo3.rs) and [Maturin](https://www.maturin.rs/). + +### Prerequisites + +- Python 3.8+ +- Rust toolchain (stable) +- [Maturin](https://www.maturin.rs/) (`pip install maturin`) + +### Building from Source + +```bash +git clone https://github.com/nephi-dev/rxml.git +cd rxml +python -m venv .venv && source .venv/bin/activate +pip install maturin +maturin develop +``` + +### Running Tests + +```bash +pytest tests/ +``` + +## Contributing + +Contributions are welcome! Please open an issue or submit a pull request on [GitHub](https://github.com/nephi-dev/rxml). + +## License + +This project is licensed under the [MIT License](LICENSE). + +## Support + +If you find this project useful, consider supporting the author: + +[![Buy Me a Coffee](https://img.shields.io/badge/Buy%20Me%20a%20Coffee-ffdd00?style=flat&logo=buy-me-a-coffee&logoColor=black)](https://buymeacoffee.com/nephilim) From 5cdd914d57a34f3d930d2de395a5914ef249de58 Mon Sep 17 00:00:00 2001 From: Matheus Mendes Date: Fri, 27 Feb 2026 02:08:10 -0300 Subject: [PATCH 5/9] chore(release): bump crate version to 2.4.0 --- Cargo.lock | 2 +- Cargo.toml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 408638a..b63e1f6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -143,7 +143,7 @@ dependencies = [ [[package]] name = "rxml" -version = "2.3.6" +version = "2.4.0" dependencies = [ "pyo3", "quick-xml", diff --git a/Cargo.toml b/Cargo.toml index d43b24f..9b2824d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rxml" -version = "2.3.6" +version = "2.4.0" edition = "2024" [lib] @@ -9,4 +9,4 @@ crate-type = ["cdylib"] [dependencies] pyo3 = "0.26.0" -quick-xml = "0.38.3" \ No newline at end of file +quick-xml = "0.38.3" From 713df3f74f950c451af51163fde70cb6e8e39e99 Mon Sep 17 00:00:00 2001 From: Matheus Mendes Date: Fri, 27 Feb 2026 02:20:10 -0300 Subject: [PATCH 6/9] ci: run release cargo tests only in workflow --- .github/workflows/CI.yml | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 6b23225..531fdf8 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -26,16 +26,7 @@ jobs: - name: Cargo clippy run: cargo clippy --all-targets -- -D warnings - name: Cargo test - run: cargo test - - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - name: Install dev dependencies - run: pip install maturin pytest - - name: Build & install (dev) - run: maturin develop - - name: Pytest - run: pytest tests/ + run: cargo test --all --release linux: runs-on: ubuntu-latest From 01dd1654035d9d3c317a7c013beea2b5af146f14 Mon Sep 17 00:00:00 2001 From: Matheus Mendes Date: Fri, 27 Feb 2026 02:20:32 -0300 Subject: [PATCH 7/9] chore: remove pytest references from docs and dev config --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- .gitignore | 1 - CONTRIBUTING.md | 5 ++--- README.md | 2 +- pyproject.toml | 1 - 5 files changed, 4 insertions(+), 7 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index e310a85..b12f1ba 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -10,7 +10,7 @@ ## Checklist -- [ ] Tests pass (`pytest tests/` and `cargo test`) +- [ ] Tests pass (`cargo test`) - [ ] Code is formatted (`cargo fmt` and `ruff format`) - [ ] Lints pass (`cargo clippy`) - [ ] Updated documentation (if applicable) diff --git a/.gitignore b/.gitignore index 1e338d4..60791e4 100644 --- a/.gitignore +++ b/.gitignore @@ -30,7 +30,6 @@ ENV/ .DS_Store # Testing -.pytest_cache/ .coverage htmlcov/ .tox/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2cb2174..c9bd64c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -30,7 +30,7 @@ Thanks for your interest in contributing to rxml! This document provides guideli 3. Install development dependencies: ```bash - pip install maturin pytest + pip install maturin ``` 4. Build the project in development mode: @@ -42,7 +42,7 @@ Thanks for your interest in contributing to rxml! This document provides guideli 5. Run the tests: ```bash - pytest tests/ + cargo test ``` ## Making Changes @@ -58,7 +58,6 @@ Thanks for your interest in contributing to rxml! This document provides guideli 3. Ensure all tests pass: ```bash - pytest tests/ cargo test ``` diff --git a/README.md b/README.md index 8e6941b..559409c 100644 --- a/README.md +++ b/README.md @@ -104,7 +104,7 @@ maturin develop ### Running Tests ```bash -pytest tests/ +cargo test ``` ## Contributing diff --git a/pyproject.toml b/pyproject.toml index b6a71a9..5cbfb0a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,7 +41,6 @@ Changelog = "https://github.com/nephi-dev/rxml/releases" [project.optional-dependencies] dev = [ - "pytest>=7.0", "maturin>=1.0,<2.0", ] From e9381d739fe60ab4eae8062a06fc00e18dbeaa77 Mon Sep 17 00:00:00 2001 From: Matheus Mendes Date: Fri, 27 Feb 2026 02:34:11 -0300 Subject: [PATCH 8/9] chore(pyproject): modernize project metadata, update Python requirements and classifiers --- .github/workflows/CI.yml | 20 ++++++++++++++++---- .pre-commit-config.yaml | 16 +++++++++++----- CHANGELOG.md | 3 ++- README.md | 4 ++-- pyproject.toml | 7 +++---- 5 files changed, 34 insertions(+), 16 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 531fdf8..813b022 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -57,7 +57,7 @@ jobs: needs: [test] strategy: matrix: - target: [x86_64, aarch64, armv7] + target: [x86_64, x86, aarch64, armv7] steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 @@ -101,11 +101,15 @@ jobs: path: dist macos: - runs-on: macos-latest needs: [test] strategy: matrix: - target: [x86_64, aarch64] + include: + - target: x86_64 + runner: macos-13 + - target: aarch64 + runner: macos-14 + runs-on: ${{ matrix.runner }} steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 @@ -142,9 +146,11 @@ jobs: release: name: Release runs-on: ubuntu-latest - if: startsWith(github.ref, 'refs/tags/') + if: startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch' needs: [linux, musllinux, windows, macos, sdist] permissions: + attestations: write # for artifact attestation + contents: read id-token: write # for trusted publishing steps: - uses: actions/download-artifact@v4 @@ -152,5 +158,11 @@ jobs: pattern: wheels-* merge-multiple: true path: dist + - name: Attest build provenance + uses: actions/attest-build-provenance@v2 + with: + subject-path: dist/* - name: Publish to PyPI uses: pypa/gh-action-pypi-publish@release/v1 + with: + packages-dir: dist diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 166f5f8..a1b4155 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -9,12 +9,18 @@ repos: - id: check-merge-conflict - id: check-added-large-files - - repo: https://github.com/doublify/pre-commit-rust - rev: v1.0 + - repo: local hooks: - - id: fmt - - id: clippy - args: ["--all-targets", "--", "-D", "warnings"] + - id: rust-fmt + name: Rust fmt + entry: cargo fmt + language: system + types: [rust] + - id: rust-clippy + name: Rust clippy + entry: cargo clippy --all-targets -- -D warnings + language: system + types: [rust] - repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.15.4 diff --git a/CHANGELOG.md b/CHANGELOG.md index e3cb815..07b4bfc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -145,7 +145,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Early refactor and initial rename to `rxml`. -[Unreleased]: https://github.com/nephi-dev/rxml/compare/2.3.6...HEAD +[Unreleased]: https://github.com/nephi-dev/rxml/compare/2.4.0...HEAD +[2.4.0]: https://github.com/nephi-dev/rxml/compare/2.3.6...2.4.0 [2.3.6]: https://github.com/nephi-dev/rxml/compare/2.3.5...2.3.6 [2.3.5]: https://github.com/nephi-dev/rxml/compare/2.3.4...2.3.5 [2.3.4]: https://github.com/nephi-dev/rxml/compare/2.3.3...2.3.4 diff --git a/README.md b/README.md index 559409c..a66db55 100644 --- a/README.md +++ b/README.md @@ -33,10 +33,10 @@ Given an XML file `note.xml`: - Example Name + Example Name - Example Name + Example Name An Example Heading An Example Body! diff --git a/pyproject.toml b/pyproject.toml index 5cbfb0a..4489745 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [build-system] -requires = ["maturin>=1.0,<2.0"] +requires = ["maturin>=1.9.6"] build-backend = "maturin" [project] @@ -7,7 +7,7 @@ name = "rxml" description = "A fast Python library for reading and writing XML files, powered by Rust." readme = "README.md" license = { text = "MIT" } -requires-python = ">=3.8" +requires-python = ">=3.10" authors = [ { name = "nephi-dev" }, ] @@ -19,12 +19,11 @@ classifiers = [ "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Programming Language :: Rust", From 3dff2091d0f2aa88050e0af55747400ac4a16ce8 Mon Sep 17 00:00:00 2001 From: Matheus Mendes Date: Fri, 27 Feb 2026 02:47:01 -0300 Subject: [PATCH 9/9] chore: update CI configuration for macOS runner and refine README formatting --- .github/workflows/CI.yml | 2 +- README.md | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 813b022..cef03e2 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -106,7 +106,7 @@ jobs: matrix: include: - target: x86_64 - runner: macos-13 + runner: macos-14 - target: aarch64 runner: macos-14 runs-on: ${{ matrix.runner }} diff --git a/README.md b/README.md index a66db55..d820695 100644 --- a/README.md +++ b/README.md @@ -12,10 +12,10 @@ A fast, lightweight Python library for reading and writing XML files, powered by ## Features -- **Fast** — Rust-powered XML parsing, up to 2× faster than the standard library. -- **Simple API** — Read, traverse, and write XML with minimal boilerplate. -- **Type-safe** — Ships with a `.pyi` stub file for full editor autocompletion and type checking. -- **Cross-platform** — Supports CPython and PyPy on Windows, macOS, and Linux. +- **Fast** - Rust-powered XML parsing, up to 2× faster than the standard library. +- **Simple API** - Read, traverse, and write XML with minimal boilerplate. +- **Type-safe** - Ships with a `.pyi` stub file for full editor autocompletion and type checking. +- **Cross-platform** - Supports CPython and PyPy on Windows, macOS, and Linux. ## Installation @@ -87,7 +87,7 @@ Refer to the [`rxml.pyi`](rxml.pyi) stub file for the complete API surface, incl ### Prerequisites -- Python 3.8+ +- Python 3.10+ - Rust toolchain (stable) - [Maturin](https://www.maturin.rs/) (`pip install maturin`) @@ -117,6 +117,6 @@ This project is licensed under the [MIT License](LICENSE). ## Support -If you find this project useful, consider supporting the author: +If you find this project useful, consider supporting me: [![Buy Me a Coffee](https://img.shields.io/badge/Buy%20Me%20a%20Coffee-ffdd00?style=flat&logo=buy-me-a-coffee&logoColor=black)](https://buymeacoffee.com/nephilim)