From a6a7325f4603ad8b1f73a6df44dc06d658f285cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Sat, 1 Sep 2018 17:06:28 +0200 Subject: [PATCH] Remove deprecation warning - remove invalid escape sequence - use read_file instead of read_fp - use importlib instead of imp and __import__ - use callable instead of instance of collections.Callable - fix silent file closing - replace SafeConfigParser by ConfigParser - replace decodestring by decodebytes - replace encodestring by encodebytes issue7666 issue7390 review53361004 --- trytond/backend/__init__.py | 34 ++++++++--------- trytond/ir/model.py | 2 +- trytond/model/modelview.py | 5 ++- trytond/modules/__init__.py | 64 +++++++++++++++++++------------- trytond/tests/test_importdata.py | 4 +- trytond/tests/test_tryton.py | 13 ++----- 6 files changed, 64 insertions(+), 58 deletions(-) diff --git a/trytond/backend/__init__.py b/trytond/backend/__init__.py index c66a55e957..c317d9e8e3 100644 --- a/trytond/backend/__init__.py +++ b/trytond/backend/__init__.py @@ -1,9 +1,8 @@ # This file is part of Tryton. The COPYRIGHT file at the top level of # this repository contains the full copyright notices and license terms. +import importlib import sys import urllib.parse -import os -import imp try: import pkg_resources except ImportError: @@ -15,26 +14,25 @@ __all__ = ['name', 'get'] def name(): - return urllib.parse.urlparse(config.get('database', 'uri', default='')).scheme + return urllib.parse.urlparse( + config.get('database', 'uri', default='')).scheme def get(prop): db_type = name() modname = 'trytond.backend.%s' % db_type - if modname not in sys.modules: - try: - __import__(modname) - except ImportError as exception: - if not pkg_resources: - raise exception + try: + module = importlib.import_module(modname) + except ImportError: + if not pkg_resources: + raise + for ep in pkg_resources.iter_entry_points( + 'trytond.backend', db_type): try: - ep, = pkg_resources.iter_entry_points( - 'trytond.backend', db_type) - except ValueError: - raise exception - mod_path = os.path.join(ep.dist.location, - *ep.module_name.split('.')[:-1]) - fp, pathname, description = imp.find_module(db_type, [mod_path]) - imp.load_module(modname, fp, pathname, description) - module = sys.modules[modname] + sys.modules[modname] = module = ep.load() + break + except ImportError: + continue + else: + raise return getattr(module, prop) diff --git a/trytond/ir/model.py b/trytond/ir/model.py index 24c9877fcf..0a88175bdf 100644 --- a/trytond/ir/model.py +++ b/trytond/ir/model.py @@ -1322,7 +1322,7 @@ class ModelGraph(Report): label += '+ ' + field.name + ': ' + field.ttype if field.relation: label += ' ' + field.relation - label += '\l' + label += '\\l' label += '}"' node_name = '"%s"' % model.model node = pydot.Node(node_name, shape='record', label=label) diff --git a/trytond/model/modelview.py b/trytond/model/modelview.py index 0194add78c..27a1cc031f 100644 --- a/trytond/model/modelview.py +++ b/trytond/model/modelview.py @@ -127,7 +127,7 @@ class ModelView(Model): attr = getattr(cls, name) if isinstance(attr, fields.Field): fields_[name] = attr - elif isinstance(attr, collections.Callable): + elif callable(attr): callables[name] = attr methods = { @@ -656,7 +656,8 @@ class ModelView(Model): if button_rules: clicks = ButtonClick.register( cls.__name__, func.__name__, records) - records = [r for r in records if all(br.test(r, clicks.get(r.id, [])) + records = [r for r in records + if all(br.test(r, clicks.get(r.id, [])) for br in button_rules)] # Reset click after filtering in case the button also has rules names = Button.get_reset(cls.__name__, func.__name__) diff --git a/trytond/modules/__init__.py b/trytond/modules/__init__.py index 05c023a158..887050213b 100644 --- a/trytond/modules/__init__.py +++ b/trytond/modules/__init__.py @@ -2,12 +2,13 @@ # this repository contains the full copyright notices and license terms. import os import sys +import importlib import itertools import logging -import imp import configparser from glob import iglob from collections import defaultdict +from importlib.machinery import FileFinder, SourceFileLoader, SOURCE_SUFFIXES from sql import Table from sql.functions import CurrentTimestamp @@ -45,6 +46,41 @@ def update_egg_modules(): update_egg_modules() +def import_module(name, fullname=None): + if fullname is None: + fullname = 'trytond.modules.' + name + try: + module = importlib.import_module(fullname) + except ImportError: + if name not in EGG_MODULES: + raise + ep = EGG_MODULES[name] + # Can not use ep.load because modules are declared in an importable + # path and it can not import submodule. + path = os.path.join( + ep.dist.location, *ep.module_name.split('.')[:-1]) + if not os.path.isdir(path): + # Find module in path + for path in sys.path: + path = os.path.join( + path, *ep.module_name.split('.')[:-1]) + if os.path.isdir(os.path.join(path, name)): + break + else: + # When testing modules from setuptools location is the + # module directory + path = os.path.dirname(ep.dist.location) + spec = FileFinder( + path, (SourceFileLoader, SOURCE_SUFFIXES) + ).find_spec(fullname) + if spec.loader: + module = spec.loader.load_module() + else: + raise + return module + + + def get_module_info(name): "Return the content of the tryton.cfg" module_config = configparser.ConfigParser() @@ -292,34 +328,10 @@ def register_classes(): MODULES.append(module) continue - if os.path.isdir(OPJ(MODULES_PATH, module)): - mod_path = MODULES_PATH - elif module in EGG_MODULES: - ep = EGG_MODULES[module] - mod_path = os.path.join(ep.dist.location, - *ep.module_name.split('.')[:-1]) - if not os.path.isdir(mod_path): - # Find module in path - for path in sys.path: - mod_path = os.path.join(path, - *ep.module_name.split('.')[:-1]) - if os.path.isdir(os.path.join(mod_path, module)): - break - if not os.path.isdir(os.path.join(mod_path, module)): - # When testing modules from setuptools location is the - # module directory - mod_path = os.path.dirname(ep.dist.location) - else: - raise Exception('Couldn\'t find module %s' % module) - mod_file, pathname, description = imp.find_module(module, - [mod_path]) - the_module = imp.load_module('trytond.modules.' + module, - mod_file, pathname, description) + the_module = import_module(module) # Some modules register nothing in the Pool if hasattr(the_module, 'register'): the_module.register() - if mod_file is not None: - mod_file.close() MODULES.append(module) diff --git a/trytond/tests/test_importdata.py b/trytond/tests/test_importdata.py index 44b5b42fa6..8c43282870 100644 --- a/trytond/tests/test_importdata.py +++ b/trytond/tests/test_importdata.py @@ -370,10 +370,10 @@ class ImportDataTestCase(unittest.TestCase): 'tests.import_data_many2many_target_test2']]), 1) self.assertEqual(Many2many.import_data(['many2many'], - [['Test\, comma']]), 1) + [['Test\\, comma']]), 1) self.assertEqual(Many2many.import_data(['many2many'], - [['Test\, comma,Test 1']]), 1) + [['Test\\, comma,Test 1']]), 1) self.assertEqual(Many2many.import_data(['many2many'], [['']]), 1) diff --git a/trytond/tests/test_tryton.py b/trytond/tests/test_tryton.py index 53cfef409a..bf949c874d 100644 --- a/trytond/tests/test_tryton.py +++ b/trytond/tests/test_tryton.py @@ -737,21 +737,16 @@ def modules_suite(modules=None, doc=True): suite_ = suite() else: suite_ = all_suite() - from trytond.modules import create_graph, get_module_list, \ - MODULES_PATH, EGG_MODULES + from trytond.modules import create_graph, get_module_list, import_module graph = create_graph(get_module_list()) for node in graph: module = node.name if modules and module not in modules: continue test_module = 'trytond.modules.%s.tests' % module - if os.path.isdir(os.path.join(MODULES_PATH, module)) or \ - module in EGG_MODULES: - try: - test_mod = __import__(test_module, fromlist=['']) - except ImportError: - continue - else: + try: + test_mod = import_module(module, test_module) + except ImportError: continue for test in test_mod.suite(): if isinstance(test, doctest.DocTestCase) and not doc: