Draft Issue: OCA/server-env
Title: server.env.mixin _compute_server_env leaks onto res.partner when auth_partner is installed (Odoo 18)
Body:
Module
server_environment (server.env.mixin)
Version
18.0
Description
When auth_partner (from OCA/rest-framework) is installed alongside server_environment, any write to res.partner raises:
AttributeError: 'res.partner' object has no attribute '_compute_server_env'
This causes 185 test failures across ~30 modules (auth_api_key, connector_search_engine, password_security, auth_saml, etc.).
Steps to Reproduce
- Install Odoo 18 with
server_environment and auth_partner (OCA/rest-framework) modules
- Attempt any write to
res.partner (e.g., archive a user, which triggers partner.signup_cancel())
- Error:
AttributeError: 'res.partner' object has no attribute '_compute_server_env'
Root Cause Analysis
server.env.mixin._setup_base() transforms fields by setting field.compute = "_compute_server_env" in-place on the field descriptor object. When auth_partner applies the mixin to auth.directory, this in-place modification appears to affect field descriptors shared with res.partner through Odoo's field registry. Since res.partner does not inherit server.env.mixin, the _compute_server_env method does not exist on it.
The error path:
users.write({'active': False})
- →
auth_signup calls partner.signup_cancel()
- →
partner.write({'signup_type': None})
- → Odoo's
determine() resolves a field's compute method
- →
getattr(records, "_compute_server_env") → AttributeError
Traceback
File "/opt/odoo/lib/odoo/odoo/fields.py", line 1425, in __set__
records.write({self.name: write_value})
File "auth_totp_mail/models/res_users.py", line 11, in write
res = super().write(vals)
File "auth_signup/models/res_users.py", line 362, in write
self.partner_id.sudo().signup_cancel()
File "auth_signup/models/res_partner.py", line 111, in signup_cancel
return self.write({'signup_type': None})
File "account/models/partner.py", line 816, in write
res = super().write(vals)
File "/opt/odoo/lib/odoo/odoo/fields.py", line ~108, in determine
needle = getattr(records, needle)
AttributeError: 'res.partner' object has no attribute '_compute_server_env'
Suggestion
_server_env_transform_field_to_read_from_env() currently modifies the field descriptor in-place (field.compute = "_compute_server_env"). Consider either:
- Creating a new computed field instead of modifying the existing descriptor
- Or ensuring the mixin's
_setup_base() only operates on fields that belong exclusively to the current model (not shared descriptors)
Draft Issue: OCA/server-env
Title:
server.env.mixin_compute_server_envleaks ontores.partnerwhenauth_partneris installed (Odoo 18)Body:
Module
server_environment(server.env.mixin)Version
18.0
Description
When
auth_partner(from OCA/rest-framework) is installed alongsideserver_environment, any write tores.partnerraises:This causes 185 test failures across ~30 modules (auth_api_key, connector_search_engine, password_security, auth_saml, etc.).
Steps to Reproduce
server_environmentandauth_partner(OCA/rest-framework) modulesres.partner(e.g., archive a user, which triggerspartner.signup_cancel())AttributeError: 'res.partner' object has no attribute '_compute_server_env'Root Cause Analysis
server.env.mixin._setup_base()transforms fields by settingfield.compute = "_compute_server_env"in-place on the field descriptor object. Whenauth_partnerapplies the mixin toauth.directory, this in-place modification appears to affect field descriptors shared withres.partnerthrough Odoo's field registry. Sinceres.partnerdoes not inheritserver.env.mixin, the_compute_server_envmethod does not exist on it.The error path:
users.write({'active': False})auth_signupcallspartner.signup_cancel()partner.write({'signup_type': None})determine()resolves a field's compute methodgetattr(records, "_compute_server_env")→AttributeErrorTraceback
Suggestion
_server_env_transform_field_to_read_from_env()currently modifies the field descriptor in-place (field.compute = "_compute_server_env"). Consider either:_setup_base()only operates on fields that belong exclusively to the current model (not shared descriptors)