This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[ping2][PATCH v2] Implement benchmark script in python


Ping!

On Tue, Feb 11, 2014 at 10:02:02AM +0530, Siddhesh Poyarekar wrote:
> Ping!
> 
> On Thu, Jan 09, 2014 at 04:49:07PM +0530, Siddhesh Poyarekar wrote:
> > Hi Mike,
> > 
> > Did you get a chance to look at this?  I'm not looking to push this
> > into 2.19, so even if you ack it now, I'll hold on to it till 2.20
> > development opens.
> > 
> > Thanks,
> > Siddhesh
> > 
> > On Tue, Dec 31, 2013 at 03:13:02PM +0530, Siddhesh Poyarekar wrote:
> > > On Tue, Dec 31, 2013 at 03:45:30AM -0500, Mike Frysinger wrote:
> > > > largely looks good.  mostly nits below.
> > > > 
> > > > when it comes to declaring coding style, i'm not sure the GNU project has one 
> > > > already for python (since they try to push Guile/scheme).  GDB has been 
> > > > growing a python code base, but a scan of that tree doesn't turn up anything 
> > > > either :(.
> > > > 
> > > > looking around the glibc tree, i think adding a section to manual/maint.texi 
> > > > would be the best bet.
> > > 
> > > Wouldn't [1] be a good place for this kind of documentation?
> > > 
> > > [1] https://sourceware.org/glibc/wiki/Style_and_Conventions
> > > 
> > > However, I believe we should have an in-tree document that at least
> > > points to the relevant wiki pages for occasional contributors.
> > > 
> > > > > --- /dev/null
> > > > > +++ b/scripts/pylintrc
> > > > 
> > > > any reason for that vs generating a default one and tweaking it ?  see 
> > > > pylint's --generate-rcfile option.
> > > 
> > > In fact, I generated the default and dumped everything I didn't
> > > change, thinking that it would be easier for you to review a smaller
> > > file :) I've included the generated and tweaked rcfile now.  How does
> > > this iteration look?
> > > 
> > > Siddhesh
> > > 
> > > 
> > > 	* scripts/bench.pl: Remove file.
> > > 	* scripts/bench.py: New benchmark script.
> > > 	* benchtests/Makefile ($(objpfx)bench-%.c): Use it.
> > > 	* benchtests/README: Mention python dependency.
> > > 	* scripts/pylintrc: New file.
> > > 	* scripts/pylint: New file.
> > > 
> > > diff --git a/benchtests/Makefile b/benchtests/Makefile
> > > index 117228b..3d41274 100644
> > > --- a/benchtests/Makefile
> > > +++ b/benchtests/Makefile
> > > @@ -127,5 +127,5 @@ $(objpfx)bench-%.c: %-inputs $(bench-deps)
> > >  	{ if [ -n "$($*-INCLUDE)" ]; then \
> > >  	  cat $($*-INCLUDE); \
> > >  	fi; \
> > > -	$(..)scripts/bench.pl $(patsubst %-inputs,%,$<); } > $@-tmp
> > > +	$(..)scripts/bench.py $(patsubst %-inputs,%,$<); } > $@-tmp
> > >  	mv -f $@-tmp $@
> > > diff --git a/benchtests/README b/benchtests/README
> > > index a5fd8da..2a940fa 100644
> > > --- a/benchtests/README
> > > +++ b/benchtests/README
> > > @@ -8,7 +8,9 @@ basic performance properties of the function.
> > >  Running the benchmark:
> > >  =====================
> > >  
> > > -The benchmark can be executed by invoking make as follows:
> > > +The benchmark needs python 2.7 or later in addition to the
> > > +dependencies required to build the GNU C Library.  One may run the
> > > +benchmark by invoking make as follows:
> > >  
> > >    $ make bench
> > >  
> > > diff --git a/scripts/bench.pl b/scripts/bench.pl
> > > deleted file mode 100755
> > > index 10f0ba4..0000000
> > > diff --git a/scripts/bench.py b/scripts/bench.py
> > > new file mode 100755
> > > index 0000000..7c3ef04
> > > --- /dev/null
> > > +++ b/scripts/bench.py
> > > @@ -0,0 +1,299 @@
> > > +#!/usr/bin/python
> > > +# Copyright (C) 2013 Free Software Foundation, Inc.
> > > +# This file is part of the GNU C Library.
> > > +#
> > > +# The GNU C 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.
> > > +#
> > > +# The GNU C 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 the GNU C Library; if not, see
> > > +# <http://www.gnu.org/licenses/>.
> > > +
> > > +"""Benchmark program generator script
> > > +
> > > +This script takes a function name as input and generates a program using
> > > +an input file located in the benchtests directory.  The name of the
> > > +input file should be of the form foo-inputs where 'foo' is the name of
> > > +the function.
> > > +"""
> > > +
> > > +from __future__ import print_function
> > > +import sys
> > > +import os
> > > +import itertools
> > > +
> > > +# Macro definitions for functions that take no arguments.  For functions
> > > +# that take arguments, the STRUCT_TEMPLATE, ARGS_TEMPLATE and
> > > +# VARIANTS_TEMPLATE are used instead.
> > > +DEFINES_TEMPLATE = '''
> > > +#define CALL_BENCH_FUNC(v, i) %(func)s ()
> > > +#define NUM_VARIANTS (1)
> > > +#define NUM_SAMPLES(v) (1)
> > > +#define VARIANT(v) FUNCNAME "()"
> > > +'''
> > > +
> > > +# Structures to store arguments for the function call.  A function may
> > > +# have its inputs partitioned to represent distinct performance
> > > +# characteristics or distinct flavors of the function.  Each such
> > > +# variant is represented by the _VARIANT structure.  The ARGS structure
> > > +# represents a single set of arguments.
> > > +STRUCT_TEMPLATE = '''
> > > +#define CALL_BENCH_FUNC(v, i) %(func)s (%(func_args)s)
> > > +
> > > +struct args
> > > +{
> > > +%(args)s
> > > +};
> > > +
> > > +struct _variants
> > > +{
> > > +  const char *name;
> > > +  int count;
> > > +  struct args *in;
> > > +};
> > > +'''
> > > +
> > > +# The actual input arguments.
> > > +ARGS_TEMPLATE = '''
> > > +struct args in%(argnum)d[%(num_args)d] = {
> > > +%(args)s
> > > +};
> > > +'''
> > > +
> > > +# The actual variants, along with macros defined to access the variants.
> > > +VARIANTS_TEMPLATE = '''
> > > +struct _variants variants[%(num_variants)d] = {
> > > +%(variants)s
> > > +};
> > > +
> > > +#define NUM_VARIANTS %(num_variants)d
> > > +#define NUM_SAMPLES(i) (variants[i].count)
> > > +#define VARIANT(i) (variants[i].name)
> > > +'''
> > > +
> > > +# Epilogue for the generated source file.
> > > +EPILOGUE = '''
> > > +#define BENCH_FUNC(i, j) ({%(getret)s CALL_BENCH_FUNC (i, j);})
> > > +#define FUNCNAME "%(func)s"
> > > +#include "bench-skeleton.c"'''
> > > +
> > > +
> > > +def gen_source(func, directives, all_vals):
> > > +    """Generate source for the function
> > > +
> > > +    Generate the C source for the function from the values and
> > > +    directives.
> > > +
> > > +    Args:
> > > +      func: The function name
> > > +      directives: A dictionary of directives applicable to this function
> > > +      all_vals: A dictionary input values
> > > +    """
> > > +    # The includes go in first.
> > > +    for header in directives['includes']:
> > > +        print('#include <%s>' % header)
> > > +
> > > +    for header in directives['include-sources']:
> > > +        print('#include "%s"' % header)
> > > +
> > > +    # Print macros.  This branches out to a separate routine if
> > > +    # the function takes arguments.
> > > +    if not directives['args']:
> > > +        print(DEFINES_TEMPLATE % {'func': func})
> > > +        outargs = []
> > > +    else:
> > > +        outargs = _print_arg_data(func, directives, all_vals)
> > > +
> > > +    # Print the output variable definitions if necessary.
> > > +    for out in outargs:
> > > +        print(out)
> > > +
> > > +    # If we have a return value from the function, make sure it is
> > > +    # assigned to prevent the compiler from optimizing out the
> > > +    # call.
> > > +    if directives['ret']:
> > > +        print('static %s volatile ret;' % directives['ret'])
> > > +        getret = 'ret = '
> > > +    else:
> > > +        getret = ''
> > > +
> > > +    print(EPILOGUE % {'getret': getret, 'func': func})
> > > +
> > > +
> > > +def _print_arg_data(func, directives, all_vals):
> > > +    """Print argument data
> > > +
> > > +    This is a helper function for gen_source that prints structure and
> > > +    values for arguments and their variants and returns output arguments
> > > +    if any are found.
> > > +
> > > +    Args:
> > > +      func: Function name
> > > +      directives: A dictionary of directives applicable to this function
> > > +      all_vals: A dictionary input values
> > > +
> > > +    Returns:
> > > +      Returns a list of definitions for function arguments that act as
> > > +      output parameters.
> > > +    """
> > > +    # First, all of the definitions.  We process writing of
> > > +    # CALL_BENCH_FUNC, struct args and also the output arguments
> > > +    # together in a single traversal of the arguments list.
> > > +    func_args = []
> > > +    arg_struct = []
> > > +    outargs = []
> > > +
> > > +    for arg, i in zip(directives['args'], itertools.count()):
> > > +        if arg[0] == '<' and arg[-1] == '>':
> > > +            pos = arg.rfind('*')
> > > +            if pos == -1:
> > > +                die('Output argument must be a pointer type')
> > > +
> > > +            outargs.append('static %s out%d;' % (arg[1:pos], i))
> > > +            func_args.append(' &out%d' % i)
> > > +        else:
> > > +            arg_struct.append('  %s volatile arg%d;' % (arg, i))
> > > +            func_args.append('variants[v].in[i].arg%d' % i)
> > > +
> > > +    print(STRUCT_TEMPLATE % {'args' : '\n'.join(arg_struct), 'func': func,
> > > +                             'func_args': ', '.join(func_args)})
> > > +
> > > +    # Now print the values.
> > > +    variants = []
> > > +    for (k, vals), i in zip(all_vals.items(), itertools.count()):
> > > +        out = ['  {%s},' % v for v in vals]
> > > +
> > > +        # Members for the variants structure list that we will
> > > +        # print later.
> > > +        variants.append('  {"%s(%s)", %d, in%d},' % (func, k, len(vals), i))
> > > +        print(ARGS_TEMPLATE % {'argnum': i, 'num_args': len(vals),
> > > +                               'args': '\n'.join(out)})
> > > +
> > > +    # Print the variants and the last set of macros.
> > > +    print(VARIANTS_TEMPLATE % {'num_variants': len(all_vals),
> > > +                               'variants': '\n'.join(variants)})
> > > +    return outargs
> > > +
> > > +
> > > +def _process_directive(d_name, d_val):
> > > +    """Process a directive.
> > > +
> > > +    Evaluate the directive name and value passed and return the
> > > +    processed value. This is a helper function for parse_file.
> > > +
> > > +    Args:
> > > +      d_name: Name of the directive
> > > +      d_value: The string value to process
> > > +
> > > +    Returns:
> > > +      The processed value, which may be the string as it is or an object
> > > +      that describes the directive.
> > > +    """
> > > +    # Process the directive values if necessary.  name and ret don't
> > > +    # need any processing.
> > > +    if d_name.startswith('include'):
> > > +        d_val = d_val.split(',')
> > > +    elif d_name == 'args':
> > > +        d_val = d_val.split(':')
> > > +
> > > +    # Return the values.
> > > +    return d_val
> > > +
> > > +
> > > +def parse_file(func):
> > > +    """Parse an input file
> > > +
> > > +    Given a function name, open and parse an input file for the function
> > > +    and get the necessary parameters for the generated code and the list
> > > +    of inputs.
> > > +
> > > +    Args:
> > > +      func: The function name
> > > +
> > > +    Returns:
> > > +      A tuple of two elements, one a dictionary of directives and the
> > > +      other a dictionary of all input values.
> > > +    """
> > > +    all_vals = {}
> > > +    # Valid directives.
> > > +    directives = {
> > > +            'name': '',
> > > +            'args': [],
> > > +            'includes': [],
> > > +            'include-sources': [],
> > > +            'ret': ''
> > > +    }
> > > +
> > > +    try:
> > > +        with open('%s-inputs' % func) as f:
> > > +            for line in f:
> > > +                # Look for directives and parse it if found.
> > > +                if line.startswith('##'):
> > > +                    try:
> > > +                        d_name, d_val = line[2:].split(':', 1)
> > > +                        d_name = d_name.strip()
> > > +                        d_val = d_val.strip()
> > > +                        directives[d_name] = _process_directive(d_name, d_val)
> > > +                    except (IndexError, KeyError):
> > > +                        die('Invalid directive: %s' % line[2:])
> > > +
> > > +                # Skip blank lines and comments.
> > > +                line = line.split('#', 1)[0].rstrip()
> > > +                if not line:
> > > +                    continue
> > > +
> > > +                # Otherwise, we're an input.  Add to the appropriate
> > > +                # input set.
> > > +                cur_name = directives['name']
> > > +                all_vals.setdefault(cur_name, [])
> > > +                all_vals[cur_name].append(line)
> > > +    except IOError as ex:
> > > +        die("Failed to open input file (%s): %s" % (ex.filename, ex.strerror))
> > > +
> > > +    return directives, all_vals
> > > +
> > > +
> > > +def die(msg):
> > > +    """Exit with an error
> > > +
> > > +    Prints an error message to the standard error stream and exits with
> > > +    a non-zero status.
> > > +
> > > +    Args:
> > > +      msg: The error message to print to standard error.
> > > +    """
> > > +    print('%s\n' % msg, file=sys.stderr)
> > > +    sys.exit(os.EX_DATAERR)
> > > +
> > > +
> > > +def main(args):
> > > +    """Main function
> > > +
> > > +    Use the first command line argument as function name and parse its
> > > +    input file to generate C source that calls the function repeatedly
> > > +    for the input.
> > > +
> > > +    Args:
> > > +      args: The command line arguments with the program name dropped.
> > > +
> > > +    Returns:
> > > +      os.EX_USAGE on error and os.EX_OK on success.
> > > +    """
> > > +    if len(args) != 1:
> > > +        print('Usage: %s <function>' % sys.argv[0])
> > > +        return os.EX_USAGE
> > > +
> > > +    directives, all_vals = parse_file(args[0])
> > > +    gen_source(args[0], directives, all_vals)
> > > +    return os.EX_OK
> > > +
> > > +
> > > +if __name__ == '__main__':
> > > +    sys.exit(main(sys.argv[1:]))
> > > diff --git a/scripts/pylint b/scripts/pylint
> > > new file mode 100755
> > > index 0000000..49a775e
> > > --- /dev/null
> > > +++ b/scripts/pylint
> > > @@ -0,0 +1,5 @@
> > > +#!/bin/sh
> > > +# Simple wrapper around the pylint program that uses the pylintrc file to
> > > +# validate the source code in files passed on command line.
> > > +
> > > +exec pylint --rcfile "${0%/*}/pylintrc" "$@"
> > > diff --git a/scripts/pylintrc b/scripts/pylintrc
> > > new file mode 100644
> > > index 0000000..a05ddfd
> > > --- /dev/null
> > > +++ b/scripts/pylintrc
> > > @@ -0,0 +1,274 @@
> > > +[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=
> > > +
> > > +
> > > +[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. See also the "--disable" option for examples.
> > > +#enable=
> > > +
> > > +# Disable the message, report, category or checker with the given id(s). You
> > > +# can either give multiple identifiers separated by comma (,) or put this
> > > +# option multiple times (only on the command line, not in the configuration
> > > +# file where it should appear only once).You can also use "--disable=all" to
> > > +# disable everything first and then reenable specific checks. For example, if
> > > +# you want to run only the similarities checker, you can use "--disable=all
> > > +# --enable=similarities". If you want to run only the classes checker, but have
> > > +# no Warning level messages displayed, use"--disable=all --enable=classes
> > > +# --disable=W"
> > > +#disable=
> > > +
> > > +
> > > +[REPORTS]
> > > +
> > > +# Set the output format. Available formats are text, parseable, colorized, msvs
> > > +# (visual studio) and html. You can also give a reporter class, eg
> > > +# mypackage.mymodule.MyReporterClass.
> > > +output-format=text
> > > +
> > > +# 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
> > > +
> > > +# Template used to display messages. This is a python new-style format string
> > > +# used to format the massage information. See doc for all details
> > > +#msg-template=
> > > +
> > > +
> > > +[MISCELLANEOUS]
> > > +
> > > +# List of note tags to take in consideration, separated by a comma.
> > > +notes=FIXME,XXX,TODO
> > > +
> > > +
> > > +[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
> > > +
> > > +# Ignore imports when computing similarities.
> > > +ignore-imports=no
> > > +
> > > +
> > > +[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]+))$
> > > +
> > > +# 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]+$
> > > +
> > > +# 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 attribute names in class
> > > +# bodies
> > > +class-attribute-rgx=([A-Za-z_][A-Za-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
> > > +# f is a useful name for a file descriptor
> > > +good-names=f,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 function or class names that do
> > > +# not require a docstring.
> > > +no-docstring-rgx=__.*__
> > > +
> > > +# Minimum line length for functions/classes that require docstrings, shorter
> > > +# ones are exempt.
> > > +docstring-min-length=-1
> > > +
> > > +
> > > +[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=
> > > +
> > > +
> > > +[FORMAT]
> > > +
> > > +# Maximum number of characters on a single line.
> > > +max-line-length=79
> > > +
> > > +# Regexp for a line that is allowed to be longer than the limit.
> > > +ignore-long-lines=^\s*(# )?<?https?://\S+>?$
> > > +
> > > +# 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='    '
> > > +
> > > +
> > > +[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
> > > +
> > > +
> > > +[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
> > > +
> > > +# List of valid names for the first argument in a metaclass class method.
> > > +valid-metaclass-classmethod-first-arg=mcs
> > > +
> > > +
> > > +[IMPORTS]
> > > +
> > > +# Deprecated modules which should not be used, separated by a comma
> > > +deprecated-modules=regsub,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=
> > > +
> > > +
> > > +[DESIGN]
> > > +
> > > +# Maximum number of arguments for function / method
> > > +max-args=5
> > > +
> > > +# 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-branches=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
> > > +
> > > +
> > > +[EXCEPTIONS]
> > > +
> > > +# Exceptions that will emit a warning when being caught. Defaults to
> > > +# "Exception"
> > > +overgeneral-exceptions=Exception

Attachment: pgpeAr71W1KjW.pgp
Description: PGP signature


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]