[Python-modules-commits] [logilab-common] 01/06: Import logilab-common_1.4.1.orig.tar.gz

Sandro Tosi morph at moszumanska.debian.org
Fri Dec 8 00:05:29 UTC 2017


This is an automated email from the git hooks/post-receive script.

morph pushed a commit to branch master
in repository logilab-common.

commit fc5466c02e2d282cc0f7996383afcc996f04fb64
Author: Sandro Tosi <morph at debian.org>
Date:   Thu Dec 7 18:56:50 2017 -0500

    Import logilab-common_1.4.1.orig.tar.gz
---
 PKG-INFO                         |  2 +-
 __pkginfo__.py                   |  2 +-
 logilab/common/configuration.py  |  6 +++---
 logilab/common/fileutils.py      |  7 +++----
 logilab/common/modutils.py       | 18 +++++++++++++++-
 logilab/common/registry.py       | 45 ++++++++++++++++++++++++++++++++--------
 logilab/common/textutils.py      |  2 ++
 logilab_common.egg-info/PKG-INFO |  2 +-
 test/data/regobjects2.py         |  2 +-
 test/unittest_configuration.py   | 16 ++++++++++++++
 test/unittest_fileutils.py       |  4 +++-
 test/unittest_modutils.py        |  8 +++++--
 test/unittest_registry.py        | 26 +++++++++++++++++++----
 test/unittest_textutils.py       |  2 ++
 14 files changed, 114 insertions(+), 28 deletions(-)

diff --git a/PKG-INFO b/PKG-INFO
index 33c5f6e..9dca2cd 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: logilab-common
-Version: 1.3.0
+Version: 1.4.1
 Summary: collection of low-level Python packages and modules used by Logilab projects
 Home-page: http://www.logilab.org/project/logilab-common
 Author: Logilab
diff --git a/__pkginfo__.py b/__pkginfo__.py
index e5c2e0d..b9f652f 100644
--- a/__pkginfo__.py
+++ b/__pkginfo__.py
@@ -25,7 +25,7 @@ modname = 'common'
 subpackage_of = 'logilab'
 subpackage_master = True
 
-numversion = (1, 3, 0)
+numversion = (1, 4, 1)
 version = '.'.join([str(num) for num in numversion])
 
 license = 'LGPL' # 2.1 or later
diff --git a/logilab/common/configuration.py b/logilab/common/configuration.py
index 52ac6df..7a54f1a 100644
--- a/logilab/common/configuration.py
+++ b/logilab/common/configuration.py
@@ -949,8 +949,8 @@ class ConfigurationMixIn(OptionsManagerMixIn, OptionsProviderMixIn):
         options_by_group = {}
         for optname, optdict in options:
             options_by_group.setdefault(optdict.get('group', self.name.upper()), []).append((optname, optdict))
-        for group, options in options_by_group.items():
-            self.add_option_group(group, None, options, self)
+        for group, group_options in options_by_group.items():
+            self.add_option_group(group, None, group_options, self)
         self.options += tuple(options)
 
     def load_defaults(self):
@@ -1045,7 +1045,7 @@ def read_old_config(newconfig, changes, configfile):
             option, oldtype, newvalue = action[1:]
             changesindex.setdefault(option, []).append((action[0], oldtype, newvalue))
             continue
-        if action[1] in ('added', 'removed'):
+        if action[0] in ('added', 'removed'):
             continue # nothing to do here
         raise Exception('unknown change %s' % action[0])
     # build a config object able to read the old config
diff --git a/logilab/common/fileutils.py b/logilab/common/fileutils.py
index 366d23d..93439d3 100644
--- a/logilab/common/fileutils.py
+++ b/logilab/common/fileutils.py
@@ -28,6 +28,7 @@ from __future__ import print_function
 
 __docformat__ = "restructuredtext en"
 
+import io
 import sys
 import shutil
 import mimetypes
