Skip to content

Commit

Permalink
Merge pull request #19 from ducted/feature/add-linting
Browse files Browse the repository at this point in the history
Feature/add linting
  • Loading branch information
calston committed Jan 25, 2017
2 parents 1169840 + edb4600 commit 3ebeb06
Show file tree
Hide file tree
Showing 58 changed files with 1,799 additions and 1,125 deletions.
123 changes: 123 additions & 0 deletions .pylintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
[MASTER]
rcfile=./.pylintrc
ignore=CVS
ignore-patterns=.*_pb2.py,test_.*.py
persistent=no
load-plugins=
jobs=2
unsafe-load-any-extension=no
extension-pkg-whitelist=
optimize-ast=no
msg-template={path}:{line}: [{msg_id}({symbol}), {obj}] {msg}

[MESSAGES CONTROL]

# Only show warnings with the listed confidence levels. Leave empty to show
# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED
confidence=

disable=R,import-star-module-level,old-octal-literal,oct-method,print-statement,unpacking-in-except,parameter-unpacking,backtick,old-raise-syntax,old-ne-operator,long-suffix,dict-view-method,dict-iter-method,metaclass-assignment,next-method-called,raising-string,indexing-exception,raw_input-builtin,long-builtin,file-builtin,execfile-builtin,coerce-builtin,cmp-builtin,buffer-builtin,basestring-builtin,apply-builtin,filter-builtin-not-iterating,using-cmp-argument,useless-suppression,range-builtin-not-iterating,suppressed-message,no-absolute-import,old-division,cmp-method,reload-builtin,zip-builtin-not-iterating,intern-builtin,unichr-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,input-builtin,round-builtin,hex-method,nonzero-method,map-builtin-not-iterating,too-few-public-methods,invalid-name,broad-except,abstract-method,bare-except,eval-used,no-init,redefined-outer-name,dangerous-default-value


[REPORTS]
output-format=colorized
files-output=no
reports=yes
evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)

[TYPECHECK]
ignore-mixin-members=yes
ignored-modules=twisted.internet.reactor,zope.interface
ignored-classes=optparse.Values,thread._local,_thread._local
# List of members which are set dynamically and missed by pylint inference
# system, and so shouldn't trigger E1101 when accessed. Python regular
# expressions are accepted.
generated-members=

contextmanager-decorators=contextlib.contextmanager

[LOGGING]
logging-modules=logging

