Skip to main content

odooscan

CI License: MIT prek Complexity: polyscan Conventional Commits

A quality and security scanner for Odoo modules, written in Rust. It parses Python with ruff's parser, and XML and CSV natively. It then builds one index of every model, field, method, XML id, view and access rule across the modules it is given, so rules can check what a single-file linter cannot. For example, it can tell you that a view names a field its model lacks, or that an XML id belongs to a module missing from depends.

uv tool install odooscan    # or: pip install odooscan
oscn check path/to/custom-addons --addons-path ~/repos/odoo/odoo,~/repos/odoo/enterprise

The wheels hold a prebuilt binary for Linux (glibc and musl), macOS and Windows; cargo build --release builds target/release/oscn anywhere else.

The command is oscn. check reports on the modules found under the given paths. --addons-path holds what those modules build on. It is indexed but never reported on, and an Odoo source checkout stands for its addons and odoo/addons directories. The variable ODOOSCAN_ADDONS_PATH sets the same thing. Without base on the addons path, the rules marked needs_index in src/rules.rs are off and a notice says so.

Other options:

  • --format github and --format gitlab are for CI (see below); json and sarif for other tools.
  • --select OD3 and --ignore OD111 filter by code prefix.
  • --exclude migrations/,tests/ hides findings in files matching gitignore-style patterns.
  • --statistics prints counts per rule.

The exit status is 1 when anything is reported, and 2 when the settings are invalid.

Configuration

oscn check reads the nearest odooscan.toml, or pyproject.toml with a [tool.odooscan] table, in the current directory or above it; --config names one instead. Its keys are the check flags, and a flag or ODOOSCAN_ADDONS_PATH replaces the key of the same name.

[tool.odooscan]
addons-path = ["../odoo", "../enterprise"]
odoo-version = "18.0"
ignore = ["OD111"]
exclude = ["/legacy", "migrations/"]
baseline = "odooscan-baseline.json"

Paths in the file are relative to it, and so are anchored exclude patterns (those with a slash before the end, such as /legacy). An unanchored one, such as migrations/, matches at any depth. Excluded files are still indexed: they only go unreported.

In CI

The scan needs the Odoo sources your modules build on. A shallow sparse clone into a hidden directory is enough, and module discovery skips hidden directories. Leaving out translations, static assets and tests makes it about 20 MB instead of 190 MB, with the same index. On GitHub, --format github annotates the pull request, with no need for the Advanced Security that SARIF upload requires on a private repository:

- uses: actions/checkout@v7
- uses: actions/checkout@v7
  with:
    repository: odoo/odoo
    ref: "18.0"
    path: .odoo
    fetch-depth: 1
    filter: blob:none
    sparse-checkout-cone-mode: false
    sparse-checkout: |
      /addons/
      /odoo/addons/
      !**/i18n/
      !**/static/
      !**/tests/
    persist-credentials: false
- uses: astral-sh/setup-uv@v10
- run: uvx --from odooscan oscn check --addons-path .odoo --format github

On GitLab, --format gitlab writes a Code Quality report for the merge request:

odooscan:
  image: python:3.13
  script:
    - git clone --depth 1 --branch 18.0 --filter=blob:none --no-checkout https://github.com/odoo/odoo .odoo
    - git -C .odoo sparse-checkout set --no-cone '/addons/' '/odoo/addons/' '!**/i18n/' '!**/static/' '!**/tests/'
    - git -C .odoo checkout 18.0
    - pip install odooscan
    - oscn check --addons-path .odoo --format gitlab > gl-code-quality-report.json
  artifacts:
    when: always
    reports:
      codequality: gl-code-quality-report.json

Pin odooscan to a version, and the actions to commit SHAs, in a real pipeline.

Series

Each rule declares the Odoo series it applies to, and every module is checked against its own series. The series is the first two parts of a five-part manifest version, so 18.0.1.2.0 means 18.0. Pass --odoo-version 18.0 for modules whose version does not name one. Those modules otherwise get only the rules that carry no range. oscn rules --odoo-version 18.0 lists the rules for a series.

