diff options
31 files changed, 242 insertions, 145 deletions
diff --git a/check_coding_style.sh b/check_coding_style.sh new file mode 100755 index 00000000..5b38e003 --- /dev/null +++ b/check_coding_style.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +autopep8 -i -r -a -a . +if [[ -n "$(git status -s)" ]]; then + echo "autopep8 yielded the following changes:" + git status -s + git --no-pager diff + exit 1 +fi + +autoflake -i -r --remove-all-unused-imports --remove-unused-variables . +if [[ -n "$(git status -s)" ]]; then + echo "autoflake yielded the following changes:" + git status -s + git --no-pager diff + exit 1 +fi + +echo "Coding style seems to be ok." +exit 0 diff --git a/examples/test_context.py b/examples/test_context.py index f3da83cb..7c0386c1 100644 --- a/examples/test_context.py +++ b/examples/test_context.py @@ -1,6 +1,7 @@ import requests from libpathod import test + def test_simple(): """ Testing the requests module with diff --git a/examples/test_setup.py b/examples/test_setup.py index 2918a4dd..f05a715e 100644 --- a/examples/test_setup.py +++ b/examples/test_setup.py @@ -1,12 +1,14 @@ import requests from libpathod import test + class Test: """ Testing the requests module with a pathod instance started for each test. """ + def setUp(self): self.d = test.Daemon() diff --git a/examples/test_setupall.py b/examples/test_setupall.py index c8948971..6e91f0de 100644 --- a/examples/test_setupall.py +++ b/examples/test_setupall.py @@ -1,10 +1,11 @@ import requests from libpathod import test + class Test: """ - Testing the requests module with - a single pathod instance started + Testing the requests module with + a single pathod instance started for the test suite. """ @classmethod diff --git a/libpathod/__init__.py b/libpathod/__init__.py index 8b137891..e69de29b 100644 --- a/libpathod/__init__.py +++ b/libpathod/__init__.py @@ -1 +0,0 @@ - diff --git a/libpathod/app.py b/libpathod/app.py index aec3d95f..20225ff7 100644 --- a/libpathod/app.py +++ b/libpathod/app.py @@ -138,7 +138,7 @@ def make_app(noapi, debug): r = language.parse_requests(spec)[0] else: r = language.parse_response(spec) - except language.ParseException, v: + except language.ParseException as v: args["syntaxerror"] = str(v) args["marked"] = v.marked() return render(template, False, **args) diff --git a/libpathod/cmdline.py b/libpathod/cmdline.py index cce02d99..d75e4330 100644 --- a/libpathod/cmdline.py +++ b/libpathod/cmdline.py @@ -163,16 +163,22 @@ def args_pathoc(argv, stdout=sys.stdout, stderr=sys.stderr): try: args.ignorecodes = [int(i) for i in args.ignorecodes.split(",") if i] except ValueError: - return parser.error("Invalid return code specification: %s"%args.ignorecodes) + return parser.error( + "Invalid return code specification: %s" % + args.ignorecodes) if args.connect_to: parts = args.connect_to.split(":") if len(parts) != 2: - return parser.error("Invalid CONNECT specification: %s"%args.connect_to) + return parser.error( + "Invalid CONNECT specification: %s" % + args.connect_to) try: parts[1] = int(parts[1]) except ValueError: - return parser.error("Invalid CONNECT specification: %s"%args.connect_to) + return parser.error( + "Invalid CONNECT specification: %s" % + args.connect_to) args.connect_to = parts else: args.connect_to = None @@ -184,15 +190,15 @@ def args_pathoc(argv, stdout=sys.stdout, stderr=sys.stderr): r = data try: reqs.extend(language.parse_requests(r)) - except language.ParseException, v: - print >> stderr, "Error parsing request spec: %s"%v.msg + except language.ParseException as v: + print >> stderr, "Error parsing request spec: %s" % v.msg print >> stderr, v.marked() sys.exit(1) args.requests = reqs return args -def go_pathoc(): # pragma: nocover +def go_pathoc(): # pragma: nocover args = args_pathoc(sys.argv) pathoc.main(args) @@ -254,9 +260,11 @@ def args_pathod(argv, stdout=sys.stdout, stderr=sys.stderr): help="Connection timeout" ) parser.add_argument( - "--limit-size", dest='sizelimit', default=None, type=str, - help='Size limit of served responses. Understands size suffixes, i.e. 100k.' - ) + "--limit-size", + dest='sizelimit', + default=None, + type=str, + help='Size limit of served responses. Understands size suffixes, i.e. 100k.') parser.add_argument( "--noapi", dest='noapi', default=False, action="store_true", help='Disable API.' @@ -270,9 +278,11 @@ def args_pathod(argv, stdout=sys.stdout, stderr=sys.stderr): help='Disable both web interface and API.' ) parser.add_argument( - "--nocraft", dest='nocraft', default=False, action="store_true", - help='Disable response crafting. If anchors are specified, they still work.' - ) + "--nocraft", + dest='nocraft', + default=False, + action="store_true", + help='Disable response crafting. If anchors are specified, they still work.') parser.add_argument( "--webdebug", dest='webdebug', default=False, action="store_true", help='Debugging mode for the web app (dev only).' @@ -286,9 +296,12 @@ def args_pathod(argv, stdout=sys.stdout, stderr=sys.stderr): help='Run in HTTPS mode.' ) group.add_argument( - "--cn", dest="cn", type=str, default=None, - help="CN for generated SSL certs. Default: %s"%pathod.DEFAULT_CERT_DOMAIN - ) + "--cn", + dest="cn", + type=str, + default=None, + help="CN for generated SSL certs. Default: %s" % + pathod.DEFAULT_CERT_DOMAIN) group.add_argument( "-C", dest='ssl_not_after_connect', default=False, action="store_true", help="Don't expect SSL after a CONNECT request." @@ -358,7 +371,9 @@ def args_pathod(argv, stdout=sys.stdout, stderr=sys.stderr): parts = ["*", parts[0]] parts[1] = os.path.expanduser(parts[1]) if not os.path.isfile(parts[1]): - return parser.error("Certificate file does not exist: %s"%parts[1]) + return parser.error( + "Certificate file does not exist: %s" % + parts[1]) certs.append(parts) args.ssl_certs = certs @@ -366,7 +381,7 @@ def args_pathod(argv, stdout=sys.stdout, stderr=sys.stderr): for i in args.anchors: parts = utils.parse_anchor_spec(i) if not parts: - return parser.error("Invalid anchor specification: %s"%i) + return parser.error("Invalid anchor specification: %s" % i) alst.append(parts) args.anchors = alst @@ -374,7 +389,7 @@ def args_pathod(argv, stdout=sys.stdout, stderr=sys.stderr): if args.sizelimit: try: sizelimit = utils.parse_size(args.sizelimit) - except ValueError, v: + except ValueError as v: return parser.error(v) args.sizelimit = sizelimit @@ -385,8 +400,8 @@ def args_pathod(argv, stdout=sys.stdout, stderr=sys.stderr): spec = data try: req = language.parse_response(spec) - except language.ParseException, v: - print >> stderr, "Error parsing anchor spec: %s"%v.msg + except language.ParseException as v: + print >> stderr, "Error parsing anchor spec: %s" % v.msg print >> stderr, v.marked() sys.exit(1) try: @@ -398,6 +413,6 @@ def args_pathod(argv, stdout=sys.stdout, stderr=sys.stderr): return args -def go_pathod(): # pragma: nocover +def go_pathod(): # pragma: nocover args = args_pathod(sys.argv) pathod.main(args) diff --git a/libpathod/language/__init__.py b/libpathod/language/__init__.py index 2444d532..c3d34c2e 100644 --- a/libpathod/language/__init__.py +++ b/libpathod/language/__init__.py @@ -18,7 +18,7 @@ def parse_response(s): raise exceptions.ParseException("Spec must be valid ASCII.", 0, 0) try: return http.Response.expr().parseString(s, parseAll=True)[0] - except pp.ParseException, v: + except pp.ParseException as v: raise exceptions.ParseException(v.msg, v.line, v.col) @@ -39,7 +39,7 @@ def parse_requests(s): ] ) ).parseString(s, parseAll=True) - except pp.ParseException, v: + except pp.ParseException as v: raise exceptions.ParseException(v.msg, v.line, v.col) expanded = [] for i in reqs: @@ -67,8 +67,7 @@ def serve(msg, fp, settings): vals = msg.values(settings) vals.reverse() - actions = msg.actions[:] - actions.sort() + actions = sorted(msg.actions[:]) actions.reverse() actions = [i.intermediate(settings) for i in actions] diff --git a/libpathod/language/actions.py b/libpathod/language/actions.py index f5b828fe..40adb4ea 100644 --- a/libpathod/language/actions.py +++ b/libpathod/language/actions.py @@ -13,6 +13,7 @@ class _Action(base.Token): actions have one thing in common: an offset that specifies where the action should take place. """ + def __init__(self, offset): self.offset = offset @@ -36,11 +37,11 @@ class _Action(base.Token): return self.spec() @abc.abstractmethod - def spec(self): # pragma: no cover + def spec(self): # pragma: no cover pass @abc.abstractmethod - def intermediate(self, settings): # pragma: no cover + def intermediate(self, settings): # pragma: no cover pass @@ -65,7 +66,7 @@ class PauseAt(_Action): return e.setParseAction(lambda x: klass(*x)) def spec(self): - return "p%s,%s"%(self.offset, self.seconds) + return "p%s,%s" % (self.offset, self.seconds) def intermediate(self, settings): return (self.offset, "pause", self.seconds) @@ -85,7 +86,7 @@ class DisconnectAt(_Action): return e.setParseAction(lambda x: klass(*x)) def spec(self): - return "d%s"%self.offset + return "d%s" % self.offset def intermediate(self, settings): return (self.offset, "disconnect") @@ -110,7 +111,7 @@ class InjectAt(_Action): return e.setParseAction(lambda x: klass(*x)) def spec(self): - return "i%s,%s"%(self.offset, self.value.spec()) + return "i%s,%s" % (self.offset, self.value.spec()) def intermediate(self, settings): return ( diff --git a/libpathod/language/base.py b/libpathod/language/base.py index a957442e..4475d15b 100644 --- a/libpathod/language/base.py +++ b/libpathod/language/base.py @@ -5,6 +5,7 @@ import pyparsing as pp from .. import utils from . import generators, exceptions +from functools import reduce class Settings: @@ -23,7 +24,6 @@ class Settings: self.is_client = is_client - Sep = pp.Optional(pp.Literal(":")).suppress() @@ -64,14 +64,14 @@ class Token(object): __metaclass__ = abc.ABCMeta @classmethod - def expr(klass): # pragma: no cover + def expr(klass): # pragma: no cover """ A parse expression. """ return None @abc.abstractmethod - def spec(self): # pragma: no cover + def spec(self): # pragma: no cover """ A parseable specification for this token. """ @@ -176,11 +176,11 @@ class TokValueGenerate(Token): return e.setParseAction(lambda x: klass(*x)) def spec(self): - s = "@%s"%self.usize + s = "@%s" % self.usize if self.unit != "b": s += self.unit if self.datatype != "bytes": - s += ",%s"%self.datatype + s += ",%s" % self.datatype return s @@ -214,7 +214,7 @@ class TokValueFile(Token): return generators.FileGenerator(s) def spec(self): - return "<'%s'"%self.path.encode("string_escape") + return "<'%s'" % self.path.encode("string_escape") TokValue = pp.MatchFirst( @@ -250,7 +250,8 @@ class _Component(Token): A value component of the primary specification of an message. Components produce byte values desribe the bytes of the message. """ - def values(self, settings): # pragma: no cover + + def values(self, settings): # pragma: no cover """ A sequence of values, which can either be strings or generators. """ @@ -268,6 +269,7 @@ class KeyValue(_Component): A key/value pair. klass.preamble: leader """ + def __init__(self, key, value): self.key, self.value = key, value @@ -280,7 +282,7 @@ class KeyValue(_Component): return e.setParseAction(lambda x: klass(*x)) def spec(self): - return "%s%s=%s"%(self.preamble, self.key.spec(), self.value.spec()) + return "%s%s=%s" % (self.preamble, self.key.spec(), self.value.spec()) def freeze(self, settings): return self.__class__( @@ -292,6 +294,7 @@ class CaselessLiteral(_Component): """ A caseless token that can take only one value. """ + def __init__(self, value): self.value = value @@ -317,6 +320,7 @@ class OptionsOrValue(_Component): """ preamble = "" options = [] + def __init__(self, value): # If it's a string, we were passed one of the options, so we lower-case # it to be canonical. The user can specify a different case by using a @@ -350,7 +354,7 @@ class OptionsOrValue(_Component): s = self.value.spec() if s[1:-1].lower() in self.options: s = s[1:-1].lower() - return "%s%s"%(self.preamble, s) + return "%s%s" % (self.preamble, s) def freeze(self, settings): return self.__class__(self.value.freeze(settings)) @@ -368,7 +372,7 @@ class Integer(_Component): ]) if outofbounds: raise exceptions.ParseException( - "Integer value must be between %s and %s."%self.bounds, + "Integer value must be between %s and %s." % self.bounds, 0, 0 ) self.value = str(value) @@ -384,7 +388,7 @@ class Integer(_Component): return self.value def spec(self): - return "%s%s"%(self.preamble, self.value) + return "%s%s" % (self.preamble, self.value) def freeze(self, settings): return self @@ -410,7 +414,7 @@ class Value(_Component): return [self.value.get_generator(settings)] def spec(self): - return "%s%s"%(self.preamble, self.value.spec()) + return "%s%s" % (self.preamble, self.value.spec()) def freeze(self, settings): return self.__class__(self.value.freeze(settings)) @@ -433,7 +437,7 @@ class FixedLengthValue(Value): # This check will fail if we know the length upfront if lenguess is not None and lenguess != self.length: raise exceptions.RenderError( - "Invalid value length: '%s' is %s bytes, should be %s."%( + "Invalid value length: '%s' is %s bytes, should be %s." % ( self.spec(), lenguess, self.length @@ -447,7 +451,7 @@ class FixedLengthValue(Value): # file inputs if l != self.length: raise exceptions.RenderError( - "Invalid value length: '%s' is %s bytes, should be %s."%( + "Invalid value length: '%s' is %s bytes, should be %s." % ( self.spec(), l, self.length @@ -481,7 +485,7 @@ class Boolean(_Component): return e.setParseAction(parse) def spec(self): - return "%s%s"%("-" if not self.value else "", self.name) + return "%s%s" % ("-" if not self.value else "", self.name) class IntField(_Component): @@ -497,7 +501,7 @@ class IntField(_Component): self.value = self.names.get(value, value) if self.value > self.max: raise exceptions.ParseException( - "Value can't exceed %s"%self.max, 0, 0 + "Value can't exceed %s" % self.max, 0, 0 ) @classmethod @@ -514,4 +518,4 @@ class IntField(_Component): return [str(self.value)] def spec(self): - return "%s%s"%(self.preamble, self.origvalue) + return "%s%s" % (self.preamble, self.origvalue) diff --git a/libpathod/language/exceptions.py b/libpathod/language/exceptions.py index c9d0b2f0..a65c7936 100644 --- a/libpathod/language/exceptions.py +++ b/libpathod/language/exceptions.py @@ -15,7 +15,7 @@ class ParseException(Exception): self.col = col def marked(self): - return "%s\n%s"%(self.s, " " * (self.col - 1) + "^") + return "%s\n%s" % (self.s, " " * (self.col - 1) + "^") def __str__(self): - return "%s at char %s"%(self.msg, self.col) + return "%s at char %s" % (self.msg, self.col) diff --git a/libpathod/language/generators.py b/libpathod/language/generators.py index 07b0be06..0da0cb4d 100644 --- a/libpathod/language/generators.py +++ b/libpathod/language/generators.py @@ -24,6 +24,7 @@ class TransformGenerator: gen: A generator to wrap transform: A function (offset, data) -> transformed """ + def __init__(self, gen, transform): self.gen = gen self.transform = transform @@ -40,7 +41,7 @@ class TransformGenerator: return self.transform(a, d) def __repr__(self): - return "'transform(%s)'"%self.gen + return "'transform(%s)'" % self.gen class RandomGenerator: @@ -60,7 +61,7 @@ class RandomGenerator: return "".join(random.choice(chars) for x in range(a, b)) def __repr__(self): - return "%s random from %s"%(self.length, self.dtype) + return "%s random from %s" % (self.length, self.dtype) class FileGenerator: @@ -79,4 +80,4 @@ class FileGenerator: return self.map.__getslice__(a, b) def __repr__(self): - return "<%s"%self.path + return "<%s" % self.path diff --git a/libpathod/language/http.py b/libpathod/language/http.py index 543cfee3..76362253 100644 --- a/libpathod/language/http.py +++ b/libpathod/language/http.py @@ -104,7 +104,7 @@ class PathodResponse(base.Token): parseAll=True ) ) - except pp.ParseException, v: + except pp.ParseException as v: raise exceptions.ParseException(v.msg, v.line, v.col) @classmethod @@ -119,7 +119,7 @@ class PathodResponse(base.Token): ] def spec(self): - return "s%s"%(self.value.spec()) + return "s%s" % (self.value.spec()) def freeze(self, settings): f = self.parsed.freeze(settings).spec() @@ -140,6 +140,7 @@ def get_header(val, headers): class _HTTPMessage(message.Message): version = "HTTP/1.1" + @property def actions(self): return self.toks(actions._Action) @@ -153,7 +154,7 @@ class _HTTPMessage(message.Message): return self.tok(Body) @abc.abstractmethod - def preamble(self, settings): # pragma: no cover + def preamble(self, settings): # pragma: no cover pass @property diff --git a/libpathod/language/message.py b/libpathod/language/message.py index 2ff40825..8c58f021 100644 --- a/libpathod/language/message.py +++ b/libpathod/language/message.py @@ -66,7 +66,7 @@ class Message(object): return l @classmethod - def expr(klass): # pragma: no cover + def expr(klass): # pragma: no cover pass def log(self, settings): diff --git a/libpathod/language/websockets.py b/libpathod/language/websockets.py index 036d4ea5..46daa467 100644 --- a/libpathod/language/websockets.py +++ b/libpathod/language/websockets.py @@ -100,6 +100,7 @@ class WebsocketFrame(message.Message): RawBody, ) logattrs = ["body"] + @property def actions(self): return self.toks(actions._Action) diff --git a/libpathod/language/writer.py b/libpathod/language/writer.py index 24f4330b..3bacbf87 100644 --- a/libpathod/language/writer.py +++ b/libpathod/language/writer.py @@ -57,5 +57,5 @@ def write_values(fp, vals, actions, sofar=0, blocksize=BLOCKSIZE): return True elif a[1] == "inject": send_chunk(fp, a[2], blocksize, 0, len(a[2])) - except netlib.tcp.NetLibDisconnect: # pragma: no cover + except netlib.tcp.NetLibDisconnect: # pragma: no cover return True diff --git a/libpathod/pathoc.py b/libpathod/pathoc.py index 3d61c9e7..edb6108f 100644 --- a/libpathod/pathoc.py +++ b/libpathod/pathoc.py @@ -52,7 +52,7 @@ class Log: elif exc_type in (tcp.NetLibDisconnect, http.HttpErrorConnClosed): self("Disconnected") elif exc_type == http.HttpError: - self("HTTP Error: %s"%exc_value.message) + self("HTTP Error: %s" % exc_value.message) self.fp.write("\n".join(self.lines)) self.fp.write("\n") self.fp.flush() @@ -63,10 +63,10 @@ class Log: def dump(self, data, hexdump): if hexdump: for line in netlib.utils.hexdump(data): - self("\t%s %s %s"%line) + self("\t%s %s %s" % line) else: for i in netlib.utils.cleanBin(data).split("\n"): - self("\t%s"%i) + self("\t%s" % i) def __call__(self, line): self.lines.append(line) @@ -78,24 +78,24 @@ class SSLInfo: def __str__(self): parts = [ - "Cipher: %s, %s bit, %s"%self.cipher, + "Cipher: %s, %s bit, %s" % self.cipher, "SSL certificate chain:" ] for i in self.certchain: parts.append("\tSubject: ") for cn in i.get_subject().get_components(): - parts.append("\t\t%s=%s"%cn) + parts.append("\t\t%s=%s" % cn) parts.append("\tIssuer: ") for cn in i.get_issuer().get_components(): - parts.append("\t\t%s=%s"%cn) + parts.append("\t\t%s=%s" % cn) parts.extend( [ - "\tVersion: %s"%i.get_version(), - "\tValidity: %s - %s"%( + "\tVersion: %s" % i.get_version(), + "\tValidity: %s - %s" % ( i.get_notBefore(), i.get_notAfter() ), - "\tSerial: %s"%i.get_serial_number(), - "\tAlgorithm: %s"%i.get_signature_algorithm() + "\tSerial: %s" % i.get_serial_number(), + "\tAlgorithm: %s" % i.get_signature_algorithm() ] ) pk = i.get_pubkey() @@ -104,10 +104,10 @@ class SSLInfo: OpenSSL.crypto.TYPE_DSA: "DSA" } t = types.get(pk.type(), "Uknown") - parts.append("\tPubkey: %s bit %s"%(pk.bits(), t)) + parts.append("\tPubkey: %s bit %s" % (pk.bits(), t)) s = certutils.SSLCert(i) if s.altnames: - parts.append("\tSANs: %s"%" ".join(s.altnames)) + parts.append("\tSANs: %s" % " ".join(s.altnames)) return "\n".join(parts) @@ -127,11 +127,18 @@ class Response: self.sslinfo = sslinfo def __repr__(self): - return "Response(%s - %s)"%(self.status_code, self.msg) + return "Response(%s - %s)" % (self.status_code, self.msg) class WebsocketFrameReader(threading.Thread): - def __init__(self, rfile, logfp, showresp, hexdump, callback, ws_read_limit): + def __init__( + self, + rfile, + logfp, + showresp, + hexdump, + callback, + ws_read_limit): threading.Thread.__init__(self) self.ws_read_limit = ws_read_limit self.logfp = logfp @@ -150,7 +157,7 @@ class WebsocketFrameReader(threading.Thread): ) def run(self): - while 1: + while True: if self.ws_read_limit == 0: break r, _, _ = select.select([self.rfile], [], [], 0.05) @@ -166,7 +173,7 @@ class WebsocketFrameReader(threading.Thread): except tcp.NetLibError: self.ws_read_limit = 0 break - log("<< %s"%frm.header.human_readable()) + log("<< %s" % frm.header.human_readable()) self.callback(frm) if self.ws_read_limit is not None: self.ws_read_limit -= 1 @@ -244,7 +251,7 @@ class Pathoc(tcp.TCPClient): def http_connect(self, connect_to): self.wfile.write( - 'CONNECT %s:%s HTTP/1.1\r\n'%tuple(connect_to) + + 'CONNECT %s:%s HTTP/1.1\r\n' % tuple(connect_to) + '\r\n' ) self.wfile.flush() @@ -254,7 +261,7 @@ class Pathoc(tcp.TCPClient): parsed = http.parse_response_line(l) if not parsed[1] == 200: raise PathocError( - "Proxy CONNECT failed: %s - %s"%(parsed[1], parsed[2]) + "Proxy CONNECT failed: %s - %s" % (parsed[1], parsed[2]) ) http.read_headers(self.rfile) @@ -275,7 +282,7 @@ class Pathoc(tcp.TCPClient): method=self.sslversion, cipher_list = self.ciphers ) - except tcp.NetLibError, v: + except tcp.NetLibError as v: raise PathocError(str(v)) self.sslinfo = SSLInfo( self.connection.get_peer_cert_chain(), @@ -285,7 +292,7 @@ class Pathoc(tcp.TCPClient): print >> fp, str(self.sslinfo) def _resp_summary(self, resp): - return "<< %s %s: %s bytes"%( + return "<< %s %s: %s bytes" % ( resp.status_code, utils.xrepr(resp.msg), len(resp.content) ) @@ -295,7 +302,7 @@ class Pathoc(tcp.TCPClient): def wait(self): if self.ws_framereader: - while 1: + while True: try: self.ws_framereader.is_done.get(timeout=0.05) self.ws_framereader.join() @@ -316,7 +323,7 @@ class Pathoc(tcp.TCPClient): with self.log() as log: if isinstance(r, basestring): r = language.parse_requests(r)[0] - log(">> %s"%r) + log(">> %s" % r) try: language.serve(r, self.wfile, self.settings) self.wfile.flush() @@ -362,7 +369,7 @@ class Pathoc(tcp.TCPClient): with self.log() as log: if isinstance(r, basestring): r = language.parse_requests(r)[0] - log(">> %s"%r) + log(">> %s" % r) resp, req = None, None try: req = language.serve(r, self.wfile, self.settings) @@ -410,13 +417,13 @@ class Pathoc(tcp.TCPClient): self.websocket_send_frame(r) -def main(args): # pragma: nocover +def main(args): # pragma: nocover memo = set([]) trycount = 0 p = None try: cnt = 0 - while 1: + while True: if cnt == args.repeat and args.repeat != 0: break if trycount > args.memolimit: @@ -464,10 +471,10 @@ def main(args): # pragma: nocover trycount = 0 try: p.connect(args.connect_to, args.showssl) - except tcp.NetLibError, v: + except tcp.NetLibError as v: print >> sys.stderr, str(v) continue - except PathocError, v: + except PathocError as v: print >> sys.stderr, str(v) sys.exit(1) if args.timeout: @@ -477,7 +484,7 @@ def main(args): # pragma: nocover ret = p.request(spec) if ret and args.oneshot: return - except (http.HttpError, tcp.NetLibError), v: + except (http.HttpError, tcp.NetLibError) as v: break p.wait() except KeyboardInterrupt: diff --git a/libpathod/pathod.py b/libpathod/pathod.py index d69d2298..4ad6cc19 100644 --- a/libpathod/pathod.py +++ b/libpathod/pathod.py @@ -85,7 +85,9 @@ class PathodHandler(tcp.BaseHandler): ) return False, log - if self.server.explain and not isinstance(crafted, language.http.PathodErrorResponse): + if self.server.explain and not isinstance( + crafted, + language.http.PathodErrorResponse): crafted = crafted.freeze(self.settings) self.info(">> Spec: %s" % crafted.spec()) response_log = language.serve( @@ -129,13 +131,14 @@ class PathodHandler(tcp.BaseHandler): m.v[0] ) self.convert_to_ssl( - cert, key, + cert, + key, handle_sni=self.handle_sni, request_client_cert=self.server.ssloptions.request_client_cert, cipher_list=self.server.ssloptions.ciphers, method=self.server.ssloptions.sslversion, ) - except tcp.NetLibError, v: + except tcp.NetLibError as v: s = str(v) self.info(s) self.addlog(dict(type="error", msg=s)) @@ -190,7 +193,7 @@ class PathodHandler(tcp.BaseHandler): self.rfile, headers, None, method, None, True ) - except http.HttpError, s: + except http.HttpError as s: s = str(s) self.info(s) self.addlog(dict(type="error", msg=s)) @@ -203,7 +206,9 @@ class PathodHandler(tcp.BaseHandler): self.addlog(retlog) return again - if not self.server.nocraft and utils.matchpath(path, self.server.craftanchor): + if not self.server.nocraft and utils.matchpath( + path, + self.server.craftanchor): spec = urllib.unquote(path)[len(self.server.craftanchor) + 1:] key = websockets.check_client_handshake(headers) self.settings.websocket_key = key @@ -212,7 +217,7 @@ class PathodHandler(tcp.BaseHandler): self.info("crafting spec: %s" % spec) try: crafted = language.parse_response(spec) - except language.ParseException, v: + except language.ParseException as v: self.info("Parse error: %s" % v.msg) crafted = language.http.make_error_response( "Parse Error", @@ -273,13 +278,14 @@ class PathodHandler(tcp.BaseHandler): try: cert, key, _ = self.server.ssloptions.get_cert(None) self.convert_to_ssl( - cert, key, + cert, + key, handle_sni=self.handle_sni, request_client_cert=self.server.ssloptions.request_client_cert, cipher_list=self.server.ssloptions.ciphers, method=self.server.ssloptions.sslversion, ) - except tcp.NetLibError, v: + except tcp.NetLibError as v: s = str(v) self.server.add_log( dict( @@ -419,7 +425,7 @@ class Pathod(tcp.TCPServer): return self.log -def main(args): # pragma: nocover +def main(args): # pragma: nocover ssloptions = SSLOptions( cn = args.cn, confdir = args.confdir, @@ -470,17 +476,17 @@ def main(args): # pragma: nocover explain = args.explain, webdebug = args.webdebug ) - except PathodError, v: - print >> sys.stderr, "Error: %s"%v + except PathodError as v: + print >> sys.stderr, "Error: %s" % v sys.exit(1) - except language.FileAccessDenied, v: - print >> sys.stderr, "Error: %s"%v + except language.FileAccessDenied as v: + print >> sys.stderr, "Error: %s" % v if args.daemonize: utils.daemonize() try: - print "%s listening on %s:%s"%( + print "%s listening on %s:%s" % ( version.NAMEVERSION, pd.address.host, pd.address.port diff --git a/libpathod/test.py b/libpathod/test.py index 6f95a797..136a6237 100644 --- a/libpathod/test.py +++ b/libpathod/test.py @@ -9,12 +9,13 @@ requests.packages.urllib3.disable_warnings() class Daemon: IFACE = "127.0.0.1" + def __init__(self, ssl=None, **daemonargs): self.q = Queue.Queue() self.thread = _PaThread(self.IFACE, self.q, ssl, daemonargs) self.thread.start() self.port = self.q.get(True, 5) - self.urlbase = "%s://%s:%s"%( + self.urlbase = "%s://%s:%s" % ( "https" if ssl else "http", self.IFACE, self.port @@ -31,13 +32,13 @@ class Daemon: """ Return a URL that will render the response in spec. """ - return "%s/p/%s"%(self.urlbase, spec) + return "%s/p/%s" % (self.urlbase, spec) def info(self): """ Return some basic info about the remote daemon. """ - resp = requests.get("%s/api/info"%self.urlbase, verify=False) + resp = requests.get("%s/api/info" % self.urlbase, verify=False) return resp.json() def last_log(self): @@ -53,14 +54,14 @@ class Daemon: """ Return the log buffer as a list of dictionaries. """ - resp = requests.get("%s/api/log"%self.urlbase, verify=False) + resp = requests.get("%s/api/log" % self.urlbase, verify=False) return resp.json()["log"] def clear_log(self): """ Clear the log. """ - resp = requests.get("%s/api/clear_log"%self.urlbase, verify=False) + resp = requests.get("%s/api/clear_log" % self.urlbase, verify=False) return resp.ok def shutdown(self): diff --git a/libpathod/utils.py b/libpathod/utils.py index e1ec013f..dd0ae425 100644 --- a/libpathod/utils.py +++ b/libpathod/utils.py @@ -22,6 +22,7 @@ class MemBool: """ Truth-checking with a memory, for use in chained if statements. """ + def __init__(self): self.v = None @@ -95,18 +96,19 @@ class Data: """ fullpath = os.path.join(self.dirname, path) if not os.path.exists(fullpath): - raise ValueError, "dataPath: %s does not exist."%fullpath + raise ValueError("dataPath: %s does not exist." % fullpath) return fullpath data = Data(__name__) -def daemonize(stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'): # pragma: nocover + +def daemonize(stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'): # pragma: nocover try: pid = os.fork() if pid > 0: sys.exit(0) - except OSError, e: + except OSError as e: sys.stderr.write("fork #1 failed: (%d) %s\n" % (e.errno, e.strerror)) sys.exit(1) os.chdir("/") @@ -116,7 +118,7 @@ def daemonize(stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'): # prag pid = os.fork() if pid > 0: sys.exit(0) - except OSError, e: + except OSError as e: sys.stderr.write("fork #2 failed: (%d) %s\n" % (e.errno, e.strerror)) sys.exit(1) si = open(stdin, 'rb') diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 00000000..bc980d56 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,9 @@ +[flake8] +max-line-length = 80 +max-complexity = 15 + +[pep8] +max-line-length = 80 +max-complexity = 15 +exclude = */contrib/* +ignore = E251,E309 diff --git a/test/test_app.py b/test/test_app.py index 7c7ac730..4536db8e 100644 --- a/test/test_app.py +++ b/test/test_app.py @@ -29,7 +29,7 @@ class TestApp(tutils.DaemonTests): assert self.get("200:da").status_code == 200 id = self.d.log()[0]["id"] assert self.getpath("/log").status_code == 200 - assert self.getpath("/log/%s"%id).status_code == 200 + assert self.getpath("/log/%s" % id).status_code == 200 assert self.getpath("/log/9999999").status_code == 404 def test_log_binary(self): @@ -52,7 +52,10 @@ class TestApp(tutils.DaemonTests): assert r.status_code == 200 assert 'Response' in r.content - r = self.getpath("/response_preview", params=dict(spec="200:b<nonexistent")) + r = self.getpath( + "/response_preview", + params=dict( + spec="200:b<nonexistent")) assert r.status_code == 200 assert 'File access denied' in r.content diff --git a/test/test_cmdline.py b/test/test_cmdline.py index c51b6cf0..5a9ee242 100644 --- a/test/test_cmdline.py +++ b/test/test_cmdline.py @@ -27,7 +27,6 @@ def test_pathod(perror): assert perror.called perror.reset_mock() - a = cmdline.args_pathod( [ "pathod", @@ -99,7 +98,9 @@ def test_pathod(perror): def test_pathoc(perror): assert cmdline.args_pathoc(["pathoc", "foo.com", "get:/"]) s = cStringIO.StringIO() - tutils.raises(SystemExit, cmdline.args_pathoc, ["pathoc", "--show-uas"], s, s) + tutils.raises( + SystemExit, cmdline.args_pathoc, [ + "pathoc", "--show-uas"], s, s) a = cmdline.args_pathoc(["pathoc", "foo.com:8888", "get:/"]) assert a.port == 8888 @@ -122,7 +123,8 @@ def test_pathoc(perror): assert perror.called perror.reset_mock() - a = cmdline.args_pathoc(["pathoc", "-c", "foo:bar", "foo.com:8888", "get:/"]) + a = cmdline.args_pathoc( + ["pathoc", "-c", "foo:bar", "foo.com:8888", "get:/"]) assert perror.called perror.reset_mock() diff --git a/test/test_language_actions.py b/test/test_language_actions.py index b7361dff..16d54806 100644 --- a/test/test_language_actions.py +++ b/test/test_language_actions.py @@ -113,8 +113,7 @@ class Test_Action: c = actions.DisconnectAt(0) assert a < b assert a == c - l = [b, a] - l.sort() + l = sorted([b, a]) assert l[0].offset == 0 def test_resolve(self): diff --git a/test/test_language_base.py b/test/test_language_base.py index 329778a9..d59ee88b 100644 --- a/test/test_language_base.py +++ b/test/test_language_base.py @@ -69,7 +69,7 @@ class TestTokValueLiteral: self.roundtrip('\'') self.roundtrip("a") self.roundtrip("\"") - #self.roundtrip("\\") + # self.roundtrip("\\") self.roundtrip("200:b'foo':i23,'\\''") self.roundtrip("\a") @@ -321,8 +321,6 @@ def test_integer(): assert BInt(3) - - class TBoolean(base.Boolean): name = "test" diff --git a/test/test_language_http.py b/test/test_language_http.py index 17bce802..3bdd0ec5 100644 --- a/test/test_language_http.py +++ b/test/test_language_http.py @@ -214,7 +214,7 @@ class TestResponse: ) try: language.parse_response("400'msg':b:") - except language.ParseException, v: + except language.ParseException as v: assert v.marked() assert str(v) @@ -293,8 +293,10 @@ def test_location_shortcut(): def test_shortcuts(): - assert language.parse_response("400:c'foo'").headers[0].key.val == "Content-Type" - assert language.parse_response("400:l'foo'").headers[0].key.val == "Location" + assert language.parse_response( + "400:c'foo'").headers[0].key.val == "Content-Type" + assert language.parse_response( + "400:l'foo'").headers[0].key.val == "Location" assert "Android" in tutils.render(parse_request("get:/:ua")) assert "User-Agent" in tutils.render(parse_request("get:/:ua")) diff --git a/test/test_pathoc.py b/test/test_pathoc.py index 8d0d5972..1735f084 100644 --- a/test/test_pathoc.py +++ b/test/test_pathoc.py @@ -128,20 +128,33 @@ class TestDaemon(_TestDaemon): tutils.raises("ssl handshake", c.connect) def test_showssl(self): - assert not "certificate chain" in self.tval(["get:/p/200"], showssl=True) + assert not "certificate chain" in self.tval( + ["get:/p/200"], + showssl=True) def test_ignorecodes(self): assert "200" in self.tval(["get:'/p/200:b@1'"]) assert "200" in self.tval(["get:'/p/200:b@1'"]) assert "200" in self.tval(["get:'/p/200:b@1'"]) assert "200" not in self.tval(["get:'/p/200:b@1'"], ignorecodes=[200]) - assert "200" not in self.tval(["get:'/p/200:b@1'"], ignorecodes=[200, 201]) + assert "200" not in self.tval( + ["get:'/p/200:b@1'"], + ignorecodes=[ + 200, + 201]) assert "202" in self.tval(["get:'/p/202:b@1'"], ignorecodes=[200, 201]) def test_timeout(self): assert "Timeout" in self.tval(["get:'/p/200:p0,10'"], timeout=0.01) - assert "HTTP" in self.tval(["get:'/p/200:p5,10'"], showresp=True, timeout=0.01) - assert not "HTTP" in self.tval(["get:'/p/200:p3,10'"], showresp=True, timeout=0.01, ignoretimeout=True) + assert "HTTP" in self.tval( + ["get:'/p/200:p5,10'"], + showresp=True, + timeout=0.01) + assert not "HTTP" in self.tval( + ["get:'/p/200:p3,10'"], + showresp=True, + timeout=0.01, + ignoretimeout=True) def test_showresp(self): reqs = ["get:/api/info:p0,0", "get:/api/info:p0,0"] diff --git a/test/test_pathod.py b/test/test_pathod.py index bfff3274..7f07c041 100644 --- a/test/test_pathod.py +++ b/test/test_pathod.py @@ -53,6 +53,7 @@ class TestNotAfterConnect(tutils.DaemonTests): ssloptions = dict( not_after_connect = True ) + def test_connect(self): r = self.pathoc( r"get:'http://foo.com/p/202':da", @@ -66,6 +67,7 @@ class TestCustomCert(tutils.DaemonTests): ssloptions = dict( certs = [("*", tutils.test_data.path("data/testkey.pem"))], ) + def test_connect(self): r = self.pathoc(r"get:/p/202") assert r.status_code == 202 @@ -78,6 +80,7 @@ class TestSSLCN(tutils.DaemonTests): ssloptions = dict( cn = "foo.com" ) + def test_connect(self): r = self.pathoc(r"get:/p/202") assert r.status_code == 202 @@ -87,6 +90,7 @@ class TestSSLCN(tutils.DaemonTests): class TestNohang(tutils.DaemonTests): nohang = True + def test_nohang(self): r = self.get("200:p0,0") assert r.status_code == 800 @@ -96,6 +100,7 @@ class TestNohang(tutils.DaemonTests): class TestHexdump(tutils.DaemonTests): hexdump = True + def test_hexdump(self): r = self.get(r"200:b'\xf0'") @@ -194,6 +199,7 @@ class CommonTests(tutils.DaemonTests): class TestDaemon(CommonTests): ssl = False + def test_connect(self): r = self.pathoc( r"get:'http://foo.com/p/202':da", diff --git a/test/test_test.py b/test/test_test.py index 943fb270..681aa290 100644 --- a/test/test_test.py +++ b/test/test_test.py @@ -8,25 +8,28 @@ logging.disable(logging.CRITICAL) class TestDaemonManual: def test_simple(self): with test.Daemon() as d: - rsp = requests.get("http://localhost:%s/p/202:da"%d.port) + rsp = requests.get("http://localhost:%s/p/202:da" % d.port) assert rsp.ok assert rsp.status_code == 202 tutils.raises( "Connection aborted", requests.get, - "http://localhost:%s/p/202:da"%d.port + "http://localhost:%s/p/202:da" % d.port ) def test_startstop_ssl(self): d = test.Daemon(ssl=True) - rsp = requests.get("https://localhost:%s/p/202:da"%d.port, verify=False) + rsp = requests.get( + "https://localhost:%s/p/202:da" % + d.port, + verify=False) assert rsp.ok assert rsp.status_code == 202 d.shutdown() tutils.raises( "Connection aborted", requests.get, - "http://localhost:%s/p/202:da"%d.port + "http://localhost:%s/p/202:da" % d.port ) def test_startstop_ssl_explicit(self): @@ -36,13 +39,15 @@ class TestDaemonManual: ssl_after_connect = False ) d = test.Daemon(ssl=ssloptions) - rsp = requests.get("https://localhost:%s/p/202:da"%d.port, verify=False) + rsp = requests.get( + "https://localhost:%s/p/202:da" % + d.port, + verify=False) assert rsp.ok assert rsp.status_code == 202 d.shutdown() tutils.raises( "Connection aborted", requests.get, - "http://localhost:%s/p/202:da"%d.port + "http://localhost:%s/p/202:da" % d.port ) - diff --git a/test/test_utils.py b/test/test_utils.py index b8aa7f12..2a158a07 100644 --- a/test/test_utils.py +++ b/test/test_utils.py @@ -14,8 +14,8 @@ def test_membool(): def test_parse_size(): assert utils.parse_size("100") == 100 assert utils.parse_size("100k") == 100 * 1024 - tutils.raises("invalid size spec", utils.parse_size, "foo") - tutils.raises("invalid size spec", utils.parse_size, "100kk") + tutils.raises("invalid size spec", utils.parse_size, "foo") + tutils.raises("invalid size spec", utils.parse_size, "100kk") def test_parse_anchor_spec(): @@ -37,4 +37,3 @@ def test_escape_unprintables(): e = utils.escape_unprintables(s) assert e.encode('ascii') assert not "PATHOD_MARKER" in e - diff --git a/test/tutils.py b/test/tutils.py index 07252b53..933c7f59 100644 --- a/test/tutils.py +++ b/test/tutils.py @@ -30,7 +30,7 @@ class DaemonTests(object): ], ssl = klass.ssl, ssloptions = so, - sizelimit = 1*1024*1024, + sizelimit = 1 * 1024 * 1024, noweb = klass.noweb, noapi = klass.noapi, nohang = klass.nohang, @@ -53,7 +53,7 @@ class DaemonTests(object): def getpath(self, path, params=None): scheme = "https" if self.ssl else "http" return requests.get( - "%s://localhost:%s/%s"%( + "%s://localhost:%s/%s" % ( scheme, self.d.port, path @@ -115,14 +115,14 @@ def raises(exc, obj, *args, **kwargs): :kwargs Arguments to be passed to the callable. """ try: - apply(obj, args, kwargs) - except (Exception, SystemExit), v: + obj(*args, **kwargs) + except (Exception, SystemExit) as v: if isinstance(exc, basestring): if exc.lower() in str(v).lower(): return else: raise AssertionError( - "Expected %s, but caught %s"%( + "Expected %s, but caught %s" % ( repr(str(exc)), v ) ) @@ -131,7 +131,7 @@ def raises(exc, obj, *args, **kwargs): return else: raise AssertionError( - "Expected %s, but caught %s %s"%( + "Expected %s, but caught %s %s" % ( exc.__name__, v.__class__.__name__, str(v) ) ) |