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.3.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.3.0
File Size Uploaded Provenance Actions
odooscan-0.3.0.tar.gz 50.1 kB Without provenance Details for odooscan-0.3.0.tar.gz

Built distributions (wheels)

Table of built distributions (wheels) for odooscan 0.3.0
File Actions
odooscan-0.3.0-py3-none-win_amd64.whl Python 3 none Windows x86-64 Details for odooscan-0.3.0-py3-none-win_amd64.whl
odooscan-0.3.0-py3-none-musllinux_1_2_x86_64.whl Python 3 none Linux musl 1.2+ x86-64 Details for odooscan-0.3.0-py3-none-musllinux_1_2_x86_64.whl
odooscan-0.3.0-py3-none-musllinux_1_2_aarch64.whl Python 3 none Linux musl 1.2+ ARM64 Details for odooscan-0.3.0-py3-none-musllinux_1_2_aarch64.whl
odooscan-0.3.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.3.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
odooscan-0.3.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl Python 3 none Linux glibc 2.17+ ARM64 Details for odooscan-0.3.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
odooscan-0.3.0-py3-none-macosx_11_0_arm64.whl Python 3 none macOS 11.0+ ARM64 Details for odooscan-0.3.0-py3-none-macosx_11_0_arm64.whl
odooscan-0.3.0-py3-none-macosx_10_12_x86_64.whl Python 3 none macOS 10.12+ x86-64 Details for odooscan-0.3.0-py3-none-macosx_10_12_x86_64.whl

Total release size: 15.0 MB

Release files / odooscan-0.3.0.tar.gz

Download URL odooscan-0.3.0.tar.gz
Size 50.1 kB
Tags Source
SHA-256 checksum
How to use checksums
60c6c98171765f74f883c6236a593de4beb50357da5e30bcb2c6c75025c19a31
BLAKE2b-256 checksum
How to use checksums
04bd060a5345771671d3272e641e9ce73a6a0bfcb12007d32c925db579f80b47
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.3.0-py3-none-win_amd64.whl

Download URL odooscan-0.3.0-py3-none-win_amd64.whl
Size 2.2 MB
Tags Python 3 Windows x86-64
SHA-256 checksum
How to use checksums
bba7358443c43dd62b9665f3810eaf8716875821b5617ddd3a3b94f64df10da0
BLAKE2b-256 checksum
How to use checksums
2bfbed95d9d50c780172dc33947a0fd179bf2b960d109e3481b6fa810d2152b4
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.3.0-py3-none-musllinux_1_2_x86_64.whl

Download URL odooscan-0.3.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
55c871cc3b7ade144d9983664584a7e03dfd13bea6ac0b81aac9ec7db79eb30c
BLAKE2b-256 checksum
How to use checksums
905411c9217d4a1523b23ab6034219cc5a9e360c7ecf0b18b73171c5803b8f71
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.3.0-py3-none-musllinux_1_2_aarch64.whl

Download URL odooscan-0.3.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
524cd5c2537fdfb03f43e2e86568608a9fc5b3b43ee2f035c2f6350df891066f
BLAKE2b-256 checksum
How to use checksums
8f2c05dbdf07249df919d1d273722a23d0ad91df98b4a7234508fe05782aa3f8
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.3.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL odooscan-0.3.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
b909ed8827826809009ee20a329e98bf36c3f30feb4cda4fb33df9b3fd1a873c
BLAKE2b-256 checksum
How to use checksums
a259f09eed925095bfeabe12e4417a7a106e0a93ed1b727bdd54fdb862c1966b
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.3.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL odooscan-0.3.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
4e1be460442fdf1c5ef2e687fc858268403a1dd5808f014c5ee7917887d590b0
BLAKE2b-256 checksum
How to use checksums
2028960e6377276c2d5e9e3bbae789dbbe5c7d181bbd97b80c3783d77a0747fb
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.3.0-py3-none-macosx_11_0_arm64.whl

Download URL odooscan-0.3.0-py3-none-macosx_11_0_arm64.whl
Size 2.0 MB
Tags Python 3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
a98d0cf41019d48da5284642d9dec626271ed941965d9a79bddb9d7fd7954e68
BLAKE2b-256 checksum
How to use checksums
f58690bceb4d3e74e080677b02bd74183a40a2393ba59d488afb4e5d7ec6eb46
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.3.0-py3-none-macosx_10_12_x86_64.whl

Download URL odooscan-0.3.0-py3-none-macosx_10_12_x86_64.whl
Size 2.1 MB
Tags Python 3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
f5e629b4cc80c947c5303d5cc1be8228ce096d945e3c1e8384f56e17b67aa123
BLAKE2b-256 checksum
How to use checksums
169a2e17a50b07aa08047c6ab9c264314b6d1e11f689a7fdd54a293734cdcd8b
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.3.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