Add pylint config and selectively fix some pylint errors

Some pylint errors are worth fixing; many are not.
This commit is contained in:
Jim Paris 2019-08-30 16:02:46 -04:00
parent 2ed544bd30
commit 2f2faeeab7
29 changed files with 124 additions and 376 deletions

250
.pylintrc
View File

@ -1,250 +0,0 @@
# -*- conf -*-
[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=datetime_tz
# Pickle collected data for later comparisons.
persistent=no
# 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.
#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=C0111,R0903,R0201,R0914,R0912,W0142,W0703,W0702
[REPORTS]
# Set the output format. Available formats are text, parseable, colorized, msvs
# (visual studio) and html
output-format=parseable
# 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
[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
[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
[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=' '
[MISCELLANEOUS]
# List of note tags to take in consideration, separated by a comma.
notes=FIXME,XXX,TODO
[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=
[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=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_]*)|(__.*__)|version)$
# 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_]{0,30}$
# Regular expression which should only match correct method names
method-rgx=[a-z_][a-z0-9_]{0,30}$
# Regular expression which should only match correct instance attribute names
attr-rgx=[a-z_][a-z0-9_]{0,30}$
# Regular expression which should only match correct argument names
argument-rgx=[a-z_][a-z0-9_]{0,30}$
# Regular expression which should only match correct variable names
variable-rgx=[a-z_][a-z0-9_]{0,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=__.*__
[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
[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-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
[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

View File

@ -20,9 +20,11 @@ develop:
docs: docs:
make -C docs make -C docs
ctrl: flake
flake:
flake8 nilmdb
lint: lint:
flake8 nilmdb --exclude=fsck.py,nilmdb_fsck.py pylint3 --rcfile=setup.cfg nilmdb
ctrl: lint
test: test:
ifneq ($(INSIDE_EMACS),) ifneq ($(INSIDE_EMACS),)
@ -44,4 +46,5 @@ clean::
gitclean:: gitclean::
git clean -dXf git clean -dXf
.PHONY: all version build dist sdist install docs lint test clean gitclean .PHONY: all version build dist sdist install docs test
.PHONY: ctrl lint flake clean gitclean

View File

@ -2,13 +2,12 @@
"""Class for performing HTTP client requests via libcurl""" """Class for performing HTTP client requests via libcurl"""
import nilmdb.utils
import nilmdb.client.httpclient
from nilmdb.client.errors import ClientError
import json import json
import contextlib import contextlib
import nilmdb.utils
import nilmdb.client.httpclient
from nilmdb.client.errors import ClientError
from nilmdb.utils.time import timestamp_to_string, string_to_timestamp from nilmdb.utils.time import timestamp_to_string, string_to_timestamp
@ -17,7 +16,7 @@ def extract_timestamp(line):
return string_to_timestamp(line.split()[0]) return string_to_timestamp(line.split()[0])
class Client(object): class Client():
"""Main client interface to the Nilm database.""" """Main client interface to the Nilm database."""
def __init__(self, url, post_json=False): def __init__(self, url, post_json=False):
@ -250,7 +249,7 @@ class Client(object):
return int(counts[0]) return int(counts[0])
class StreamInserter(object): class StreamInserter():
"""Object returned by stream_insert_context() that manages """Object returned by stream_insert_context() that manages
the insertion of rows of data into a particular path. the insertion of rows of data into a particular path.

View File

@ -1,13 +1,13 @@
"""HTTP client library""" """HTTP client library"""
from nilmdb.client.errors import ClientError, ServerError, Error
import json import json
import urllib.parse import urllib.parse
import requests import requests
from nilmdb.client.errors import ClientError, ServerError, Error
class HTTPClient(object):
class HTTPClient():
"""Class to manage and perform HTTP requests from the client""" """Class to manage and perform HTTP requests from the client"""
def __init__(self, baseurl="", post_json=False, verify_ssl=True): def __init__(self, baseurl="", post_json=False, verify_ssl=True):
"""If baseurl is supplied, all other functions that take """If baseurl is supplied, all other functions that take
@ -46,10 +46,10 @@ class HTTPClient(object):
args["traceback"] = jsonerror["traceback"] args["traceback"] = jsonerror["traceback"]
except Exception: except Exception:
pass pass
if code >= 400 and code <= 499: if 400 <= code <= 499:
raise ClientError(**args) raise ClientError(**args)
else: else:
if code >= 500 and code <= 599: if 500 <= code <= 599:
if args["message"] is None: if args["message"] is None:
args["message"] = ("(no message; try disabling " args["message"] = ("(no message; try disabling "
"response.stream option in " "response.stream option in "

View File

@ -3,15 +3,15 @@
"""Provide a NumpyClient class that is based on normal Client, but has """Provide a NumpyClient class that is based on normal Client, but has
additional methods for extracting and inserting data via Numpy arrays.""" additional methods for extracting and inserting data via Numpy arrays."""
import contextlib
import numpy
import nilmdb.utils import nilmdb.utils
import nilmdb.client.client import nilmdb.client.client
import nilmdb.client.httpclient import nilmdb.client.httpclient
from nilmdb.client.errors import ClientError from nilmdb.client.errors import ClientError
import contextlib
import numpy
def layout_to_dtype(layout): def layout_to_dtype(layout):
ltype = layout.split('_')[0] ltype = layout.split('_')[0]
@ -151,7 +151,7 @@ class StreamInserterNumpy(nilmdb.client.client.StreamInserter):
def insert(self, array): def insert(self, array):
"""Insert Numpy data, which must match the layout type.""" """Insert Numpy data, which must match the layout type."""
if type(array) != numpy.ndarray: if not isinstance(array, numpy.ndarray):
array = numpy.array(array) array = numpy.array(array)
if array.ndim == 1: if array.ndim == 1:
# Already a structured array; just verify the type # Already a structured array; just verify the type
@ -251,7 +251,7 @@ class StreamInserterNumpy(nilmdb.client.client.StreamInserter):
# If we have no endpoints, or equal endpoints, it's OK as long # If we have no endpoints, or equal endpoints, it's OK as long
# as there's no data to send # as there's no data to send
if (start_ts is None or end_ts is None) or (start_ts == end_ts): if (start_ts is None or end_ts is None) or (start_ts == end_ts):
if len(array) == 0: if not array:
return return
raise ClientError("have data to send, but invalid start/end times") raise ClientError("have data to send, but invalid start/end times")

View File

@ -1,18 +1,17 @@
"""Command line client functionality""" """Command line client functionality"""
import nilmdb.client
from nilmdb.utils.printf import fprintf, sprintf
import datetime_tz
import nilmdb.utils.time
import sys
import os import os
import sys
import signal
import argparse import argparse
from argparse import ArgumentDefaultsHelpFormatter as def_form from argparse import ArgumentDefaultsHelpFormatter as def_form
import signal
import nilmdb.client
from nilmdb.utils.printf import fprintf, sprintf
import nilmdb.utils.time
import argcomplete import argcomplete
import datetime_tz
# Valid subcommands. Defined in separate files just to break # Valid subcommands. Defined in separate files just to break
# things up -- they're still called with Cmdline as self. # things up -- they're still called with Cmdline as self.
@ -39,7 +38,7 @@ class JimArgumentParser(argparse.ArgumentParser):
self.exit(2, sprintf("error: %s\n", message)) self.exit(2, sprintf("error: %s\n", message))
class Complete(object): class Complete():
# Completion helpers, for using argcomplete (see # Completion helpers, for using argcomplete (see
# extras/nilmtool-bash-completion.sh) # extras/nilmtool-bash-completion.sh)
def escape(self, s): def escape(self, s):
@ -86,7 +85,7 @@ class Complete(object):
return results return results
class Cmdline(object): class Cmdline():
def __init__(self, argv=None): def __init__(self, argv=None):
self.argv = argv or sys.argv[1:] self.argv = argv or sys.argv[1:]

View File

@ -1,7 +1,7 @@
import nilmdb.client
from argparse import RawDescriptionHelpFormatter as raw_form from argparse import RawDescriptionHelpFormatter as raw_form
import nilmdb.client
def setup(self, sub): def setup(self, sub):
cmd = sub.add_parser("create", help="Create a new stream", cmd = sub.add_parser("create", help="Create a new stream",

View File

@ -1,9 +1,10 @@
from nilmdb.utils.printf import printf
import nilmdb.client
import fnmatch import fnmatch
from argparse import ArgumentDefaultsHelpFormatter as def_form from argparse import ArgumentDefaultsHelpFormatter as def_form
from nilmdb.utils.printf import printf
import nilmdb.client
def setup(self, sub): def setup(self, sub):
cmd = sub.add_parser("destroy", help="Delete a stream and all data", cmd = sub.add_parser("destroy", help="Delete a stream and all data",

View File

@ -1,6 +1,7 @@
import sys
from nilmdb.utils.printf import printf from nilmdb.utils.printf import printf
import nilmdb.client import nilmdb.client
import sys
def setup(self, sub): def setup(self, sub):

View File

@ -1,9 +1,9 @@
from argparse import ArgumentDefaultsHelpFormatter as def_form
import nilmdb.client import nilmdb.client
from nilmdb.utils.printf import printf from nilmdb.utils.printf import printf
from nilmdb.utils import human_size from nilmdb.utils import human_size
from argparse import ArgumentDefaultsHelpFormatter as def_form
def setup(self, sub): def setup(self, sub):
cmd = sub.add_parser("info", help="Server information", cmd = sub.add_parser("info", help="Server information",

View File

@ -1,10 +1,10 @@
import sys
from nilmdb.utils.printf import printf from nilmdb.utils.printf import printf
import nilmdb.client import nilmdb.client
import nilmdb.utils.timestamper as timestamper import nilmdb.utils.timestamper as timestamper
import nilmdb.utils.time import nilmdb.utils.time
import sys
def setup(self, sub): def setup(self, sub):
cmd = sub.add_parser("insert", help="Insert data", cmd = sub.add_parser("insert", help="Insert data",

View File

@ -1,9 +1,9 @@
from argparse import ArgumentDefaultsHelpFormatter as def_form
from nilmdb.utils.printf import printf from nilmdb.utils.printf import printf
import nilmdb.utils.time import nilmdb.utils.time
from nilmdb.utils.interval import Interval from nilmdb.utils.interval import Interval
from argparse import ArgumentDefaultsHelpFormatter as def_form
def setup(self, sub): def setup(self, sub):
cmd = sub.add_parser("intervals", help="List intervals", cmd = sub.add_parser("intervals", help="List intervals",

View File

@ -1,9 +1,9 @@
from nilmdb.utils.printf import printf
import nilmdb.utils.time
import fnmatch import fnmatch
from argparse import ArgumentDefaultsHelpFormatter as def_form from argparse import ArgumentDefaultsHelpFormatter as def_form
from nilmdb.utils.printf import printf
import nilmdb.utils.time
def setup(self, sub): def setup(self, sub):
cmd = sub.add_parser("list", help="List streams", cmd = sub.add_parser("list", help="List streams",

View File

@ -1,6 +1,7 @@
import fnmatch
from nilmdb.utils.printf import printf from nilmdb.utils.printf import printf
import nilmdb.client import nilmdb.client
import fnmatch
def setup(self, sub): def setup(self, sub):

View File

@ -1,7 +1,7 @@
import nilmdb.client
from argparse import ArgumentDefaultsHelpFormatter as def_form from argparse import ArgumentDefaultsHelpFormatter as def_form
import nilmdb.client
def setup(self, sub): def setup(self, sub):
cmd = sub.add_parser("rename", help="Rename a stream", cmd = sub.add_parser("rename", help="Rename a stream",

View File

@ -1,11 +1,13 @@
#!/usr/bin/python #!/usr/bin/python
import nilmdb.server
import argparse
import os import os
import socket
import cherrypy
import sys import sys
import socket
import argparse
import cherrypy
import nilmdb.server
def main(): def main():

View File

@ -1,19 +1,15 @@
# Fixed record size bulk data storage # Fixed record size bulk data storage
# Need absolute_import so that "import nilmdb" won't pull in import os
# nilmdb.py, but will pull the parent nilmdb module instead. import re
import sys
import pickle
import tempfile
from nilmdb.utils.printf import sprintf from nilmdb.utils.printf import sprintf
from nilmdb.utils.time import timestamp_to_string from nilmdb.utils.time import timestamp_to_string
import nilmdb.utils import nilmdb.utils
import os
import pickle
import re
import sys
import tempfile
import nilmdb.utils.lock import nilmdb.utils.lock
from . import rocket from . import rocket
@ -24,7 +20,7 @@ fd_cache_size = 8
@nilmdb.utils.must_close(wrap_verify=False) @nilmdb.utils.must_close(wrap_verify=False)
class BulkData(object): class BulkData():
def __init__(self, basepath, **kwargs): def __init__(self, basepath, **kwargs):
if isinstance(basepath, str): if isinstance(basepath, str):
self.basepath = self._encode_filename(basepath) self.basepath = self._encode_filename(basepath)
@ -93,7 +89,7 @@ class BulkData(object):
# Look for any files in subdirectories. Fully empty subdirectories # Look for any files in subdirectories. Fully empty subdirectories
# are OK; they might be there during a rename # are OK; they might be there during a rename
for (root, dirs, files) in os.walk(ospath): for (root, dirs, files) in os.walk(ospath):
if len(files): if files:
raise ValueError( raise ValueError(
"non-empty subdirs of this path already exist") "non-empty subdirs of this path already exist")
@ -265,7 +261,7 @@ class BulkData(object):
@nilmdb.utils.must_close(wrap_verify=False) @nilmdb.utils.must_close(wrap_verify=False)
class Table(object): class Table():
"""Tools to help access a single table (data at a specific OS path).""" """Tools to help access a single table (data at a specific OS path)."""
# See design.md for design details # See design.md for design details

View File

@ -7,8 +7,9 @@ Object that represents a NILM database file.
Manages both the SQL database and the table storage backend. Manages both the SQL database and the table storage backend.
""" """
# Need absolute_import so that "import nilmdb" won't pull in import os
# nilmdb.py, but will pull the parent nilmdb module instead. import errno
import sqlite3
import nilmdb.utils import nilmdb.utils
from nilmdb.utils.printf import printf from nilmdb.utils.printf import printf
@ -20,10 +21,6 @@ from nilmdb.server.interval import Interval, DBInterval, IntervalSet
from nilmdb.server import bulkdata from nilmdb.server import bulkdata
from nilmdb.server.errors import NilmDBError, StreamError, OverlapError from nilmdb.server.errors import NilmDBError, StreamError, OverlapError
import sqlite3
import os
import errno
# Note about performance and transactions: # Note about performance and transactions:
# #
# Committing a transaction in the default sync mode (PRAGMA synchronous=FULL) # Committing a transaction in the default sync mode (PRAGMA synchronous=FULL)
@ -80,7 +77,7 @@ _sql_schema_updates = {
@nilmdb.utils.must_close() @nilmdb.utils.must_close()
class NilmDB(object): class NilmDB():
verbose = 0 verbose = 0
def __init__(self, basepath, def __init__(self, basepath,
@ -462,7 +459,7 @@ class NilmDB(object):
# Verify that no intervals are present, and clear the cache # Verify that no intervals are present, and clear the cache
iset = self._get_intervals(stream_id) iset = self._get_intervals(stream_id)
if len(iset): if iset:
raise NilmDBError("all intervals must be removed before " raise NilmDBError("all intervals must be removed before "
"destroying a stream") "destroying a stream")
self._get_intervals.cache_remove(self, stream_id) self._get_intervals.cache_remove(self, stream_id)

View File

@ -1,20 +1,18 @@
"""CherryPy-based server for accessing NILM database via HTTP""" """CherryPy-based server for accessing NILM database via HTTP"""
# Need absolute_import so that "import nilmdb" won't pull in import os
# nilmdb.py, but will pull the nilmdb module instead. import json
import socket
import traceback
import psutil
import cherrypy
import nilmdb.server import nilmdb.server
from nilmdb.utils.printf import sprintf from nilmdb.utils.printf import sprintf
from nilmdb.server.errors import NilmDBError from nilmdb.server.errors import NilmDBError
from nilmdb.utils.time import string_to_timestamp from nilmdb.utils.time import string_to_timestamp
import cherrypy
import os
import socket
import json
import psutil
import traceback
from nilmdb.server.serverutil import ( from nilmdb.server.serverutil import (
chunked_response, chunked_response,
response_type, response_type,
@ -31,7 +29,7 @@ from nilmdb.server.serverutil import (
cherrypy.tools.CORS_allow = cherrypy.Tool('on_start_resource', CORS_allow) cherrypy.tools.CORS_allow = cherrypy.Tool('on_start_resource', CORS_allow)
class NilmApp(object): class NilmApp():
def __init__(self, db): def __init__(self, db):
self.db = db self.db = db
@ -39,10 +37,6 @@ class NilmApp(object):
# CherryPy apps # CherryPy apps
class Root(NilmApp): class Root(NilmApp):
"""Root application for NILM database""" """Root application for NILM database"""
def __init__(self, db):
super(Root, self).__init__(db)
# / # /
@cherrypy.expose @cherrypy.expose
def index(self): def index(self):
@ -190,9 +184,7 @@ class Stream(NilmApp):
except TypeError as e: except TypeError as e:
raise NilmDBError("can't parse 'data' parameter: " + str(e)) raise NilmDBError("can't parse 'data' parameter: " + str(e))
for key in data: for key in data:
if not (isinstance(data[key], str) or if not isinstance(data[key], (str, float, int)):
isinstance(data[key], float) or
isinstance(data[key], int)):
raise NilmDBError("metadata values must be a string or number") raise NilmDBError("metadata values must be a string or number")
function(path, data) function(path, data)
@ -400,7 +392,7 @@ class Stream(NilmApp):
return content(start, end) return content(start, end)
class Exiter(object): class Exiter():
"""App that exits the server, for testing""" """App that exits the server, for testing"""
@cherrypy.expose @cherrypy.expose
def index(self): def index(self):
@ -414,7 +406,7 @@ class Exiter(object):
index._cp_config = {'response.stream': True} index._cp_config = {'response.stream': True}
class Server(object): class Server():
def __init__(self, db, host='127.0.0.1', port=8080, def __init__(self, db, host='127.0.0.1', port=8080,
stoppable=False, # whether /exit URL exists stoppable=False, # whether /exit URL exists
fast_shutdown=False, # don't wait for clients to disconn. fast_shutdown=False, # don't wait for clients to disconn.

View File

@ -1,13 +1,14 @@
"""Miscellaneous decorators and other helpers for running a CherryPy """Miscellaneous decorators and other helpers for running a CherryPy
server""" server"""
import cherrypy
import sys
import os import os
import decorator import sys
import json import json
import decorator
import functools import functools
import cherrypy
# Helper to parse parameters into booleans # Helper to parse parameters into booleans
def bool_param(s): def bool_param(s):
@ -130,11 +131,12 @@ def json_error_page(status, message, traceback, version,
"""Return a custom error page in JSON so the client can parse it""" """Return a custom error page in JSON so the client can parse it"""
errordata = {"status": status, errordata = {"status": status,
"message": message, "message": message,
"version": version,
"traceback": traceback} "traceback": traceback}
# Don't send a traceback if the error was 400-499 (client's fault) # Don't send a traceback if the error was 400-499 (client's fault)
code = int(status.split()[0]) code = int(status.split()[0])
if not force_traceback: if not force_traceback:
if code >= 400 and code <= 499: if 400 <= code <= 499:
errordata["traceback"] = "" errordata["traceback"] = ""
# Override the response type, which was previously set to text/html # Override the response type, which was previously set to text/html
cherrypy.serving.response.headers['Content-Type'] = ( cherrypy.serving.response.headers['Content-Type'] = (

View File

@ -7,15 +7,15 @@ def human_size(num):
"""Human friendly file size""" """Human friendly file size"""
unit_list = list(zip(['bytes', 'kiB', 'MiB', 'GiB', 'TiB'], unit_list = list(zip(['bytes', 'kiB', 'MiB', 'GiB', 'TiB'],
[0, 0, 1, 2, 2])) [0, 0, 1, 2, 2]))
if num > 1: if num == 0:
exponent = min(int(log(num, 1024)), len(unit_list) - 1) return '0 bytes'
quotient = float(num) / 1024**exponent if num == 1:
unit, num_decimals = unit_list[exponent]
format_string = '{:.%sf} {}' % (num_decimals)
return format_string.format(quotient, unit)
elif num == 1:
return '1 byte' return '1 byte'
return '0 bytes' exponent = min(int(log(num, 1024)), len(unit_list) - 1)
quotient = float(num) / 1024**exponent
unit, num_decimals = unit_list[exponent]
format_string = '{:.%sf} {}' % (num_decimals)
return format_string.format(quotient, unit)
def du(path): def du(path):

View File

@ -19,8 +19,8 @@ def imerge(*iterables):
h_append = h.append h_append = h.append
for it in map(iter, iterables): for it in map(iter, iterables):
try: try:
next = it.__next__ nexter = it.__next__
h_append([next(), next]) h_append([nexter(), nexter])
except _Stop: except _Stop:
pass pass
heapq.heapify(h) heapq.heapify(h)
@ -28,9 +28,9 @@ def imerge(*iterables):
while 1: while 1:
try: try:
while 1: while 1:
v, next = s = h[0] # raises IndexError when h is empty v, nexter = s = h[0] # raises IndexError when h is empty
yield v yield v
s[0] = next() # raises StopIteration when exhausted s[0] = nexter() # raises StopIteration when exhausted
siftup(h, 0) # restore heap condition siftup(h, 0) # restore heap condition
except _Stop: except _Stop:
heappop(h) # remove empty iterator heappop(h) # remove empty iterator

View File

@ -54,7 +54,7 @@ def lru_cache(size=10, onremove=None, keys=slice(None)):
if key in cache: if key in cache:
evict(cache.pop(key)) evict(cache.pop(key))
else: else:
if len(cache) > 0: if cache:
if len(args) != len(next(iter(cache.keys()))): if len(args) != len(next(iter(cache.keys()))):
raise KeyError("trying to remove from LRU cache, but " raise KeyError("trying to remove from LRU cache, but "
"number of arguments doesn't match the " "number of arguments doesn't match the "

View File

@ -1,7 +1,7 @@
from nilmdb.utils.printf import fprintf
import sys import sys
import inspect import inspect
import decorator import decorator
from nilmdb.utils.printf import fprintf
def must_close(errorfile=sys.stderr, wrap_verify=False): def must_close(errorfile=sys.stderr, wrap_verify=False):

View File

@ -47,7 +47,7 @@ def serializer_proxy(obj_or_type):
The proxied requests, including instantiation, are performed in a The proxied requests, including instantiation, are performed in a
single thread and serialized between caller threads. single thread and serialized between caller threads.
""" """
class SerializerCallProxy(object): class SerializerCallProxy():
def __init__(self, call_queue, func, objectproxy): def __init__(self, call_queue, func, objectproxy):
self.call_queue = call_queue self.call_queue = call_queue
self.func = func self.func = func
@ -64,10 +64,10 @@ def serializer_proxy(obj_or_type):
else: else:
raise exc_info[1].with_traceback(exc_info[2]) raise exc_info[1].with_traceback(exc_info[2])
class SerializerObjectProxy(object): class SerializerObjectProxy():
def __init__(self, obj_or_type, *args, **kwargs): def __init__(self, obj_or_type, *args, **kwargs):
self.__object = obj_or_type self.__object = obj_or_type
if type(obj_or_type) == type: if isinstance(obj_or_type, type):
classname = obj_or_type.__name__ classname = obj_or_type.__name__
else: else:
classname = obj_or_type.__class__.__name__ classname = obj_or_type.__class__.__name__
@ -118,7 +118,7 @@ def serializer_proxy(obj_or_type):
to serializer_proxy. Otherwise, pass the call through.""" to serializer_proxy. Otherwise, pass the call through."""
ret = SerializerCallProxy(self.__call_queue, ret = SerializerCallProxy(self.__call_queue,
self.__object, self)(*args, **kwargs) self.__object, self)(*args, **kwargs)
if type(self.__object) == type: if isinstance(self.__object, type):
# Instantiation # Instantiation
self.__object = ret self.__object = ret
return self return self

View File

@ -1,5 +1,5 @@
from nilmdb.utils.printf import sprintf
import threading import threading
from nilmdb.utils.printf import sprintf
def verify_proxy(obj_or_type, check_thread=True, def verify_proxy(obj_or_type, check_thread=True,
@ -16,10 +16,10 @@ def verify_proxy(obj_or_type, check_thread=True,
check_concurrent = True # Fail if two functions are concurrently check_concurrent = True # Fail if two functions are concurrently
# run through this proxy # run through this proxy
""" """
class Namespace(object): class Namespace():
pass pass
class VerifyCallProxy(object): class VerifyCallProxy():
def __init__(self, func, parent_namespace): def __init__(self, func, parent_namespace):
self.func = func self.func = func
self.parent_namespace = parent_namespace self.parent_namespace = parent_namespace
@ -63,7 +63,7 @@ def verify_proxy(obj_or_type, check_thread=True,
p.concur_lock.release() p.concur_lock.release()
return ret return ret
class VerifyObjectProxy(object): class VerifyObjectProxy():
def __init__(self, obj_or_type, *args, **kwargs): def __init__(self, obj_or_type, *args, **kwargs):
p = Namespace() p = Namespace()
self.__ns = p self.__ns = p
@ -73,7 +73,7 @@ def verify_proxy(obj_or_type, check_thread=True,
p.concur_tname = None p.concur_tname = None
p.concur_callee = None p.concur_callee = None
self.__obj = obj_or_type self.__obj = obj_or_type
if type(obj_or_type) in (type, type): if isinstance(obj_or_type, type):
p.classname = self.__obj.__name__ p.classname = self.__obj.__name__
else: else:
p.classname = self.__obj.__class__.__name__ p.classname = self.__obj.__class__.__name__
@ -88,7 +88,7 @@ def verify_proxy(obj_or_type, check_thread=True,
"""Call this to instantiate the type, if a type was passed """Call this to instantiate the type, if a type was passed
to verify_proxy. Otherwise, pass the call through.""" to verify_proxy. Otherwise, pass the call through."""
ret = VerifyCallProxy(self.__obj, self.__ns)(*args, **kwargs) ret = VerifyCallProxy(self.__obj, self.__ns)(*args, **kwargs)
if type(self.__obj) in (type, type): if isinstance(self.__obj, type):
# Instantiation # Instantiation
self.__obj = ret self.__obj = ret
return self return self

View File

@ -1,6 +1,6 @@
import datetime_tz
import re import re
import time import time
import datetime_tz
# Range # Range
min_timestamp = (-2**63) min_timestamp = (-2**63)
@ -10,15 +10,15 @@ max_timestamp = (2**63 - 1)
epsilon = 1 epsilon = 1
def string_to_timestamp(str): def string_to_timestamp(string):
"""Convert a string that represents an integer number of microseconds """Convert a string that represents an integer number of microseconds
since epoch.""" since epoch."""
try: try:
# Parse a string like "1234567890123456" and return an integer # Parse a string like "1234567890123456" and return an integer
return int(str) return int(string)
except ValueError: except ValueError:
# Try parsing as a float, in case it's "1234567890123456.0" # Try parsing as a float, in case it's "1234567890123456.0"
return int(round(float(str))) return int(round(float(string)))
def timestamp_to_string(timestamp): def timestamp_to_string(timestamp):
@ -108,9 +108,9 @@ def parse_time(toparse):
try: try:
val = float(toparse) val = float(toparse)
# range is from about year 2001 - 2128 # range is from about year 2001 - 2128
if val > 1e9 and val < 5e9: if 1e9 < val < 5e9:
return unix_to_timestamp(val) return unix_to_timestamp(val)
if val > 1e15 and val < 5e15: if 1e15 < val < 5e15:
return val return val
except ValueError: except ValueError:
pass pass

View File

@ -4,7 +4,7 @@ from nilmdb.utils.printf import sprintf
import nilmdb.utils.time import nilmdb.utils.time
class Timestamper(object): class Timestamper():
"""A file-like object that adds timestamps to lines of an input file.""" """A file-like object that adds timestamps to lines of an input file."""
def __init__(self, infile, ts_iter): def __init__(self, infile, ts_iter):
"""file: filename, or another file-like object """file: filename, or another file-like object

View File

@ -47,5 +47,10 @@ tag_prefix=nilmdb-
parentdir_prefix=nilmdb- parentdir_prefix=nilmdb-
[flake8] [flake8]
exclude=_version.py,fsck.py,nilmdb_fsck.py
extend-ignore=E731 extend-ignore=E731
per-file-ignores=__init__.py:F401,E402 serializer.py:E722 mustclose.py:E722 per-file-ignores=__init__.py:F401,E402 serializer.py:E722 mustclose.py:E722
[pylint]
ignore=_version.py,fsck.py,nilmdb_fsck.py
disable=C0103,C0111,R0913,R0914