Adopting on an existing codebase

oscn check --write-baseline records every current finding in odooscan-baseline.json beside the configuration file, and later runs given --baseline odooscan-baseline.json (or the baseline key) report only new ones. A finding is recorded by file, code and message, not line, so edits around it do not bring it back. When findings are fixed, a notice says so; write the baseline again to drop them and keep the file shrinking.

Suppressing a finding

Write odooscan: ignore[OD103] in a comment, or noqa: OD103. A trailing comment covers its own line, and a comment alone on a line covers the next one. odooscan: ignore without codes covers every rule. XML takes the same text inside <!-- -->.

Layout

  • crates/odooscan_core/src/project.rs finds modules, parses every file in parallel, and keeps per-file facts.
    • python.rs, xml.rs, csvdata.rs and manifest.rs extract those facts and raise the single-file rules.
  • index.rs merges the facts. It resolves fields through _inherit, _inherits and delegate=True, related comodels, view inheritance, and the dependency scope of each module.
  • checks.rs holds the cross-file rules.
  • rules.rs is the registry: code, series range, severity and category.
  • crates/odooscan is the CLI.

Testing

cargo test runs a snapshot over crates/odooscan_core/tests/fixtures. That fixture is a small core (base, mail) plus custom modules written to trigger every rule; review changes with cargo insta review. The false-positive oracle is Odoo itself: a scan of core must report exactly the findings recorded in tests/oracle/, as CONTRIBUTING.md describes.

Metadata

Release files for odooscan 0.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for odooscan 0.4.0
File Size Uploaded Provenance Actions
odooscan-0.4.0.tar.gz 58.5 kB Without provenance Details for odooscan-0.4.0.tar.gz

Built distributions (wheels)

Table of built distributions (wheels) for odooscan 0.4.0
File Actions
odooscan-0.4.0-py3-none-win_amd64.whl Python 3 none Windows x86-64 Details for odooscan-0.4.0-py3-none-win_amd64.whl
odooscan-0.4.0-py3-none-musllinux_1_2_x86_64.whl Python 3 none Linux musl 1.2+ x86-64 Details for odooscan-0.4.0-py3-none-musllinux_1_2_x86_64.whl
odooscan-0.4.0-py3-none-musllinux_1_2_aarch64.whl Python 3 none Linux musl 1.2+ ARM64 Details for odooscan-0.4.0-py3-none-musllinux_1_2_aarch64.whl
odooscan-0.4.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl Python 3 none Linux glibc 2.17+ x86-64 Details for odooscan-0.4.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
odooscan-0.4.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl Python 3 none Linux glibc 2.17+ ARM64 Details for odooscan-0.4.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
odooscan-0.4.0-py3-none-macosx_11_0_arm64.whl Python 3 none macOS 11.0+ ARM64 Details for odooscan-0.4.0-py3-none-macosx_11_0_arm64.whl
odooscan-0.4.0-py3-none-macosx_10_12_x86_64.whl Python 3 none macOS 10.12+ x86-64 Details for odooscan-0.4.0-py3-none-macosx_10_12_x86_64.whl

Total release size: 15.3 MB

Release files / odooscan-0.4.0.tar.gz

