Skip to content

Commit

Permalink
Merge branch 'release/4.0.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
klen committed Jun 8, 2014
2 parents 391a99f + 5f3fc79 commit b6ed6bb
Show file tree
Hide file tree
Showing 10 changed files with 160 additions and 77 deletions.
6 changes: 6 additions & 0 deletions Changelog
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
2014-06-08 horneds

* WARNING: Change format INI-options. See README for details.
* INI configurations could be read from `pylama.ini`, `setup.cfg`,
`pytest.ini`, `tox.ini` files.

2014-06-07 horneds

* Reduce duplicate messages #3
Expand Down
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ clean:

.PHONY: upload
upload:
python setup.py sdist upload || echo 'Upload already'
@python setup.py sdist upload || echo 'Already uploaded'
@python setup.py bdist_wheel upload || echo 'Already uploaded'

.PHONY: t
t: audit
Expand Down
131 changes: 90 additions & 41 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ Docs are available at https://pylama.readthedocs.org/. Pull requests with docume

.. contents::


.. _requirements:

Requirements:
Expand All @@ -62,7 +61,7 @@ Requirements:

Instalation:
============
**Pylama** should be installed using pip: ::
**Pylama** could be installed using pip: ::
::

$ pip install pylama
Expand All @@ -84,68 +83,79 @@ Recursive check a path. ::

$ pylama <path_to_directory_or_file>

Ignore some errors ::
Ignore errors ::

$ pylama -i W,E501

Customize linters ::
.. note:: You could choose a group erros `D`,`E1` and etc or special errors `C0312`

Choose code checkers ::

$ pylama -l "pep8,mccabe"

Customize linters for JavaScript::
Choose code chekers for JavaScript::

$ pylama --linters=gjslint --ignore=E:0010 <path_to_directory_or_file>

.. _options:

Set Pylama (checkers) options
=============================

Command line options
====================
--------------------

::

$ pylama --help

usage: main.py [-h] [--verbose] [--format {pep8,pylint}] [--select SELECT]
[--linters LINTERS] [--ignore IGNORE] [--skip SKIP]
[--complexity COMPLEXITY] [--report REPORT] [--hook]
[--options OPTIONS]
usage: pylama [-h] [--verbose] [--version] [--format {pep8,pylint}]
[--select SELECT] [--linters LINTERS] [--ignore IGNORE]
[--skip SKIP] [--report REPORT] [--hook] [--async]
[--options OPTIONS] [--force]
[path]

Code audit tool for python.

positional arguments:
path Path on file or directory.
path Path on file or directory for code check.

optional arguments:
-h, --help show this help message and exit
--verbose, -v Verbose mode.
--version show program's version number and exit
--format {pep8,pylint}, -f {pep8,pylint}
Error format.
Choose errors format (pep8, pylint).
--select SELECT, -s SELECT
Select errors and warnings. (comma-separated)
Select errors and warnings. (comma-separated list)
--linters LINTERS, -l LINTERS
Select linters. (comma-separated). Choices are
pep8,pep257,mccabe,pyflakes,pylint,gjslint.
Select linters. (comma-separated).
--ignore IGNORE, -i IGNORE
Ignore errors and warnings. (comma-separated)
Ignore errors and warnings. (comma-separated list)
--skip SKIP Skip files by masks (comma-separated, Ex.
*/messages.py*)
--complexity COMPLEXITY, -c COMPLEXITY
Set mccabe complexity.
*/messages.py)
--report REPORT, -r REPORT
Filename for report.
Send report to file [REPORT]
--hook Install Git (Mercurial) hook.
--async Enable async mode. Usefull for checking a lot of
files. Dont supported with pylint.
--options OPTIONS, -o OPTIONS
Select configuration file. By default is
'<CURDIR>/pylama.ini'

--force, -F Force code checking (if linter doesnt allow)

.. _modeline:

File modeline
=============
File modelines
--------------

You can set options for **Pylama** inside a source files. Use
pylama *modeline* for this.

Format: ::

# pylama:{name1}={value1}:{name2}={value2}:...

You can set :ref:`options` for **Pylama** inside a source files.

::

Expand All @@ -156,49 +166,88 @@ You can set :ref:`options` for **Pylama** inside a source files.
Disable code checking for current file: ::

.. Somethere in code
# skip=1
# pylama:skip=1

The options have a must higher priority.

.. _skiplines:

Skip lines
==========
Skip lines (noqa)
-----------------

Just add `# noqa` in end of line for ignore. ::
Just add `# noqa` in end of line for ignore.

.. Somethere in code
x=d+34 # noqa
::

def urgent_fuction():
unused_var = 'No errors here' # noqa


.. _config:

Configuration file
==================
Configuration files
-------------------

When starting **Pylama** try loading configuration file.

The programm searches for the first matching ini-style configuration file in
the directories of command line argument. Pylama looks for the configuration
in this order: ::

When starting **Pylama** try loading configuration file. By default: `<CURDIR>/pylama.ini`,
but you set it with "-o" option.
pylama.ini
pytest.ini
tox.ini
setup.ini

Section `main` contains a global options (see :ref:`options`), like `linters` and `skip`.
You could set configuration file manually by "-o" option.

Other sections could set :ref:`modeline` for a custom files by filepath mask.
Pylama search sections with name starts `pylama`.

Example: `pylama.ini` ::
Section `pylama` contains a global options, like `linters` and `skip`.

