From 036a3ab0fb250699de36dfac6685ef8db94e1460 Mon Sep 17 00:00:00 2001 From: David Douard Date: Wed, 26 Mar 2014 10:48:11 +0100 Subject: [configuration] fix docstring --- configuration.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configuration.py b/configuration.py index fa93a05..a508bc8 100644 --- a/configuration.py +++ b/configuration.py @@ -394,7 +394,7 @@ def ini_format(stream, options, encoding): format_section = ini_format_section def rest_format_section(stream, section, options, encoding=None, doc=None): - """format an options section using the INI format""" + """format an options section using as ReST formatted output""" encoding = _get_encoding(encoding, stream) if section: print >> stream, '%s\n%s' % (section, "'"*len(section)) -- cgit v1.2.1 From 81b05beb105c8c24fec62c3f2ec36d8a3ed68c3d Mon Sep 17 00:00:00 2001 From: Aurelien Campeas Date: Tue, 27 May 2014 09:44:09 +0200 Subject: [modutils] return list of cleaned modules Closes #255526. --- modutils.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modutils.py b/modutils.py index 2756841..d0cccf3 100644 --- a/modutils.py +++ b/modutils.py @@ -455,13 +455,16 @@ def get_source_file(filename, include_no_ext=False): def cleanup_sys_modules(directories): """remove submodules of `directories` from `sys.modules`""" + cleaned = [] for modname, module in sys.modules.items(): modfile = getattr(module, '__file__', None) if modfile: for directory in directories: if modfile.startswith(directory): + cleaned.append(modname) del sys.modules[modname] break + return cleaned def is_python_source(filename): -- cgit v1.2.1 From e98b4762a4415a0759d2eeb3f3fe6da11e4030ba Mon Sep 17 00:00:00 2001 From: Aurelien Campeas Date: Thu, 3 Jul 2014 14:34:50 +0200 Subject: [pkg] prepare 0.62.0 --- ChangeLog | 6 +++++- debian/changelog | 6 ++++++ python-logilab-common.spec | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1948de6..0485cde 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,10 @@ ChangeLog for logilab.common ============================ +2014-03-07 -- 0.62.0 + * modutils: cleanup_sys_modules returns the list of cleaned modules + + 2014-02-11 -- 0.61.0 * pdf_ext: removed, it had no known users (CVE-2014-1838) @@ -20,7 +24,7 @@ ChangeLog for logilab.common * ensure file is closed, may cause pb depending on the interpreter, eg pypy) (#180876) - + * fix support for `extend_path` based nested namespace packages ; Report and patch by John Johnson (#177651) diff --git a/debian/changelog b/debian/changelog index 49b1834..f1cb5c6 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +logilab-common (0.62.0-1) unstable; urgency=low + + * new upstream release + + -- Aurelien Campeas Thu, 03 Jul 2014 14:31:32 +0200 + logilab-common (0.61.0-1) unstable; urgency=low * new upstream release diff --git a/python-logilab-common.spec b/python-logilab-common.spec index f63e49c..a5944fc 100644 --- a/python-logilab-common.spec +++ b/python-logilab-common.spec @@ -10,7 +10,7 @@ %{!?_python_sitelib: %define _python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")} Name: %{python}-logilab-common -Version: 0.61.0 +Version: 0.62.0 Release: logilab.1%{?dist} Summary: Common libraries for Logilab projects -- cgit v1.2.1 From d1d8f793af6d015d885b9ea67b5741d5a093e2f4 Mon Sep 17 00:00:00 2001 From: Aurelien Campeas Date: Thu, 3 Jul 2014 15:04:06 +0200 Subject: [pkg] missing version bump --- __pkginfo__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/__pkginfo__.py b/__pkginfo__.py index d3be555..e1a4022 100644 --- a/__pkginfo__.py +++ b/__pkginfo__.py @@ -1,4 +1,4 @@ -# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved. +# copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved. # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr # # This file is part of logilab-common. @@ -25,7 +25,7 @@ modname = 'common' subpackage_of = 'logilab' subpackage_master = True -numversion = (0, 61, 0) +numversion = (0, 62, 0) version = '.'.join([str(num) for num in numversion]) license = 'LGPL' # 2.1 or later -- cgit v1.2.1 -- cgit v1.2.1 From 17e760c92c956d89e4d6eef54de49eb2d07ed54c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sylvain=20Th=C3=A9nault?= Date: Fri, 25 Jul 2014 10:34:53 +0200 Subject: [shellutils] don't use class decorator, we still need py 2.5 compat for some time. Closes #258060 --- ChangeLog | 3 +++ shellutils.py | 6 ++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0485cde..ed55101 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,9 @@ ChangeLog for logilab.common ============================ +-- + * shellutils: restore py 2.5 compat by removing usage of class decorator + 2014-03-07 -- 0.62.0 * modutils: cleanup_sys_modules returns the list of cleaned modules diff --git a/shellutils.py b/shellutils.py index 28c2b42..69ee1e4 100644 --- a/shellutils.py +++ b/shellutils.py @@ -1,4 +1,4 @@ -# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved. +# copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved. # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr # # This file is part of logilab-common. @@ -226,7 +226,7 @@ def unzip(archive, destdir): outfile.write(zfobj.read(name)) outfile.close() -@deprecated('Use subprocess.Popen instead') + class Execute: """This is a deadlock safe version of popen2 (no stdin), that returns an object with errorlevel, out and err. @@ -237,6 +237,8 @@ class Execute: self.out, self.err = cmd.communicate() self.status = os.WEXITSTATUS(cmd.returncode) +Execute = deprecated('Use subprocess.Popen instead')(Execute) + def acquire_lock(lock_file, max_try=10, delay=10, max_delay=3600): """Acquire a lock represented by a file on the file system -- cgit v1.2.1 From f0924b600f7d6641cf79befad4b5f3f603737fd0 Mon Sep 17 00:00:00 2001 From: Julien Cristau Date: Sun, 27 Jul 2014 14:56:00 +0200 Subject: graph: ensure we get predictable ordering --- graph.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/graph.py b/graph.py index d62e8c0..9a77495 100644 --- a/graph.py +++ b/graph.py @@ -63,7 +63,7 @@ class DotBackend: assert charset.lower() in ('utf-8', 'iso-8859-1', 'latin1'), \ 'unsupported charset %s' % charset self.emit('charset="%s"' % charset) - for param in additionnal_param.iteritems(): + for param in sorted(additionnal_param.iteritems()): self.emit('='.join(param)) def get_source(self): -- cgit v1.2.1 From 58170703232700d6b3523d672e71a2c78655b4c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sylvain=20Th=C3=A9nault?= Date: Fri, 4 Apr 2014 12:26:53 +0200 Subject: [pytest] drop coverage option, broken for a while --- ChangeLog | 1 + pytest.py | 27 +-------------------------- 2 files changed, 2 insertions(+), 26 deletions(-) diff --git a/ChangeLog b/ChangeLog index ed55101..f64e1fc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,7 @@ ChangeLog for logilab.common -- * shellutils: restore py 2.5 compat by removing usage of class decorator + * pytest: drop broken --coverage option 2014-03-07 -- 0.62.0 * modutils: cleanup_sys_modules returns the list of cleaned modules diff --git a/pytest.py b/pytest.py index 2d6ccf9..8767938 100644 --- a/pytest.py +++ b/pytest.py @@ -105,9 +105,6 @@ pytest path/to/mytests.py -m '(not long and database) or regr' pytest one (will run both test_thisone and test_thatone) pytest path/to/mytests.py -s not (will skip test_notthisone) - -pytest --coverage test_foo.py - (only if logilab.devtools is available) """ ENABLE_DBC = False @@ -604,7 +601,7 @@ def make_parser(): action="callback", help="Verbose output") parser.add_option('-i', '--pdb', callback=rebuild_and_store, dest="pdb", action="callback", - help="Enable test failure inspection (conflicts with --coverage)") + help="Enable test failure inspection") parser.add_option('-x', '--exitfirst', callback=rebuild_and_store, dest="exitfirst", default=False, action="callback", help="Exit on first failure " @@ -631,14 +628,6 @@ def make_parser(): parser.add_option('-m', '--match', default=None, dest='tags_pattern', help="only execute test whose tag match the current pattern") - try: - from logilab.devtools.lib.coverage import Coverage - parser.add_option('--coverage', dest="coverage", default=False, - action="store_true", - help="run tests with pycoverage (conflicts with --pdb)") - except ImportError: - pass - if DJANGO_FOUND: parser.add_option('-J', '--django', dest='django', default=False, action="store_true", @@ -652,8 +641,6 @@ def parseargs(parser): """ # parse the command line options, args = parser.parse_args() - if options.pdb and getattr(options, 'coverage', False): - parser.error("'pdb' and 'coverage' options are exclusive") filenames = [arg for arg in args if arg.endswith('.py')] if filenames: if len(filenames) > 1: @@ -683,16 +670,9 @@ def run(): options, explicitfile = parseargs(parser) # mock a new command line sys.argv[1:] = parser.newargs - covermode = getattr(options, 'coverage', None) cvg = None if not '' in sys.path: sys.path.insert(0, '') - if covermode: - # control_import_coverage(rootdir) - from logilab.devtools.lib.coverage import Coverage - cvg = Coverage([rootdir]) - cvg.erase() - cvg.start() if DJANGO_FOUND and options.django: tester = DjangoTester(cvg, options) else: @@ -719,12 +699,7 @@ def run(): import traceback traceback.print_exc() finally: - if covermode: - cvg.stop() - cvg.save() tester.show_report() - if covermode: - print 'coverage information stored, use it with pycoverage -ra' sys.exit(tester.errcode) class SkipAwareTestProgram(unittest.TestProgram): -- cgit v1.2.1 From 86dc908ee0df6f8bf9a0bd11d9952dcaba0689e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Laura=20M=C3=A9dioni?= Date: Fri, 25 Jul 2014 10:13:23 +0200 Subject: [configuration] closes #185648 : load options in config file order Option should be processed in file order, not declaration order. related to issue #87 on pylint : https://bitbucket.org/logilab/pylint/issue/87 --- ChangeLog | 1 + configuration.py | 24 ++++++++++++++-------- test/unittest_configuration.py | 45 ++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 60 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index f64e1fc..0560fef 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,7 @@ ChangeLog for logilab.common -- * shellutils: restore py 2.5 compat by removing usage of class decorator * pytest: drop broken --coverage option + * configuration: load options in config file order (#185648) 2014-03-07 -- 0.62.0 * modutils: cleanup_sys_modules returns the list of cleaned modules diff --git a/configuration.py b/configuration.py index a508bc8..e5ce210 100644 --- a/configuration.py +++ b/configuration.py @@ -96,7 +96,15 @@ Quick start: simplest usage multiple=4,5,6 number=3 - >>> + + Note : starting with Python 2.7 ConfigParser is able to take into + account the order of occurrences of the options into a file (by + using an OrderedDict). If you have two options changing some common + state, like a 'disable-all-stuff' and a 'enable-some-stuff-a', their + order of appearance will be significant : the last specified in the + file wins. For earlier version of python and logilab.common newer + than 0.61 the behaviour is unspecified. + """ __docformat__ = "restructuredtext en" @@ -655,13 +663,13 @@ class OptionsManagerMixIn(object): options provider) """ parser = self.cfgfile_parser - for provider in self.options_providers: - for section, option, optdict in provider.all_options(): - try: - value = parser.get(section, option) - provider.set_option(option, value, optdict=optdict) - except (NoSectionError, NoOptionError), ex: - continue + for section in parser.sections(): + for option, value in parser.items(section): + try: + self.global_set_option(option, value) + except (KeyError, OptionError): + # TODO handle here undeclared options appearing in the config file + continue def load_configuration(self, **kwargs): """override configuration according to given parameters diff --git a/test/unittest_configuration.py b/test/unittest_configuration.py index a8e3c0f..edcb5db 100644 --- a/test/unittest_configuration.py +++ b/test/unittest_configuration.py @@ -1,4 +1,4 @@ -# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved. +# copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved. # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr # # This file is part of logilab-common. @@ -25,7 +25,7 @@ from sys import version_info from logilab.common.testlib import TestCase, unittest_main from logilab.common.optik_ext import OptionValueError -from logilab.common.configuration import Configuration, \ +from logilab.common.configuration import Configuration, OptionError, \ OptionsManagerMixIn, OptionsProviderMixIn, Method, read_old_config, \ merge_options @@ -47,6 +47,8 @@ OPTIONS = [('dothis', {'type':'yn', 'action': 'store', 'default': True, 'metavar ('diffgroup', {'type':'string', 'default':'pouet', 'metavar': '', 'group': 'agroup'}), + ('reset-value', {'type': 'string', 'metavar': '', 'short': 'r', + 'dest':'value'}), ] @@ -149,6 +151,38 @@ diffgroup=zou finally: os.remove(file) + def test_option_order(self): + """ Check that options are taken into account in the command line order + and not in the order they are defined in the Configuration object. + """ + file = tempfile.mktemp() + stream = open(file, 'w') + try: + stream.write("""[Test] +reset-value=toto +value=tata +""") + stream.close() + self.cfg.load_file_configuration(file) + finally: + os.remove(file) + self.assertEqual(self.cfg['value'], 'tata') + + def test_unsupported_options(self): + file = tempfile.mktemp() + stream = open(file, 'w') + try: + stream.write("""[Test] +whatever=toto +value=tata +""") + stream.close() + self.cfg.load_file_configuration(file) + finally: + os.remove(file) + self.assertEqual(self.cfg['value'], 'tata') + self.assertRaises(OptionError, self.cfg.__getitem__, 'whatever') + def test_generate_config(self): stream = StringIO() self.cfg.generate_config(stream) @@ -170,6 +204,8 @@ multiple-choice=yo,ye named=key:val +#reset-value= + [AGROUP] @@ -197,6 +233,8 @@ multiple-choice=yo,ye named=key:val +reset-value=' ' + [AGROUP] @@ -251,6 +289,7 @@ Options: --choice= --multiple-choice= --named= + -r , --reset-value= Agroup: --diffgroup= @@ -309,6 +348,8 @@ multiple-choice=yo,ye named=key:val +reset-value=' ' + [AGROUP] -- cgit v1.2.1 From b0f384ef4bb2d7e5ac419320c73199b0aed65ee7 Mon Sep 17 00:00:00 2001 From: Denis Laxalde Date: Thu, 5 Jun 2014 10:06:59 +0200 Subject: [testlib] Handle skip methods as in unittest Just copied this piece of code from unittest.TestCase.run which: * makes it possible to skip whole TestCase (using class decorator), * handle conditional skip (skipIf). As an aside, with this, setUp() is not executed anymore when a test is skipped. Closes #252838. --- ChangeLog | 2 ++ testlib.py | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/ChangeLog b/ChangeLog index 0560fef..5406478 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,8 @@ ChangeLog for logilab.common -- * shellutils: restore py 2.5 compat by removing usage of class decorator * pytest: drop broken --coverage option + * testlib: support for skipping whole test class and conditional skip, don't + run setUp for skipped tests * configuration: load options in config file order (#185648) 2014-03-07 -- 0.62.0 diff --git a/testlib.py b/testlib.py index 817149c..683c7ac 100644 --- a/testlib.py +++ b/testlib.py @@ -579,6 +579,16 @@ class TestCase(unittest.TestCase): # if result.cvg: # result.cvg.start() testMethod = self._get_test_method() + if (getattr(self.__class__, "__unittest_skip__", False) or + getattr(testMethod, "__unittest_skip__", False)): + # If the class or method was skipped. + try: + skip_why = (getattr(self.__class__, '__unittest_skip_why__', '') + or getattr(testMethod, '__unittest_skip_why__', '')) + self._addSkip(result, skip_why) + finally: + result.stopTest(self) + return if runcondition and not runcondition(testMethod): return # test is skipped result.startTest(self) -- cgit v1.2.1 From badbe09d2a79dd17353a4ddaedcf76b873a37182 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Cardona?= Date: Mon, 28 Jul 2014 22:30:10 +0200 Subject: Remove CVS file IDs --- test/data/module.py | 1 - test/unittest_table.py | 1 - test/unittest_tree.py | 1 - test/unittest_ureports_html.py | 1 - test/unittest_ureports_text.py | 1 - test/utils.py | 1 - 6 files changed, 6 deletions(-) diff --git a/test/data/module.py b/test/data/module.py index 9b85430..4e1abce 100644 --- a/test/data/module.py +++ b/test/data/module.py @@ -2,7 +2,6 @@ """test module for astng """ -__revision__ = '$Id: module.py,v 1.9 2003-11-24 13:40:26 syt Exp $' from logilab.common import modutils, Execute as spawn from logilab.common.astutils import * diff --git a/test/unittest_table.py b/test/unittest_table.py index d2db8b7..7c58d69 100644 --- a/test/unittest_table.py +++ b/test/unittest_table.py @@ -19,7 +19,6 @@ Unittests for table management """ -__revision__ = '$Id: unittest_table.py,v 1.13 2006-04-09 22:30:53 nico Exp $' import sys import os diff --git a/test/unittest_tree.py b/test/unittest_tree.py index 8e7f4bd..fb8e303 100644 --- a/test/unittest_tree.py +++ b/test/unittest_tree.py @@ -19,7 +19,6 @@ unit tests for module logilab.common.tree squeleton generated by /home/syt/bin/py2tests on Jan 20 at 10:43:25 """ -__revision__ = "$Id: unittest_tree.py,v 1.9 2005-09-07 23:44:02 nico Exp $" from logilab.common.testlib import TestCase, unittest_main from logilab.common.tree import * diff --git a/test/unittest_ureports_html.py b/test/unittest_ureports_html.py index c849c4f..2298eec 100644 --- a/test/unittest_ureports_html.py +++ b/test/unittest_ureports_html.py @@ -18,7 +18,6 @@ '''unit tests for ureports.html_writer ''' -__revision__ = "$Id: unittest_ureports_html.py,v 1.3 2005-05-27 12:27:08 syt Exp $" from utils import WriterTC from logilab.common.testlib import TestCase, unittest_main diff --git a/test/unittest_ureports_text.py b/test/unittest_ureports_text.py index 25a2194..dd39dd8 100644 --- a/test/unittest_ureports_text.py +++ b/test/unittest_ureports_text.py @@ -18,7 +18,6 @@ '''unit tests for ureports.text_writer ''' -__revision__ = "$Id: unittest_ureports_text.py,v 1.4 2005-05-27 12:27:08 syt Exp $" from utils import WriterTC from logilab.common.testlib import TestCase, unittest_main diff --git a/test/utils.py b/test/utils.py index 957d7eb..f54c179 100644 --- a/test/utils.py +++ b/test/utils.py @@ -18,7 +18,6 @@ '''unit tests utilities for ureports ''' -__revision__ = "$Id: utils.py,v 1.3 2005-05-27 12:27:08 syt Exp $" from cStringIO import StringIO from logilab.common.ureports.nodes import * -- cgit v1.2.1 From cf1a3bbc247e7bf26519190fb176a746f2fa067a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Cardona?= Date: Wed, 16 Jul 2014 22:35:13 +0200 Subject: Remove unused imports --- configuration.py | 3 +-- dbf.py | 1 - fileutils.py | 1 - 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/configuration.py b/configuration.py index e5ce210..0b03e90 100644 --- a/configuration.py +++ b/configuration.py @@ -117,8 +117,7 @@ import sys import re from os.path import exists, expanduser from copy import copy -from ConfigParser import ConfigParser, NoOptionError, NoSectionError, \ - DuplicateSectionError +from ConfigParser import ConfigParser, NoOptionError, NoSectionError from warnings import warn from logilab.common.compat import callable, raw_input, str_encode as _encode diff --git a/dbf.py b/dbf.py index 8def2d2..3396383 100644 --- a/dbf.py +++ b/dbf.py @@ -36,7 +36,6 @@ import os, os.path import sys import csv import tempfile -import ConfigParser class Dbase: def __init__(self): diff --git a/fileutils.py b/fileutils.py index 4ac9270..7a028b1 100644 --- a/fileutils.py +++ b/fileutils.py @@ -32,7 +32,6 @@ from os.path import isabs, isdir, islink, split, exists, normpath, join from os.path import abspath from os import sep, mkdir, remove, listdir, stat, chmod, walk from stat import ST_MODE, S_IWRITE -from cStringIO import StringIO from logilab.common import STD_BLACKLIST as BASE_BLACKLIST, IGNORED_EXTENSIONS from logilab.common.shellutils import find -- cgit v1.2.1