Skip to content

[18.0] component: fix component init compat with py3.10#529

Closed
simahawk wants to merge 1 commit into
18.0from
18-fix-env-init
Closed

[18.0] component: fix component init compat with py3.10#529
simahawk wants to merge 1 commit into
18.0from
18-fix-env-init

Conversation

@simahawk
Copy link
Copy Markdown
Contributor

@simahawk simahawk commented May 7, 2026

In Python 3.10, dynamically reassigning __bases__ on a class (as done in _build_component) incorrectly propagates slot descriptors from classes that become transitively reachable through the new MRO.

odoo.models.BaseModel declares env as a __slots__ entry, which creates a data descriptor on the class. When _build_component rewrites ComponentClass.__bases__, Python 3.10 surfaces this slot descriptor in the component's MRO. Since the slot storage does not exist on component instances, any attempt to assign self.env = value raises AttributeError: can't set attribute.

This bug was fixed in Python 3.12 (see cpython#95573), which is why the issue could not be reproduced locally.

The fix defines env as a property with both getter and setter directly on AbstractComponent. Since AbstractComponent always precedes BaseModel in the built class MRO, the property descriptor takes priority, and self.env = value correctly routes through the setter regardless of Python version.

Solves a problem introduced by #504

If this does not work we have to revert that PR.

@OCA-git-bot
Copy link
Copy Markdown
Contributor

Hi @guewen,
some modules you are maintaining are being modified, check this out!

In Python 3.10, dynamically reassigning __bases__ on a class (as done in _build_component) incorrectly propagates slot descriptors from classes that become transitively reachable through the new MRO.

odoo.models.BaseModel declares env as a __slots__ entry, which creates a data descriptor on the class. When _build_component rewrites ComponentClass.__bases__, Python 3.10 surfaces this slot descriptor in the component's MRO. Since the slot storage does not exist on component instances, any attempt to assign self.env = value raises AttributeError: can't set attribute.

This bug was fixed in Python 3.12 (see cpython#95573), which is why the issue could not be reproduced locally.

The fix defines env as a property with both getter and setter directly on AbstractComponent. Since AbstractComponent always precedes BaseModel in the built class MRO, the property descriptor takes priority, and self.env = value correctly routes through the setter regardless of Python version.
@simahawk
Copy link
Copy Markdown
Contributor Author

simahawk commented May 7, 2026

Does not work for 3.10. Rolling back here #530

@simahawk simahawk closed this May 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants