Skip to content

Conversation

@j03-dev
Copy link
Owner

@j03-dev j03-dev commented Nov 25, 2025

  • chore: bump upgrade some crates pyo3 to v0.27 pyo3-stub-gen to 2bec9c3
  • bump version to 0.7.4
  • chore: bump stub_gen crates
  • display the error as default

Summary by CodeRabbit

  • Chores

    • Version bumped to 0.7.4
    • Updated Python bindings stack and build config (python-source added)
    • CI macOS runners updated to macOS-14
  • Style

    • Formatting and spacing cleanup across public type hints and stubs
  • Documentation

    • README version badge updated to 0.7.4
  • Bug Fixes

    • Error reporting now displays exception details by default unless DEBUG is explicitly false
    • Improved conversion of internal errors to Python-facing exceptions

✏️ Tip: You can customize this high-level summary in your review settings.

pyo3 to v0.27
pyo3-stub-gen to 2bec9c3

Signed-off-by: FITAHIANA Nomeniavo Joe <24nomeniavo@gmail.com>
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 25, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

Version bump and dependency updates; many .pyi formatting/type-hint whitespace edits; adds IntoPyException trait and blanket impl; changes into_response DEBUG handling to default true; wraps several extraction returns in Ok(...); adds maturin python-source and stub-generator post-processing.

Changes

Cohort / File(s) Summary
Version & Build
Cargo.toml, README.md, pyproject.toml
Package version bumped to 0.7.4; pyo3 and related Python-binding deps updated; python-source = "." added under [tool.maturin]; README version badge updated.
Python stubs (formatting only)
oxapy/__init__.pyi, oxapy/exceptions/__init__.pyi, oxapy/jwt/__init__.pyi, oxapy/serializer/__init__.pyi, oxapy/templating/__init__.pyi
Whitespace and type-hint formatting normalized across many public signatures and constructors; no semantic/API changes.
Stub generation
src/bin/stub_gen.rs
Reordered imports and added a post-processing shell step: find generated .pyi files and run sed to rewrite certain return annotations in-place.
Exception plumbing
src/exceptions.rs, src/lib.rs
New public trait IntoPyException<T> and a blanket impl for Result<T, E> added in src/exceptions.rs; removed local trait/impl from lib.rs and import now references crate::exceptions::IntoPyException.
JWT / imports
src/jwt.rs
Import reorganization to reference Wrap from crate::json and IntoPyException/exception helpers from crate::exceptions; no behavioral changes.
Error-display / response logic
src/into_response.rs
DEBUG parsing logic changed: missing/unparsable DEBUG now defaults to true, so error details are displayed unless DEBUG is explicitly false.
Serializer / JSON return handling
src/serializer/mod.rs, src/json.rs
Several functions changed to explicitly wrap extracted values in Ok(repr.extract()?) to align with PyResult return types and use ? for propagation.

Sequence Diagram(s)

sequenceDiagram
    participant Rust as Rust code
    participant Exceptions as crate::exceptions
    participant Py as Python layer

    rect rgb(240,248,255)
    Note over Rust,Exceptions: Exception conversion (new)
    Rust->>Exceptions: result.into_py_exception()
    Exceptions-->>Rust: PyResult<T> (maps Err -> PyException)
    Rust->>Py: return PyResult
    end
Loading
sequenceDiagram
    participant Request as Request handler
    participant IntoResp as into_response.rs
    participant Logger as Error display

    Request->>IntoResp: produce error value
    alt DEBUG unset or unparsable (defaults true)
        IntoResp->>Logger: value.display(py) 
    else DEBUG explicitly "false"
        Note right of IntoResp: skip display
    end
    IntoResp->>Request: return Response with error info
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~30 minutes

  • Pay attention to exception trait relocation and usages across modules (src/exceptions.rs, src/lib.rs, src/jwt.rs).
  • Verify DEBUG behavior change in src/into_response.rs for runtime impact.
  • Review the stub-generator post-processing shell command for correctness and cross-platform safety.

Possibly related PRs

Suggested labels

new version

Poem

🐰 Bumped a hop from point-seven-three to four,
Stubs tidied gently, traits now at the core,
Errors speak aloud unless DEBUG says "no",
JSON wrapped in Ok, tidy paths to go,
I nibble bits of code and hop for more! 🥕

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'chore/pyo3 0.27' directly relates to the main change: upgrading pyo3 from 0.26 to 0.27 and related dependencies, which is the primary objective.
Docstring Coverage ✅ Passed Docstring coverage is 82.91% which is sufficient. The required threshold is 80.00%.

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 11be8d4 and 6a0d717.

📒 Files selected for processing (1)
  • .github/workflows/CI.yaml (1 hunks)

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (2)
README.md (1)

12-12: Add alt text for the version badge image

The new version badge <img> lacks alt, which markdownlint (MD045) flags and which slightly hurts accessibility. A brief alt text (or empty alt if you consider it decorative) would address this.

Example:

