|
1 | 1 | # -*- coding: utf-8 -*-
|
| 2 | +import ast |
2 | 3 | import collections
|
3 | 4 | import functools
|
4 | 5 | import logging
|
5 | 6 | import re
|
| 7 | +import sys |
6 | 8 | import warnings
|
7 | 9 |
|
8 | 10 | import lxml
|
|
34 | 36 | from .const import NEARLYWARN
|
35 | 37 | from .helpers import _dashboard_actions, _validate_model, resolve_model_fields_path
|
36 | 38 | from .inherit import for_each_inherit
|
37 |
| -from .misc import SelfPrintEvalContext, version_gte |
| 39 | +from .misc import SelfPrintEvalContext, ast_unparse, literal_replace, version_gte |
38 | 40 | from .pg import column_exists, get_value_or_en_translation, table_exists
|
39 | 41 | from .records import edit_view
|
40 | 42 |
|
@@ -100,6 +102,8 @@ def is_leaf(leaf):
|
100 | 102 | del expression # unset so it's not used directly
|
101 | 103 |
|
102 | 104 |
|
| 105 | +AST_CONSTANT_TYPES = (ast.Constant, ast.Str) if sys.version_info < (3, 12) else (ast.Constant,) |
| 106 | + |
103 | 107 | _logger = logging.getLogger(__name__)
|
104 | 108 | DomainField = collections.namedtuple("DomainField", "table domain_column model_select")
|
105 | 109 | """
|
@@ -248,6 +252,41 @@ def _replace_path(cr, old, new, src_model, dst_model, path_str):
|
248 | 252 |
|
249 | 253 |
|
250 | 254 | def _adapt_one_domain(cr, target_model, old, new, model, domain, adapter=None, force_adapt=False):
|
| 255 | + if not isinstance(domain, basestring): |
| 256 | + # defer to the old adapter that replaces invalid terms |
| 257 | + return _adapt_one_domain_old(cr, target_model, old, new, model, domain, adapter, force_adapt) |
| 258 | + |
| 259 | + def domain_check(ast_node): |
| 260 | + if all( |
| 261 | + ( |
| 262 | + isinstance(term, (ast.Tuple, ast.List)) |
| 263 | + and len(term.elts) == 3 |
| 264 | + and isinstance(term.elts[1], AST_CONSTANT_TYPES) |
| 265 | + ) |
| 266 | + or isinstance(term, AST_CONSTANT_TYPES) |
| 267 | + for term in ast_node.elts |
| 268 | + ) and any(isinstance(term, (ast.Tuple, ast.List)) and len(term.elts) == 3 for term in ast_node.elts): |
| 269 | + # it looks like a domain, let's adapt it |
| 270 | + internal_domain = _adapt_one_domain_old( |
| 271 | + cr, |
| 272 | + target_model, |
| 273 | + old, |
| 274 | + new, |
| 275 | + model, |
| 276 | + ast_unparse(ast_node), |
| 277 | + adapter=adapter, |
| 278 | + force_adapt=force_adapt, |
| 279 | + ) |
| 280 | + return ast.parse(unicode(internal_domain), mode="eval").body if internal_domain else ast_node |
| 281 | + return ast_node |
| 282 | + |
| 283 | + new_domain = literal_replace(domain, {ast.List([literal_replace.WILDCARD], None): domain_check}) |
| 284 | + if new_domain != domain: |
| 285 | + return new_domain |
| 286 | + return None |
| 287 | + |
| 288 | + |
| 289 | +def _adapt_one_domain_old(cr, target_model, old, new, model, domain, adapter=None, force_adapt=False): |
251 | 290 | if not adapter:
|
252 | 291 | adapter = lambda leaf, _, __: [leaf]
|
253 | 292 |
|
|
0 commit comments