Skip to main content

Extensible Python linter written in Rust

Project description

jg-lint

Extensible Python linter with a Rust core.

Installation

Requires Python 3.14+.

uv add jg-lint

or with pip:

pip install jg-lint

or with Poetry:

poetry add jg-lint

Development install

To build from source, you need Maturin and a Rust toolchain:

git clone https://github.com/giacosoft/jg-lint.git
cd jg-lint
uv sync
uv run maturin develop

Usage

jg-lint check <paths...>

Lint one or more files or directories:

jg-lint check src/
jg-lint check src/ lib/ main.py
jg-lint check --config path/to/project src/

The --config flag points to the directory containing pyproject.toml (defaults to .).

Output looks like:

src/app.py:12:1: MY001 TODO comments should be tracked as issues
src/app.py:45:1: MY001 TODO comments should be tracked as issues

Found 2 violation(s)

Exit code is 1 if any violations are found, 0 otherwise.

Inline suppression

Some rules opt in to per-line suppression via # noqa:

x = something()  # noqa: MY001
y = another()  # noqa: MY001, MY002

By design, # noqa is not honored by default — rules must explicitly set allow_noqa = True to allow it. This keeps suppression intentional and reserved for cases where the rule author has decided it's acceptable.

Configuration

All configuration lives in pyproject.toml under [tool.jg-lint]:

[tool.jg-lint]
select = ["MY"]              # only run rules matching these prefixes (empty = all)
ignore = ["MY002"]           # skip these rules globally
exclude = [".venv/**", "build/**"]
rules_path = "./rules"       # directory containing your custom rule modules

[tool.jg-lint.per-file-ignores]
"tests/**" = ["MY001"]       # skip MY001 in test files

Writing custom rules

1. Create a rule module

Put it inside the directory you've configured as rules_path (e.g. ./rules/no_todo.py or ./rules/no_todo/__init__.py).

from jg_linter import Rule, Violation


class NoTodoComments(Rule):
    code = "MY001"
    message = "TODO comments should be tracked as issues"

    def check(self, file_path: str, content: str) -> list[Violation]:
        violations = []
        for i, line in enumerate(content.splitlines(), 1):
            if "# TODO" in line:
                violations.append(
                    Violation(file_path, i, 1, self.code, self.message)
                )
        return violations


def get_rules() -> list[Rule]:
    return [NoTodoComments()]

Each rule needs:

  • code -- unique identifier (e.g. MY001)
  • message -- human-readable description
  • check(file_path, content) -- returns a list of Violation objects

Set test_only = True on a rule to run it only against test files (files named test_*.py, *_test.py, or inside a tests/ directory).

Set allow_noqa = True on a rule to allow inline # noqa: CODE suppression. Without this, the rule cannot be silenced per-line and can only be turned off project-wide via ignore or per-file-ignores.

2. Point jg-lint at the rules folder

[tool.jg-lint]
rules_path = "./rules"

Every top-level .py file and package inside rules_path is imported automatically; any module exposing get_rules() contributes rules. Files and folders starting with _ are skipped. The rules directory is prepended to sys.path during loading, so no PYTHONPATH setup is needed.

3. Run

jg-lint check src/
src/app.py:3:1: MY001 TODO comments should be tracked as issues
src/utils.py:17:1: MY001 TODO comments should be tracked as issues

Found 2 violation(s)

Contributing

You need a Rust toolchain (stable), Python 3.14+, and uv.

git clone https://github.com/giacosoft/jg-lint.git
cd jg-lint
uv sync
uv run maturin develop

Tests

cargo test                 # Rust unit tests
uv run pytest              # Python tests (rebuild with `maturin develop` if Rust changed)

Linting and formatting

Before opening a PR, run the same checks CI does:

# Rust
cargo fmt --all -- --check          # formatting
cargo clippy --all-targets -- -D warnings   # lints (fails on any warning)
cargo audit                          # CVEs in dependencies (install with `cargo install cargo-audit`)

# Python
uv run ruff check .                  # lint
uv run ruff format --check .         # format check

To auto-fix:

cargo fmt --all
cargo clippy --fix --all-targets
uv run ruff check --fix .
uv run ruff format .

License

MIT — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

jg_lint-0.4.0.tar.gz (23.4 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

jg_lint-0.4.0-cp315-cp315-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.2 MB view details)

Uploaded CPython 3.15manylinux: glibc 2.17+ x86-64

jg_lint-0.4.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.2 MB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.17+ ARM64

jg_lint-0.4.0-cp314-cp314-win_amd64.whl (926.3 kB view details)

Uploaded CPython 3.14Windows x86-64

jg_lint-0.4.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.2 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.17+ x86-64

jg_lint-0.4.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.2 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.17+ ARM64

jg_lint-0.4.0-cp314-cp314-macosx_11_0_arm64.whl (1.0 MB view details)

Uploaded CPython 3.14macOS 11.0+ ARM64

jg_lint-0.4.0-cp314-cp314-macosx_10_12_x86_64.whl (1.1 MB view details)