-<a href='https://github.com/j03-dev/oxapy/#'><img src='https://img.shields.io/badge/version-0.7.4-%23b7410e'/></a>
+<a href='https://github.com/j03-dev/oxapy/#'><img src='https://img.shields.io/badge/version-0.7.4-%23b7410e' alt='OxAPY version 0.7.4'/></a>
src/exceptions.rs (1)

13-21: IntoPyException provides a clean, reusable Result→PyErr bridge

The public IntoPyException<T> trait with its blanket impl for Result<T, E: ToString> is a straightforward way to convert common Rust errors (e.g., from jsonschema, Mutex::lock, IO) into PyExceptions, and it matches how the rest of the crate is using it.

Since this is now part of the public exceptions API, consider adding a brief doc comment explaining that it’s intended for turning ordinary Result<T, E> values into PyResult<T> for Python interop.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f553632 and 0a11092.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (15)
  • Cargo.toml (2 hunks)
  • README.md (1 hunks)
  • oxapy/__init__.pyi (44 hunks)
  • oxapy/exceptions/__init__.pyi (7 hunks)
  • oxapy/jwt/__init__.pyi (4 hunks)
  • oxapy/serializer/__init__.pyi (17 hunks)
  • oxapy/templating/__init__.pyi (2 hunks)
  • pyproject.toml (1 hunks)
  • src/bin/stub_gen.rs (0 hunks)
  • src/exceptions.rs (1 hunks)
  • src/into_response.rs (2 hunks)
  • src/json.rs (2 hunks)
  • src/jwt.rs (1 hunks)
  • src/lib.rs (2 hunks)
  • src/serializer/mod.rs (1 hunks)
💤 Files with no reviewable changes (1)
  • src/bin/stub_gen.rs
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-11-22T14:44:51.678Z
Learnt from: j03-dev
Repo: j03-dev/oxapy PR: 82
File: src/routing.rs:412-417
Timestamp: 2025-11-22T14:44:51.678Z
Learning: In oxapy's Router (src/routing.rs), the `middleware()` method implements a layered architecture: it adds the middleware to the current layer, then creates a new empty layer via `self.layers.push(Layer::default())`. This is intentional - subsequent routes registered after the middleware call go into the new layer without inheriting the middleware from the previous layer. Each layer maintains its own routes and middlewares independently. When a request is processed, the system searches through layers to find a matching route and applies only that layer's middlewares.

Applied to files:

  • oxapy/__init__.pyi
🧬 Code graph analysis (3)
src/lib.rs (1)
src/exceptions.rs (1)
  • exceptions (138-148)
src/into_response.rs (1)
src/exceptions.rs (1)
  • exceptions (138-148)
oxapy/serializer/__init__.pyi (1)
oxapy/exceptions/__init__.pyi (1)
  • ClientError (20-31)
🪛 markdownlint-cli2 (0.18.1)
README.md

12-12: Images should have alternate text (alt text)

(MD045, no-alt-text)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (13)
  • GitHub Check: musllinux (ubuntu-22.04, aarch64)
  • GitHub Check: linux (ubuntu-22.04, aarch64)
  • GitHub Check: macos (macos-14, aarch64)
  • GitHub Check: linux (ubuntu-22.04, s390x)
  • GitHub Check: linux (ubuntu-22.04, armv7)
  • GitHub Check: linux (ubuntu-22.04, ppc64le)
  • GitHub Check: linux (ubuntu-22.04, x86_64)
  • GitHub Check: linux (ubuntu-22.04, x86)
  • GitHub Check: musllinux (ubuntu-22.04, x86)
  • GitHub Check: windows (windows-latest, x86)
  • GitHub Check: windows (windows-latest, x64)
  • GitHub Check: musllinux (ubuntu-22.04, armv7)
  • GitHub Check: musllinux (ubuntu-22.04, x86_64)
🔇 Additional comments (7)
src/json.rs (1)

20-21: Explicit Ok(...) wrapping keeps PyResult semantics clear

Wrapping serialized_data.extract(py)? / deserialized_data.extract(py)? in Ok(...) matches the PyResult<_> signature of the closures and keeps error propagation unchanged. Looks good.

Also applies to: 29-30

pyproject.toml (1)

19-21: Confirm python-source="." matches your package layout

Setting python-source="." makes maturin treat the repo root as the Python source directory, which is fine if your oxapy package lives there. If your Python code is under src/ or elsewhere, this may need to be adjusted.

Please verify that maturin build (or your CI build) still discovers and packages oxapy as expected with this setting.

src/serializer/mod.rs (1)

247-269: Single-instance data branch now aligns with PyResult return type

Returning Ok(repr.extract()?) in the non-many path matches the PyResult<Py<PyAny>> signature and is consistent with how errors are propagated elsewhere in this getter.

Cargo.toml (1)

3-3: Dependency and crate version bumps look consistent with the PR goals

The move to oxapy 0.7.4 and the pyo3 / pyo3-async-runtimes / pyo3-stub-gen updates align with the stated objective of tracking pyo3 0.27.