[main]
::

[pylama]
format = pylint
skip = */.tox/*,*/.env/*
linters = pylint,mccabe
ignore = F0401,C0111,E731

Code checker related options
----------------------------

You could set options for special code checker with pylama configurations.

::

[pylama:pyflakes]
builtins = _

[pylama:pep8]
max_line_length = 100

[*/pylama/main.py]

Set options for file (group of files)
-------------------------------------

You could set options for special file (group of files)
with sections:

The options have a higher priority than in the `pylama` section.

::

[pylama:*/pylama/main.py]
ignore = C901,R0914,W0212
select = R

[*/tests.py]
[pylama:*/tests.py]
ignore = C0110

[*/setup.py]
[pylama:*/setup.py]
skip = 1


Writing a linter
================

Expand Down
2 changes: 1 addition & 1 deletion pylama/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"""

__version__ = "3.3.2"
__version__ = "4.0.0"
__project__ = "pylama"
__author__ = "Kirill Klenov <horneds@gmail.com>"
__license__ = "GNU LGPL"
59 changes: 40 additions & 19 deletions pylama/config.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
""" Parse arguments from command line and configuration files. """
import fnmatch
import sys
from os import getcwd, path
import os
from re import compile as re

import logging
Expand All @@ -21,8 +21,11 @@
#: A default checkers
DEFAULT_LINTERS = 'pep8', 'pyflakes', 'mccabe'

CURDIR = getcwd()
DEFAULT_INI_PATH = path.join(CURDIR, 'pylama.ini')
CURDIR = os.getcwd()
CONFIG_FILES = [
os.path.join(CURDIR, basename) for basename in
('pylama.ini', 'setup.cfg', 'tox.ini', 'pytest.ini')
]


class _Default(object):
Expand Down Expand Up @@ -67,7 +70,7 @@ def parse_linters(linters):
PARSER = ArgumentParser(description="Code audit tool for python.")
PARSER.add_argument(
"path", nargs='?', default=_Default(CURDIR),
help="Path on file or directory.")
help="Path on file or directory for code check.")

PARSER.add_argument(
"--verbose", "-v", action='store_true', help="Verbose mode.")
Expand All @@ -77,11 +80,11 @@ def parse_linters(linters):

PARSER.add_argument(
"--format", "-f", default=_Default('pep8'), choices=['pep8', 'pylint'],
help="Error format.")
help="Choose errors format (pep8, pylint).")

PARSER.add_argument(
"--select", "-s", default=_Default(''), type=split_csp_str,
help="Select errors and warnings. (comma-separated)")
help="Select errors and warnings. (comma-separated list)")


PARSER.add_argument(
Expand All @@ -100,7 +103,7 @@ def parse_linters(linters):
type=lambda s: [re(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="Filename for report.")
PARSER.add_argument("--report", "-r", help="Send report to file [REPORT]")
PARSER.add_argument(
"--hook", action="store_true", help="Install Git (Mercurial) hook.")

Expand All @@ -110,9 +113,13 @@ def parse_linters(linters):
"Dont supported with pylint.")

PARSER.add_argument(
"--options", "-o", default=_Default(DEFAULT_INI_PATH),
"--options", "-o", default="",
help="Select configuration file. By default is '<CURDIR>/pylama.ini'")

PARSER.add_argument(
"--force", "-F", action='store_true', default=_Default(False),
help="Force code checking (if linter doesnt allow)")


ACTIONS = dict((a.dest, a) for a in PARSER._actions)

Expand Down Expand Up @@ -147,17 +154,22 @@ def parse_options(args=None, config=True, **overrides): # noqa
setattr(options, k, _Default(v))

# Parse file related options
for k, s in cfg.sections.items():
if k == cfg.default_section:
for name, opts in cfg.sections.items():

if not name.startswith('pylama'):
continue
if k in LINTERS:
options.linter_params[k] = dict(s)

if name == cfg.default_section:
continue
mask = re(fnmatch.translate(k))
options.file_params[mask] = dict(s)
options.file_params[mask]['lint'] = int(
options.file_params[mask].get('lint', 1)
)

name = name[7:]

if name in LINTERS:
options.linter_params[name] = dict(opts)
continue

mask = re(fnmatch.translate(name))
options.file_params[mask] = dict(opts)

# Postprocess options
opts = dict(options.__dict__.items())
Expand All @@ -183,14 +195,21 @@ def process_value(name, value):
return value


def get_config(ini_path=DEFAULT_INI_PATH):
def get_config(ini_path=None):
""" Load configuration from INI.
:return Namespace:
"""
config = Namespace()
config.default_section = 'main'
config.default_section = 'pylama'

if not ini_path:
for path in CONFIG_FILES:
if os.path.isfile(path) and os.access(path, os.R_OK):
ini_path = path
break

config.read(ini_path)

return config
Expand All @@ -203,3 +222,5 @@ def setup_logger(options):
LOGGER.removeHandler(STREAM)
LOGGER.addHandler(logging.FileHandler(options.report, mode='w'))
LOGGER.info('Try to read configuration from: ' + options.options)

# pylama:ignore=W0212
2 changes: 1 addition & 1 deletion pylama/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def run(path='', code=None, options=None):

lname, linter = item

if not linter or path and not linter.allow(path):
if not linter:
continue

LOGGER.info("Run %s", lname)
Expand Down

0 comments on commit b6ed6bb

Please sign in to comment.