@@ -282,10 +283,8 @@ def lines(path, comments=None):
 
     :warning: at some point this function will probably return an iterator
     """
-    stream = open(path, 'U')
-    result = stream_lines(stream, comments)
-    stream.close()
-    return result
+    with io.open(path) as stream:
+        return stream_lines(stream, comments)
 
 
 def stream_lines(stream, comments=None):
diff --git a/logilab/common/modutils.py b/logilab/common/modutils.py
index f8e91ad..030cfa3 100644
--- a/logilab/common/modutils.py
+++ b/logilab/common/modutils.py
@@ -49,6 +49,7 @@ except ImportError:
 ZIPFILE = object()
 
 from logilab.common import STD_BLACKLIST, _handle_blacklist
+from logilab.common.deprecation import deprecated
 
 # Notes about STD_LIB_DIR
 # Consider arch-specific installation for STD_LIB_DIR definition
@@ -234,8 +235,11 @@ def _path_from_filename(filename):
         return filename
 
 
+ at deprecated('you should avoid using modpath_from_file()')
 def modpath_from_file(filename, extrapath=None):
-    """given a file path return the corresponding splitted module's name
+    """DEPRECATED: doens't play well with symlinks and sys.meta_path
+
+    Given a file path return the corresponding splitted module's name
     (i.e name of a module or package splitted on '.')
 
     :type filename: str
@@ -493,6 +497,18 @@ def cleanup_sys_modules(directories):
     return cleaned
 
 
+def clean_sys_modules(names):
+    """remove submodules starting with name from `names` from `sys.modules`"""
+    cleaned = set()
+    for modname in list(sys.modules):
+        for name in names:
+            if modname.startswith(name):
+                del sys.modules[modname]
+                cleaned.add(modname)
+                break
+    return cleaned
+
+
 def is_python_source(filename):
     """
     rtype: bool
diff --git a/logilab/common/registry.py b/logilab/common/registry.py
index 35b8eb7..07d4353 100644
--- a/logilab/common/registry.py
+++ b/logilab/common/registry.py
@@ -81,6 +81,7 @@ from __future__ import print_function
 __docformat__ = "restructuredtext en"
 
 import sys
+import pkgutil
 import types
 import weakref
 import traceback as tb
@@ -94,6 +95,7 @@ from six import string_types, add_metaclass
 from logilab.common.modutils import modpath_from_file
 from logilab.common.logging_ext import set_log_methods
 from logilab.common.decorators import classproperty
+from logilab.common.deprecation import deprecated
 
 
 class RegistryException(Exception):
@@ -210,12 +212,22 @@ class RegistrableInstance(RegistrableObject):
         """Add a __module__ attribute telling the module where the instance was
         created, for automatic registration.
         """
+        module = kwargs.pop('__module__', None)
         obj = super(RegistrableInstance, cls).__new__(cls)
-        # XXX subclass must no override __new__
-        filepath = tb.extract_stack(limit=2)[0][0]
-        obj.__module__ = _modname_from_path(filepath)
+        if module is None:
+            warn('instantiate {0} with '
+                 '__module__=__name__'.format(cls.__name__),
+                 DeprecationWarning)
+            # XXX subclass must no override __new__
+            filepath = tb.extract_stack(limit=2)[0][0]
+            obj.__module__ = _modname_from_path(filepath)
+        else:
+            obj.__module__ = module
         return obj
 
+    def __init__(self, __module__=None):
+        super(RegistrableInstance, self).__init__()
+
 
 class Registry(dict):
     """The registry store a set of implementations associated to identifier:
@@ -486,11 +498,10 @@ class RegistryStore(dict):
     Controlling object registration
     -------------------------------
 
-    Dynamic loading is triggered by calling the
-    :meth:`register_objects` method, given a list of directories to
-    inspect for python modules.
+    Dynamic loading is triggered by calling the :meth:`register_modnames`
+    method, given a list of modules names to inspect.
 
-    .. automethod:: register_objects
+    .. automethod:: register_modnames
 
     For each module, by default, all compatible objects are registered
     automatically. However if some objects come as replacement of
@@ -675,6 +686,7 @@ class RegistryStore(dict):
         self._loadedmods = {}
         return filemods
 
+    @deprecated('use register_modnames() instead')
     def register_objects(self, path, extrapath=None):
         """register all objects found walking down <path>"""
         # load views from each directory in the instance's path
@@ -684,6 +696,23 @@ class RegistryStore(dict):
             self.load_file(filepath, modname)
         self.initialization_completed()
 
+    def register_modnames(self, modnames):
+        """register all objects found in <modnames>"""
+        self.reset()
+        self._loadedmods = {}
+        self._toloadmods = {}
+        toload = []
+        for modname in modnames:
+            filepath = pkgutil.find_loader(modname).get_filename()
+            if filepath[-4:] in ('.pyc', '.pyo'):
+                # The source file *must* exists
+                filepath = filepath[:-1]
+            self._toloadmods[modname] = filepath
+            toload.append((filepath, modname))
+        for filepath, modname in toload:
+            self.load_file(filepath, modname)
+        self.initialization_completed()
+
     def initialization_completed(self):
         """call initialization_completed() on all known registries"""
         for reg in self.values():
@@ -1117,8 +1146,6 @@ class yes(Predicate): # pylint: disable=C0103
 
 # deprecated stuff #############################################################
 
-from logilab.common.deprecation import deprecated
-
 @deprecated('[lgc 0.59] use Registry.objid class method instead')
 def classid(cls):
     return '%s.%s' % (cls.__module__, cls.__name__)
diff --git a/logilab/common/textutils.py b/logilab/common/textutils.py
index 9046f97..356b1a8 100644
--- a/logilab/common/textutils.py
+++ b/logilab/common/textutils.py
@@ -70,6 +70,8 @@ MANUAL_UNICODE_MAP = {
     u'\xf8': u'o',    # LATIN SMALL LETTER O WITH STROKE
     u'\xbb': u'"',    # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
     u'\xdf': u'ss',   # LATIN SMALL LETTER SHARP S
+    u'\u2013': u'-',  # HYPHEN
+    u'\u2019': u"'",  # SIMPLE QUOTE
     }
 
 def unormalize(ustring, ignorenonascii=None, substitute=None):
diff --git a/logilab_common.egg-info/PKG-INFO b/logilab_common.egg-info/PKG-INFO
index 33c5f6e..9dca2cd 100644
--- a/logilab_common.egg-info/PKG-INFO
+++ b/logilab_common.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: logilab-common
-Version: 1.3.0
+Version: 1.4.1
 Summary: collection of low-level Python packages and modules used by Logilab projects
 Home-page: http://www.logilab.org/project/logilab-common
 Author: Logilab
diff --git a/test/data/regobjects2.py b/test/data/regobjects2.py
index 5c28b51..091b9f7 100644
--- a/test/data/regobjects2.py
+++ b/test/data/regobjects2.py
@@ -5,4 +5,4 @@ class MyRegistrableInstance(RegistrableInstance):
     __select__ = yes()
     __registry__ = 'zereg'
 
-instance = MyRegistrableInstance()
+instance = MyRegistrableInstance(__module__=__name__)
diff --git a/test/unittest_configuration.py b/test/unittest_configuration.py
index f59a0e0..ea7cdca 100644
--- a/test/unittest_configuration.py
+++ b/test/unittest_configuration.py
@@ -469,6 +469,22 @@ class RegrTC(TestCase):
         self.linter.load_command_line_configuration([])
         self.assertEqual(self.linter.config.profile, False)
 
+    def test_register_options_multiple_groups(self):
+        """ensure multiple option groups can be registered at once"""
+        config = Configuration()
+        self.assertEqual(config.options, ())
+        new_options = (
+            ('option1', {'type': 'string', 'help': '',
+                         'group': 'g1', 'level': 2}),
+            ('option2', {'type': 'string', 'help': '',
+                         'group': 'g1', 'level': 2}),
+            ('option3', {'type': 'string', 'help': '',
+                         'group': 'g2', 'level': 2}),
+        )
+        config.register_options(new_options)
+        self.assertEqual(config.options, new_options)
+
+
 class MergeTC(TestCase):
 
     def test_merge1(self):
diff --git a/test/unittest_fileutils.py b/test/unittest_fileutils.py
index 80cefe4..555e73f 100644
--- a/test/unittest_fileutils.py
+++ b/test/unittest_fileutils.py
@@ -18,6 +18,7 @@
 """unit tests for logilab.common.fileutils"""
 
 import doctest
+import io
 import sys, os, tempfile, shutil
 from stat import S_IWRITE
 from os.path import join
@@ -54,7 +55,8 @@ class GetModeTC(TestCase):
 
 class NormReadTC(TestCase):
     def test_known_values_norm_read(self):
-        data = open(NEWLINES_TXT, 'U').read()
+        with io.open(NEWLINES_TXT) as f:
+            data = f.read()
         self.assertEqual(data.strip(), '\n'.join(['# mixed new lines', '1', '2', '3']))
 
 
diff --git a/test/unittest_modutils.py b/test/unittest_modutils.py
index d1fcaf9..ec2a5c8 100644
--- a/test/unittest_modutils.py
+++ b/test/unittest_modutils.py
@@ -21,6 +21,7 @@ unit tests for module modutils (module manipulation utilities)
 
 import doctest
 import sys
+import warnings
 try:
     __file__
 except NameError:
@@ -117,8 +118,11 @@ class modpath_from_file_tc(ModutilsTestCase):
     """ given an absolute file path return the python module's path as a list """
 
     def test_knownValues_modpath_from_file_1(self):
-        self.assertEqual(modutils.modpath_from_file(modutils.__file__),
-                         ['logilab', 'common', 'modutils'])
+        with warnings.catch_warnings(record=True) as warns:
+            self.assertEqual(modutils.modpath_from_file(modutils.__file__),
+                             ['logilab', 'common', 'modutils'])
+            self.assertIn('you should avoid using modpath_from_file()',
+                          [str(w.message) for w in warns])
 
     def test_knownValues_modpath_from_file_2(self):
         self.assertEqual(modutils.modpath_from_file('unittest_modutils.py',
diff --git a/test/unittest_registry.py b/test/unittest_registry.py
index d07c73e..1c07e4c 100644
--- a/test/unittest_registry.py
+++ b/test/unittest_registry.py
@@ -23,6 +23,7 @@ import os.path as osp
 import sys
 from operator import eq, lt, le, gt
 from contextlib import contextmanager
+import warnings
 
 logging.basicConfig(level=logging.ERROR)
 
@@ -177,8 +178,20 @@ class RegistryStoreTC(TestCase):
         store = RegistryStore()
         store.setdefault('zereg')
         with prepended_syspath(self.datadir):
-            store.register_objects([self.datapath('regobjects.py'),
-                                    self.datapath('regobjects2.py')])
+            with warnings.catch_warnings(record=True) as warns:
+                store.register_objects([self.datapath('regobjects.py'),
+                                        self.datapath('regobjects2.py')])
+                self.assertIn('use register_modnames() instead',
+                              [str(w.message) for w in warns])
+        self.assertEqual(['zereg'], list(store.keys()))
+        self.assertEqual(set(('appobject1', 'appobject2', 'appobject3')),
+                         set(store['zereg']))
+
+    def test_autoload_modnames(self):
+        store = RegistryStore()
+        store.setdefault('zereg')
+        with prepended_syspath(self.datadir):
+            store.register_modnames(['regobjects', 'regobjects2'])
         self.assertEqual(['zereg'], list(store.keys()))
         self.assertEqual(set(('appobject1', 'appobject2', 'appobject3')),
                          set(store['zereg']))
@@ -187,13 +200,18 @@ class RegistryStoreTC(TestCase):
 class RegistrableInstanceTC(TestCase):
 
     def test_instance_modulename(self):
+        with warnings.catch_warnings(record=True) as warns:
+            obj = RegistrableInstance()
+            self.assertEqual(obj.__module__, 'unittest_registry')
+            self.assertIn('instantiate RegistrableInstance with __module__=__name__',
+                          [str(w.message) for w in warns])
         # no inheritance
-        obj = RegistrableInstance()
+        obj = RegistrableInstance(__module__=__name__)
         self.assertEqual(obj.__module__, 'unittest_registry')
         # with inheritance from another python file
         with prepended_syspath(self.datadir):
             from regobjects2 import instance, MyRegistrableInstance
-            instance2 = MyRegistrableInstance()
+            instance2 = MyRegistrableInstance(__module__=__name__)
             self.assertEqual(instance.__module__, 'regobjects2')
             self.assertEqual(instance2.__module__, 'unittest_registry')
 
diff --git a/test/unittest_textutils.py b/test/unittest_textutils.py
index 8deb4ee..330d49c 100644
--- a/test/unittest_textutils.py
+++ b/test/unittest_textutils.py
@@ -244,6 +244,8 @@ class UnormalizeTC(TestCase):
                 (u'ÀÈÙÉÏÎÔÊÇ', u'AEUEIIOEC'),
                 (u'\xa0', u' '), # NO-BREAK SPACE managed by NFKD decomposition
                 (u'\u0154', u'R'),
+                (u'Pointe d\u2019Yves', u"Pointe d'Yves"),
+                (u'Bordeaux\u2013Mérignac', u'Bordeaux-Merignac'),
                ]
         for input, output in data:
             yield self.assertEqual, tu.unormalize(input), output

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/logilab-common.git



More information about the Python-modules-commits mailing list