summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichal Minar <miminar@redhat.com>2012-11-28 10:24:59 +0100
committerMichal Minar <miminar@redhat.com>2012-11-28 10:24:59 +0100
commit148b5b7d18c449b87b1103c05612ff2a2fe83233 (patch)
tree44ec8759acb37b79bae705550e37a8cb7885b20c
parent084ed5a5ffe8dccd0436e880449a6b39863690a4 (diff)
downloadopenlmi-providers-148b5b7d18c449b87b1103c05612ff2a2fe83233.tar.gz
openlmi-providers-148b5b7d18c449b87b1103c05612ff2a2fe83233.tar.xz
openlmi-providers-148b5b7d18c449b87b1103c05612ff2a2fe83233.zip
added pylintlmi checker for python source checking
pylintlmi uses pylint (python source code checking utility) - giving it custom configuration for openlmi project and plugins with additional checks for usage see src/software/README renamed directory "src/software/providers" to "src/software/openlmi/software" * allows installation to custom PYTHONPATH together with openlmi-python egg * that also allows running pylint on sources in devel directory without messages like: W0403: 28,0: Relative import 'openlmi.software.core', should be 'openlmi.software.openlmi.software.core' E0611: 28,0: No name 'software' in module 'openlmi' F0401: 28,0: Unable to import 'openlmi.software.core'
-rw-r--r--src/software/openlmi/__init__.py21
-rw-r--r--src/software/openlmi/software/LMI_SoftwareFileCheck.py (renamed from src/software/providers/LMI_SoftwareFileCheck.py)0
-rw-r--r--src/software/openlmi/software/LMI_SoftwareInstalledPackage.py (renamed from src/software/providers/LMI_SoftwareInstalledPackage.py)0
-rw-r--r--src/software/openlmi/software/LMI_SoftwarePackage.py (renamed from src/software/providers/LMI_SoftwarePackage.py)0
-rw-r--r--src/software/openlmi/software/LMI_SoftwarePackageChecks.py (renamed from src/software/providers/LMI_SoftwarePackageChecks.py)0
-rw-r--r--src/software/openlmi/software/__init__.py (renamed from src/software/providers/__init__.py)0
-rw-r--r--src/software/openlmi/software/util/__init__.py (renamed from src/software/providers/util/__init__.py)0
-rw-r--r--src/software/openlmi/software/util/common.py (renamed from src/software/providers/util/common.py)0
-rw-r--r--src/software/openlmi/software/util/singletonmixin.py (renamed from src/software/providers/util/singletonmixin.py)0
l---------src/software/providers1
-rw-r--r--src/software/setup.py4
-rw-r--r--tools/pylint/README36
-rw-r--r--tools/pylint/logilab-modutils-0.57.1.patch22
-rw-r--r--tools/pylint/plugins/__init__.py20
-rw-r--r--tools/pylint/plugins/cim_provider_checker.py149
-rw-r--r--tools/pylint/plugins/unittest_checker.py82
-rwxr-xr-xtools/pylint/pylintlmi8
-rw-r--r--tools/pylint/pylintrc249
18 files changed, 590 insertions, 2 deletions
diff --git a/src/software/openlmi/__init__.py b/src/software/openlmi/__init__.py
new file mode 100644
index 0000000..085d611
--- /dev/null
+++ b/src/software/openlmi/__init__.py
@@ -0,0 +1,21 @@
+# Software Management Providers
+#
+# Copyright (C) 2012 Red Hat, Inc. All rights reserved.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+# Authors: Michal Minar <miminar@redhat.com>
+#
+__import__('pkg_resources').declare_namespace(__name__)
diff --git a/src/software/providers/LMI_SoftwareFileCheck.py b/src/software/openlmi/software/LMI_SoftwareFileCheck.py
index c667352..c667352 100644
--- a/src/software/providers/LMI_SoftwareFileCheck.py
+++ b/src/software/openlmi/software/LMI_SoftwareFileCheck.py
diff --git a/src/software/providers/LMI_SoftwareInstalledPackage.py b/src/software/openlmi/software/LMI_SoftwareInstalledPackage.py
index 51d15b6..51d15b6 100644
--- a/src/software/providers/LMI_SoftwareInstalledPackage.py
+++ b/src/software/openlmi/software/LMI_SoftwareInstalledPackage.py
diff --git a/src/software/providers/LMI_SoftwarePackage.py b/src/software/openlmi/software/LMI_SoftwarePackage.py
index 2395dca..2395dca 100644
--- a/src/software/providers/LMI_SoftwarePackage.py
+++ b/src/software/openlmi/software/LMI_SoftwarePackage.py
diff --git a/src/software/providers/LMI_SoftwarePackageChecks.py b/src/software/openlmi/software/LMI_SoftwarePackageChecks.py
index a2f798b..a2f798b 100644
--- a/src/software/providers/LMI_SoftwarePackageChecks.py
+++ b/src/software/openlmi/software/LMI_SoftwarePackageChecks.py
diff --git a/src/software/providers/__init__.py b/src/software/openlmi/software/__init__.py
index 2ebe827..2ebe827 100644
--- a/src/software/providers/__init__.py
+++ b/src/software/openlmi/software/__init__.py
diff --git a/src/software/providers/util/__init__.py b/src/software/openlmi/software/util/__init__.py
index 2ebe827..2ebe827 100644
--- a/src/software/providers/util/__init__.py
+++ b/src/software/openlmi/software/util/__init__.py
diff --git a/src/software/providers/util/common.py b/src/software/openlmi/software/util/common.py
index 7b54f1e..7b54f1e 100644
--- a/src/software/providers/util/common.py
+++ b/src/software/openlmi/software/util/common.py
diff --git a/src/software/providers/util/singletonmixin.py b/src/software/openlmi/software/util/singletonmixin.py
index 8051695..8051695 100644
--- a/src/software/providers/util/singletonmixin.py
+++ b/src/software/openlmi/software/util/singletonmixin.py
diff --git a/src/software/providers b/src/software/providers
new file mode 120000
index 0000000..6105f87
--- /dev/null
+++ b/src/software/providers
@@ -0,0 +1 @@
+openlmi/software \ No newline at end of file
diff --git a/src/software/setup.py b/src/software/setup.py
index 433be41..25eb001 100644
--- a/src/software/setup.py
+++ b/src/software/setup.py
@@ -6,10 +6,10 @@ setup(
author_email='miminar@redhat.com',
url='https://fedorahosted.org/openlmi/',
version='0.5',
- package=['openlmi'],
- package_dir={'openlmi.software': 'providers'},
+ namespace_packages=['openlmi'],
packages=['openlmi.software', 'openlmi.software.util'],
install_requires=['openlmi'],
+ license="LGPLv2+",
classifiers=[
'License :: OSI Approved :: GNU Lesser General Public License v2 or later (LGPLv2+)',
'Operating System :: POSIX :: Linux',
diff --git a/tools/pylint/README b/tools/pylint/README
new file mode 100644
index 0000000..0f30dc2
--- /dev/null
+++ b/tools/pylint/README
@@ -0,0 +1,36 @@
+This tool uses pylint to check for errors in python code.
+Before using it, please ensure, that you have installed openlmi-python
+and all of the other cim provider packages, that you want to chek, into
+your PYTHONPATH.
+
+INSTALLATION TO PYTHON PATH
+ * If checking already installed providers under /usr/lib/pythonX.Y/*
+ you may skip this step.
+ 1. Choose some directory for your PYTHONPATH, if you don't have one yet. eg:
+ $ mkdir ~/.python_sandbox
+ $ export PYTHONPATH=~/.python_sandbox
+ note: you may put the export line into you .profile
+ 2. Go to the directory of python egg, you want to install and install it:
+ $ cd openlmi-providers/src/python
+ $ python setup.py develop --install-dir=$PYTHONPATH
+ 3. Repeat step 2 for providers you want to check.
+ 4. Check sources.
+
+FIX FOR PYLINT
+ * Due to a bug in pylint's module handling, it fails to work with namespace
+ packages. A bug is described here: http://www.logilab.org/ticket/8796
+ * To fix this you may apply attached patch "logilab-modutils-0.57.1.patch"
+ to logilab module (this one is for version 0.57.1):
+ $ patch -d /usr/lib/python2.7/site-packages/logilab -p1 \
+ <logilab-modutils-0.57.1.patch
+
+RUNNING PYLINT CHECKER
+ 1. Add pylint directory to your PATH:
+ $ cd openlmi-providers
+ $ export PATH=`pwd`/tools/pylint:"$PATH"
+ 2. Use it
+ * Run it on single module:
+ $ cd src/software
+ $ pylintlmi openlmi/software/LMI_SoftwarePackage.py
+ * Run it on whole package:
+ $ pylintlmi openlmi
diff --git a/tools/pylint/logilab-modutils-0.57.1.patch b/tools/pylint/logilab-modutils-0.57.1.patch
new file mode 100644
index 0000000..6cae893
--- /dev/null
+++ b/tools/pylint/logilab-modutils-0.57.1.patch
@@ -0,0 +1,22 @@
+Index: logilab/common/modutils.py
+===================================================================
+--- logilab.orig/common/modutils.py
++++ logilab/common/modutils.py
+@@ -34,6 +34,7 @@ import os
+ from os.path import splitext, join, abspath, isdir, dirname, exists, basename
+ from imp import find_module, load_module, C_BUILTIN, PY_COMPILED, PKG_DIRECTORY
+ from distutils.sysconfig import get_config_var, get_python_lib, get_python_version
++import pkg_resources
+
+ try:
+ import zipimport
+@@ -601,6 +602,9 @@ def _module_file(modpath, path=None):
+ checkeggs = False
+ imported = []
+ while modpath:
++ if modpath[0] in pkg_resources._namespace_packages and len(modpath) > 1:
++ module = sys.modules[modpath.pop(0)]
++ path = module.__path__
+ try:
+ _, mp_filename, mp_desc = find_module(modpath[0], path)
+ except ImportError:
diff --git a/tools/pylint/plugins/__init__.py b/tools/pylint/plugins/__init__.py
new file mode 100644
index 0000000..2ebe827
--- /dev/null
+++ b/tools/pylint/plugins/__init__.py
@@ -0,0 +1,20 @@
+# Software Management Providers
+#
+# Copyright (C) 2012 Red Hat, Inc. All rights reserved.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+# Authors: Michal Minar <miminar@redhat.com>
+#
diff --git a/tools/pylint/plugins/cim_provider_checker.py b/tools/pylint/plugins/cim_provider_checker.py
new file mode 100644
index 0000000..253cb9d
--- /dev/null
+++ b/tools/pylint/plugins/cim_provider_checker.py
@@ -0,0 +1,149 @@
+# -*- encoding: utf-8 -*-
+# Software Management Providers
+#
+# Copyright (C) 2012 Red Hat, Inc. All rights reserved.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+# Authors: Michal Minar <miminar@redhat.com>
+"""
+Pylint checker for CIM provider modules and classes.
+"""
+
+import re
+from logilab.astng import node_classes # pylint: disable=W0403
+from logilab.astng import scoped_nodes # pylint: disable=W0403
+from pylint.interfaces import IASTNGChecker
+from pylint.checkers import BaseChecker
+
+_RE_PROVIDER_CLASS_NAME = re.compile(
+ r'^(?P<prefix>[A-Z][a-zA-Z0-9]*)_(?P<name>[A-Z][a-zA-Z]*)$')
+_RE_PROVIDER_MODULE_NAME = re.compile(
+ r'^((?P<parent>.*)\.)?(?P<basename>(?P<prefix>[A-Z][a-zA-Z0-9]*)'
+ r'_(?P<name>[A-Z][a-zA-Z]*))$')
+_RE_COMMON_MODULE_NAME = re.compile(
+ r'^([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+)$')
+
+def supress_cim_provider_messages(linter, node):
+ """
+ Supress some warnings for CIMProvider2 subclass.
+ @param node is a subclass of CIMProvider2
+ """
+ assert isinstance(node, scoped_nodes.Class)
+ if ( 'Values' in node
+ and isinstance(node['Values'], scoped_nodes.Class)):
+ linter.disable('R0903', scope='module', line=node['Values'].lineno)
+ linter.disable('C0111', scope='module', line=node['Values'].lineno)
+ for child in node['Values'].get_children():
+ if not isinstance(child, scoped_nodes.Class):
+ continue
+ linter.disable('R0903', scope='module', line=child.lineno)
+ linter.disable('C0111', scope='module', line=child.lineno)
+
+class CIMProviderChecker(BaseChecker):
+ """
+ Checks for compliance to naming conventions for python cim providers.
+ """
+
+ __implements__ = IASTNGChecker
+
+ name = 'cim_provider'
+ msgs = {
+ 'C9904': ('Invalid provider class name %s',
+ "Class name representing cim provider should be in inform "
+ "<prefix>_<name>. Where <prefix> and <name> should be both "
+ "written in CamelCase."),
+ 'C9905': ('Invalid provider module name %s',
+ "Module containing cim provider(s) should be named as "
+ "<prefix>_<name>. Where both <prefix> and <name> are "
+ "CamelCased strings."),
+ 'C9906': ('Prefixes of module and class does not match: %s != %s',
+ "Module prefix has to match provider class prefix."),
+ 'E9907': ("Missing get_providers function in module %s",
+ "Provider module must contain get_providers function."),
+ 'W9908': ("get_providers in module %s is not a function",
+ "get_providers should be a callable function."),
+ 'W9909': ("Missing provider name \"%s\" in providers dictionary.",
+ "Function get_providers returns providers association"
+ " dictionary, that must include all module's provider"
+ " classes."),
+ 'C9910': ("Prefix different from LMI: %s",
+ "All OpenLMI CIM classes have LMI_ ORGID prefix."),
+ 'C9911': ("Invalid module name: %s",
+ "All modules, that does not declare cim provider class"
+ " should be named according to this regexp:"
+ " '^(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$'."),
+ }
+
+ # this is important so that your checker is executed before others
+ priority = -2
+
+ def visit_class(self, node):
+ """
+ Check every class, which inherits from
+ pywbem.cim_provider2.CIMProvider2.
+ """
+ if "CIMProvider2" in [a.name for a in node.ancestors()]:
+ clsm = _RE_PROVIDER_CLASS_NAME.match(node.name)
+ if not clsm:
+ self.add_message('C9904', node=node, args=node.name)
+ parent = node.parent
+ while not isinstance(parent, scoped_nodes.Module):
+ parent = parent.parent
+ modm = _RE_PROVIDER_MODULE_NAME.match(parent.name)
+ if not modm:
+ self.add_message('C9905', node=node, args=parent.name)
+ if not clsm:
+ return
+ if clsm.group('prefix') != modm.group('prefix'):
+ self.add_message('C9906', node=node,
+ args=(modm.group('prefix'), clsm.group('prefix')))
+ if clsm.group('prefix') != 'LMI':
+ self.add_message('C9910', node=node, args=clsm.group('prefix'))
+ if not 'get_providers' in parent.keys():
+ self.add_message('E9907', node=parent, args=parent.name)
+ return
+ getprovs = parent['get_providers']
+ if not isinstance(getprovs, scoped_nodes.Function):
+ self.add_message('W9908', node=getprovs, args=parent.name)
+ ret = getprovs.last_child()
+ if not isinstance(ret, node_classes.Return):
+ return
+ dictionary = ret.get_children().next()
+ if not isinstance(dictionary, node_classes.Dict):
+ return
+ if not node.name in [i[0].value for i in dictionary.items]:
+ self.add_message('W9909', node=getprovs, args=node.name)
+ supress_cim_provider_messages(self.linter, node)
+
+ def visit_module(self, node):
+ """
+ Check for invalid module name.
+ """
+ modm = _RE_PROVIDER_MODULE_NAME.match(node.name)
+ if modm:
+ if not _RE_COMMON_MODULE_NAME.match(node.name):
+ for child in node.get_children():
+ if ( isinstance(child, scoped_nodes.Class)
+ and 'CIMProvider2' in [
+ a.name for a in child.ancestors()]):
+ break
+ else:
+ self.add_message('C9911', node=node, args=node.name)
+
+def register(linter):
+ """required method to auto register our checker"""
+ linter.register_checker(CIMProviderChecker(linter))
+
diff --git a/tools/pylint/plugins/unittest_checker.py b/tools/pylint/plugins/unittest_checker.py
new file mode 100644
index 0000000..da9e6e7
--- /dev/null
+++ b/tools/pylint/plugins/unittest_checker.py
@@ -0,0 +1,82 @@
+# -*- encoding: utf-8 -*-
+# Copyright (C) 2012 Red Hat, Inc. All rights reserved.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+# Authors: Michal Minar <miminar@redhat.com>
+#
+"""Pylint plugin to check OpenLMI unittest modules."""
+
+from logilab.astng import scoped_nodes
+from pylint.interfaces import IASTNGChecker
+from pylint.checkers import BaseChecker
+import unittest
+
+def is_test_case_method(node):
+ """
+ Check, whether node method is defined by TestCase base class.
+ """
+ if ( isinstance(node, scoped_nodes.Function)
+ and node.name in unittest.TestCase.__dict__):
+ return True
+ return False
+
+def is_test_case_subclass(node):
+ """
+ Check, whether node is a subclass of TestCase base class.
+ """
+ if not isinstance(node, scoped_nodes.Class):
+ return False
+ for ancestor in node.ancestors():
+ if ( ancestor.name == 'TestCase'
+ and ancestor.getattr('__module__')[0].value.startswith('unittest')):
+ return True
+ return False
+
+class TestCaseChecker(BaseChecker):
+ """
+ Checker for OpenLMI unittest modules.
+ Right now it just suppresses unwanted messages.
+ """
+
+ __implements__ = IASTNGChecker
+
+ name = 'unittest_case'
+ # When we do have some real warning messages/reports,
+ # remote W9920. We need it just to get registered.
+ msgs = { 'W9920': ('Dummy', "This is a dummy message.")}
+
+ priority = -1
+
+ def visit_class(self, node):
+ """
+ Suppress Naming and 'Attribute creation out of __init__'
+ errors for every TestCase subclass.
+ """
+ if not is_test_case_subclass(node):
+ return
+ if 'setUp' in node:
+ self.linter.disable('W0201',
+ scope='module', line=node['setUp'].lineno)
+ for child in node.get_children():
+ if not is_test_case_method(child):
+ continue
+ self.linter.disable('C0103',
+ scope='module', line=child.lineno)
+
+def register(linter):
+ """required method to auto register our checker"""
+ linter.register_checker(TestCaseChecker(linter))
+
diff --git a/tools/pylint/pylintlmi b/tools/pylint/pylintlmi
new file mode 100755
index 0000000..4e39aeb
--- /dev/null
+++ b/tools/pylint/pylintlmi
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+dir=`dirname $0`
+[[ -z "$dir" ]] && dir=.
+
+export PYLINTRC=$dir/pylintrc
+export PYTHONPATH="$PYTHONPATH:$dir/plugins"
+exec pylint $@
diff --git a/tools/pylint/pylintrc b/tools/pylint/pylintrc
new file mode 100644
index 0000000..f065e65
--- /dev/null
+++ b/tools/pylint/pylintrc
@@ -0,0 +1,249 @@
+[MASTER]
+
+# Specify a configuration file.
+#rcfile=
+
+# Python code to execute, usually for sys.path manipulation such as
+# pygtk.require().
+init-hook=
+
+# Profiled execution.
+profile=no
+
+# Add files or directories to the blacklist. They should be base names, not
+# paths.
+ignore=CVS
+
+# Pickle collected data for later comparisons.
+persistent=yes
+
+# List of plugins (as comma separated values of python modules names) to load,
+# usually to register additional checkers.
+load-plugins=unittest_checker,cim_provider_checker
+
+
+[MESSAGES CONTROL]
+
+# Enable the message, report, category or checker with the given id(s). You can
+# either give multiple identifier separated by comma (,) or put this option
+# multiple time.
+#enable=
+
+# Disable the message, report, category or checker with the given id(s). You
+# can either give multiple identifier separated by comma (,) or put this option
+# multiple time (only on the command line, not in the configuration file where
+# it should appear only once).
+disable=I0011
+
+
+[REPORTS]
+
+# Set the output format. Available formats are text, parseable, colorized, msvs
+# (visual studio) and html
+output-format=text
+
+# Include message's id in output
+include-ids=yes
+
+# Put messages in a separate file for each module / package specified on the
+# command line instead of printing them on stdout. Reports (if any) will be
+# written in a file name "pylint_global.[txt|html]".
+files-output=no
+
+# Tells whether to display a full report or only the messages
+reports=yes
+
+# Python expression which should return a note less than 10 (10 is the highest
+# note). You have access to the variables errors warning, statement which
+# respectively contain the number of errors / warnings messages and the total
+# number of statements analyzed. This is used by the global evaluation report
+# (RP0004).
+evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
+
+# Add a comment according to your evaluation note. This is used by the global
+# evaluation report (RP0004).
+comment=no
+
+
+[VARIABLES]
+
+# Tells whether we should check for unused import in __init__ files.
+init-import=no
+
+# A regular expression matching the beginning of the name of dummy variables
+# (i.e. not used).
+dummy-variables-rgx=_|dummy
+
+# List of additional names supposed to be defined in builtins. Remember that
+# you should avoid to define new builtins when possible.
+additional-builtins=
+
+
+[SIMILARITIES]
+
+# Minimum lines number of a similarity.
+min-similarity-lines=4
+
+# Ignore comments when computing similarities.
+ignore-comments=yes
+
+# Ignore docstrings when computing similarities.
+ignore-docstrings=yes
+
+
+[FORMAT]
+
+# Maximum number of characters on a single line.
+max-line-length=80
+
+# Maximum number of lines in a module
+max-module-lines=1000
+
+# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
+# tab).
+indent-string=' '
+
+
+[BASIC]
+
+# Required attributes for module, separated by a comma
+required-attributes=
+
+# List of builtins function names that should not be used, separated by a comma
+bad-functions=map,filter,apply,input
+
+# Regular expression which should only match correct module names
+module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+)|([A-Z][a-zA-Z]*_[A-Z][a-zA-Z0-9]*))$
+
+# Regular expression which should only match correct module level names
+const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$
+
+# Regular expression which should only match correct class names
+class-rgx=(([A-Z_][a-zA-Z0-9]+)|([A-Z][a-zA-Z]*_[A-Z][a-zA-Z0-9]*))$
+
+# Regular expression which should only match correct function names
+function-rgx=[a-z_][a-z0-9_]{2,30}$
+
+# Regular expression which should only match correct method names
+method-rgx=[a-z_][a-z0-9_]{2,30}$
+
+# Regular expression which should only match correct instance attribute names
+attr-rgx=[a-z_][a-z0-9_]{2,30}$
+
+# Regular expression which should only match correct argument names
+argument-rgx=[a-z_][a-z0-9_]{2,30}$
+
+# Regular expression which should only match correct variable names
+variable-rgx=[a-z_][a-z0-9_]{2,30}$
+
+# Regular expression which should only match correct list comprehension /
+# generator expression variable names
+inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$
+
+# Good variable names which should always be accepted, separated by a comma
+good-names=i,j,k,ex,Run,_
+
+# Bad variable names which should always be refused, separated by a comma
+bad-names=foo,bar,baz,toto,tutu,tata
+
+# Regular expression which should only match functions or classes name which do
+# not require a docstring
+no-docstring-rgx=__.*__
+
+
+[MISCELLANEOUS]
+
+# List of note tags to take in consideration, separated by a comma.
+notes=FIXME,XXX,TODO
+
+
+[TYPECHECK]
+
+# Tells whether missing members accessed in mixin class should be ignored. A
+# mixin class is detected if its name ends with "mixin" (case insensitive).
+ignore-mixin-members=yes
+
+# List of classes names for which member attributes should not be checked
+# (useful for classes with attributes dynamically set).
+ignored-classes=SQLObject
+
+# When zope mode is activated, add a predefined set of Zope acquired attributes
+# to generated-members.
+zope=no
+
+# List of members which are set dynamically and missed by pylint inference
+# system, and so shouldn't trigger E0201 when accessed. Python regular
+# expressions are accepted.
+generated-members=REQUEST,acl_users,aq_parent
+
+
+[DESIGN]
+
+# Maximum number of arguments for function / method
+max-args=8
+
+# Argument names that match this expression will be ignored. Default to name
+# with leading underscore
+ignored-argument-names=_.*
+
+# Maximum number of locals for function / method body
+max-locals=15
+
+# Maximum number of return / yield for function / method body
+max-returns=6
+
+# Maximum number of branch for function / method body
+max-branchs=12
+
+# Maximum number of statements in function / method body
+max-statements=50
+
+# Maximum number of parents for a class (see R0901).
+max-parents=7
+
+# Maximum number of attributes for a class (see R0902).
+max-attributes=7
+
+# Minimum number of public methods for a class (see R0903).
+min-public-methods=2
+
+# Maximum number of public methods for a class (see R0904).
+max-public-methods=20
+
+
+[CLASSES]
+
+# List of interface methods to ignore, separated by a comma. This is used for
+# instance to not check methods defines in Zope's Interface base class.
+ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by
+
+# List of method names used to declare (i.e. assign) instance attributes.
+defining-attr-methods=__init__,__new__,setUp
+
+# List of valid names for the first argument in a class method.
+valid-classmethod-first-arg=cls
+
+
+[IMPORTS]
+
+# Deprecated modules which should not be used, separated by a comma
+deprecated-modules=regsub,string,TERMIOS,Bastion,rexec
+
+# Create a graph of every (i.e. internal and external) dependencies in the
+# given file (report RP0402 must not be disabled)
+import-graph=
+
+# Create a graph of external dependencies in the given file (report RP0402 must
+# not be disabled)
+ext-import-graph=
+
+# Create a graph of internal dependencies in the given file (report RP0402 must
+# not be disabled)
+int-import-graph=
+
+
+[EXCEPTIONS]
+
+# Exceptions that will emit a warning when being caught. Defaults to
+# "Exception"
+overgeneral-exceptions=Exception