Uploaded CPython 3.14macOS 10.12+ x86-64

File details

Details for the file jg_lint-0.4.0.tar.gz.

File metadata

  • Download URL: jg_lint-0.4.0.tar.gz
  • Upload date:
  • Size: 23.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for jg_lint-0.4.0.tar.gz
Algorithm Hash digest
SHA256 21b87ee15e0ffff7c054f821fe711070272b39a6c893221eb8be0b490c1a6f30
MD5 8fdc8f1bc17e1210664b15a815a3ccf7
BLAKE2b-256 54397830fb4c49eba7c99fba0b85b641b3a82d8299473fc22711127f0602f3a9

See more details on using hashes here.

Provenance

The following attestation bundles were made for jg_lint-0.4.0.tar.gz:

Publisher: release.yml on jangia/jg-lint

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file jg_lint-0.4.0-cp315-cp315-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for jg_lint-0.4.0-cp315-cp315-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 e29044bdad3c320fb3c0d306a8671e9f90c02197da1e0532e59a08f4f1e576ba
MD5 c1cec359802636fa563e59596b37f03a
BLAKE2b-256 8aa7f1b94092b40ca510241407824fea9d21e99f9d5a628e54406260168cf4db

See more details on using hashes here.

Provenance

The following attestation bundles were made for jg_lint-0.4.0-cp315-cp315-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on jangia/jg-lint

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file jg_lint-0.4.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for jg_lint-0.4.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 5b51a31f6234403e0a95a5fe63631acaf7d5b131e3893ab5edab0ddea0b95a5a
MD5 58232b128118b9d6846cd88b3bf0ff2a
BLAKE2b-256 9062726878ddf7780c5716be8381f8d50854bf216bc37977dad84dc0a3db9d06

See more details on using hashes here.

Provenance

The following attestation bundles were made for jg_lint-0.4.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on jangia/jg-lint

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file jg_lint-0.4.0-cp314-cp314-win_amd64.whl.

File metadata

  • Download URL: jg_lint-0.4.0-cp314-cp314-win_amd64.whl
  • Upload date:
  • Size: 926.3 kB
  • Tags: CPython 3.14, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for jg_lint-0.4.0-cp314-cp314-win_amd64.whl
Algorithm Hash digest
SHA256 3eaab4bda4e6bbce01097941f66899274658f7e4d154bc6654598079c0c713ba
MD5 8b0ddf87d6f59feae55597b194cd8781
BLAKE2b-256 8a68220d87dbd534ff271351a875b9226e5d47dd7620a2d01cd076ccd9c5a7a6

See more details on using hashes here.

Provenance

The following attestation bundles were made for jg_lint-0.4.0-cp314-cp314-win_amd64.whl:

Publisher: release.yml on jangia/jg-lint

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file jg_lint-0.4.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for jg_lint-0.4.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 2833ad9465da76b99b999206767a33dcf666c03d89dcc16d2a15d8294e895c20
MD5 0157a56c9f392e19128a046ac3afbb6c
BLAKE2b-256 a5127ebc48b85abbf6abf1dc37e244e67888e3a0c42f9fe9b3268f965a89a009

See more details on using hashes here.

Provenance

The following attestation bundles were made for jg_lint-0.4.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on jangia/jg-lint

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file jg_lint-0.4.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for jg_lint-0.4.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 63e49c3ccb76779a637ed637faa6ef411ddf6fff4310a08d86f87daff8c6a344
MD5 c897bbb6cb9383511251390f69a9f84c
BLAKE2b-256 a4f5df10570301e889fec2c825710198a9349704c4a692fb96c8c21d1bb63366

See more details on using hashes here.

Provenance

The following attestation bundles were made for jg_lint-0.4.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on jangia/jg-lint

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file jg_lint-0.4.0-cp314-cp314-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for jg_lint-0.4.0-cp314-cp314-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 2c82edd560f9431806cb3f8fc2bca1e8a1d1277cd326234d71f4a338bbc148ef
MD5 a5ce199d3a2effa90418b601b20f1900
BLAKE2b-256 a0b7be7a7f96b947fad7e09e5d4064c3a0edfcb18b728f1cb5250ad23ee512bc

See more details on using hashes here.

Provenance

The following attestation bundles were made for jg_lint-0.4.0-cp314-cp314-macosx_11_0_arm64.whl:

Publisher: release.yml on jangia/jg-lint

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file jg_lint-0.4.0-cp314-cp314-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for jg_lint-0.4.0-cp314-cp314-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 5283994e2d815c05c68569e01d1c398aeb0fcf763c740d1b398eb0c42d763f17
MD5 68de74c0d5fbc7abf1dfd39ae94eab59
BLAKE2b-256 9aaef956705cada39b31bc643c3a859a26bfb5f87b57e02d246b6511d20411c7

See more details on using hashes here.

Provenance

The following attestation bundles were made for jg_lint-0.4.0-cp314-cp314-macosx_10_12_x86_64.whl:

Publisher: release.yml on jangia/jg-lint

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page