Skip to content

The Wanderer's Guide

Your Odoo module can travel across many versions, like a traveler visits many places. Polytropos means "the one of many paths" - your companion on this journey.

In this tutorial, you'll build a multi-version Odoo module from scratch.

What You Need

  • Python 3.10+
  • uv installed

Create Your Module

Make a folder for your addon:

uvx polytropos init myproject/addons/travel_inventory

This creates a basic pyproject.toml file (and some others that help).

Set Up Multiple Versions

Edit the generated pyproject.toml to support different Odoo releases:

myproject/addons/travel_inventory/pyproject.toml
[build-system]
requires = ["polytropos[build]"]
build-backend = "polytropos.build"

[project]
name = "odoo-addon-travel-inventory"
version = "1.0.0"
description = "The paths I have traveled"
requires-python = ">=3.10"

[tool.polytropos]
default_odoo_release = "19.0"

[[tool.polytropos.manifest]]
depends = ["auth_oauth"]
data = [
    "security/ir.model.access.csv",
    "views/res_partner_form.xml",
]

[[tool.polytropos.manifest]]
releases = ">=18"
depends = ["auth_passkey"]
data = [
    "templates/login.xml",
]

What this does:

  • Defines an Odoo module named travel_inventory
  • Default Odoo release is 19.0
  • All releases implement OAuth for travelers
  • Odoo 18.0 adds passkey support, so our module also supports that by adding extra auth_passkey and a new view

Add Your Code

An exercise for the reader.

Develop in Editable Mode in Different Integration Environments

Create an Odoo integration environment for Odoo 17:

myproject/integrations/odoo17/pyproject.toml
[project]
name = "odoo17-integrated"
version = "0.1.0"
dependencies = [
    "odoo",
    "odoo-addon-travel-inventory",
]

[tool.uv]
config-settings = { odoo_release = "17.0" }

[tool.uv.sources]
odoo = { url = "https://nightly.odoo.com/17.0/nightly/src/odoo_17.0.20260319.tar.gz" }
odoo-addon-travel-inventory = { path = "../../addons/travel_inventory", editable = true }

Build and install everything:

cd myproject/integrations/odoo17
uv sync
uv run odoo --stop-after-init -i travel_inventory

Warning

uv sync can fail for missing build dependencies.

Odoo will fail to install the module if it can't find Postgres.

Of course you can do the same for Odoo 18, 19, etc., each one in a separate folder.

Tip

When uv supports per-project config-settings, you will be able to manage all integration environments from a single parent pyproject.toml.

Build Wheels for Different Releases

Build wheel for Odoo 19.0:

uv build --wheel --config-setting odoo_release=19.0

Build for Odoo 18.0:

uv build --wheel --config-setting odoo_release=18.0

Build for Odoo 17.0:

uv build --wheel --config-setting odoo_release=17.0

Each build creates a wheel with the version in the name:

  • dist/odoo-addon-travel-inventory-19.0.1.0.0-py3-none-any.whl
  • dist/odoo-addon-travel-inventory-18.0.1.0.0-py3-none-any.whl
  • dist/odoo-addon-travel-inventory-17.0.1.0.0-py3-none-any.whl

Check the Wheel

Look inside a built wheel:

unzip -l dist/*.whl

You'll see the __manifest__.py with the right version.

What You Now Have

A multi-version Odoo module that:

  • Uses one codebase for all versions
  • Creates different manifests for each Odoo release
  • Builds version-specific wheels for each Odoo instance

See Also