Skip to content

Conversation

@cesarcoatl
Copy link
Member

@cesarcoatl cesarcoatl commented Jun 17, 2025

Summary by Sourcery

Unify the main package and stub distribution within a single repository by restructuring testing environments, CI workflows, packaging, and versioning for both the Python package and its stubs.

New Features:

  • Add a dedicated stubs package under stubs/ with stub files, packaging metadata, and its own requirements.
  • Define new tox environments for separate installation, type-checking, and styling of both the package and stubs.
  • Introduce GitHub Actions jobs to pip-compile upgrade, build, and publish both the package and stubs to PyPI.

Enhancements:

  • Refactor tox.ini to consolidate and parameterize test environments across Python versions for pkg and stubs.
  • Revise pre-commit hooks to target pkg/src and stubs directories with appropriate tool configurations.
  • Modularize CI workflows using workflow_call and pr-build.yml, replacing external composites and adding automated pip-compile upgrade steps.
  • Extend commitizen config to bump version in both package about.py and stubs pyproject.toml.

Build:

  • Add a pr-build.yml workflow to orchestrate Jython tests, tox-Docker, and tox-GH jobs.

CI:

  • Replace external GH workflow usages with local reusable workflows, add pip-compile upgrade, PR creation, and separate publish-pkg/publish-stubs jobs in GitHub Actions.

Documentation:

  • Add a README and project metadata (pyproject.toml) for the stubs distribution.

@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Jun 17, 2025

Reviewer's Guide

This PR restructures the project to treat the core library and its type stubs as two parallel distributions by reorganizing Tox environments, CI pipelines, and pre-commit hooks, and by introducing a standalone stubs package with its own build and packaging metadata.

Class diagram for new stubs types in incendium-stubs

classDiagram
    class DisposableConnection {
        +__init__(database: AnyStr, retries: int)
        +database: AnyStr
        +status: AnyStr
        +__enter__() DisposableConnection
        +__exit__(exc_type, exc_val, exc_tb)
    }
    class Param {
        +__init__(name_or_index: Union[int, AnyStr], type_code: int, value: Optional[Any])
        +name_or_index: Union[int, AnyStr]
        +type_code: int
        +value: Optional[Any]
    }
    class InParam {
        +__init__(name_or_index: Union[int, AnyStr], type_code: int, value: Any)
    }
    class OutParam {
        +__init__(name_or_index: Union[int, AnyStr], type_code: int)
    }
    class TransactionManager {
        +tx_id: AnyStr
        +__init__(database: AnyStr, isolation_level: Optional[int], timeout: Optional[int])
        +__enter__() AnyStr
        +__exit__(exc_type, exc_val, exc_tb)
    }
    class IncendiumUser {
        +__init__(user: PyUser)
        +contact_info: List[ContactInfo]
        +email: List[AnyStr]
        +first_name: AnyStr
        +full_name: AnyStr
        +last_name: AnyStr
        +locale: AnyStr
        +roles: List[AnyStr]
    }
    class Error {
        +message: AnyStr
        +__init__(message: AnyStr)
    }
    class JavaError {
        +cause: Optional[Throwable]
        +inner_exception: InnerException
        +message: AnyStr
        +__init__(message: AnyStr, inner_exception: InnerException, cause: Optional[Throwable], remove_substring: Optional[AnyStr])
    }
    class ApplicationError {
    }
    class GatewayError {
        +__init__(message: AnyStr, inner_exception: InnerException, cause: Optional[Throwable])
    }
    class MSSQLError {
        +__init__(message: AnyStr, inner_exception: InnerException, cause: Optional[Throwable])
    }
    class TagError {
    }
    class _NanoXML {
        +indent: AnyStr
        +root: AnyStr
        +__init__(root: AnyStr, indent: AnyStr)
        +add_element(name: AnyStr)
        +add_sub_element(name: AnyStr, value: AnyStr)
        +close_element(name: AnyStr)
        +to_string()
    }
    Param <|-- InParam
    Param <|-- OutParam
    JavaError <|-- ApplicationError
    JavaError <|-- GatewayError
    JavaError <|-- MSSQLError
    Error <|-- TagError
Loading

File-Level Changes

Change Details Files
Tox configuration refactored to handle both pkg and stubs
  • Split top-level env_list into separate pkg and stubs targets
  • Renamed and scoped testenvs (install-pkg, typecheck-pkg, typecheck-stubs, style-pkg, style-stubs)
  • Added change_dir directives to point to pkg or stubs
  • Created a standalone tox.ini under stubs for stub‐only testing
tox.ini
stubs/tox.ini
CI workflows revamped for dual distribution
  • Replaced composite pip-compile upgrade with separate pkg/stubs steps in pip-compile-upgrade.yml
  • Merged pre-commit and pylint jobs into unified ci.yml with workflow_call
  • Introduced pr-build.yml to orchestrate jython and tox-docker/gh matrix
  • Split publish job into publish-pkg and publish-stubs in publish.yml
.github/workflows/pip-compile-upgrade.yml
.github/workflows/ci.yml
.github/workflows/pr-build.yml
.github/workflows/publish.yml
.github/workflows/jython.yml
Pre-commit hooks extended and scoped for pkg and stubs
  • Added file filters and namespacing for pkg/src in sort-all, ssort, unimport, isort, docformatter, flake8, pydocstyle, pylint
  • Added flake8-stubs hook with flake8-pyi and stubs/.flake8 config
  • Configured isort to use pkg/.isort.cfg
  • Retained default stubs styling hooks under stubs folder
.pre-commit-config.yaml
Standalone stubs package introduced
  • Added stubs/ directory with stub modules (.pyi) under stubs/stubs/incendium
  • Included packaging metadata (pyproject.toml, README.md, LICENSE references)
  • Generated stubs requirements.txt via uv and provided uv.toml
  • Provided stub distribution configs (.isort.cfg, .mypy.ini, .flake8)
stubs/README.md
stubs/pyproject.toml
stubs/requirements.txt
stubs/stubs/incendium/**/*.pyi
stubs/uv.toml
stubs/.isort.cfg
stubs/.mypy.ini
stubs/.flake8
Project metadata updated to include stubs versioning
  • Appended stubs pyproject.toml as version_files entry in cz.toml
.cz.toml

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey @cesarcoatl - I've reviewed your changes - here's some feedback:

  • Consider simplifying the duplicated tox [testenv:*] definitions by using inheritance or factors (e.g. basepython= and deps= references) so you don’t have to repeat nearly identical blocks for pkg vs stubs.
  • In the pip-compile-upgrade workflow you’re calling two different actions (pip-compile-upgrade vs uv-pip-compile-upgrade)—either standardize on one or add a comment explaining why they differ to avoid confusion.
  • It would help to add a pre-commit mypy hook targeting .pyi files so stub changes get type-checked automatically during commits.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Consider simplifying the duplicated tox `[testenv:*]` definitions by using inheritance or factors (e.g. `basepython=` and `deps=` references) so you don’t have to repeat nearly identical blocks for pkg vs stubs.
- In the pip-compile-upgrade workflow you’re calling two different actions (`pip-compile-upgrade` vs `uv-pip-compile-upgrade`)—either standardize on one or add a comment explaining why they differ to avoid confusion.
- It would help to add a pre-commit mypy hook targeting `.pyi` files so stub changes get type-checked automatically during commits.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@cesarcoatl cesarcoatl merged commit 0f3cea2 into main Jun 17, 2025
8 checks passed
@cesarcoatl cesarcoatl deleted the chore/unify-incendium-incendium-stubs branch June 17, 2025 18:47
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