Download URL odooscan-0.4.0.tar.gz
Size 58.5 kB
Tags Source
SHA-256 checksum
How to use checksums
a7c65b5a864e4dc980976c0e90e6e7dab840bb5883dc87b28a084c07a3ab95ab
BLAKE2b-256 checksum
How to use checksums
ea6c7cfe2115f9badeb5990e2f49d1ac60d067426aaabcfeb4e4805f72e56f91
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.6 {"installer":{"name":"uv","version":"0.13.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / odooscan-0.4.0-py3-none-win_amd64.whl

Download URL odooscan-0.4.0-py3-none-win_amd64.whl
Size 2.2 MB
Tags Python 3 Windows x86-64
SHA-256 checksum
How to use checksums
f4520c4d919a264c9d5c8b01a89dd05274c254033969f9a8b84bb718719f6059
BLAKE2b-256 checksum
How to use checksums
6e322780623563342ad654ece965fc3c78159008a308767c6882ab1bf088eeb2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.6 {"installer":{"name":"uv","version":"0.13.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / odooscan-0.4.0-py3-none-musllinux_1_2_x86_64.whl

Download URL odooscan-0.4.0-py3-none-musllinux_1_2_x86_64.whl
Size 2.3 MB
Tags Linux musl 1.2+ x86-64 Python 3
SHA-256 checksum
How to use checksums
d716b19cb9c0b652d2bbde3ee3279609675f75ed1ff470e7134b80ccd6095f6d
BLAKE2b-256 checksum
How to use checksums
c8312d3910002892e8438ee3b1562ebaec356edb58401d0e8742467dbb1304c4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.6 {"installer":{"name":"uv","version":"0.13.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / odooscan-0.4.0-py3-none-musllinux_1_2_aarch64.whl

Download URL odooscan-0.4.0-py3-none-musllinux_1_2_aarch64.whl
Size 2.1 MB
Tags Linux musl 1.2+ ARM64 Python 3
SHA-256 checksum
How to use checksums
d0d47aaa943d1eaafeba16fa7d98c777e79af238f72db7815adbb87494a763ab
BLAKE2b-256 checksum
How to use checksums
a72a7bc7f33cf1661f7a382b97f1ccc986b8fa6dd8e35f0b364bdafad0f97a49
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.6 {"installer":{"name":"uv","version":"0.13.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / odooscan-0.4.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL odooscan-0.4.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 2.2 MB
Tags Linux glibc 2.17+ x86-64 Python 3
SHA-256 checksum
How to use checksums
f46b6d158060255dafb5faa477141b91049236df753392950fef3c16e743b7de
BLAKE2b-256 checksum
How to use checksums
380322dd71481b0a6db76adf1074e4f7094bb068ea858da667eb67d0df8cd802
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.6 {"installer":{"name":"uv","version":"0.13.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / odooscan-0.4.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL odooscan-0.4.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 2.1 MB
Tags Linux glibc 2.17+ ARM64 Python 3
SHA-256 checksum
How to use checksums
a35394521400feb790b35f8042dbd2e87322d46c06511c61df8dcbf0528d1e96
BLAKE2b-256 checksum
How to use checksums
ba6f8c0f7c48026b4ef223ec4445178456fbbc84921b3806d81a39d9ced44fa9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.6 {"installer":{"name":"uv","version":"0.13.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / odooscan-0.4.0-py3-none-macosx_11_0_arm64.whl

Download URL odooscan-0.4.0-py3-none-macosx_11_0_arm64.whl
Size 2.1 MB
Tags Python 3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
b55c3957b417e0787da11fc9f6b49852750049e3cd0159cfeca1df75b731144c
BLAKE2b-256 checksum
How to use checksums
211aa377ba3af625fb38c2559ec61504f786c0c973fa6cece69cbc795957d3b5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.6 {"installer":{"name":"uv","version":"0.13.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / odooscan-0.4.0-py3-none-macosx_10_12_x86_64.whl

Download URL odooscan-0.4.0-py3-none-macosx_10_12_x86_64.whl
Size 2.2 MB
Tags Python 3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
c24f462589916781efbcfdcab73e4e8e92d1448776d1ae71803e2e1f0868ea67
BLAKE2b-256 checksum
How to use checksums
c3819e28cdd6918e1d22beb409a26db0b7fe8d8ee71fc267bfc20612da6ec0c7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.6 {"installer":{"name":"uv","version":"0.13.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for odooscan 0.4.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page