Please make sure your CI (or local matrix) exercises all supported Python versions with these new versions (especially pyo3 0.27 and pyo3-async-runtimes 0.27) to catch any upstream breaking changes early.

Also applies to: 16-18

src/lib.rs (1)

24-27: Reusing IntoPyException from exceptions centralizes error conversion

Importing crate::exceptions::IntoPyException (with pyo3::prelude::*) avoids re-defining the trait here and keeps conversions like ctrlc::set_handler(...).into_py_exception()? consistent across the crate.

Also applies to: 48-49

src/into_response.rs (1)

4-7: DEBUG handling and IntoPyException usage match the intended behavior

Importing IntoPyException here ties in with the to_response! macro’s use of value.try_into().into_py_exception(), keeping Rust→Python error conversion consistent.

For From<PyErr> for Response, the updated DEBUG logic now prints the Python exception by default and only suppresses value.display(py) when DEBUG=false, which aligns with the “display the error as default” goal while still returning a 500 with a JSON detail field.

Also applies to: 89-95

oxapy/serializer/__init__.pyi (1)

186-186: No breaking changes identified. The review comment can be resolved.

The addition of the ty parameter to Field.__new__ does not break existing code because:

  1. All Field subclasses (CharField, EmailField, DateField, etc.) have their own __new__ signatures that do not include the ty parameter. They start with required as the first optional parameter.

  2. Only subclass instantiation is used in the codebase (serializer.EmailField(), serializer.CharField(min_length=8), etc.). No direct Field() instantiation was found.

  3. The Field docstring explicitly states: "You usually use one of the subclasses (CharField, EmailField, IntegerField, etc.) rather than instantiating this directly."

The stub-only nature of this package (backed by PyO3) means subclasses completely override the parent __new__ method, so the Field signature change has no impact on runtime usage.

Signed-off-by: FITAHIANA Nomeniavo Joe <24nomeniavo@gmail.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/bin/stub_gen.rs (1)

8-23: Consider checking the subprocess exit status and avoiding unused output capture

Right now Command::new("find")...output()?; only fails on IO/spawn errors and ignores the actual find/sed exit status, and it also captures stdout/stderr you later discard.

Two small improvements:

  1. Avoid capturing output when you don’t use it:
-        .output()?;
+        .status()?;
  1. (Optional but recommended) Check status.success() and surface a meaningful error if the post‑processing fails, so broken find/sed invocations don’t silently leave stubs unmodified.

Also keep in mind this implicitly relies on GNU find/sed semantics (especially sed -i), so this binary is effectively “Linux-only” unless your CI/dev story already assumes those tools.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0a11092 and 11be8d4.

📒 Files selected for processing (5)
  • oxapy/__init__.pyi (44 hunks)
  • oxapy/exceptions/__init__.pyi (7 hunks)
  • oxapy/jwt/__init__.pyi (4 hunks)
  • oxapy/serializer/__init__.pyi (17 hunks)
  • src/bin/stub_gen.rs (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • oxapy/serializer/init.pyi
🚧 Files skipped from review as they are similar to previous changes (2)
  • oxapy/exceptions/init.pyi
  • oxapy/init.pyi
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (12)
  • GitHub Check: windows (windows-latest, x64)
  • GitHub Check: linux (ubuntu-22.04, armv7)
  • GitHub Check: linux (ubuntu-22.04, x86)
  • GitHub Check: linux (ubuntu-22.04, s390x)
  • GitHub Check: linux (ubuntu-22.04, x86_64)
  • GitHub Check: linux (ubuntu-22.04, ppc64le)
  • GitHub Check: musllinux (ubuntu-22.04, aarch64)
  • GitHub Check: windows (windows-latest, x86)
  • GitHub Check: musllinux (ubuntu-22.04, x86_64)
  • GitHub Check: musllinux (ubuntu-22.04, x86)
  • GitHub Check: musllinux (ubuntu-22.04, armv7)
  • GitHub Check: linux (ubuntu-22.04, aarch64)
🔇 Additional comments (3)
src/bin/stub_gen.rs (1)

3-3: Import position and aliasing look fine

Using pyo3_stub_gen::Result as the main return type is consistent with the rest of this binary; no issues here.

oxapy/jwt/__init__.pyi (2)

12-67: Jwt API signatures look consistent with documented behavior

The constructor and generate_token/verify_token annotations match the described usage and return types; the formatting-only tweaks here don’t introduce any typing or API issues. No changes requested.


103-130: JWT exception __new__ annotations now correctly return the exception type

The __new__ methods for JwtDecodingError, JwtEncodingError, JwtError, JwtInvalidAlgorithm, and JwtInvalidClaim now return their respective exception classes instead of a tuple, which aligns the stubs with runtime behavior and resolves the earlier critical typing problem. Looks good.

@j03-dev j03-dev merged commit 383801b into main Nov 25, 2025
16 of 17 checks passed
This was referenced Jan 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants