Hello community, here is the log from the commit of package python-pylama for openSUSE:Factory checked in at 2019-02-19 12:01:08 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-pylama (Old) and /work/SRC/openSUSE:Factory/.python-pylama.new.28833 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-pylama" Tue Feb 19 12:01:08 2019 rev:3 rq:677093 version:7.6.6 Changes: -------- --- /work/SRC/openSUSE:Factory/python-pylama/python-pylama.changes 2018-12-24 11:42:04.541415751 +0100 +++ /work/SRC/openSUSE:Factory/.python-pylama.new.28833/python-pylama.changes 2019-02-19 12:02:20.385077891 +0100 @@ -1,0 +2,8 @@ +Mon Feb 18 10:47:20 UTC 2019 - Tomáš Chvátal <[email protected]> + +- Update to version 7.6.6: + * various async and tests fixes + * no actual upstream changelog updated since 7.4 release +- Actually run tests + +------------------------------------------------------------------- Old: ---- pylama-7.4.3.tar.gz New: ---- dummy.py pylama-7.6.6.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-pylama.spec ++++++ --- /var/tmp/diff_new_pack.sw4xGI/_old 2019-02-19 12:02:21.033077557 +0100 +++ /var/tmp/diff_new_pack.sw4xGI/_new 2019-02-19 12:02:21.041077553 +0100 @@ -1,7 +1,7 @@ # # spec file for package python-pylama # -# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,53 +17,49 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} -%bcond_with test Name: python-pylama -Version: 7.4.3 +Version: 7.6.6 Release: 0 Summary: Code audit tool for python License: LGPL-3.0-only Group: Development/Languages/Python -Url: https://github.com/klen/pylama +URL: https://github.com/klen/pylama Source: https://files.pythonhosted.org/packages/source/p/pylama/pylama-%{version}.tar.gz -BuildRequires: %{python_module setuptools} -BuildRequires: fdupes -BuildRequires: python-rpm-macros -%if %{with test} +Source1: https://raw.githubusercontent.com/klen/pylama/develop/dummy.py +BuildRequires: %{python_module eradicate >= 0.2} BuildRequires: %{python_module mccabe >= 0.5.2} BuildRequires: %{python_module pycodestyle >= 2.3.1} BuildRequires: %{python_module pydocstyle >= 2.0.0} BuildRequires: %{python_module pyflakes >= 1.5.0} +BuildRequires: %{python_module pylint} BuildRequires: %{python_module pytest} -BuildRequires: %{python_module py} -BuildRequires: %{python_module radon} -BuildRequires: python-configparser -%endif -Requires: python-py +BuildRequires: %{python_module radon >= 1.4.2} +BuildRequires: %{python_module setuptools} +BuildRequires: fdupes +BuildRequires: git-core +BuildRequires: python-rpm-macros +Requires: python-setuptools +Requires(post): update-alternatives +Requires(postun): update-alternatives Recommends: python-mccabe >= 0.5.2 Recommends: python-pycodestyle >= 2.3.1 Recommends: python-pydocstyle >= 2.0.0 Recommends: python-pyflakes >= 1.5.0 -Recommends: python-radon -%ifpython2 -Requires: python-configparser -%endif +Recommends: python-pylint +Recommends: python-radon >= 1.4.2 BuildArch: noarch -Requires(post): update-alternatives -Requires(postun): update-alternatives - %python_subpackages %description -Code audit tool for Python and JavaScript. Pylama wraps these tools: - -* PEP8_ © 2012-2013, Florent Xicluna; -* PEP257_ © 2012, GreenSteam, <http://greensteam.dk/> -* PyFlakes_ © 2005-2013, Kevin Watters; -* Mccabe_ © Ned Batchelder; +Audit tool for Python and JavaScript. Pylama wraps these tools: +* PEP8 +* PEP257 +* PyFlakes +* Mccabe %prep %setup -q -n pylama-%{version} +cp %{SOURCE1} . %build export LANG=en_US.UTF-8 @@ -72,15 +68,14 @@ %install export LANG=en_US.UTF-8 %python_install +%python_expand rm -rf %{buildroot}%{$python_sitelib}/tests %python_expand %fdupes %{buildroot}%{$python_sitelib} %python_clone -a %{buildroot}%{_bindir}/pylama -%if %{with test} %check export LANG=en_US.UTF-8 -%python_expand py.test-%{$python_bin_suffix} pylama/pytest.py -%endif +%python_expand py.test-%{$python_bin_suffix} -v tests/ %post %python_install_alternative pylama @@ -89,7 +84,6 @@ %python_uninstall_alternative pylama %files %{python_files} -%defattr(-,root,root,-) %doc AUTHORS Changelog README.rst %license LICENSE %python_alternative %{_bindir}/pylama ++++++ dummy.py ++++++ #!/usr/bin/env python # coding: utf-8 # (c) 2005 Divmod, Inc. See LICENSE file for details # commented code #import os # from foo import junk # a = 3 a = 4 #foo(1, 2, 3) class Message(object): message = '' message_args = () def __init__(self, filename, loc, use_column=True): self.filename = filename self.lineno = loc.lineno self.col = getattr(loc, 'col_offset', None) if use_column else None test = 1 if test == 1: if test == 1: return 28 elif test == 2: return 28 return 28 elif test == 2: return 28 def __str__(self): return '%s:%s: %s' % (self.filename, self.lineno, self.message % self.message_args) class UnusedImport(Message): message = 'W402 %r imported but unused' def __init__(self, filename, lineno, name): Message.__init__(self, filename, lineno) self.message_args = (name,) class RedefinedWhileUnused(Message): message = 'W801 redefinition of unused %r from line %r' def __init__(self, filename, lineno, name, orig_lineno): Message.__init__(self, filename, lineno) self.message_args = (name, orig_lineno) class ImportShadowedByLoopVar(Message): message = 'W403 import %r from line %r shadowed by loop variable' def __init__(self, filename, lineno, name, orig_lineno): Message.__init__(self, filename, lineno) self.message_args = (name, orig_lineno) class ImportStarUsed(Message): message = "W404 'from %s import *' used; unable to detect undefined names" def __init__(self, filename, lineno, modname): Message.__init__(self, filename, lineno) self.message_args = (modname,) class UndefinedName(Message): message = 'W802 undefined name %r' def __init__(self, filename, lineno, name): Message.__init__(self, filename, lineno) self.message_args = (name,) class UndefinedExport(Message): message = 'W803 undefined name %r in __all__' def __init__(self, filename, lineno, name): Message.__init__(self, filename, lineno) self.message_args = (name,) class UndefinedLocal(Message): message = "W804 local variable %r (defined in enclosing scope on line " \ "%r) referenced before assignment" def __init__(self, filename, lineno, name, orig_lineno): Message.__init__(self, filename, lineno) self.message_args = (name, orig_lineno) class DuplicateArgument(Message): message = 'W805 duplicate argument %r in function definition' def __init__(self, filename, lineno, name): Message.__init__(self, filename, lineno) self.message_args = (name,) class RedefinedFunction(Message): message = 'W806 redefinition of function %r from line %r' def __init__(self, filename, lineno, name, orig_lineno): Message.__init__(self, filename, lineno) self.message_args = (name, orig_lineno) class LateFutureImport(Message): message = 'W405 future import(s) %r after other statements' def __init__(self, filename, lineno, names): Message.__init__(self, filename, lineno) self.message_args = (names,) class UnusedVariable(Message): """ Indicates that a variable has been explicitly assigned to but not actually used. """ message = 'W806 local variable %r is assigned to but never used' def __init__(self, filename, lineno, names): Message.__init__(self, filename, lineno) self.message_args = (names,) error = 1 # noQa and some comments ++++++ pylama-7.4.3.tar.gz -> pylama-7.6.6.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylama-7.4.3/AUTHORS new/pylama-7.6.6/AUTHORS --- old/pylama-7.4.3/AUTHORS 2017-09-13 16:15:27.000000000 +0200 +++ new/pylama-7.6.6/AUTHORS 2018-11-02 11:58:42.000000000 +0100 @@ -10,13 +10,16 @@ * Daniel O'onnell' (https://github.com/mruwnik) * Diego Rabatone Oliveira (https://github.com/diraol) * Fábio C. Barrionuevo da Luz (https://github.com/luzfcb) +* Gram (https://github.com/orsinium) * GrandVizierOlaf (https://github.com/grandvizierolaf) * Grzegorz Śliwiński (https://github.com/fizyk) * Jarek Śmiejczak (https://github.com/jotes) * Jens Persson (https://github.com/MrShark) * Johan Bloemberg (https://github.com/aequitas) +* Max Nordlund (https://github.com/maxnordlund) * Michael (https://github.com/michael-k) * Roman Osipenko (https://github.com/romanosipenko) * Serg Baburin (https://github.com/gmist) * Tomasz Karbownicki (https://github.com/trojkat) +* Tsuyoshi Hombashi (https://github.com/thombashi) * lukaszpiotr (https://github.com/lukaszpiotr) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylama-7.4.3/PKG-INFO new/pylama-7.6.6/PKG-INFO --- old/pylama-7.4.3/PKG-INFO 2017-09-13 16:32:09.000000000 +0200 +++ new/pylama-7.6.6/PKG-INFO 2018-11-02 11:59:14.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: pylama -Version: 7.4.3 +Version: 7.6.6 Summary: pylama -- Code audit tool for python Home-page: https://github.com/klen/pylama @@ -21,6 +21,7 @@ * Pylint_ © 2013, Logilab (should be installed 'pylama_pylint' module); * Radon_ © Michele Lacchia * gjslint_ © The Closure Linter Authors (should be installed 'pylama_gjslint' module); + * eradicate_ © Steven Myint; .. _badges: @@ -55,7 +56,7 @@ Requirements: ============= - - Python (2.7, 3.2, 3.3) + - Python (2.7, 3.4, 3.5, 3.6, 3.7) - To use JavaScript checker (``gjslint``) you need to install ``python-gflags`` with ``pip install python-gflags``. - If your tests are failing on Win platform you are missing: ``curses`` - http://www.lfd.uci.edu/~gohlke/pythonlibs/ (The curses library supplies a terminal-independent screen-painting and keyboard-handling facility for text-based terminals) @@ -113,10 +114,11 @@ $ pylama --help - usage: pylama [-h] [--verbose] [--version] [--format {pycodestyle,pylint}] - [--select SELECT] [--sort SORT] [--linters LINTERS] - [--ignore IGNORE] [--skip SKIP] [--report REPORT] [--hook] - [--async] [--options OPTIONS] [--force] [--abspath] + usage: pylama [-h] [--verbose] [--version] + [--format {pep8,pycodestyle,pylint,parsable}] [--select SELECT] + [--sort SORT] [--linters LINTERS] [--ignore IGNORE] + [--skip SKIP] [--report REPORT] [--hook] [--concurrent] + [--options FILE] [--force] [--abspath] [paths [paths ...]] Code audit tool for python. @@ -128,14 +130,15 @@ -h, --help show this help message and exit --verbose, -v Verbose mode. --version show program's version number and exit - --format {pycodestyle,pylint}, -f {pycodestyle,pylint} - Choose errors format (pycodestyle, pylint). + --format {pep8,pycodestyle,pylint,parsable}, -f {pep8,pycodestyle,pylint,parsable} + Choose errors format (pycodestyle, pylint, parsable). --select SELECT, -s SELECT Select errors and warnings. (comma-separated list) --sort SORT Sort result by error types. Ex. E,W,D --linters LINTERS, -l LINTERS - Select linters. (comma-separated). Choices are - mccabe,pycodestyle,pyflakes,pydocstyle. + Select linters. (comma-separated). Choices are mccabe, + pep257,pydocstyle,pep8,pycodestyle,pyflakes,pylint,iso + rt. --ignore IGNORE, -i IGNORE Ignore errors and warnings. (comma-separated) --skip SKIP Skip files by masks (comma-separated, Ex. @@ -143,13 +146,14 @@ --report REPORT, -r REPORT Send report to file [REPORT] --hook Install Git (Mercurial) hook. - --async Enable async mode. Useful for checking a lot of - files. Not supported by pylint. + --concurrent, --async + Enable async mode. Useful for checking a lot of files. + Unsupported with pylint. --options FILE, -o FILE Specify configuration file. Looks for pylama.ini, setup.cfg, tox.ini, or pytest.ini in the current - directory. - --force, -F Force code checking (if linter doesnt allow) + directory (default: None). + --force, -F Force code checking (if linter doesn't allow) --abspath, -a Use absolute paths in output. @@ -341,10 +345,23 @@ from pylama.main import check_path, parse_options - my_redefined_options = {...} + # Use and/or modify 0 or more of the options defined as keys in the variable my_redefined_options below. + # To use defaults for any option, remove that key completely. + my_redefined_options = { + 'linters': ['pep257', 'pydocstyle', 'pycodestyle', 'pyflakes' ...], + 'ignore': ['D203', 'D213', 'D406', 'D407', 'D413' ...], + 'select': ['R1705' ...], + 'sort': 'F,E,W,C,D,...', + 'skip': '*__init__.py,*/test/*.py,...', + 'async': True, + 'force': True + ... + } + # relative path of the directory in which pylama should check my_path = '...' + options = parse_options([my_path], **my_redefined_options) - errors = check_path(options) + errors = check_path(options, rootdir='.') .. _bagtracker: @@ -391,9 +408,12 @@ .. _Pytest: http://pytest.org .. _gjslint: https://developers.google.com/closure/utilities .. _klen: http://klen.github.io/ - .. _Radon: https://github.com/rubik/radon + .. _eradicate: https://github.com/myint/eradicate + .. |logo| image:: https://raw.github.com/klen/pylama/develop/docs/_static/logo.png :width: 100 + .. _Radon: https://github.com/rubik/radon + Keywords: pylint,pep8,pycodestyle,pyflakes,mccabe,linter,qa,pep257,pydocstyle Platform: Any diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylama-7.4.3/README.rst new/pylama-7.6.6/README.rst --- old/pylama-7.4.3/README.rst 2017-09-13 16:15:27.000000000 +0200 +++ new/pylama-7.6.6/README.rst 2018-11-02 11:58:42.000000000 +0100 @@ -12,6 +12,7 @@ * Pylint_ © 2013, Logilab (should be installed 'pylama_pylint' module); * Radon_ © Michele Lacchia * gjslint_ © The Closure Linter Authors (should be installed 'pylama_gjslint' module); +* eradicate_ © Steven Myint; .. _badges: @@ -46,7 +47,7 @@ Requirements: ============= -- Python (2.7, 3.2, 3.3) +- Python (2.7, 3.4, 3.5, 3.6, 3.7) - To use JavaScript checker (``gjslint``) you need to install ``python-gflags`` with ``pip install python-gflags``. - If your tests are failing on Win platform you are missing: ``curses`` - http://www.lfd.uci.edu/~gohlke/pythonlibs/ (The curses library supplies a terminal-independent screen-painting and keyboard-handling facility for text-based terminals) @@ -104,10 +105,11 @@ $ pylama --help - usage: pylama [-h] [--verbose] [--version] [--format {pycodestyle,pylint}] - [--select SELECT] [--sort SORT] [--linters LINTERS] - [--ignore IGNORE] [--skip SKIP] [--report REPORT] [--hook] - [--async] [--options OPTIONS] [--force] [--abspath] + usage: pylama [-h] [--verbose] [--version] + [--format {pep8,pycodestyle,pylint,parsable}] [--select SELECT] + [--sort SORT] [--linters LINTERS] [--ignore IGNORE] + [--skip SKIP] [--report REPORT] [--hook] [--concurrent] + [--options FILE] [--force] [--abspath] [paths [paths ...]] Code audit tool for python. @@ -119,14 +121,15 @@ -h, --help show this help message and exit --verbose, -v Verbose mode. --version show program's version number and exit - --format {pycodestyle,pylint}, -f {pycodestyle,pylint} - Choose errors format (pycodestyle, pylint). + --format {pep8,pycodestyle,pylint,parsable}, -f {pep8,pycodestyle,pylint,parsable} + Choose errors format (pycodestyle, pylint, parsable). --select SELECT, -s SELECT Select errors and warnings. (comma-separated list) --sort SORT Sort result by error types. Ex. E,W,D --linters LINTERS, -l LINTERS - Select linters. (comma-separated). Choices are - mccabe,pycodestyle,pyflakes,pydocstyle. + Select linters. (comma-separated). Choices are mccabe, + pep257,pydocstyle,pep8,pycodestyle,pyflakes,pylint,iso + rt. --ignore IGNORE, -i IGNORE Ignore errors and warnings. (comma-separated) --skip SKIP Skip files by masks (comma-separated, Ex. @@ -134,13 +137,14 @@ --report REPORT, -r REPORT Send report to file [REPORT] --hook Install Git (Mercurial) hook. - --async Enable async mode. Useful for checking a lot of - files. Not supported by pylint. + --concurrent, --async + Enable async mode. Useful for checking a lot of files. + Unsupported with pylint. --options FILE, -o FILE Specify configuration file. Looks for pylama.ini, setup.cfg, tox.ini, or pytest.ini in the current - directory. - --force, -F Force code checking (if linter doesnt allow) + directory (default: None). + --force, -F Force code checking (if linter doesn't allow) --abspath, -a Use absolute paths in output. @@ -332,10 +336,23 @@ from pylama.main import check_path, parse_options - my_redefined_options = {...} + # Use and/or modify 0 or more of the options defined as keys in the variable my_redefined_options below. + # To use defaults for any option, remove that key completely. + my_redefined_options = { + 'linters': ['pep257', 'pydocstyle', 'pycodestyle', 'pyflakes' ...], + 'ignore': ['D203', 'D213', 'D406', 'D407', 'D413' ...], + 'select': ['R1705' ...], + 'sort': 'F,E,W,C,D,...', + 'skip': '*__init__.py,*/test/*.py,...', + 'async': True, + 'force': True + ... + } + # relative path of the directory in which pylama should check my_path = '...' + options = parse_options([my_path], **my_redefined_options) - errors = check_path(options) + errors = check_path(options, rootdir='.') .. _bagtracker: @@ -382,6 +399,9 @@ .. _Pytest: http://pytest.org .. _gjslint: https://developers.google.com/closure/utilities .. _klen: http://klen.github.io/ -.. _Radon: https://github.com/rubik/radon +.. _eradicate: https://github.com/myint/eradicate + .. |logo| image:: https://raw.github.com/klen/pylama/develop/docs/_static/logo.png :width: 100 +.. _Radon: https://github.com/rubik/radon + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylama-7.4.3/pylama/__init__.py new/pylama-7.6.6/pylama/__init__.py --- old/pylama-7.4.3/pylama/__init__.py 2017-09-13 16:31:54.000000000 +0200 +++ new/pylama-7.6.6/pylama/__init__.py 2018-11-02 11:58:42.000000000 +0100 @@ -4,7 +4,7 @@ :license: BSD, see LICENSE for more details. """ -__version__ = "7.4.3" +__version__ = "7.6.6" __project__ = "pylama" __author__ = "Kirill Klenov <[email protected]>" __license__ = "GNU LGPL" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylama-7.4.3/pylama/async.py new/pylama-7.6.6/pylama/async.py --- old/pylama-7.4.3/pylama/async.py 2017-06-26 17:51:03.000000000 +0200 +++ new/pylama-7.6.6/pylama/async.py 1970-01-01 01:00:00.000000000 +0100 @@ -1,75 +0,0 @@ -"""Support for checking code asynchronously.""" - -import logging -import threading - -try: - import Queue -except ImportError: - import queue as Queue - - -try: - import multiprocessing - - CPU_COUNT = multiprocessing.cpu_count() - -except (ImportError, NotImplementedError): - CPU_COUNT = 1 - -from .core import run - - -LOGGER = logging.getLogger('pylama') - - -class Worker(threading.Thread): - """Get tasks from queue and run.""" - - def __init__(self, path_queue, result_queue): - """ Init worker. """ - threading.Thread.__init__(self) - self.path_queue = path_queue - self.result_queue = result_queue - - def run(self): - """ Run tasks from queue. """ - while True: - path, params = self.path_queue.get() - errors = run(path, **params) - self.result_queue.put(errors) - self.path_queue.task_done() - - -def check_async(paths, options, rootdir=None): - """Check given paths asynchronously. - - :return list: list of errors - - """ - LOGGER.info('Async code checking is enabled.') - path_queue = Queue.Queue() - result_queue = Queue.Queue() - - for num in range(CPU_COUNT): - worker = Worker(path_queue, result_queue) - worker.setDaemon(True) - LOGGER.info('Start worker #%s', (num + 1)) - worker.start() - - for path in paths: - path_queue.put((path, dict(options=options, rootdir=rootdir))) - - path_queue.join() - - errors = [] - while True: - try: - errors += result_queue.get(False) - except Queue.Empty: - break - - return errors - - -# pylama:ignore=W0212,D210,F0001 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylama-7.4.3/pylama/check_async.py new/pylama-7.6.6/pylama/check_async.py --- old/pylama-7.4.3/pylama/check_async.py 1970-01-01 01:00:00.000000000 +0100 +++ new/pylama-7.6.6/pylama/check_async.py 2018-10-02 17:43:34.000000000 +0200 @@ -0,0 +1,75 @@ +"""Support for checking code asynchronously.""" + +import logging +import threading + +try: + import Queue +except ImportError: + import queue as Queue + + +try: + import multiprocessing + + CPU_COUNT = multiprocessing.cpu_count() + +except (ImportError, NotImplementedError): + CPU_COUNT = 1 + +from .core import run + + +LOGGER = logging.getLogger('pylama') + + +class Worker(threading.Thread): + """Get tasks from queue and run.""" + + def __init__(self, path_queue, result_queue): + """ Init worker. """ + threading.Thread.__init__(self) + self.path_queue = path_queue + self.result_queue = result_queue + + def run(self): + """ Run tasks from queue. """ + while True: + path, params = self.path_queue.get() + errors = run(path, **params) + self.result_queue.put(errors) + self.path_queue.task_done() + + +def check_async(paths, options, rootdir=None): + """Check given paths asynchronously. + + :return list: list of errors + + """ + LOGGER.info('Async code checking is enabled.') + path_queue = Queue.Queue() + result_queue = Queue.Queue() + + for num in range(CPU_COUNT): + worker = Worker(path_queue, result_queue) + worker.setDaemon(True) + LOGGER.info('Start worker #%s', (num + 1)) + worker.start() + + for path in paths: + path_queue.put((path, dict(options=options, rootdir=rootdir))) + + path_queue.join() + + errors = [] + while True: + try: + errors += result_queue.get(False) + except Queue.Empty: + break + + return errors + + +# pylama:ignore=W0212,D210,F0001 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylama-7.4.3/pylama/config.py new/pylama-7.6.6/pylama/config.py --- old/pylama-7.4.3/pylama/config.py 2017-09-13 16:15:27.000000000 +0200 +++ new/pylama-7.6.6/pylama/config.py 2018-10-09 19:30:11.000000000 +0200 @@ -12,7 +12,7 @@ from .lint.extensions import LINTERS #: A default checkers -DEFAULT_LINTERS = 'pycodestyle', 'pyflakes', 'mccabe' +DEFAULT_LINTERS = 'pycodestyle', 'pyflakes', 'mccabe', 'eradicate' CURDIR = os.getcwd() CONFIG_FILES = 'pylama.ini', 'setup.cfg', 'tox.ini', 'pytest.ini' @@ -21,7 +21,9 @@ SKIP_PATTERN = re.compile(r'# *noqa\b', re.I).search # Parse a modelines -MODELINE_RE = re.compile(r'^\s*#\s+(?:pylama:)\s*((?:[\w_]*=[^:\n\s]+:?)+)', re.I | re.M) +MODELINE_RE = re.compile( + r'^\s*#\s+(?:pylama:)\s*((?:[\w_]*=[^:\n\s]+:?)+)', + re.I | re.M) # Setup a logger LOGGER = logging.getLogger('pylama') @@ -46,7 +48,6 @@ """ Split comma separated string into unique values, keeping their order. :returns: list of splitted values - """ seen = set() values = val if isinstance(val, (list, tuple)) else val.strip().split(',') @@ -111,7 +112,7 @@ "--linters", "-l", default=_Default(','.join(DEFAULT_LINTERS)), type=parse_linters, help=( "Select linters. (comma-separated). Choices are %s." - % ','.join(s for s in LINTERS.keys()) + % ','.join(s for s in LINTERS) )) PARSER.add_argument( @@ -120,7 +121,8 @@ PARSER.add_argument( "--skip", default=_Default(''), - type=lambda s: [re.compile(fnmatch.translate(p)) for p in s.split(',') if p], + type=lambda s: [re.compile(fnmatch.translate(p)) + for p in s.split(',') if p], help="Skip files by masks (comma-separated, Ex. */messages.py)") PARSER.add_argument("--report", "-r", help="Send report to file [REPORT]") @@ -128,7 +130,7 @@ "--hook", action="store_true", help="Install Git (Mercurial) hook.") PARSER.add_argument( - "--async", action="store_true", + "--concurrent", "--async", action="store_true", help="Enable async mode. Useful for checking a lot of files. " "Unsupported with pylint.") @@ -148,10 +150,11 @@ help="Use absolute paths in output.") -ACTIONS = dict((a.dest, a) for a in PARSER._actions) # pylint: disable=protected-access +ACTIONS = dict((a.dest, a) + for a in PARSER._actions) # pylint: disable=protected-access -def parse_options(args=None, config=True, rootdir=CURDIR, **overrides): # noqa +def parse_options(args=None, config=True, rootdir=CURDIR, **overrides): # noqa """ Parse options from command line and configuration files. :return argparse.Namespace: @@ -173,21 +176,24 @@ if isinstance(passed_value, _Default): if opt == 'paths': val = val.split() + if opt == 'skip': + val = fix_pathname_sep(val) setattr(options, opt, _Default(val)) # Parse file related options for name, opts in cfg.sections.items(): - if not name.startswith('pylama') or name == cfg.default_section: + if name == cfg.default_section: continue - name = name[7:] + if name.startswith('pylama'): + name = name[7:] if name in LINTERS: options.linters_params[name] = dict(opts) continue - mask = re.compile(fnmatch.translate(name)) + mask = re.compile(fnmatch.translate(fix_pathname_sep(name))) options.file_params[mask] = dict(opts) # Override options @@ -199,9 +205,9 @@ if isinstance(value, _Default): setattr(options, name, process_value(name, value.value)) - if options.async and 'pylint' in options.linters: + if options.concurrent and 'pylint' in options.linters: LOGGER.warning('Can\'t parse code asynchronously with pylint enabled.') - options.async = False + options.concurrent = False return options @@ -242,7 +248,7 @@ config = Namespace() config.default_section = 'pylama' - if not ini_path or ini_path == 'None': + if not ini_path: path = get_default_config_file(rootdir) if path: config.read(path) @@ -260,6 +266,11 @@ LOGGER.addHandler(logging.FileHandler(options.report, mode='w')) if options.options: - LOGGER.info('Try to read configuration from: ' + options.options) + LOGGER.info('Try to read configuration from: %r', options.options) + + +def fix_pathname_sep(val): + """Fix pathnames for Win.""" + return val.replace(os.altsep or "\\", os.sep) # pylama:ignore=W0212,D210,F0001 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylama-7.4.3/pylama/core.py new/pylama-7.6.6/pylama/core.py --- old/pylama-7.4.3/pylama/core.py 2017-09-13 16:15:27.000000000 +0200 +++ new/pylama-7.6.6/pylama/core.py 2018-11-02 11:58:42.000000000 +0100 @@ -50,7 +50,7 @@ for item in params.get('linters') or linters: if not isinstance(item, tuple): - item = (item, LINTERS.get(item)) + item = item, LINTERS.get(item) lname, linter = item @@ -60,39 +60,46 @@ lparams = linters_params.get(lname, dict()) LOGGER.info("Run %s %s", lname, lparams) + ignore, select = merge_params(params, lparams) + linter_errors = linter.run( - path, code=code, ignore=params.get("ignore", set()), - select=params.get("select", set()), params=lparams) - if linter_errors: - for er in linter_errors: - errors.append(Error(filename=path, linter=lname, **er)) + path, code=code, ignore=ignore, select=select, params=lparams) + if not linter_errors: + continue + + errors += filter_errors([ + Error(filename=path, linter=lname, **er) for er in linter_errors + ], ignore=ignore, select=select) except IOError as e: - LOGGER.debug("IOError %s", e) + LOGGER.error("IOError %s", e) errors.append(Error(text=str(e), filename=path, linter=lname)) except SyntaxError as e: - LOGGER.debug("SyntaxError %s", e) + LOGGER.error("SyntaxError %s", e) errors.append( Error(linter='pylama', lnum=e.lineno, col=e.offset, text='E0100 SyntaxError: {}'.format(e.args[0]), filename=path)) - except Exception as e: # noqa + except Exception as e: # noqa import traceback - LOGGER.info(traceback.format_exc()) - - errors = filter_errors(errors, **params) # noqa + LOGGER.error(traceback.format_exc()) errors = list(remove_duplicates(errors)) if code and errors: errors = filter_skiplines(code, errors) - key = lambda e: e.lnum if options and options.sort: sort = dict((v, n) for n, v in enumerate(options.sort, 1)) - key = lambda e: (sort.get(e.type, 999), e.lnum) + + def key(e): + return (sort.get(e.type, 999), e.lnum) + else: + def key(e): + return e.lnum + return sorted(errors, key=key) @@ -124,6 +131,8 @@ for key in ('ignore', 'select', 'linters'): params[key] += process_value(key, config.get(key, [])) params['skip'] = bool(int(config.get('skip', False))) + # TODO: skip what? This is causing erratic behavior for linters. + params['skip'] = False params['ignore'] = set(params['ignore']) params['select'] = set(params['select']) @@ -174,6 +183,19 @@ return errors +def merge_params(params, lparams): + """Merge global ignore/select with linter local params.""" + ignore = params.get('ignore', set()) + if 'ignore' in lparams: + ignore = ignore | set(lparams['ignore']) + + select = params.get('select', set()) + if 'select' in lparams: + select = select | set(lparams['select']) + + return ignore, select + + class CodeContext(object): """Read file if code is None. """ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylama-7.4.3/pylama/lint/extensions.py new/pylama-7.6.6/pylama/lint/extensions.py --- old/pylama-7.4.3/pylama/lint/extensions.py 2016-11-29 10:10:34.000000000 +0100 +++ new/pylama-7.6.6/pylama/lint/extensions.py 2018-10-09 18:48:22.000000000 +0200 @@ -9,6 +9,12 @@ pass try: + from pylama.lint.pylama_eradicate import Linter + LINTERS['eradicate'] = Linter() +except ImportError: + pass + +try: from pylama.lint.pylama_pydocstyle import Linter LINTERS['pep257'] = Linter() # for compatibility LINTERS['pydocstyle'] = Linter() @@ -34,6 +40,12 @@ except ImportError: pass +try: + from pylama.lint.pylama_pylint import Linter + LINTERS['pylint'] = Linter() +except ImportError: + pass + from pkg_resources import iter_entry_points diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylama-7.4.3/pylama/lint/pylama_eradicate.py new/pylama-7.6.6/pylama/lint/pylama_eradicate.py --- old/pylama-7.4.3/pylama/lint/pylama_eradicate.py 1970-01-01 01:00:00.000000000 +0100 +++ new/pylama-7.6.6/pylama/lint/pylama_eradicate.py 2018-10-02 17:43:19.000000000 +0200 @@ -0,0 +1,36 @@ +"""Commented-out code checking.""" +from eradicate import commented_out_code_line_numbers +from pylama.lint import Linter as Abstract + +try: + converter = unicode +except NameError: + converter = str + + +class Linter(Abstract): + + """Run commented-out code checking.""" + + @staticmethod + def run(path, code=None, params=None, **meta): + """Eradicate code checking. + + :return list: List of errors. + """ + code = converter(code) + line_numbers = commented_out_code_line_numbers(code) + lines = code.split('\n') + + result = [] + for line_number in line_numbers: + line = lines[line_number - 1] + result.append(dict( + lnum=line_number, + offset=len(line) - len(line.rstrip()), + # https://github.com/sobolevn/flake8-eradicate#output-example + text=converter('E800: Found commented out code: ') + line, + # https://github.com/sobolevn/flake8-eradicate#error-codes + type='E800', + )) + return result diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylama-7.4.3/pylama/lint/pylama_pycodestyle.py new/pylama-7.6.6/pylama/lint/pylama_pycodestyle.py --- old/pylama-7.4.3/pylama/lint/pylama_pycodestyle.py 2017-06-26 17:44:04.000000000 +0200 +++ new/pylama-7.6.6/pylama/lint/pylama_pycodestyle.py 2018-10-02 17:43:06.000000000 +0200 @@ -1,5 +1,5 @@ """pycodestyle support.""" -from pycodestyle import BaseReport, StyleGuide, get_parser +from pycodestyle import BaseReport, StyleGuide, get_parser, _parse_multi_options from pylama.lint import Linter as Abstract @@ -24,9 +24,13 @@ for option in parser.option_list: if option.dest and option.dest in params: value = params[option.dest] - if not isinstance(value, str): - continue - params[option.dest] = option.convert_value(option, params[option.dest]) + if isinstance(value, str): + params[option.dest] = option.convert_value(option, value) + + for key in ["filename", "exclude", "select", "ignore"]: + if key in params and isinstance(params[key], str): + params[key] = _parse_multi_options(params[key]) + P8Style = StyleGuide(reporter=_PycodestyleReport, **params) buf = StringIO(code) return P8Style.input_file(path, lines=buf.readlines()) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylama-7.4.3/pylama/lint/pylama_pylint.py new/pylama-7.6.6/pylama/lint/pylama_pylint.py --- old/pylama-7.4.3/pylama/lint/pylama_pylint.py 1970-01-01 01:00:00.000000000 +0100 +++ new/pylama-7.6.6/pylama/lint/pylama_pylint.py 2018-10-09 19:29:12.000000000 +0200 @@ -0,0 +1,109 @@ +"""Pylint integration to Pylama.""" +import logging +from os import path as op, environ + +from astroid import MANAGER +from pylama.lint import Linter as BaseLinter +from pylint.__pkginfo__ import numversion +from pylint.lint import Run +from pylint.reporters import BaseReporter + + +CURDIR = op.abspath(op.dirname(__file__)) +HOME_RCFILE = op.abspath(op.join(environ.get('HOME', ''), '.pylintrc')) +LAMA_RCFILE = op.abspath(op.join(CURDIR, 'pylint.rc')) + + +logger = logging.getLogger('pylama') + + +class Linter(BaseLinter): + """Check code with Pylint.""" + + @staticmethod + def run(path, code, params=None, ignore=None, select=None, **meta): + """Pylint code checking. + + :return list: List of errors. + """ + logger.debug('Start pylint') + + clear_cache = params.pop('clear_cache', False) + if clear_cache: + MANAGER.astroid_cache.clear() + + class Reporter(BaseReporter): + + def __init__(self): + self.errors = [] + super(Reporter, self).__init__() + + def _display(self, layout): + pass + + def handle_message(self, msg): + self.errors.append(dict( + lnum=msg.line, + col=msg.column, + text="%s %s" % (msg.msg_id, msg.msg), + type=msg.msg_id[0] + )) + + params = _Params(ignore=ignore, select=select, params=params) + logger.debug(params) + + reporter = Reporter() + + kwargs = { + (numversion[0] == 1 and 'exit' or 'do_exit'): False + } + + Run([path] + params.to_attrs(), reporter=reporter, **kwargs) + + return reporter.errors + + +class _Params(object): + """Store pylint params.""" + + def __init__(self, select=None, ignore=None, params=None): + + params = dict(params) + + if op.exists(HOME_RCFILE): + params['rcfile'] = HOME_RCFILE + + if select: + enable = params.get('enable', None) + params['enable'] = select | set(enable.split(",") if enable else []) + + if ignore: + disable = params.get('disable', None) + params['disable'] = ignore | set(disable.split(",") if disable else []) + + self.params = dict( + (name.replace('_', '-'), self.prepare_value(value)) + for name, value in params.items() if value is not None) + + @staticmethod + def prepare_value(value): + """Prepare value to pylint.""" + if isinstance(value, (list, tuple, set)): + return ",".join(value) + + if isinstance(value, bool): + return "y" if value else "n" + + return str(value) + + def to_attrs(self): + """Convert to argument list.""" + return ["--%s=%s" % item for item in self.params.items()] + + def __str__(self): + return " ".join(self.to_attrs()) + + def __repr__(self): + return "<Pylint %s>" % self + +# pylama:ignore=W0403 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylama-7.4.3/pylama/main.py new/pylama-7.6.6/pylama/main.py --- old/pylama-7.4.3/pylama/main.py 2016-10-25 19:22:56.000000000 +0200 +++ new/pylama-7.6.6/pylama/main.py 2018-10-09 18:48:35.000000000 +0200 @@ -7,7 +7,7 @@ from .config import parse_options, CURDIR, setup_logger from .core import LOGGER, run -from .async import check_async +from .check_async import check_async def check_path(options, rootdir=None, candidates=None, code=None): @@ -25,7 +25,8 @@ path = op.abspath(path_) if op.isdir(path): for root, _, files in walk(path): - candidates += [op.relpath(op.join(root, f), CURDIR) for f in files] + candidates += [op.relpath(op.join(root, f), CURDIR) + for f in files] else: candidates.append(path) @@ -35,7 +36,8 @@ paths = [] for path in candidates: - if not options.force and not any(l.allow(path) for _, l in options.linters): + if not options.force and not any(l.allow(path) + for _, l in options.linters): continue if not op.exists(path): @@ -43,7 +45,7 @@ paths.append(path) - if options.async: + if options.concurrent: return check_async(paths, options, rootdir) errors = [] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylama-7.4.3/pylama.egg-info/PKG-INFO new/pylama-7.6.6/pylama.egg-info/PKG-INFO --- old/pylama-7.4.3/pylama.egg-info/PKG-INFO 2017-09-13 16:32:09.000000000 +0200 +++ new/pylama-7.6.6/pylama.egg-info/PKG-INFO 2018-11-02 11:59:14.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: pylama -Version: 7.4.3 +Version: 7.6.6 Summary: pylama -- Code audit tool for python Home-page: https://github.com/klen/pylama @@ -21,6 +21,7 @@ * Pylint_ © 2013, Logilab (should be installed 'pylama_pylint' module); * Radon_ © Michele Lacchia * gjslint_ © The Closure Linter Authors (should be installed 'pylama_gjslint' module); + * eradicate_ © Steven Myint; .. _badges: @@ -55,7 +56,7 @@ Requirements: ============= - - Python (2.7, 3.2, 3.3) + - Python (2.7, 3.4, 3.5, 3.6, 3.7) - To use JavaScript checker (``gjslint``) you need to install ``python-gflags`` with ``pip install python-gflags``. - If your tests are failing on Win platform you are missing: ``curses`` - http://www.lfd.uci.edu/~gohlke/pythonlibs/ (The curses library supplies a terminal-independent screen-painting and keyboard-handling facility for text-based terminals) @@ -113,10 +114,11 @@ $ pylama --help - usage: pylama [-h] [--verbose] [--version] [--format {pycodestyle,pylint}] - [--select SELECT] [--sort SORT] [--linters LINTERS] - [--ignore IGNORE] [--skip SKIP] [--report REPORT] [--hook] - [--async] [--options OPTIONS] [--force] [--abspath] + usage: pylama [-h] [--verbose] [--version] + [--format {pep8,pycodestyle,pylint,parsable}] [--select SELECT] + [--sort SORT] [--linters LINTERS] [--ignore IGNORE] + [--skip SKIP] [--report REPORT] [--hook] [--concurrent] + [--options FILE] [--force] [--abspath] [paths [paths ...]] Code audit tool for python. @@ -128,14 +130,15 @@ -h, --help show this help message and exit --verbose, -v Verbose mode. --version show program's version number and exit - --format {pycodestyle,pylint}, -f {pycodestyle,pylint} - Choose errors format (pycodestyle, pylint). + --format {pep8,pycodestyle,pylint,parsable}, -f {pep8,pycodestyle,pylint,parsable} + Choose errors format (pycodestyle, pylint, parsable). --select SELECT, -s SELECT Select errors and warnings. (comma-separated list) --sort SORT Sort result by error types. Ex. E,W,D --linters LINTERS, -l LINTERS - Select linters. (comma-separated). Choices are - mccabe,pycodestyle,pyflakes,pydocstyle. + Select linters. (comma-separated). Choices are mccabe, + pep257,pydocstyle,pep8,pycodestyle,pyflakes,pylint,iso + rt. --ignore IGNORE, -i IGNORE Ignore errors and warnings. (comma-separated) --skip SKIP Skip files by masks (comma-separated, Ex. @@ -143,13 +146,14 @@ --report REPORT, -r REPORT Send report to file [REPORT] --hook Install Git (Mercurial) hook. - --async Enable async mode. Useful for checking a lot of - files. Not supported by pylint. + --concurrent, --async + Enable async mode. Useful for checking a lot of files. + Unsupported with pylint. --options FILE, -o FILE Specify configuration file. Looks for pylama.ini, setup.cfg, tox.ini, or pytest.ini in the current - directory. - --force, -F Force code checking (if linter doesnt allow) + directory (default: None). + --force, -F Force code checking (if linter doesn't allow) --abspath, -a Use absolute paths in output. @@ -341,10 +345,23 @@ from pylama.main import check_path, parse_options - my_redefined_options = {...} + # Use and/or modify 0 or more of the options defined as keys in the variable my_redefined_options below. + # To use defaults for any option, remove that key completely. + my_redefined_options = { + 'linters': ['pep257', 'pydocstyle', 'pycodestyle', 'pyflakes' ...], + 'ignore': ['D203', 'D213', 'D406', 'D407', 'D413' ...], + 'select': ['R1705' ...], + 'sort': 'F,E,W,C,D,...', + 'skip': '*__init__.py,*/test/*.py,...', + 'async': True, + 'force': True + ... + } + # relative path of the directory in which pylama should check my_path = '...' + options = parse_options([my_path], **my_redefined_options) - errors = check_path(options) + errors = check_path(options, rootdir='.') .. _bagtracker: @@ -391,9 +408,12 @@ .. _Pytest: http://pytest.org .. _gjslint: https://developers.google.com/closure/utilities .. _klen: http://klen.github.io/ - .. _Radon: https://github.com/rubik/radon + .. _eradicate: https://github.com/myint/eradicate + .. |logo| image:: https://raw.github.com/klen/pylama/develop/docs/_static/logo.png :width: 100 + .. _Radon: https://github.com/rubik/radon + Keywords: pylint,pep8,pycodestyle,pyflakes,mccabe,linter,qa,pep257,pydocstyle Platform: Any diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylama-7.4.3/pylama.egg-info/SOURCES.txt new/pylama-7.6.6/pylama.egg-info/SOURCES.txt --- old/pylama-7.4.3/pylama.egg-info/SOURCES.txt 2017-09-13 16:32:09.000000000 +0200 +++ new/pylama-7.6.6/pylama.egg-info/SOURCES.txt 2018-11-02 11:59:14.000000000 +0100 @@ -8,7 +8,7 @@ setup.py pylama/__init__.py pylama/__main__.py -pylama/async.py +pylama/check_async.py pylama/config.py pylama/core.py pylama/errors.py @@ -27,8 +27,14 @@ pylama/libs/inirama.py pylama/lint/__init__.py pylama/lint/extensions.py +pylama/lint/pylama_eradicate.py pylama/lint/pylama_mccabe.py pylama/lint/pylama_pycodestyle.py pylama/lint/pylama_pydocstyle.py pylama/lint/pylama_pyflakes.py -pylama/lint/pylama_radon.py \ No newline at end of file +pylama/lint/pylama_pylint.py +pylama/lint/pylama_radon.py +tests/__init__.py +tests/test_config.py +tests/test_core.py +tests/test_linters.py \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylama-7.4.3/pylama.egg-info/top_level.txt new/pylama-7.6.6/pylama.egg-info/top_level.txt --- old/pylama-7.4.3/pylama.egg-info/top_level.txt 2017-09-13 16:32:09.000000000 +0200 +++ new/pylama-7.6.6/pylama.egg-info/top_level.txt 2018-11-02 11:59:14.000000000 +0100 @@ -1 +1,2 @@ pylama +tests diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylama-7.4.3/requirements.txt new/pylama-7.6.6/requirements.txt --- old/pylama-7.4.3/requirements.txt 2017-09-13 16:10:31.000000000 +0200 +++ new/pylama-7.6.6/requirements.txt 2018-10-10 16:51:58.000000000 +0200 @@ -4,4 +4,3 @@ pycodestyle >= 2.3.1 pydocstyle >= 2.0.0 pyflakes >= 1.5.0 -# radon >= 1.4.2 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylama-7.4.3/setup.cfg new/pylama-7.6.6/setup.cfg --- old/pylama-7.4.3/setup.cfg 2017-09-13 16:32:09.000000000 +0200 +++ new/pylama-7.6.6/setup.cfg 2018-11-02 11:59:14.000000000 +0100 @@ -16,7 +16,7 @@ builtins = _ [pylama:pylint] -disable = R0921,E1002 +ignore = R,E1002,W0511 max-line-length = 100 [pylama:pycodestyle] @@ -28,7 +28,7 @@ [pylama:pylama/main.py] ignore = R0914,W0212,C901,E1103 -[pylama:test_pylama.py] +[pylama:tests/*] ignore = D,E1103 [egg_info] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylama-7.4.3/setup.py new/pylama-7.6.6/setup.py --- old/pylama-7.4.3/setup.py 2017-06-26 17:51:03.000000000 +0200 +++ new/pylama-7.6.6/setup.py 2018-10-09 18:48:22.000000000 +0200 @@ -3,14 +3,14 @@ """Setup pylama installation.""" import re -import sys from os import path as op +from io import open # noqa from setuptools import setup, find_packages _read = lambda f: open( - op.join(op.dirname(__file__), f)).read() if op.exists(f) else '' + op.join(op.dirname(__file__), f), encoding='utf-8').read() if op.exists(f) else '' _meta = _read('pylama/__init__.py') _license = re.search(r'^__license__\s*=\s*"(.*)"', _meta, re.M).group(1) @@ -19,7 +19,7 @@ install_requires = [ l.replace('==', '>=') for l in _read('requirements.txt').split('\n') - if l and not l.startswith('#') and not l.startswith('-')] + if l and not l.startswith(('#', '-'))] meta = dict( name=_project, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylama-7.4.3/tests/test_config.py new/pylama-7.6.6/tests/test_config.py --- old/pylama-7.4.3/tests/test_config.py 1970-01-01 01:00:00.000000000 +0100 +++ new/pylama-7.6.6/tests/test_config.py 2018-11-02 11:58:42.000000000 +0100 @@ -0,0 +1,67 @@ +from pylama.config import parse_options, get_config +from pylama.core import run, prepare_params + + +def test_config(): + config = get_config() + assert config + + options = parse_options() + assert options + assert options.skip + assert not options.verbose + assert options.paths == ['pylama'] + + options = parse_options(['-l', 'pydocstyle,pycodestyle', '-i', 'E']) + linters, _ = zip(*options.linters) + assert set(linters) == set(['pydocstyle', 'pycodestyle']) + assert options.ignore == ['E'] + + options = parse_options('-o dummy dummy.py'.split()) + linters, _ = zip(*options.linters) + assert set(linters) == set(['pycodestyle', 'mccabe', 'pyflakes', 'eradicate']) + assert options.skip == [] + + +def test_ignore_select(): + options = parse_options() + options.ignore = ['E301', 'D102'] + options.linters = ['pycodestyle', 'pydocstyle', 'pyflakes', 'mccabe'] + errors = run('dummy.py', options=options) + assert len(errors) == 31 + + numbers = [error.number for error in errors] + assert 'D100' in numbers + assert 'E301' not in numbers + assert 'D102' not in numbers + + options.ignore = ['E3', 'D', 'E2'] + errors = run('dummy.py', options=options) + assert not errors + + options.select = ['E301'] + errors = run('dummy.py', options=options) + assert len(errors) == 1 + assert errors[0]['col'] + + +def test_prepare_params(): + p1 = dict(ignore='W', select='R01', skip='0') + p2 = dict(ignore='E34,R45', select='E') + options = parse_options(ignore=['D'], config=False) + params = prepare_params(p1, p2, options) + assert params == { + 'ignore': set(['R45', 'E34', 'W', 'D']), + 'select': set(['R01', 'E']), + 'skip': False, 'linters': []} + + +def test_merge_params(): + from pylama.core import merge_params + + params = {'ignore': {1, 2, 3}} + lparams = {'ignore': {4, 5}} + + ignore, _ = merge_params(params, lparams) + assert ignore == {1, 2, 3, 4, 5} + assert params['ignore'] == {1, 2, 3} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylama-7.4.3/tests/test_core.py new/pylama-7.6.6/tests/test_core.py --- old/pylama-7.4.3/tests/test_core.py 1970-01-01 01:00:00.000000000 +0100 +++ new/pylama-7.6.6/tests/test_core.py 2018-11-02 11:58:42.000000000 +0100 @@ -0,0 +1,76 @@ +import os.path as op + +from pylama.check_async import check_async +from pylama.config import parse_options +from pylama.core import filter_errors, parse_modeline, run +from pylama.errors import Error, remove_duplicates +from pylama.hook import git_hook, hg_hook +from pylama.main import shell, check_path + + +def test_filter_errors(): + assert list(filter_errors([Error(text='E1')], select=['E'], ignore=['E101'])) + assert not list(filter_errors([Error(text='W1')], select=['W100'], ignore=['W'])) + + +def test_remove_duplicates(): + errors = [Error(linter='pycodestyle', text='E701'), Error(linter='pylint', text='C0321')] + errors = list(remove_duplicates(errors)) + assert len(errors) == 1 + + +def test_parser_modeline(): + code = """ + bla bla bla + # pylama: ignore=W12,E14:select=R:skip=0 + """ + params = parse_modeline(code) + assert params == dict(ignore='W12,E14', select='R', skip='0') + + +def test_checkpath(): + path = op.abspath('dummy.py') + options = parse_options([path]) + result = check_path(options) + assert result + assert result[0].filename == 'dummy.py' + + +def test_linters_params(): + options = parse_options(linters='mccabe', config=False) + options.linters_params['mccabe'] = dict(complexity=1) + errors = run('dummy.py', options=options) + assert len(errors) == 1 + + options.linters_params['mccabe'] = dict(complexity=20) + errors = run('dummy.py', options=options) + assert not errors + + +def test_sort(): + options = parse_options() + options.sort = ['C', 'D'] + errors = run('dummy.py', options=options) + assert errors[0].type == 'C' + + +def test_shell(): + errors = shell('-o dummy dummy.py'.split(), error=False) + assert errors + + errors = shell(['unknown.py'], error=False) + assert not errors + + +def test_git_hook(): + assert not git_hook(False) + + +def test_hg_hook(): + assert not hg_hook(None, dict()) + + +def test_async(): + options = parse_options(config=False) + errors = check_async(['dummy.py'], options=options, rootdir='.') + assert errors diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylama-7.4.3/tests/test_linters.py new/pylama-7.6.6/tests/test_linters.py --- old/pylama-7.4.3/tests/test_linters.py 1970-01-01 01:00:00.000000000 +0100 +++ new/pylama-7.6.6/tests/test_linters.py 2018-11-02 11:58:42.000000000 +0100 @@ -0,0 +1,54 @@ +from pylama.config import parse_options +from pylama.core import run +from pylama.lint.extensions import LINTERS + + +def test_mccabe(): + mccabe = LINTERS.get('mccabe') + errors = mccabe.run('dummy.py', '', params={}) + assert errors == [] + + +def test_eradicate(): + eradicate = LINTERS.get('eradicate') + errors = eradicate.run('', code="\n".join([ + "#import os", + "# from foo import junk", + "#a = 3", + "a = 4", + "#foo(1, 2, 3)", + ])) + assert len(errors) == 4 + + +def test_pyflakes(): + options = parse_options(linters=['pyflakes'], config=False) + assert options.linters + errors = run('dummy.py', code="\n".join([ + "import sys", + "def test():", + " unused = 1" + ]), options=options) + assert len(errors) == 2 + + +def test_pycodestyle(): + options = parse_options(linters=['pycodestyle'], config=False) + assert len(options.linters) == 1 + errors = run('dummy.py', options=options) + numbers = [error.number for error in errors] + assert len(errors) == 4 + assert 'E265' in numbers + assert 'E301' in numbers + assert 'E501' in numbers + + options.linters_params['pycodestyle'] = dict(max_line_length=60) + errors = run('dummy.py', options=options) + assert len(errors) == 13 + + +def test_pydocstyle(): + options = parse_options(linters=['pydocstyle']) + assert len(options.linters) == 1 + errors = run('dummy.py', options=options) + assert errors
