Frequently Asked Questions¶
Multi-release Odoo addons? Are you crazy?¶
Developing multi-release Odoo addons isn’t officially supported. That makes sense for Odoo SA — each release is a full product. Need new features? Just upgrade. Their strict no-database-changes rule, auto-forward ports, and 3-year support policy keep things manageable. When a new Odoo ships, their whole product upgrades. This works great for upstream.
For downstream, multi-release addons also bring challenges:
- Code decay, messy shared code, and tech debt
- Can’t always use the newest ORM features in older versions
So, yeah, maybe we’re crazy. But if you’re crazy like us, here’s what you now can do:
- Develop addons that are production-ready the day a new Odoo is released
- Maintain your module like any normal Python project — treat Odoo as just another dependency
- Build your own product on top of Odoo
- Support older releases with way less work
- Never migrate modules again — just add or drop Odoo release support
Crazy too? Welcome aboard!
Installation¶
How do I install polytropos?¶
From PyPI (recommended):
Or with uv:
You can also run it without installing it:
Can I install from GitLab Packages?¶
Yes! The package is public, so no authentication required. GitLab Packages mirrors PyPI releases:
pip install polytropos --index-url https://gitlab.com/api/v4/projects/moduon%2Fpolytropos/packages/pypi/simple
Or with uv, add this to your pyproject.toml:
[[tool.uv.pip]]
index-url = "https://gitlab.com/api/v4/projects/moduon%2Fpolytropos/packages/pypi/simple"
Do I need uv?¶
uv is recommended for best experience, but not required. You can also use pip.
Can't I just use Nix?¶
Of course!
Usage¶
How do I create a new module?¶
This creates a pyproject.toml with sensible defaults.
How do I build a wheel for a specific Odoo release?¶
The wheel will include the Odoo release in its version (e.g.,
odoo-addon-my-module-17.0.1.0.0-py3-none-any.whl).
How do I develop in editable mode?¶
Use uv's built-in editable support:
Then set the Odoo release:
Or add it in your integration environment's pyproject.toml:
Odoo development¶
How to generate multi-release translations¶
Let's say your module works accross Odoo 18 and 19, and you want to add the translations.
-
Export Odoo 18 translations (old-style CLI):
-
Export Odoo 19 translations:
-
Join the translations (following upstream docs):
-
Clear mono-release translation files:
-
Now that you have the final
my_addon.potfile, you can use it to translate your addon. It will include all strings needed for all releases.
Configuration¶
What's the difference between releases and default_odoo_release?¶
default_odoo_release: Fallback odoo release to use when building/installingreleases: Which Odoo releases this manifest section applies to
Example
Polytropos uses PEP 440 version specifiers.
How does version building work?¶
Polytropos combines your module version with the Odoo release:
- Module version:
1.2.3(frompyproject.toml) - Odoo release:
17.0 - Full version:
17.0.1.2.3
This follows Odoo's versioning convention where the Odoo release comes first.
Documentation¶
How to read a specific version of the docs?¶
Warning
Public docs are built on last commit always, so they might not exactly reflect the last published stable version.
To get a specific version of the docs, run:
git_ref=v3.1.0 # Change for the docs you want to see
nix --extra-experimental-features 'nix-command flakes' --accept-flake-config \
"gitlab:moduon/polytropos/$git_ref#livedocs"
It will run a local docs server built at that specific version.
Architecture¶
Polytropos uses manifestoo-core for metadata generation:
- Polytropos reads
pyproject.tomland generates a version-specific__manifest__.py - Manifestoo-core converts the Odoo manifest to Python package metadata (including
Requires-Distconversion of Odoo addon dependencies) - Polytropos builds the wheel from the metadata
Why the addon version must have 3 or more components?¶
The version format A.B.X.Y.Z (5 components) is required so that manifestoo-core and
Odoo are able to distinguish between the Odoo release and the addon version. The format
breaks down as:
A.B- Odoo release, always prepended by Polytropos (e.g.,17.0)X.Y.Z- Module version (e.g.,1.2.3)
Your module version must have at least 3 components (X.Y.Z). If your module version has
fewer than 3 components (e.g., 1.0), polytropos will raise an error.
Troubleshooting¶
uv sync fails with "missing build dependencies"¶
Make sure your integration environment's pyproject.toml includes polytropos as a build
dependency:
uv sync doesn't rebuild when I switch Odoo release¶
UV caches builds by source file hash. When you switch Odoo releases, UV may not detect that it should rebuild because the source files haven't technically changed from its perspective.
To fix this, add cache keys
to your addon's pyproject.toml:
[tool.uv]
cache-keys = [
{ env = "ODOO_RELEASE" },
{ file = "*.md" },
{ file = "pyproject.toml" },
{ file = "src/__manifest__.py" },
]
Why these cache keys:
ODOO_RELEASE: Affects the built release. It is the recommended approach when developing in multi-release environments, as it is very easy to switch and hook with direnv or similar tools.*.md: The README is bundled into the__manifest__.py, so these changes should trigger a rebuild.pyproject.toml: Changes to the manifest configuration should trigger a rebuild, since they affect the generated manifest.src/__manifest__.py: The generated manifest is a crucial artifact for distribution, so this tells UV to rebuild it always.
The built wheel has wrong Odoo release¶
Make sure you're passing the correct odoo_release config setting to uv/pip when
building.
uv build fails because sdist and wheel have different versions¶
Running uv build on an addon will fail with:
uv build --no-build-isolation
Building source distribution...
Building wheel from source distribution...
× Failed to build
│ `polytropos/examples/conditional_assets`
╰─▶ The source distribution declares version 1.0.0, but the wheel declares version 19.0.1.0.0
This is on purpose.
To workaround the problem, build in 2 separate steps: