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. 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
    sparse-checkout: |
      addons
      odoo/addons
    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 --sparse https://github.com/odoo/odoo .odoo
    - git -C .odoo sparse-checkout set addons odoo/addons
    - 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 Odoo core must stay near-silent for the index-aware rules, so run one after any change to them:

git -C ~/repos/odoo/odoo archive origin/18.0 -- addons odoo/addons ':(exclude,glob)**/static/**' | tar -x -C /tmp/odoo-18.0
oscn check /tmp/odoo-18.0 --odoo-version 18.0 --statistics

Metadata

Release files for odooscan 0.2.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.2.0
File Size Uploaded Provenance Actions
odooscan-0.2.0.tar.gz 46.8 kB Without provenance Details for odooscan-0.2.0.tar.gz

Built distributions (wheels)

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

Total release size: 14.9 MB

Release files / odooscan-0.2.0.tar.gz

Download URL odooscan-0.2.0.tar.gz
Size 46.8 kB
Tags Source
SHA-256 checksum
How to use checksums
4fd8e4245b53b75882f83cf2d5d239aa69e3f438846a05491f4c9dc90ecddebc
BLAKE2b-256 checksum
How to use checksums
f96001e607559ec81b232a96d3f4539a3f8cda538f7c16ad5f64bba32d2c5ab5
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.2.0-py3-none-win_amd64.whl

Download URL odooscan-0.2.0-py3-none-win_amd64.whl
Size 2.2 MB
Tags Python 3 Windows x86-64
SHA-256 checksum
How to use checksums
3f2651db3141700c810a3e8576432ded3d2d59cd4289927b8f3f6938ff9f6366
BLAKE2b-256 checksum
How to use checksums
73dc5acc3d7a829ffab40e7c6a02009ddde1e5f7076767baa3a5dbea34d986c8
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.2.0-py3-none-musllinux_1_2_x86_64.whl

Download URL odooscan-0.2.0-py3-none-musllinux_1_2_x86_64.whl
Size 2.2 MB
Tags Linux musl 1.2+ x86-64 Python 3
SHA-256 checksum
How to use checksums
b2e3c766b4251f994d822313fa80dd0dad1ac6fa83b1d07774d44330168fcd30
BLAKE2b-256 checksum
How to use checksums
e8a669bc1474f866c1dd071f630c88b897037e14b327bb14433584cd810168c4
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.2.0-py3-none-musllinux_1_2_aarch64.whl

Download URL odooscan-0.2.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
b429b64d68e84bf3f244d266e298100f185d81b3c7c41610d264f4e49556e5b8
BLAKE2b-256 checksum
How to use checksums
3c7306f9769d4a5a5c4a3518486fd3b7874d7932331d7fddda73583586518fb0
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.2.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL odooscan-0.2.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
0cbfe37a60b6256b10e8aa81cdc6c0a154dd9305fabf311b236dce8f59066c88
BLAKE2b-256 checksum
How to use checksums
0254b87377c0678a05d3ad7470571dafb4d2e0caf48d35d8c8b7b3eba3c80a7e
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.2.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL odooscan-0.2.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
db4fb79ba54f0bd21c13c43fd3984b08836aea0ac4f4921e0a971fb87e7be723
BLAKE2b-256 checksum
How to use checksums
64edc19a99f4a60b0b4cb1fb9055e39664a2015231d12e551a18f9baebb8f54c
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.2.0-py3-none-macosx_11_0_arm64.whl

Download URL odooscan-0.2.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
69ee02ad6a006e9a05b3126ca002afbc2a38c11a75b6fc677517b780dca19eac
BLAKE2b-256 checksum
How to use checksums
533e55f5d0e571ebcffd1eb9b15bddb2c79d7acc46e2f31b2dff6549ad727d3f
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.2.0-py3-none-macosx_10_12_x86_64.whl

Download URL odooscan-0.2.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
ad3300ac03b4228e182704dcd8dfe4021cb9ea753914ace87ee058365618ef79
BLAKE2b-256 checksum
How to use checksums
1eb4bbebb51a1b57f0154902e05cb752288bfcb83d0f57d11cf9cd9f50d0bd35
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.2.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