From 40c1de87d821dea9933d920aac13cab1f149f9d9 Mon Sep 17 00:00:00 2001 From: Florent Xicluna Date: Sun, 15 Jan 2012 22:42:14 +0100 Subject: [PATCH 1/8] [REF] remove unused import, always import literal_eval from tools.safe_eval. bzr revid: florent.xicluna@gmail.com-20120115214214-0rjwn80choc9g0fs --- openerp/addons/base/ir/ir_actions.py | 5 ++--- openerp/netsvc.py | 1 - openerp/service/http_server.py | 14 +++++--------- openerp/service/web_services.py | 1 + openerp/service/websrv_lib.py | 3 --- openerp/sql_db.py | 5 ++--- openerp/tests/common.py | 1 - openerp/tests/test_ir_sequence.py | 3 --- openerp/tests/test_xmlrpc.py | 1 - 9 files changed, 10 insertions(+), 24 deletions(-) diff --git a/openerp/addons/base/ir/ir_actions.py b/openerp/addons/base/ir/ir_actions.py index f02269fa9bc..96b6bae848f 100644 --- a/openerp/addons/base/ir/ir_actions.py +++ b/openerp/addons/base/ir/ir_actions.py @@ -18,7 +18,6 @@ # along with this program. If not, see . # ############################################################################## -import ast import copy import logging import os @@ -31,7 +30,7 @@ import netsvc from osv import fields,osv from report.report_sxw import report_sxw, report_rml from tools.config import config -from tools.safe_eval import safe_eval as eval +from tools.safe_eval import safe_eval as eval, literal_eval from tools.translate import _ from socket import gethostname @@ -920,7 +919,7 @@ class act_client(osv.osv): def _get_params(self, cr, uid, ids, field_name, arg, context): return dict([ - ((record.id, ast.literal_eval(record.params_store)) + ((record.id, literal_eval(record.params_store)) if record.params_store else (record.id, False)) for record in self.browse(cr, uid, ids, context=context) ]) diff --git a/openerp/netsvc.py b/openerp/netsvc.py index c1120763ad4..ca08a362771 100644 --- a/openerp/netsvc.py +++ b/openerp/netsvc.py @@ -30,7 +30,6 @@ import socket import sys import threading import time -import traceback import types from pprint import pformat diff --git a/openerp/service/http_server.py b/openerp/service/http_server.py index 506138b7fb4..66d701e0681 100644 --- a/openerp/service/http_server.py +++ b/openerp/service/http_server.py @@ -39,21 +39,17 @@ static HTTP, DAV or other. """ -from websrv_lib import * -import openerp.netsvc as netsvc -import errno -import threading -import openerp.tools as tools +import base64 import posixpath import urllib import os -import select -import socket -import xmlrpclib import logging - from SimpleXMLRPCServer import SimpleXMLRPCDispatcher +from websrv_lib import * +import openerp.netsvc as netsvc +import openerp.tools as tools + try: import fcntl except ImportError: diff --git a/openerp/service/web_services.py b/openerp/service/web_services.py index f486a050a7f..3fa65d8c9ce 100644 --- a/openerp/service/web_services.py +++ b/openerp/service/web_services.py @@ -39,6 +39,7 @@ import openerp.sql_db as sql_db import openerp.tools as tools import openerp.modules import openerp.exceptions +from openerp.service import http_server #.apidoc title: Exported Service methods #.apidoc module-mods: member-order: bysource diff --git a/openerp/service/websrv_lib.py b/openerp/service/websrv_lib.py index a4bdebcec27..1e276ab7fa2 100644 --- a/openerp/service/websrv_lib.py +++ b/openerp/service/websrv_lib.py @@ -32,9 +32,6 @@ usable in other projects, too. """ -import socket -import base64 -import errno import SocketServer from BaseHTTPServer import * from SimpleHTTPServer import SimpleHTTPRequestHandler diff --git a/openerp/sql_db.py b/openerp/sql_db.py index 63ab2a13fb9..82851abd034 100644 --- a/openerp/sql_db.py +++ b/openerp/sql_db.py @@ -37,8 +37,7 @@ __all__ = ['db_connect', 'close_db'] from threading import currentThread import logging -from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT, ISOLATION_LEVEL_READ_COMMITTED, ISOLATION_LEVEL_SERIALIZABLE,\ - ISOLATION_LEVEL_REPEATABLE_READ +from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT, ISOLATION_LEVEL_READ_COMMITTED, ISOLATION_LEVEL_REPEATABLE_READ from psycopg2.psycopg1 import cursor as psycopg1cursor from psycopg2.pool import PoolError @@ -421,7 +420,7 @@ class ConnectionPool(object): try: result = psycopg2.connect(dsn=dsn, connection_factory=PsycoConnection) - except psycopg2.Error, e: + except psycopg2.Error: self.__logger.exception('Connection to the database failed') raise self._connections.append((result, True)) diff --git a/openerp/tests/common.py b/openerp/tests/common.py index 57ebead925e..44696384ce7 100644 --- a/openerp/tests/common.py +++ b/openerp/tests/common.py @@ -1,7 +1,6 @@ # -*- coding: utf-8 -*- import os import time -import unittest2 import xmlrpclib import openerp diff --git a/openerp/tests/test_ir_sequence.py b/openerp/tests/test_ir_sequence.py index c926a52ed64..2e9623c09b9 100644 --- a/openerp/tests/test_ir_sequence.py +++ b/openerp/tests/test_ir_sequence.py @@ -7,11 +7,8 @@ # > OPENERP_ADDONS_PATH='../../../addons/trunk' OPENERP_PORT=8069 \ # OPENERP_DATABASE=yy PYTHONPATH=../:. unit2 test_ir_sequence # This assume an existing database. -import os import psycopg2 -import time import unittest2 -import xmlrpclib import openerp import common diff --git a/openerp/tests/test_xmlrpc.py b/openerp/tests/test_xmlrpc.py index 65d40af866a..954d3447360 100644 --- a/openerp/tests/test_xmlrpc.py +++ b/openerp/tests/test_xmlrpc.py @@ -6,7 +6,6 @@ # OPENERP_DATABASE=yy nosetests tests/test_xmlrpc.py # > OPENERP_ADDONS_PATH='../../../addons/trunk' OPENERP_PORT=8069 \ # OPENERP_DATABASE=yy PYTHONPATH=../:. unit2 test_xmlrpc -import os import time import unittest2 import xmlrpclib From 290961f08a60720c7bcf1c892645219537514c68 Mon Sep 17 00:00:00 2001 From: Florent Xicluna Date: Sun, 15 Jan 2012 22:47:02 +0100 Subject: [PATCH 2/8] [REF] consistently use simplejson as json library. bzr revid: florent.xicluna@gmail.com-20120115214702-dh7i7w17ubepc6eo --- openerp/osv/fields.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openerp/osv/fields.py b/openerp/osv/fields.py index 3a8448e22e5..c8226d27dfe 100644 --- a/openerp/osv/fields.py +++ b/openerp/osv/fields.py @@ -46,7 +46,7 @@ import openerp.netsvc as netsvc import openerp.tools as tools from openerp.tools.translate import _ from openerp.tools import float_round, float_repr -import json +import simplejson as json def _symbol_set(symb): if symb == None or symb == False: From 4d77130107e22969aa37e67fff5c4ab2029c6b81 Mon Sep 17 00:00:00 2001 From: Vo Minh Thu Date: Wed, 18 Jan 2012 12:24:00 +0100 Subject: [PATCH 3/8] [IMP] tools: removed literal_eval as we drop python 2.6 support. bzr revid: vmt@openerp.com-20120118112400-n7uulbbwm7wr5lpu --- openerp/addons/base/test/base_test.yml | 12 +++--- openerp/tools/safe_eval.py | 58 +------------------------- 2 files changed, 7 insertions(+), 63 deletions(-) diff --git a/openerp/addons/base/test/base_test.yml b/openerp/addons/base/test/base_test.yml index 450719af046..fe22e3a4935 100644 --- a/openerp/addons/base/test/base_test.yml +++ b/openerp/addons/base/test/base_test.yml @@ -13,17 +13,17 @@ 2. Try simple literal definition to verify it works with literal_eval - !python {model: ir.model}: | - from tools.safe_eval import literal_eval + import ast expected = (1, {"a": 9}, (True, False, None)) - actual = literal_eval('(1, {"a": 9}, (True, False, None))') + actual = ast.literal_eval('(1, {"a": 9}, (True, False, None))') assert actual == expected, "Simple python expressions are not working with literal_eval" - 3. Try arithmetic expression in literal_eval to verify it does not work - !python {model: ir.model}: | - from tools.safe_eval import literal_eval + import ast try: - literal_eval('(1, {"a": 2*9}, (True, False, None))') + ast.literal_eval('(1, {"a": 2*9}, (True, False, None))') assert False, "literal_eval should not accept arithmetic expressions" except ValueError: pass @@ -31,9 +31,9 @@ 4. Try forbidden expressions in literal_eval to verify they are not allowed - !python {model: ir.model}: | - from tools.safe_eval import literal_eval + import ast try: - literal_eval('{"a": True.__class__}') + ast.literal_eval('{"a": True.__class__}') assert False, "literal_eval should accept only literals" except ValueError: pass diff --git a/openerp/tools/safe_eval.py b/openerp/tools/safe_eval.py index f215bb2df8d..4a28d9de016 100644 --- a/openerp/tools/safe_eval.py +++ b/openerp/tools/safe_eval.py @@ -30,14 +30,13 @@ condition/math builtins. # - http://code.activestate.com/recipes/286134/ # - safe_eval in lp:~xrg/openobject-server/optimize-5.0 # - safe_eval in tryton http://hg.tryton.org/hgwebdir.cgi/trytond/rev/bbb5f73319ad -# - python 2.6's ast.literal_eval from opcode import HAVE_ARGUMENT, opmap, opname from types import CodeType import logging import os -__all__ = ['test_expr', 'literal_eval', 'safe_eval', 'const_eval', 'ext_eval' ] +__all__ = ['test_expr', 'safe_eval', 'const_eval', 'ext_eval' ] # The time module is usually already provided in the safe_eval environment # but some code, e.g. datetime.datetime.now() (Windows/Python 2.5.2, bug @@ -161,61 +160,6 @@ def expr_eval(expr): c = test_expr(expr, _EXPR_OPCODES) return eval(c) - -# Port of Python 2.6's ast.literal_eval for use under Python 2.5 -SAFE_CONSTANTS = {'None': None, 'True': True, 'False': False} - -try: - # first, try importing directly - from ast import literal_eval -except ImportError: - import _ast as ast - - def _convert(node): - if isinstance(node, ast.Str): - return node.s - elif isinstance(node, ast.Num): - return node.n - elif isinstance(node, ast.Tuple): - return tuple(map(_convert, node.elts)) - elif isinstance(node, ast.List): - return list(map(_convert, node.elts)) - elif isinstance(node, ast.Dict): - return dict((_convert(k), _convert(v)) for k, v - in zip(node.keys, node.values)) - elif isinstance(node, ast.Name): - if node.id in SAFE_CONSTANTS: - return SAFE_CONSTANTS[node.id] - raise ValueError('malformed or disallowed expression') - - def parse(expr, filename='', mode='eval'): - """parse(source[, filename], mode]] -> code object - Parse an expression into an AST node. - Equivalent to compile(expr, filename, mode, PyCF_ONLY_AST). - """ - return compile(expr, filename, mode, ast.PyCF_ONLY_AST) - - def literal_eval(node_or_string): - """literal_eval(expression) -> value - Safely evaluate an expression node or a string containing a Python - expression. The string or node provided may only consist of the - following Python literal structures: strings, numbers, tuples, - lists, dicts, booleans, and None. - - >>> literal_eval('[1,True,"spam"]') - [1, True, 'spam'] - - >>> literal_eval('1+3') - Traceback (most recent call last): - ... - ValueError: malformed or disallowed expression - """ - if isinstance(node_or_string, basestring): - node_or_string = parse(node_or_string) - if isinstance(node_or_string, ast.Expression): - node_or_string = node_or_string.body - return _convert(node_or_string) - def _import(name, globals=None, locals=None, fromlist=None, level=-1): if globals is None: globals = {} From b5caa70b833be8ad63f42b92c70bf5a3e9ccd610 Mon Sep 17 00:00:00 2001 From: Vo Minh Thu Date: Wed, 18 Jan 2012 12:41:09 +0100 Subject: [PATCH 4/8] [IMP] tools: removed some functools functions (they were there for previous python versions). bzr revid: vmt@openerp.com-20120118114109-txh1cjv503xautty --- openerp/addons/base/ir/ir_mail_server.py | 1 - openerp/osv/osv.py | 2 +- openerp/sql_db.py | 12 ++--- openerp/tools/func.py | 68 ++---------------------- openerp/tools/misc.py | 12 ++--- 5 files changed, 13 insertions(+), 82 deletions(-) diff --git a/openerp/addons/base/ir/ir_mail_server.py b/openerp/addons/base/ir/ir_mail_server.py index 3cb1446a146..aca4778830f 100644 --- a/openerp/addons/base/ir/ir_mail_server.py +++ b/openerp/addons/base/ir/ir_mail_server.py @@ -34,7 +34,6 @@ from osv import osv from osv import fields from openerp.tools.translate import _ from openerp.tools import html2text -from openerp.tools.func import wraps import openerp.tools as tools # ustr was originally from tools.misc. diff --git a/openerp/osv/osv.py b/openerp/osv/osv.py index 85df3e7e219..44597bf6507 100644 --- a/openerp/osv/osv.py +++ b/openerp/osv/osv.py @@ -21,6 +21,7 @@ #.apidoc title: Objects Services (OSV) +from functools import wraps import logging from psycopg2 import IntegrityError, errorcodes @@ -29,7 +30,6 @@ import openerp import openerp.netsvc as netsvc import openerp.pooler as pooler import openerp.sql_db as sql_db -from openerp.tools.func import wraps from openerp.tools.translate import translate from openerp.osv.orm import MetaModel, Model, TransientModel, AbstractModel import openerp.exceptions diff --git a/openerp/sql_db.py b/openerp/sql_db.py index 82851abd034..a268cfd3b2e 100644 --- a/openerp/sql_db.py +++ b/openerp/sql_db.py @@ -35,13 +35,13 @@ See also: the `pooler` module __all__ = ['db_connect', 'close_db'] -from threading import currentThread +from functools import wraps import logging -from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT, ISOLATION_LEVEL_READ_COMMITTED, ISOLATION_LEVEL_REPEATABLE_READ -from psycopg2.psycopg1 import cursor as psycopg1cursor -from psycopg2.pool import PoolError - import psycopg2.extensions +from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT, ISOLATION_LEVEL_READ_COMMITTED, ISOLATION_LEVEL_REPEATABLE_READ +from psycopg2.pool import PoolError +from psycopg2.psycopg1 import cursor as psycopg1cursor +from threading import currentThread import warnings psycopg2.extensions.register_type(psycopg2.extensions.UNICODE) @@ -66,7 +66,7 @@ psycopg2.extensions.register_type(psycopg2.extensions.new_type((700, 701, 1700,) import tools -from tools.func import wraps, frame_codeinfo +from tools.func import frame_codeinfo from datetime import datetime as mdt from datetime import timedelta import threading diff --git a/openerp/tools/func.py b/openerp/tools/func.py index 9f52f1da956..d1797e30b9a 100644 --- a/openerp/tools/func.py +++ b/openerp/tools/func.py @@ -20,68 +20,10 @@ # ############################################################################## -__all__ = ['partial', 'wraps', 'update_wrapper', 'synchronized'] - -try: - from functools import partial, wraps, update_wrapper -except ImportError: - # The functools module doesn't exist in python < 2.5 - # Code taken from python 2.5 - # http://svn.python.org/view/python/tags/r254/Lib/functools.py?view=markup - - def partial(fun, *args, **kwargs): - """ Partial implementation - - See: http://svn.python.org/view/python/tags/r254/Lib/functools.py - """ - def _partial(*args2, **kwargs2): - return fun(*(args+args2), **dict(kwargs, **kwargs2)) - return _partial - - ### --- code from python 2.5 - - # update_wrapper() and wraps() are tools to help write - # wrapper functions that can handle naive introspection - - WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__doc__') - WRAPPER_UPDATES = ('__dict__',) - def update_wrapper(wrapper, - wrapped, - assigned = WRAPPER_ASSIGNMENTS, - updated = WRAPPER_UPDATES): - """Update a wrapper function to look like the wrapped function - - wrapper is the function to be updated - wrapped is the original function - assigned is a tuple naming the attributes assigned directly - from the wrapped function to the wrapper function (defaults to - functools.WRAPPER_ASSIGNMENTS) - updated is a tuple naming the attributes off the wrapper that - are updated with the corresponding attribute from the wrapped - function (defaults to functools.WRAPPER_UPDATES) - """ - for attr in assigned: - setattr(wrapper, attr, getattr(wrapped, attr)) - for attr in updated: - getattr(wrapper, attr).update(getattr(wrapped, attr, {})) - # Return the wrapper so this can be used as a decorator via partial() - return wrapper - - def wraps(wrapped, - assigned = WRAPPER_ASSIGNMENTS, - updated = WRAPPER_UPDATES): - """Decorator factory to apply update_wrapper() to a wrapper function - - Returns a decorator that invokes update_wrapper() with the decorated - function as the wrapper argument and the arguments to wraps() as the - remaining arguments. Default arguments are as for update_wrapper(). - This is a convenience function to simplify applying partial() to - update_wrapper(). - """ - return partial(update_wrapper, wrapped=wrapped, - assigned=assigned, updated=updated) - +__all__ = ['synchronized'] +from functools import wraps +from inspect import getsourcefile def synchronized(lock_attr='_lock'): def decorator(func): @@ -96,10 +38,6 @@ def synchronized(lock_attr='_lock'): return wrapper return decorator - - -from inspect import getsourcefile - def frame_codeinfo(fframe, back=0): """ Return a (filename, line) pair for a previous frame . @return (filename, lineno) where lineno is either int or string=='' diff --git a/openerp/tools/misc.py b/openerp/tools/misc.py index 7fdb2f07386..b888c898e40 100644 --- a/openerp/tools/misc.py +++ b/openerp/tools/misc.py @@ -26,6 +26,7 @@ Miscelleanous tools used by OpenERP. """ +from functools import wraps import inspect import subprocess import logging @@ -50,10 +51,7 @@ from email import Encoders from itertools import islice, izip from lxml import etree from which import which -if sys.version_info[:2] < (2, 4): - from threadinglocal import local -else: - from threading import local +from threading import local try: from html2text import html2text except ImportError: @@ -715,8 +713,6 @@ def human_size(sz): return "%0.2f %s" % (s, units[i]) def logged(f): - from func import wraps - @wraps(f) def wrapper(*args, **kwargs): from pprint import pformat @@ -742,8 +738,6 @@ class profile(object): self.fname = fname def __call__(self, f): - from func import wraps - @wraps(f) def wrapper(*args, **kwargs): class profile_wrapper(object): @@ -1200,4 +1194,4 @@ class UnquoteEvalContext(defaultdict): def __missing__(self, key): return unquote(key) -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: From 8c3daeea1286cd52c2ba857e198d7061347e5be8 Mon Sep 17 00:00:00 2001 From: Vo Minh Thu Date: Wed, 18 Jan 2012 12:46:40 +0100 Subject: [PATCH 5/8] [IMP] tools: removed __builtin__.{all,any} (they were there for previous python versions). bzr revid: vmt@openerp.com-20120118114640-sm71f9fi48n4qn3q --- openerp/tools/misc.py | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/openerp/tools/misc.py b/openerp/tools/misc.py index b888c898e40..67e4fd6e655 100644 --- a/openerp/tools/misc.py +++ b/openerp/tools/misc.py @@ -545,28 +545,6 @@ class currency(float): def to_xml(s): return s.replace('&','&').replace('<','<').replace('>','>') -# to be compatible with python 2.4 -import __builtin__ -if not hasattr(__builtin__, 'all'): - def all(iterable): - for element in iterable: - if not element: - return False - return True - - __builtin__.all = all - del all - -if not hasattr(__builtin__, 'any'): - def any(iterable): - for element in iterable: - if element: - return True - return False - - __builtin__.any = any - del any - def get_iso_codes(lang): if lang.find('_') != -1: if lang.split('_')[0] == lang.split('_')[1].lower(): From a236a3ac75f58bec71598c0144a2417f6459ee18 Mon Sep 17 00:00:00 2001 From: Vo Minh Thu Date: Wed, 18 Jan 2012 12:49:10 +0100 Subject: [PATCH 6/8] [IMP] tools: removed deprecated debug() function. bzr revid: vmt@openerp.com-20120118114910-xrynwguzu0e5zsng --- openerp/tools/misc.py | 34 ---------------------------------- 1 file changed, 34 deletions(-) diff --git a/openerp/tools/misc.py b/openerp/tools/misc.py index 67e4fd6e655..6739f45cc5a 100644 --- a/openerp/tools/misc.py +++ b/openerp/tools/misc.py @@ -731,40 +731,6 @@ class profile(object): return wrapper -def debug(what): - """ - This method allow you to debug your code without print - Example: - >>> def func_foo(bar) - ... baz = bar - ... debug(baz) - ... qnx = (baz, bar) - ... debug(qnx) - ... - >>> func_foo(42) - - This will output on the logger: - - [Wed Dec 25 00:00:00 2008] DEBUG:func_foo:baz = 42 - [Wed Dec 25 00:00:00 2008] DEBUG:func_foo:qnx = (42, 42) - - To view the DEBUG lines in the logger you must start the server with the option - --log-level=debug - - """ - warnings.warn("The tools.debug() method is deprecated, please use logging.", - DeprecationWarning, stacklevel=2) - from inspect import stack - from pprint import pformat - st = stack()[1] - param = re.split("debug *\((.+)\)", st[4][0].strip())[1].strip() - while param.count(')') > param.count('('): param = param[:param.rfind(')')] - what = pformat(what) - if param != what: - what = "%s = %s" % (param, what) - logging.getLogger(st[3]).debug(what) - - __icons_list = ['STOCK_ABOUT', 'STOCK_ADD', 'STOCK_APPLY', 'STOCK_BOLD', 'STOCK_CANCEL', 'STOCK_CDROM', 'STOCK_CLEAR', 'STOCK_CLOSE', 'STOCK_COLOR_PICKER', 'STOCK_CONNECT', 'STOCK_CONVERT', 'STOCK_COPY', 'STOCK_CUT', 'STOCK_DELETE', From c7094ab49fc832871b42261aee0dad485e393203 Mon Sep 17 00:00:00 2001 From: Vo Minh Thu Date: Wed, 18 Jan 2012 12:57:43 +0100 Subject: [PATCH 7/8] [IMP] tools: removed our copy of the copy module. bzr revid: vmt@openerp.com-20120118115743-ce6p993l8v2kqlux --- openerp/tools/copy.py | 441 ------------------------------------- openerp/wizard/__init__.py | 3 +- 2 files changed, 2 insertions(+), 442 deletions(-) delete mode 100644 openerp/tools/copy.py diff --git a/openerp/tools/copy.py b/openerp/tools/copy.py deleted file mode 100644 index 2f8ddb52cd3..00000000000 --- a/openerp/tools/copy.py +++ /dev/null @@ -1,441 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-2009 Tiny SPRL (). -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## - -""" -FROM Python 2.5 -Generic (shallow and deep) copying operations. - -Interface summary: - - import copy - - x = copy.copy(y) # make a shallow copy of y - x = copy.deepcopy(y) # make a deep copy of y - -For module specific errors, copy.Error is raised. - -The difference between shallow and deep copying is only relevant for -compound objects (objects that contain other objects, like lists or -class instances). - -- A shallow copy constructs a new compound object and then (to the - extent possible) inserts *the same objects* into it that the - original contains. - -- A deep copy constructs a new compound object and then, recursively, - inserts *copies* into it of the objects found in the original. - -Two problems often exist with deep copy operations that don't exist -with shallow copy operations: - - a) recursive objects (compound objects that, directly or indirectly, - contain a reference to themselves) may cause a recursive loop - - b) because deep copy copies *everything* it may copy too much, e.g. - administrative data structures that should be shared even between - copies - -Python's deep copy operation avoids these problems by: - - a) keeping a table of objects already copied during the current - copying pass - - b) letting user-defined classes override the copying operation or the - set of components copied - -This version does not copy types like module, class, function, method, -nor stack trace, stack frame, nor file, socket, window, nor array, nor -any similar types. - -Classes can use the same interfaces to control copying that they use -to control pickling: they can define methods called __getinitargs__(), -__getstate__() and __setstate__(). See the documentation for module -"pickle" for information on these methods. -""" - -import types -from copy_reg import dispatch_table - -class Error(Exception): - pass -error = Error # backward compatibility - -try: - from org.python.core import PyStringMap -except ImportError: - PyStringMap = None - -__all__ = ["Error", "copy", "deepcopy"] - -def copy(x): - """Shallow copy operation on arbitrary Python objects. - - See the module's __doc__ string for more info. - """ - - cls = type(x) - - copier = _copy_dispatch.get(cls) - if copier: - return copier(x) - - copier = getattr(cls, "__copy__", None) - if copier: - return copier(x) - - reductor = dispatch_table.get(cls) - if reductor: - rv = reductor(x) - else: - reductor = getattr(x, "__reduce_ex__", None) - if reductor: - rv = reductor(2) - else: - reductor = getattr(x, "__reduce__", None) - if reductor: - rv = reductor() - else: - raise Error("un(shallow)copyable object of type %s" % cls) - - return _reconstruct(x, rv, 0) - - -_copy_dispatch = d = {} - -def _copy_immutable(x): - return x -for t in (type(None), int, long, float, bool, str, tuple, - frozenset, type, xrange, types.ClassType, - types.BuiltinFunctionType, - types.FunctionType): - d[t] = _copy_immutable -for name in ("ComplexType", "UnicodeType", "CodeType"): - t = getattr(types, name, None) - if t is not None: - d[t] = _copy_immutable - -def _copy_with_constructor(x): - return type(x)(x) -for t in (list, dict, set): - d[t] = _copy_with_constructor - -def _copy_with_copy_method(x): - return x.copy() -if PyStringMap is not None: - d[PyStringMap] = _copy_with_copy_method - -def _copy_inst(x): - if hasattr(x, '__copy__'): - return x.__copy__() - if hasattr(x, '__getinitargs__'): - args = x.__getinitargs__() - y = x.__class__(*args) - else: - y = _EmptyClass() - y.__class__ = x.__class__ - if hasattr(x, '__getstate__'): - state = x.__getstate__() - else: - state = x.__dict__ - if hasattr(y, '__setstate__'): - y.__setstate__(state) - else: - y.__dict__.update(state) - return y -d[types.InstanceType] = _copy_inst - -del d - -def deepcopy(x, memo=None, _nil=None): - """Deep copy operation on arbitrary Python objects. - - See the module's __doc__ string for more info. - """ - - if memo is None: - memo = {} - if _nil is None: - _nil = {} - - d = id(x) - y = memo.get(d, _nil) - if y is not _nil: - return y - - cls = type(x) - - copier = _deepcopy_dispatch.get(cls) - if copier: - y = copier(x, memo) - else: - try: - issc = issubclass(cls, type) - except TypeError: # cls is not a class (old Boost; see SF #502085) - issc = 0 - if issc: - y = _deepcopy_atomic(x, memo) - else: - copier = getattr(x, "__deepcopy__", None) - if copier: - y = copier(memo) - else: - reductor = dispatch_table.get(cls) - if reductor: - rv = reductor(x) - else: - reductor = getattr(x, "__reduce_ex__", None) - if reductor: - rv = reductor(2) - else: - reductor = getattr(x, "__reduce__", None) - if reductor: - rv = reductor() - else: - raise Error( - "un(deep)copyable object of type %s" % cls) - y = _reconstruct(x, rv, 1, memo) - - memo[d] = y - _keep_alive(x, memo) # Make sure x lives at least as long as d - return y - -_deepcopy_dispatch = d = {} - -def _deepcopy_atomic(x, memo): - return x -d[type(None)] = _deepcopy_atomic -d[int] = _deepcopy_atomic -d[long] = _deepcopy_atomic -d[float] = _deepcopy_atomic -d[bool] = _deepcopy_atomic -try: - d[complex] = _deepcopy_atomic -except NameError: - pass -d[str] = _deepcopy_atomic -try: - d[unicode] = _deepcopy_atomic -except NameError: - pass -try: - d[types.CodeType] = _deepcopy_atomic -except AttributeError: - pass -d[type] = _deepcopy_atomic -d[xrange] = _deepcopy_atomic -d[types.ClassType] = _deepcopy_atomic -d[types.BuiltinFunctionType] = _deepcopy_atomic -d[types.FunctionType] = _deepcopy_atomic - -def _deepcopy_list(x, memo): - y = [] - memo[id(x)] = y - for a in x: - y.append(deepcopy(a, memo)) - return y -d[list] = _deepcopy_list - -def _deepcopy_tuple(x, memo): - y = [] - for a in x: - y.append(deepcopy(a, memo)) - d = id(x) - try: - return memo[d] - except KeyError: - pass - for i in range(len(x)): - if x[i] is not y[i]: - y = tuple(y) - break - else: - y = x - memo[d] = y - return y -d[tuple] = _deepcopy_tuple - -def _deepcopy_dict(x, memo): - y = {} - memo[id(x)] = y - for key, value in x.iteritems(): - y[deepcopy(key, memo)] = deepcopy(value, memo) - return y -d[dict] = _deepcopy_dict -if PyStringMap is not None: - d[PyStringMap] = _deepcopy_dict - -def _keep_alive(x, memo): - """Keeps a reference to the object x in the memo. - - Because we remember objects by their id, we have - to assure that possibly temporary objects are kept - alive by referencing them. - We store a reference at the id of the memo, which should - normally not be used unless someone tries to deepcopy - the memo itself... - """ - try: - memo[id(memo)].append(x) - except KeyError: - # aha, this is the first one :-) - memo[id(memo)]=[x] - -def _deepcopy_inst(x, memo): - if hasattr(x, '__deepcopy__'): - return x.__deepcopy__(memo) - if hasattr(x, '__getinitargs__'): - args = x.__getinitargs__() - args = deepcopy(args, memo) - y = x.__class__(*args) - else: - y = _EmptyClass() - y.__class__ = x.__class__ - memo[id(x)] = y - if hasattr(x, '__getstate__'): - state = x.__getstate__() - else: - state = x.__dict__ - state = deepcopy(state, memo) - if hasattr(y, '__setstate__'): - y.__setstate__(state) - else: - y.__dict__.update(state) - return y -d[types.InstanceType] = _deepcopy_inst - -def _reconstruct(x, info, deep, memo=None): - if isinstance(info, str): - return x - assert isinstance(info, tuple) - if memo is None: - memo = {} - n = len(info) - assert n in (2, 3, 4, 5) - callable, args = info[:2] - if n > 2: - state = info[2] - else: - state = {} - if n > 3: - listiter = info[3] - else: - listiter = None - if n > 4: - dictiter = info[4] - else: - dictiter = None - if deep: - args = deepcopy(args, memo) - y = callable(*args) - memo[id(x)] = y - if listiter is not None: - for item in listiter: - if deep: - item = deepcopy(item, memo) - y.append(item) - if dictiter is not None: - for key, value in dictiter: - if deep: - key = deepcopy(key, memo) - value = deepcopy(value, memo) - y[key] = value - if state: - if deep: - state = deepcopy(state, memo) - if hasattr(y, '__setstate__'): - y.__setstate__(state) - else: - if isinstance(state, tuple) and len(state) == 2: - state, slotstate = state - else: - slotstate = None - if state is not None: - y.__dict__.update(state) - if slotstate is not None: - for key, value in slotstate.iteritems(): - setattr(y, key, value) - return y - -del d - -del types - -# Helper for instance creation without calling __init__ -class _EmptyClass: - pass - -def _test(): - l = [None, 1, 2L, 3.14, 'xyzzy', (1, 2L), [3.14, 'abc'], - {'abc': 'ABC'}, (), [], {}] - l1 = copy(l) - print l1==l - l1 = map(copy, l) - print l1==l - l1 = deepcopy(l) - print l1==l - class C: - def __init__(self, arg=None): - self.a = 1 - self.arg = arg - if __name__ == '__main__': - import sys - file = sys.argv[0] - else: - file = __file__ - self.fp = open(file) - self.fp.close() - def __getstate__(self): - return {'a': self.a, 'arg': self.arg} - def __setstate__(self, state): - for key, value in state.iteritems(): - setattr(self, key, value) - def __deepcopy__(self, memo=None): - new = self.__class__(deepcopy(self.arg, memo)) - new.a = self.a - return new - c = C('argument sketch') - l.append(c) - l2 = copy(l) - print l == l2 - print l - print l2 - l2 = deepcopy(l) - print l == l2 - print l - print l2 - l.append({l[1]: l, 'xyz': l[2]}) - l3 = copy(l) - import repr - print map(repr.repr, l) - print map(repr.repr, l1) - print map(repr.repr, l2) - print map(repr.repr, l3) - l3 = deepcopy(l) - import repr - print map(repr.repr, l) - print map(repr.repr, l1) - print map(repr.repr, l2) - print map(repr.repr, l3) - -if __name__ == '__main__': - _test() - -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/wizard/__init__.py b/openerp/wizard/__init__.py index 3ba23fdab79..848915d5091 100644 --- a/openerp/wizard/__init__.py +++ b/openerp/wizard/__init__.py @@ -19,8 +19,9 @@ # ############################################################################## +import copy + import openerp.netsvc as netsvc -from openerp.tools import copy from openerp.tools.misc import UpdateableStr, UpdateableDict from openerp.tools.translate import translate from lxml import etree From 0f9721533dffe9a44491e84ff888cfaa1f9023f6 Mon Sep 17 00:00:00 2001 From: Vo Minh Thu Date: Wed, 18 Jan 2012 13:33:34 +0100 Subject: [PATCH 8/8] [IMP] fields: use simplejson instead of json (for consistency with orm.py). bzr revid: vmt@openerp.com-20120118123334-xxunyo1ph8jiwxc0 --- openerp/osv/fields.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openerp/osv/fields.py b/openerp/osv/fields.py index 3a8448e22e5..871fc32f884 100644 --- a/openerp/osv/fields.py +++ b/openerp/osv/fields.py @@ -46,7 +46,7 @@ import openerp.netsvc as netsvc import openerp.tools as tools from openerp.tools.translate import _ from openerp.tools import float_round, float_repr -import json +import simplejson def _symbol_set(symb): if symb == None or symb == False: @@ -1324,10 +1324,10 @@ class serialized(_column): """ def _symbol_set_struct(val): - return json.dumps(val) + return simplejson.dumps(val) def _symbol_get_struct(self, val): - return json.loads(val or '{}') + return simplejson.loads(val or '{}') _prefetch = False _type = 'serialized'