If you're an Odoo developer, it's essential for you to understand what circular dependency is, why it happens, its impact, and how to resolve it. Let’s dive in.
What is Circular Dependency? Why Does It Happen?
Circular dependency is a situation where two or more modules (or classes, beans, etc.) depend on each other, either directly or indirectly. Here’s an image to help you understand it better:
I’ve marked Circular Dependency
in red and Linear Dependency
in green, because circular dependencies are considered harmful in the Odoo environment. In fact, Odoo itself restricts circular dependencies.
First Example Case
- A depends on B
- B depends on C
- C depends on A ✅ circular, even though it's indirect
Second Example Case
Let’s say you create module_a
and define a model model.master
. Then you create module_b
and inherit model.master
. But in module_a
, you define a function on model.master
that uses a field coming from module_b
.
This setup might work fine when both modules are already installed. However, it becomes a problem if one or both modules haven't been installed yet. It will cause an error when trying to install one of the modules, preventing it from being installed at all. This kind of structure is highly discouraged in Odoo.
Why Is Circular Dependency Bad? What Are the Consequences?
Fundamentally, Odoo does not support circular dependencies, whether direct or indirect. This is because it can cause errors, especially during:
- Module installation or upgrade
- Dependency resolution in the manifest (
__manifest__.py
) - Auto-loading of interdependent models or fields before the modules are ready
Examples of potential errors:
RecursionError: maximum recursion depth exceeded
Module loading failed due to unresolved dependencies: circular reference
Some dependency may be missing
How to Avoid Circular Dependency?
- Move shared functions to a dedicated utility module (e.g.,
base_utils
) - Use inheritance (
_inherit
) instead ofdepends
if you only want to extend behavior - Use
@api.model
or dynamic imports only when needed, not during module loading - Avoid importing across modules at the top-level (e.g.,
import module_x
) — move imports inside functions or methods to enable lazy loading - Install the
Odoo IDE
extension to easily identify model field ownership
Let me know if you'd like this styled as a blog post draft or formatted in Markdown.