[FORMAT]
max-line-length=80
ignore-long-lines=^\s*(# )?<?https?://\S+>?$
single-line-if-stmt=no
no-space-check=trailing-comma,dict-separator
max-module-lines=1000
indent-string=' '
indent-after-paren=4
expected-line-ending-format=

[SPELLING]
spelling-dict=
spelling-ignore-words=
spelling-private-dict-file=
spelling-store-unknown-words=no

[MISCELLANEOUS]
notes=FIXME,XXX,TODO

[SIMILARITIES]
min-similarity-lines=4
ignore-comments=yes
ignore-docstrings=yes
ignore-imports=no

[BASIC]
good-names=i,j,k,ex,Run,_
bad-names=foo,bar,baz,toto,tutu,tata
name-group=
include-naming-hint=no
property-classes=abc.abstractproperty
docstring-min-length=-1

function-rgx=_?_?[A-Za-z_][A-Za-z0-9_]{1,30}$
method-rgx=_?_?[a-z_][A-Za-z0-9_]{1,30}$
argument-rgx=_?[a-z_][A-Za-z0-9_]{1,30}$
variable-rgx=_?[a-z_][A-Za-z0-9_]{1,30}$
inlinevar-rgx=_?[a-z_][A-Za-z0-9_]{1,30}$
attr-rgx=_?[a-z_][A-Za-z0-9_]{1,30}$

[ELIF]
max-nested-blocks=5


[VARIABLES]
init-import=no
dummy-variables-rgx=(_+[a-zA-Z0-9]*?$)|dummy
additional-builtins=
callbacks=cb_,_cb
redefining-builtins-modules=six.moves,future.builtins

[IMPORTS]
deprecated-modules=regsub,TERMIOS,Bastion,rexec
import-graph=
ext-import-graph=
int-import-graph=
known-standard-library=
known-third-party=enchant
analyse-fallback-blocks=no

[CLASSES]

defining-attr-methods=__init__,__new__,setUp
valid-classmethod-first-arg=cls
valid-metaclass-classmethod-first-arg=mcs
exclude-protected=_asdict,_fields,_replace,_source,_make

[DESIGN]
max-args=15
ignored-argument-names=_.*
max-locals=15
max-returns=6
max-branches=13
max-statements=50
max-parents=7
max-attributes=30
min-public-methods=1
max-public-methods=20
max-bool-expr=5

[EXCEPTIONS]
overgeneral-exceptions=Exception
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ python:
- 3.5
install:
- pip install .
- pip install pylint
before_install:
- wget http://aphyr.com/riemann/riemann_0.2.6_all.deb
- sudo apt-get update
Expand All @@ -13,6 +14,7 @@ before_install:
- sudo /etc/init.d/riemann start
script:
- trial duct
- pylint duct

after_script:
- sudo /etc/init.d/riemann stop
4 changes: 3 additions & 1 deletion duct/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,7 @@
from duct import service

def makeService(config):
# Create DuctService
"""
Create DuctService object
"""
return service.DuctService(config)
36 changes: 22 additions & 14 deletions duct/aggregators.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,33 @@
def Counter32(a, b, delta):
"""
.. module:: aggregators
:synopsis: Aggregation functions
.. moduleauthor:: Colin Alston <colin@imcol.in>
"""


def Counter32(al, br, delta):
"""32bit counter aggregator with wrapping
"""
if b < a:
c = 4294967295 - a
return (c + b) / float(delta)
if br < al:
ch = 4294967295 - al
return (ch + br) / float(delta)

return (b - a) / float(delta)
return (br - al) / float(delta)

def Counter64(a, b, delta):
def Counter64(al, br, delta):
"""64bit counter aggregator with wrapping
"""
if b < a:
c = 18446744073709551615 - a
return (c + b) / float(delta)
if br < al:
ch = 18446744073709551615 - al
return (ch + br) / float(delta)

return (b - a) / float(delta)
return (br - al) / float(delta)

def Counter(a, b, delta):
def Counter(al, br, delta):
"""Counter derivative
"""
if b < a:
return None
if br < al:
return None

return (b - a) / float(delta)
return (br - al) / float(delta)
92 changes: 50 additions & 42 deletions duct/configuration.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,33 @@
"""
.. module:: configuration
:platform: Unix
:synopsis: Configuration file parser
.. moduleauthor:: Colin Alston <colin@imcol.in>
"""

import os
import yaml
import itertools
import copy
import yaml

from twisted.python import log

class ConfigurationError(Exception):
"""General exception class for Duct configuration issues
"""
pass

class ConfigFile(object):
"""Duct configuration file parser and accessor
"""
def __init__(self, path):
if os.path.exists(path):
with open(path, 'rt') as conf:
self.raw_config = yaml.load(conf)

if not self.raw_config:
self.raw_config = {}
log.msg("Warning: No configuration content")
else:
raise Exception("Configuration file '%s' not found" % path)

Expand All @@ -37,25 +44,25 @@ def __init__(self, path):

self._parse_config()

def _validate_type(self, item, type):
if not isinstance(type, tuple):
type = (type, )
def _validate_type(self, item, vtype):
if not isinstance(vtype, tuple):
vtype = (vtype, )

parse = False
for t in type:
for vt in vtype:
try:
assert(isinstance(self.raw_config.get(item, t()), type))
assert isinstance(self.raw_config.get(item, vt()), vtype)
parse = True
except AssertionError as e:
except AssertionError:
pass

if not parse:
raise ConfigurationError("%s must be one of type %s" % (
item, repr(type)))
raise ConfigurationError(
"%s must be one of type %s" % (item, repr(vtype)))

def _validate_config(self):
for k,v in self.known_items.items():
self._validate_type(k, v)
for key, val in self.known_items.items():
self._validate_type(key, val)

def _parse_config(self):
self._merge_includes()
Expand All @@ -73,31 +80,29 @@ def _merge_includes(self):

for ipath in paths:
if os.path.exists(ipath):
files = [
os.path.join(ipath, f) for f in os.listdir(ipath)
if (f.endswith('.yml') or f.endswith('.yaml'))
]
files = [os.path.join(ipath, fi) for fi in os.listdir(ipath)
if fi.endswith('.yml') or fi.endswith('.yaml')]

for f in files:
with open(f, 'rt') as yaml_path:
for conf_file in files:
with open(conf_file, 'rt') as yaml_path:
conf = yaml.load(yaml_path)
for k,v in conf.items():
if k in self.raw_config:
if both(v, self.raw_config[k], dict):
for key, val in conf.items():
if key in self.raw_config:
if both(val, self.raw_config[key], dict):
# Merge dicts
for k2, v2 in v.items():
self.raw_config[k][j2] = v2
for k2, v2 in val.items():
self.raw_config[key][k2] = v2

elif both(v, self.raw_config[k], list):
elif both(val, self.raw_config[key], list):
# Extend lists
self.raw_config[k].extend(v)
self.raw_config[key].extend(val)
else:
# Overwrite
self.raw_config[k] = v
self.raw_config[key] = val
else:
self.raw_config[k] = v
log.msg(
'Loadded additional configuration from %s' % f)
self.raw_config[key] = val
log.msg('Loadded additional configuration from %s'
% conf_file)
else:
log.msg(
'Config Error: include_path %s does not exist' % ipath)
Expand All @@ -109,7 +114,7 @@ def _build_blueprints(self):

if blueprints:
# Make sure raw config stubs exist if we have any blueprints
if not 'sources' in self.raw_config:
if 'sources' not in self.raw_config:
self.raw_config['sources'] = []

for blueprint in blueprints:
Expand All @@ -118,30 +123,30 @@ def _build_blueprints(self):
if not isinstance(toolboxes, list):
tbs = [tbs]

tbs = [toolboxes[t] for t in tbs]
tbs = [toolboxes[tool] for tool in tbs]

# Compute a dot product of all the config settings vectors
inversions = []
for k, v in blueprint.get('sets', {}).items():
inversions.append([(k, j) for j in v])
for key, val in blueprint.get('sets', {}).items():
inversions.append([(key, jay) for jay in val])

for options in itertools.product(*inversions):
for toolbox in tbs:
for source in toolbox.get('sources', []):
# Make a copy of the source dict
mysource = copy.copy(source)

# Merge toolbox defaults
for k, v in toolbox.get('defaults', {}).items():
mysource[k] = v
for key, val in toolbox.get('defaults', {}).items():
mysource[key] = val

# Merge blueprint defaults
for k, v in blueprint.get('defaults', {}).items():
mysource[k] = v
for key, val in blueprint.get('defaults', {}).items():
mysource[key] = val

# Merge set permutation
for k, v in options:
mysource[k] = v
for key, val in options:
mysource[key] = val

# Bolt it into our real config file
self.raw_config['sources'].append(mysource)
Expand All @@ -154,6 +159,9 @@ def _build_blueprints(self):
del self.raw_config['blueprint']

def get(self, item, default=None):
"""Returns `item` from configuration if it exists, otherwise returns
`default`
"""
return self.raw_config.get(item, default)

def __getitem__(self, item):
Expand Down
3 changes: 1 addition & 2 deletions duct/interfaces.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
"""
.. module:: interfaces
:platform: Unix
:synopsis: Generic interfaces
.. moduleauthor:: Colin Alston <colin@imcol.in>
"""

from zope.interface import Interface


# pylint: disable=E0239,W0221
class IDuctProtocol(Interface):
"""Interface for Duct client protocols"""

Expand Down
Loading

0 comments on commit 3ebeb06

Please sign in to comment.