Hello community,
here is the log from the commit of package python-salt-testing for openSUSE:Factory checked in at 2014-08-06 11:42:33
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-salt-testing (Old)
and /work/SRC/openSUSE:Factory/.python-salt-testing.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-salt-testing"
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-salt-testing/python-salt-testing.changes 2014-05-02 14:03:05.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.python-salt-testing.new/python-salt-testing.changes 2014-08-06 11:42:34.000000000 +0200
@@ -1,0 +2,11 @@
+Tue Aug 5 19:14:58 UTC 2014 - aboe76@gmail.com
+
+- updated to 2014.8.5
+ + Added with_system_user, with_system_group and with_system_user_and_group which surpasses the functionality from the now deprecated with_system_account.
+ + Added expensiveTest decorator which is supposed to mark tests which cost money
+ + Allow passing a path to the docker binary
+ + Updated the PEP8 PyLint plugin to support some newly added messages
+ + Improved the string formatting pylint plugin
+ + Support mock_open as a fake object so that import errors are not triggered
+
+-------------------------------------------------------------------
Old:
----
SaltTesting-2014.4.24.tar.gz
New:
----
SaltTesting-2014.8.5.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-salt-testing.spec ++++++
--- /var/tmp/diff_new_pack.FllUCi/_old 2014-08-06 11:42:35.000000000 +0200
+++ /var/tmp/diff_new_pack.FllUCi/_new 2014-08-06 11:42:35.000000000 +0200
@@ -17,7 +17,7 @@
Name: python-salt-testing
-Version: 2014.4.24
+Version: 2014.8.5
Release: 0
Summary: Testing tools needed in the several Salt Stack projects
License: Apache-2.0
++++++ SaltTesting-2014.4.24.tar.gz -> SaltTesting-2014.8.5.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/SaltTesting-2014.4.24/PKG-INFO new/SaltTesting-2014.8.5/PKG-INFO
--- old/SaltTesting-2014.4.24/PKG-INFO 2014-04-24 14:04:42.000000000 +0200
+++ new/SaltTesting-2014.8.5/PKG-INFO 2014-08-05 17:29:44.000000000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: SaltTesting
-Version: 2014.4.24
+Version: 2014.8.5
Summary: Required testing tools needed in the several Salt Stack projects.
Home-page: http://saltstack.org
Author: Pedro Algarvio
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/SaltTesting-2014.4.24/SaltTesting.egg-info/PKG-INFO new/SaltTesting-2014.8.5/SaltTesting.egg-info/PKG-INFO
--- old/SaltTesting-2014.4.24/SaltTesting.egg-info/PKG-INFO 2014-04-24 14:04:32.000000000 +0200
+++ new/SaltTesting-2014.8.5/SaltTesting.egg-info/PKG-INFO 2014-08-05 17:29:39.000000000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: SaltTesting
-Version: 2014.4.24
+Version: 2014.8.5
Summary: Required testing tools needed in the several Salt Stack projects.
Home-page: http://saltstack.org
Author: Pedro Algarvio
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/SaltTesting-2014.4.24/salttesting/case.py new/SaltTesting-2014.8.5/salttesting/case.py
--- old/SaltTesting-2014.4.24/salttesting/case.py 2014-01-20 16:48:54.000000000 +0100
+++ new/SaltTesting-2014.8.5/salttesting/case.py 2014-06-10 20:18:34.000000000 +0200
@@ -36,7 +36,8 @@
arg_str,
catch_stderr=False,
with_retcode=False,
- timeout=None):
+ timeout=None,
+ raw=False):
'''
Execute a script with the given argument string
'''
@@ -133,13 +134,28 @@
else:
out, err = process.communicate()
# Force closing stderr/stdout to release file descriptors
- process.stdout.close()
- process.stderr.close()
+ if process.stdout is not None:
+ process.stdout.close()
+ if process.stderr is not None:
+ process.stderr.close()
try:
if with_retcode:
- return out.splitlines(), err.splitlines(), process.returncode
+ if out is not None and err is not None:
+ if not raw:
+ return out.splitlines(), err.splitlines(), process.returncode
+ else:
+ return out, err, process.returncode
+ return out.splitlines(), [], process.returncode
else:
- return out.splitlines(), err.splitlines()
+ if out is not None and err is not None:
+ if not raw:
+ return out.splitlines(), err.splitlines()
+ else:
+ return out, err
+ if not raw:
+ return out.splitlines(), []
+ else:
+ return out, []
finally:
try:
process.terminate()
@@ -152,9 +168,15 @@
try:
if with_retcode:
- return data[0].splitlines(), process.returncode
+ if not raw:
+ return data[0].splitlines(), process.returncode
+ else:
+ return data[0], process.returncode
else:
- return data[0].splitlines()
+ if not raw:
+ return data[0].splitlines()
+ else:
+ return data[0]
finally:
try:
process.terminate()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/SaltTesting-2014.4.24/salttesting/helpers.py new/SaltTesting-2014.8.5/salttesting/helpers.py
--- old/SaltTesting-2014.4.24/salttesting/helpers.py 2014-02-08 02:08:52.000000000 +0100
+++ new/SaltTesting-2014.8.5/salttesting/helpers.py 2014-08-05 00:38:30.000000000 +0200
@@ -21,17 +21,53 @@
from functools import wraps
# Import Salt Testing libs
+from salttesting import __version_info__
from salttesting.unit import skip, _id
log = logging.getLogger(__name__)
-def destructiveTest(func):
- @wraps(func)
+def destructiveTest(caller):
+ if inspect.isclass(caller):
+ # We're decorating a class
+ old_setUp = getattr(caller, 'setUp', None)
+
+ def setUp(self, *args, **kwargs):
+ if os.environ.get('DESTRUCTIVE_TESTS', 'False').lower() == 'false':
+ self.skipTest('Destructive tests are disabled')
+ if old_setUp is not None:
+ old_setUp(self, *args, **kwargs)
+ caller.setUp = setUp
+ return caller
+
+ # We're simply decorating functions
+ @wraps(caller)
def wrap(cls):
if os.environ.get('DESTRUCTIVE_TESTS', 'False').lower() == 'false':
cls.skipTest('Destructive tests are disabled')
- return func(cls)
+ return caller(cls)
+ return wrap
+
+
+def expensiveTest(caller):
+ if inspect.isclass(caller):
+ # We're decorating a class
+ old_setUp = getattr(caller, 'setUp', None)
+
+ def setUp(self, *args, **kwargs):
+ if os.environ.get('EXPENSIVE_TESTS', 'False').lower() == 'false':
+ self.skipTest('Expensive tests are disabled')
+ if old_setUp is not None:
+ old_setUp(self, *args, **kwargs)
+ caller.setUp = setUp
+ return caller
+
+ # We're simply decorating functions
+ @wraps(caller)
+ def wrap(cls):
+ if os.environ.get('EXPENSIVE_TESTS', 'False').lower() == 'false':
+ cls.skipTest('Expensive tests are disabled')
+ return caller(cls)
return wrap
@@ -448,19 +484,41 @@
return decorator
-def with_system_account(username, on_existing='delete', delete=True):
+def with_system_account(account, on_existing='delete', delete=True):
+ '''
+ This method has been deprecated in favour of ``with_system_user``, please
+ use it instead.
+ '''
+ import warnings
+ caller = inspect.getframeinfo(sys._getframe(1))
+ message = (
+ '\'with_system_account()\' in use in {filename}, line number '
+ '{lineno} has been deprecated in favour of \'with_system_user()\' '
+ 'for 8 months now. Please us it instead.'.format(
+ filename=caller.filename,
+ lineno=caller.lineno
+ )
+ )
+ if __version_info__ > (2014, 12):
+ # 8 months should be more than enough to deprecate this
+ raise RuntimeError(message)
+ warnings.warn(message, DeprecationWarning)
+ return with_system_user(account, on_existing=on_existing, delete=delete)
+
+
+def with_system_user(username, on_existing='delete', delete=True):
'''
- Create and optionally destroy a system account to be used within a test
- case. The system account is crated using the ``user`` salt module.
+ Create and optionally destroy a system user to be used within a test
+ case. The system user is crated using the ``user`` salt module.
The decorated testcase function must accept 'username' as an argument.
- :param username: The desired username for the system account.
+ :param username: The desired username for the system user.
:param on_existing: What to do when the desired username is taken. The
available options are:
- * nothing: Do nothing, act as if the account was created.
- * delete: delete and re-create the existing account
+ * nothing: Do nothing, act as if the user was created.
+ * delete: delete and re-create the existing user
* skip: skip the test case
'''
if on_existing not in ('nothing', 'delete', 'skip'):
@@ -479,45 +537,45 @@
@wraps(func)
def wrap(cls):
- # Let's add the account to the system.
- log.debug('Creating system account for {0!r}'.format(username))
- create_account = cls.run_function('user.add', [username])
- if not create_account:
- log.debug('Failed to create system account')
- # The account was not created
+ # Let's add the user to the system.
+ log.debug('Creating system user {0!r}'.format(username))
+ create_user = cls.run_function('user.add', [username])
+ if not create_user:
+ log.debug('Failed to create system user')
+ # The user was not created
if on_existing == 'skip':
cls.skipTest(
- 'Failed to create system account for {0!r}'.format(
+ 'Failed to create system user {0!r}'.format(
username
)
)
if on_existing == 'delete':
log.debug(
- 'Deleting the system account for {0!r}'.format(
+ 'Deleting the system user {0!r}'.format(
username
)
)
- delete_account = cls.run_function(
+ delete_user = cls.run_function(
'user.delete', [username, True, True]
)
- if not delete_account:
+ if not delete_user:
cls.skipTest(
- 'An account by the username {0!r} already '
- 'existed on the system and re-creating it was '
- 'not possible'.format(username)
+ 'A user named {0!r} already existed on the '
+ 'system and re-creating it was not possible'
+ .format(username)
)
log.debug(
- 'Second time creating system account for {0!r}'.format(
+ 'Second time creating system user {0!r}'.format(
username
)
)
- create_account = cls.run_function('user.add', [username])
- if not create_account:
+ create_user = cls.run_function('user.add', [username])
+ if not create_user:
cls.skipTest(
- 'An account by the username {0!r} already '
- 'existed, was deleted as requested, but '
- 're-creating it was not possible'.format(username)
+ 'A user named {0!r} already existed, was deleted '
+ 'as requested, but re-creating it was not possible'
+ .format(username)
)
failure = None
@@ -536,22 +594,282 @@
failure = sys.exc_info()
finally:
if delete:
- delete_account = cls.run_function(
+ delete_user = cls.run_function(
'user.delete', [username, True, True]
)
- if not delete_account:
+ if not delete_user:
+ if failure is None:
+ log.warning(
+ 'Although the actual test-case did not fail, '
+ 'deleting the created system user {0!r} '
+ 'afterwards did.'.format(username)
+ )
+ else:
+ log.warning(
+ 'The test-case failed and also did the removal'
+ ' of the system user {0!r}'.format(username)
+ )
+ if failure is not None:
+ # If an exception was thrown, raise it
+ raise failure[0], failure[1], failure[2]
+ return wrap
+ return decorator
+
+
+def with_system_group(group, on_existing='delete', delete=True):
+ '''
+ Create and optionally destroy a system group to be used within a test
+ case. The system user is crated using the ``group`` salt module.
+
+ The decorated testcase function must accept 'group' as an argument.
+
+ :param group: The desired group name for the system user.
+ :param on_existing: What to do when the desired username is taken. The
+ available options are:
+
+ * nothing: Do nothing, act as if the group was created.
+ * delete: delete and re-create the existing user
+ * skip: skip the test case
+ '''
+ if on_existing not in ('nothing', 'delete', 'skip'):
+ raise RuntimeError(
+ 'The value of \'on_existing\' can only be one of, '
+ '\'nothing\', \'delete\' and \'skip\''
+ )
+
+ if not isinstance(delete, bool):
+ raise RuntimeError(
+ 'The value of \'delete\' can only be \'True\' or \'False\''
+ )
+
+ def decorator(func):
+
+ @wraps(func)
+ def wrap(cls):
+
+ # Let's add the user to the system.
+ log.debug('Creating system group {0!r}'.format(group))
+ create_group = cls.run_function('group.add', [group])
+ if not create_group:
+ log.debug('Failed to create system group')
+ # The group was not created
+ if on_existing == 'skip':
+ cls.skipTest(
+ 'Failed to create system group {0!r}'.format(group)
+ )
+
+ if on_existing == 'delete':
+ log.debug(
+ 'Deleting the system group {0!r}'.format(group)
+ )
+ delete_group = cls.run_function('group.delete', [group])
+ if not delete_group:
+ cls.skipTest(
+ 'A group named {0!r} already existed on the '
+ 'system and re-creating it was not possible'
+ .format(group)
+ )
+ log.debug(
+ 'Second time creating system group {0!r}'.format(
+ group
+ )
+ )
+ create_group = cls.run_function('group.add', [group])
+ if not create_group:
+ cls.skipTest(
+ 'A group named {0!r} already existed, was deleted '
+ 'as requested, but re-creating it was not possible'
+ .format(group)
+ )
+
+ failure = None
+ try:
+ try:
+ return func(cls, group)
+ except Exception as exc: # pylint: disable=W0703
+ log.error(
+ 'Running {0!r} raised an exception: {1}'.format(
+ func, exc
+ ),
+ exc_info=True
+ )
+ # Store the original exception details which will be raised
+ # a little further down the code
+ failure = sys.exc_info()
+ finally:
+ if delete:
+ delete_group = cls.run_function('group.delete', [group])
+ if not delete_group:
if failure is None:
log.warning(
- 'Although the actual test-case did not fail '
- 'deleting the created system account for '
- '{0!r} afterwards did.'.format(username)
+ 'Although the actual test-case did not fail, '
+ 'deleting the created system group {0!r} '
+ 'afterwards did.'.format(group)
)
else:
log.warning(
'The test-case failed and also did the removal'
- ' of the system account for {0!r}'.format(
- username
- )
+ ' of the system group {0!r}'.format(group)
+ )
+ if failure is not None:
+ # If an exception was thrown, raise it
+ raise failure[0], failure[1], failure[2]
+ return wrap
+ return decorator
+
+
+def with_system_user_and_group(username, group,
+ on_existing='delete', delete=True):
+ '''
+ Create and optionally destroy a system user and group to be used within a
+ test case. The system user is crated using the ``user`` salt module, and
+ the system group is created with the ``group`` salt module.
+
+ The decorated testcase function must accept both the 'username' and 'group'
+ arguments.
+
+ :param username: The desired username for the system user.
+ :param group: The desired name for the system group.
+ :param on_existing: What to do when the desired username is taken. The
+ available options are:
+
+ * nothing: Do nothing, act as if the user was created.
+ * delete: delete and re-create the existing user
+ * skip: skip the test case
+ '''
+ if on_existing not in ('nothing', 'delete', 'skip'):
+ raise RuntimeError(
+ 'The value of \'on_existing\' can only be one of, '
+ '\'nothing\', \'delete\' and \'skip\''
+ )
+
+ if not isinstance(delete, bool):
+ raise RuntimeError(
+ 'The value of \'delete\' can only be \'True\' or \'False\''
+ )
+
+ def decorator(func):
+
+ @wraps(func)
+ def wrap(cls):
+
+ # Let's add the user to the system.
+ log.debug('Creating system user {0!r}'.format(username))
+ create_user = cls.run_function('user.add', [username])
+ log.debug('Creating system group {0!r}'.format(group))
+ create_group = cls.run_function('group.add', [group])
+ if not create_user:
+ log.debug('Failed to create system user')
+ # The user was not created
+ if on_existing == 'skip':
+ cls.skipTest(
+ 'Failed to create system user {0!r}'.format(
+ username
+ )
+ )
+
+ if on_existing == 'delete':
+ log.debug(
+ 'Deleting the system user {0!r}'.format(
+ username
+ )
+ )
+ delete_user = cls.run_function(
+ 'user.delete', [username, True, True]
+ )
+ if not delete_user:
+ cls.skipTest(
+ 'A user named {0!r} already existed on the '
+ 'system and re-creating it was not possible'
+ .format(username)
+ )
+ log.debug(
+ 'Second time creating system user {0!r}'.format(
+ username
+ )
+ )
+ create_user = cls.run_function('user.add', [username])
+ if not create_user:
+ cls.skipTest(
+ 'A user named {0!r} already existed, was deleted '
+ 'as requested, but re-creating it was not possible'
+ .format(username)
+ )
+ if not create_group:
+ log.debug('Failed to create system group')
+ # The group was not created
+ if on_existing == 'skip':
+ cls.skipTest(
+ 'Failed to create system group {0!r}'.format(group)
+ )
+
+ if on_existing == 'delete':
+ log.debug(
+ 'Deleting the system group {0!r}'.format(group)
+ )
+ delete_group = cls.run_function('group.delete', [group])
+ if not delete_group:
+ cls.skipTest(
+ 'A group named {0!r} already existed on the '
+ 'system and re-creating it was not possible'
+ .format(group)
+ )
+ log.debug(
+ 'Second time creating system group {0!r}'.format(
+ group
+ )
+ )
+ create_group = cls.run_function('group.add', [group])
+ if not create_group:
+ cls.skipTest(
+ 'A group named {0!r} already existed, was deleted '
+ 'as requested, but re-creating it was not possible'
+ .format(group)
+ )
+
+ failure = None
+ try:
+ try:
+ return func(cls, username, group)
+ except Exception as exc: # pylint: disable=W0703
+ log.error(
+ 'Running {0!r} raised an exception: {1}'.format(
+ func, exc
+ ),
+ exc_info=True
+ )
+ # Store the original exception details which will be raised
+ # a little further down the code
+ failure = sys.exc_info()
+ finally:
+ if delete:
+ delete_user = cls.run_function(
+ 'user.delete', [username, True, True]
+ )
+ delete_group = cls.run_function('group.delete', [group])
+ if not delete_user:
+ if failure is None:
+ log.warning(
+ 'Although the actual test-case did not fail, '
+ 'deleting the created system user {0!r} '
+ 'afterwards did.'.format(username)
+ )
+ else:
+ log.warning(
+ 'The test-case failed and also did the removal'
+ ' of the system user {0!r}'.format(username)
+ )
+ if not delete_group:
+ if failure is None:
+ log.warning(
+ 'Although the actual test-case did not fail, '
+ 'deleting the created system group {0!r} '
+ 'afterwards did.'.format(group)
+ )
+ else:
+ log.warning(
+ 'The test-case failed and also did the removal'
+ ' of the system group {0!r}'.format(group)
)
if failure is not None:
# If an exception was thrown, raise it
@@ -587,12 +905,12 @@
def decorator(caller):
if inspect.isclass(caller):
-
# We're decorating a class
- old_init = caller.__init__
+ old_setUp = getattr(caller, 'setUp', None)
- def new_init(self, *args, **kwargs):
- old_init(self, *args, **kwargs)
+ def setUp(self, *args, **kwargs):
+ if old_setUp is not None:
+ old_setUp(self, *args, **kwargs)
if not hasattr(self, 'run_function'):
raise RuntimeError(
@@ -603,16 +921,12 @@
)
for name in names:
- if name not in self.run_function('sys.doc'):
- reason = 'Salt module {0!r} is not available'.format(
- name
- )
- for fname in dir(self):
- if not fname.startswith('test_'):
- continue
- setattr(self, fname, lambda: self.skipTest(reason))
- break
- caller.__init__ = new_init
+ if not hasattr(self, '__salt_sys_docs__'):
+ # cache salts documentation
+ self.__salt_sys_docs__ = self.run_function('sys.doc')
+ if name not in self.__salt_sys_docs__:
+ self.skipTest('Salt module {0!r} is not available'.format(name))
+ caller.setUp = setUp
return caller
# We're simply decorating functions
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/SaltTesting-2014.4.24/salttesting/mock.py new/SaltTesting-2014.8.5/salttesting/mock.py
--- old/SaltTesting-2014.4.24/salttesting/mock.py 2014-01-02 12:03:08.000000000 +0100
+++ new/SaltTesting-2014.8.5/salttesting/mock.py 2014-08-05 01:16:27.000000000 +0200
@@ -38,6 +38,8 @@
# Let's not fail on imports by providing fake objects and classes
+ Mock = MagicMock
+
class MagicMock(object):
__name__ = '{0}.fakemock'.format(__name__)
@@ -54,7 +56,6 @@
def __call__(self, *args, **kwargs):
return self
- Mock = MagicMock
patch = MagicMock()
sentinel = object()
DEFAULT = object()
@@ -62,6 +63,8 @@
FILTER_DIR = True
NonCallableMock = MagicMock()
NonCallableMagicMock = MagicMock()
+ mock_open = object()
+ PropertyMock = object()
call = tuple
ANY = object()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/SaltTesting-2014.4.24/salttesting/parser/__init__.py new/SaltTesting-2014.8.5/salttesting/parser/__init__.py
--- old/SaltTesting-2014.4.24/salttesting/parser/__init__.py 2014-04-18 02:21:34.000000000 +0200
+++ new/SaltTesting-2014.8.5/salttesting/parser/__init__.py 2014-08-05 00:38:30.000000000 +0200
@@ -92,6 +92,7 @@
class SaltTestingParser(optparse.OptionParser):
support_docker_execution = False
support_destructive_tests_selection = False
+ support_expensive_tests_selection = False
source_code_basedir = None
_known_interpreters = {
@@ -153,6 +154,15 @@
'or removing users from your system for example. '
'Default: %default')
)
+ if self.support_expensive_tests_selection is True:
+ self.test_selection_group.add_option(
+ '--run-expensive',
+ action='store_true',
+ default=False,
+ help=('Run expensive tests. Expensive tests are any tests that, '
+ 'once configured, cost money to run, such as creating or '
+ 'destroying cloud instances on a cloud provider.')
+ )
self.test_selection_group.add_option(
'-n',
@@ -199,6 +209,11 @@
help='Skip docker container deletion on exit if errors '
'occurred. Default: False'
)
+ self.docked_selection_group.add_option(
+ '--docker-binary',
+ help='The docker binary on the host system. Default: %default',
+ default='/usr/bin/docker',
+ )
self.add_option_group(self.docked_selection_group)
self.output_options_group = optparse.OptionGroup(
@@ -339,6 +354,11 @@
# destructive tests should be executed or not.
os.environ['DESTRUCTIVE_TESTS'] = str(self.options.run_destructive)
+ if self.support_expensive_tests_selection:
+ # Set the required environment variable in order to know if
+ # expensive tests should be executed or not.
+ os.environ['EXPENSIVE_TESTS'] = str(self.options.run_expensive)
+
def validate_options(self):
'''
Validate the provided options. Override this method to run your own
@@ -702,7 +722,7 @@
tempfile.mktemp(prefix='docked-testsuite-', suffix='.cid')
)
call = subprocess.Popen(
- ['docker',
+ [self.options.docker_binary,
'run',
#'--rm=true', Do not remove the container automatically, we need
# to get information back, even for stopped containers
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/SaltTesting-2014.4.24/salttesting/pylintplugins/pep8.py new/SaltTesting-2014.8.5/salttesting/pylintplugins/pep8.py
--- old/SaltTesting-2014.4.24/salttesting/pylintplugins/pep8.py 2014-04-15 10:37:43.000000000 +0200
+++ new/SaltTesting-2014.8.5/salttesting/pylintplugins/pep8.py 2014-06-10 20:19:41.000000000 +0200
@@ -13,6 +13,8 @@
# Let's use absolute imports
from __future__ import absolute_import
+import sys
+import logging
# Import PyLint libs
from pylint.interfaces import IRawChecker
@@ -25,13 +27,16 @@
HAS_PEP8 = True
except ImportError:
HAS_PEP8 = False
- import logging
- logging.getLogger(__name__).warning(
- 'No pep8 library could be imported. No PEP8 check\'s will be done'
- )
+ msg = 'No pep8 library could be imported. No PEP8 check\'s will be done'
+ if logging.root.handlers:
+ logging.getLogger(__name__).warning(msg)
+ else:
+ sys.stderr.write('{0}\n'.format(msg))
_PROCESSED_NODES = {}
+_KNOWN_PEP8_IDS = []
+_UNHANDLED_PEP8_IDS = []
if HAS_PEP8 is True:
@@ -95,12 +100,25 @@
# This will be handled by PyLint itself, skip it
continue
- if pylintcode not in self.msgs:
- # Log warning??
+ if pylintcode not in _KNOWN_PEP8_IDS:
+ if pylintcode not in _UNHANDLED_PEP8_IDS:
+ _UNHANDLED_PEP8_IDS.append(pylintcode)
+ msg = 'The following code, {0}, was not handled by the PEP8 plugin'.format(pylintcode)
+ if logging.root.handlers:
+ logging.getLogger(__name__).warning(msg)
+ else:
+ sys.stderr.write('{0}\n'.format(msg))
continue
- if code == 'E113':
+ if pylintcode not in self._msgs:
+ # Not for our class implementation to handle
+ continue
+
+ if code in ('E111', 'E113'):
if _PROCESSED_NODES[node.path].lines[lineno-1].strip().startswith('#'):
+ # If E111 is triggered in a comment I consider it, at
+ # least, bad judgement. See https://github.com/jcrocholl/pep8/issues/300
+
# If E113 is triggered in comments, which I consider a bug,
# skip it. See https://github.com/jcrocholl/pep8/issues/274
continue
@@ -137,10 +155,18 @@
'continuation-line-over-indented-for-visual-indent'),
'E8128': ('PEP8 %s: continuation line under-indented for visual indent',
'continuation-line-under-indented-for-visual-indent'),
+ 'E8129': ('PEP8 %s: visually indented line with same indent as next logical line',
+ 'visually-indented-line-with-same-indent-as-next-logical-line'),
+ 'E8131': ('PEP8 %s: unaligned for hanging indent',
+ 'unaligned-for-hanging-indent'),
'E8133': ('PEP8 %s: closing bracket is missing indentation',
'closing-bracket-is-missing-indentation'),
}
+ msgs_map = {
+ 'E8126': 'C0330'
+ }
+
class PEP8Whitespace(_PEP8BaseChecker):
'''
@@ -176,6 +202,8 @@
'at-least-two-spaces-before-inline-comment'),
'E8262': ("PEP8 %s: inline comment should start with '# '",
"inline-comment-should-start-with-'#-'"),
+ 'E8265': ("PEP8 %s: block comment should start with '# '",
+ "block-comment-should-start-with-'# '"),
'E8271': ('PEP8 %s: multiple spaces after keyword',
'multiple-spaces-after-keyword'),
'E8272': ('PEP8 %s: multiple spaces before keyword',
@@ -184,6 +212,11 @@
'E8274': ('PEP8 %s: tab before keyword', 'tab-before-keyword'),
}
+ msgs_map = {
+ 'E8222': 'C0326',
+ 'E8251': 'C0326'
+ }
+
class PEP8BlankLine(_PEP8BaseChecker):
'''
@@ -246,6 +279,10 @@
"comparison-to-None-should-be-'if-cond-is-None:'"),
'E8712': ("PEP8 %s: comparison to True should be 'if cond is True:' or 'if cond:'",
"comparison-to-True-should-be-'if-cond-is-True:'-or-'if-cond:'"),
+ 'E8713': ("PEP8 %s: test for membership should be 'not in'",
+ "test-for-membership-should-be 'not in'"),
+ 'E8714': ("PEP8 %s: test for object identity should be 'is not'",
+ "test-for-object-identity-should-be-'is not'"),
'E8721': ("PEP8 %s: do not compare types, use 'isinstance()'",
"do-not-compare-types,-use-'isinstance()'"),
}
@@ -288,6 +325,11 @@
'blank-line-contains-whitespace'),
}
+ msgs_map = {
+ 'W8291': 'C0303',
+ 'W8293': 'C0303'
+ }
+
class PEP8BlankLineWarning(_PEP8BaseChecker):
'''
@@ -317,6 +359,17 @@
}
+# ----- Keep Track Of Handled PEP8 MSG IDs -------------------------------------------------------------------------->
+for checker in locals().values():
+ try:
+ if issubclass(checker, _PEP8BaseChecker):
+ _KNOWN_PEP8_IDS.extend(checker._msgs.keys())
+ except TypeError:
+ # Not class
+ continue
+# <---- Keep Track Of Handled PEP8 MSG IDs ---------------------------------------------------------------------------
+
+
def register(linter):
'''
required method to auto register this checker
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/SaltTesting-2014.4.24/salttesting/pylintplugins/strings.py new/SaltTesting-2014.8.5/salttesting/pylintplugins/strings.py
--- old/SaltTesting-2014.4.24/salttesting/pylintplugins/strings.py 2014-01-12 22:17:08.000000000 +0100
+++ new/SaltTesting-2014.8.5/salttesting/pylintplugins/strings.py 2014-06-10 20:18:34.000000000 +0200
@@ -11,6 +11,7 @@
Extended String Formatting Checkers
'''
+import re
import sys
try:
# >= pylint 1.0
@@ -19,7 +20,7 @@
from logilab import astng as astroid
from pylint.checkers import utils
from pylint.checkers import BaseChecker
-from pylint.checkers.utils import check_messages
+from pylint.checkers.utils import check_messages, parse_format_string
try:
# >= pylint 1.0
@@ -36,9 +37,17 @@
'E1320': ('String format call with un-indexed curly braces: %r',
'un-indexed-curly-braces-error',
'Under python 2.6 the curly braces on a \'string.format()\' '
- 'call MUST be indexed.')
+ 'call MUST be indexed.'),
+ 'W1321': ('String substitution used instead of string formattting on: %r',
+ 'string-substitution-usage-warning',
+ 'String substitution used instead of string formattting'),
+ 'E1321': ('String substitution used instead of string formattting on: %r',
+ 'string-substitution-usage-error',
+ 'String substitution used instead of string formattting'),
}
+BAD_FORMATTING_SLOT = re.compile(r'(\{![\w]{1}\}|\{\})')
+
class StringCurlyBracesFormatIndexChecker(BaseChecker):
@@ -53,15 +62,52 @@
'help': 'Force un-indexed curly braces on a '
'\'string.format()\' call to always be an error.'}
),
+ ('enforce-string-formatting-over-substitution',
+ {'default': 1, 'type': 'yn', 'metavar': '