[MERGE] cleaned some imports, removed some code for older python versions.
bzr revid: vmt@openerp.com-20120118160305-ucennaoqehjuut1z
This commit is contained in:
commit
418739cf3e
|
@ -18,6 +18,7 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import ast
|
||||
import copy
|
||||
import logging
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -30,7 +30,6 @@ import socket
|
|||
import sys
|
||||
import threading
|
||||
import time
|
||||
import traceback
|
||||
import types
|
||||
from pprint import pformat
|
||||
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -32,9 +32,6 @@
|
|||
usable in other projects, too.
|
||||
"""
|
||||
|
||||
import socket
|
||||
import base64
|
||||
import errno
|
||||
import SocketServer
|
||||
from BaseHTTPServer import *
|
||||
from SimpleHTTPServer import SimpleHTTPRequestHandler
|
||||
|
|
|
@ -35,14 +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_SERIALIZABLE,\
|
||||
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)
|
||||
|
@ -67,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
|
||||
|
@ -423,7 +422,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))
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import os
|
||||
import time
|
||||
import unittest2
|
||||
import xmlrpclib
|
||||
|
||||
import openerp
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,441 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
|
||||
#
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
"""
|
||||
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:
|
|
@ -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==''
|
||||
|
|
|
@ -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:
|
||||
|
@ -547,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():
|
||||
|
@ -715,8 +691,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 +716,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):
|
||||
|
@ -759,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',
|
||||
|
@ -1200,4 +1138,4 @@ class UnquoteEvalContext(defaultdict):
|
|||
def __missing__(self, key):
|
||||
return unquote(key)
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -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='<unknown>', 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 = {}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue