From c0d19adafd376688d19750ad73278081f222240c Mon Sep 17 00:00:00 2001 From: ed Date: Sat, 10 Feb 2024 15:28:54 +0000 Subject: [PATCH] python 2.7 is totally fine --- bin/partftpy_client.py | 2 +- partftpy/TftpClient.py | 11 +++++------ partftpy/TftpContexts.py | 13 ++++++++----- partftpy/TftpPacketFactory.py | 5 ++++- partftpy/TftpPacketTypes.py | 9 ++++++--- partftpy/TftpServer.py | 9 ++++++--- partftpy/TftpShared.py | 5 ++++- partftpy/TftpStates.py | 13 ++++++++----- partftpy/__init__.py | 10 +++------- setup.py | 7 +++++-- 10 files changed, 50 insertions(+), 34 deletions(-) diff --git a/bin/partftpy_client.py b/bin/partftpy_client.py index 3f09098..e1640ac 100755 --- a/bin/partftpy_client.py +++ b/bin/partftpy_client.py @@ -107,7 +107,7 @@ def main(): parser.print_help() sys.exit(1) - class Progress: + class Progress(object): def __init__(self, out): self.progress = 0 self.out = out diff --git a/partftpy/TftpClient.py b/partftpy/TftpClient.py index c167b23..0003b44 100644 --- a/partftpy/TftpClient.py +++ b/partftpy/TftpClient.py @@ -1,4 +1,7 @@ +# coding: utf-8 # vim: ts=4 sw=4 et ai: +from __future__ import print_function, unicode_literals + """This module implements the TFTP Client functionality. Instantiate an instance of the client, and then use its upload or download method. Logging is performed via a standard logging object set in TftpShared.""" @@ -55,12 +58,8 @@ def download( Note: If output is a hyphen, stdout is used.""" # We're downloading. - log.debug("Creating download context with the following params:") - log.debug(f"host = {self.host}, port = {self.iport}, filename = {filename}") - log.debug( - "options = %s, packethook = %s, timeout = %s" - % (self.options, packethook, timeout) - ) + t = "DL-ctx: host = %s, port = %s, filename = %s, options = %s, packethook = %s, timeout = %s" + log.debug(t, self.host, self.iport, filename, self.options, packethook, timeout) self.context = TftpContextClientDownload( self.host, self.iport, diff --git a/partftpy/TftpContexts.py b/partftpy/TftpContexts.py index 2e55d8f..4474383 100644 --- a/partftpy/TftpContexts.py +++ b/partftpy/TftpContexts.py @@ -1,4 +1,7 @@ +# coding: utf-8 # vim: ts=4 sw=4 et ai: +from __future__ import print_function, unicode_literals + """This module implements all contexts for state handling during uploads and downloads, the main interface to which being the TftpContext base class. @@ -28,7 +31,7 @@ ############################################################################### -class TftpMetrics: +class TftpMetrics(object): """A class representing metrics of the transfer.""" def __init__(self): @@ -78,7 +81,7 @@ def add_dup(self, pkt): ############################################################################### -class TftpContext: +class TftpContext(object): """The base class of the contexts.""" def __init__(self, host, port, timeout, retries=DEF_TIMEOUT_RETRIES, localip=""): @@ -247,7 +250,7 @@ def __init__( self.upload_open = upload_open def __str__(self): - return f"{self.host}:{self.port} {self.state}" + return "%s:%s %s" % (self.host, self.port, self.state) def start(self, buffer): """ @@ -314,7 +317,7 @@ def __init__( ) def __str__(self): - return f"{self.host}:{self.port} {self.state}" + return "%s:%s %s" % (self.host, self.port, self.state) def start(self): log.info("Sending tftp upload request to %s" % self.host) @@ -400,7 +403,7 @@ def __init__( ) def __str__(self): - return f"{self.host}:{self.port} {self.state}" + return "%s:%s %s" % (self.host, self.port, self.state) def start(self): """Initiate the download.""" diff --git a/partftpy/TftpPacketFactory.py b/partftpy/TftpPacketFactory.py index 4fb6403..da6c440 100644 --- a/partftpy/TftpPacketFactory.py +++ b/partftpy/TftpPacketFactory.py @@ -1,4 +1,7 @@ +# coding: utf-8 # vim: ts=4 sw=4 et ai: +from __future__ import print_function, unicode_literals + """This module implements the TftpPacketFactory class, which can take a binary buffer, and return the appropriate TftpPacket object to represent it, via the parse() method.""" @@ -12,7 +15,7 @@ log = logging.getLogger("partftpy.TftpPacketFactory") -class TftpPacketFactory: +class TftpPacketFactory(object): """This class generates TftpPacket objects. It is responsible for parsing raw buffers off of the wire and returning objects representing them, via the parse() method.""" diff --git a/partftpy/TftpPacketTypes.py b/partftpy/TftpPacketTypes.py index 7332e58..a8a21ab 100644 --- a/partftpy/TftpPacketTypes.py +++ b/partftpy/TftpPacketTypes.py @@ -1,4 +1,7 @@ +# coding: utf-8 # vim: ts=4 sw=4 et ai: +from __future__ import print_function, unicode_literals + """This module implements the packet types of TFTP itself, and the corresponding encode and decode methods for them.""" @@ -12,7 +15,7 @@ log = logging.getLogger("partftpy.TftpPacketTypes") -class TftpSession: +class TftpSession(object): """This class is the base class for the tftp client and server. Any shared code should be in this class.""" @@ -20,7 +23,7 @@ class TftpSession: pass -class TftpPacketWithOptions: +class TftpPacketWithOptions(object): """This class exists to permit some TftpPacket subclasses to share code regarding options handling. It does not inherit from TftpPacket, as the goal is just to share code here, and not cause diamond inheritance.""" @@ -99,7 +102,7 @@ def decode_options(self, buffer): return options -class TftpPacket: +class TftpPacket(object): """This class is the parent class of all tftp packet classes. It is an abstract class, providing an interface, and should not be instantiated directly.""" diff --git a/partftpy/TftpServer.py b/partftpy/TftpServer.py index af728bf..c4bdfe6 100644 --- a/partftpy/TftpServer.py +++ b/partftpy/TftpServer.py @@ -1,4 +1,7 @@ +# coding: utf-8 # vim: ts=4 sw=4 et ai: +from __future__ import print_function, unicode_literals + """This module implements the TFTP Server functionality. Instantiate an instance of the server, and then run the listen() method to listen for client requests. Logging is performed via a standard logging object set in @@ -58,7 +61,7 @@ def __init__(self, tftproot="/tftpboot", dyn_file_func=None, upload_open=None): for name in "dyn_file_func", "upload_open": attr = getattr(self, name) if attr and not callable(attr): - raise TftpException(f"{name} supplied, but it is not callable.") + raise TftpException("%s supplied, but it is not callable." % (name,)) if os.path.exists(self.root): log.debug("tftproot %s does exist", self.root) if not os.path.isdir(self.root): @@ -92,7 +95,7 @@ def listen( # listenip = listenip if listenip else '0.0.0.0' if not listenip: listenip = "0.0.0.0" - log.info(f"Server requested on ip {listenip}, port {listenport}") + log.info("Server requested on ip %s, port %s" % (listenip, listenport)) try: # FIXME - sockets should be non-blocking self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) @@ -163,7 +166,7 @@ def listen( # Forge a session key based on the client's IP and port, # which should safely work through NAT. - key = f"{raddress}:{rport}" + key = "%s:%s" % (raddress, rport) if key not in self.sessions: log.debug( diff --git a/partftpy/TftpShared.py b/partftpy/TftpShared.py index 027b2c6..60ba34a 100644 --- a/partftpy/TftpShared.py +++ b/partftpy/TftpShared.py @@ -1,4 +1,7 @@ +# coding: utf-8 # vim: ts=4 sw=4 et ai: +from __future__ import print_function, unicode_literals + """This module holds all objects shared by all other modules in partftpy.""" @@ -28,7 +31,7 @@ def tftpassert(condition, msg): raise TftpException(msg) -class TftpErrors: +class TftpErrors(object): """This class is a convenience for defining the common tftp error codes, and making them more readable in the code.""" diff --git a/partftpy/TftpStates.py b/partftpy/TftpStates.py index 5d2d6c1..1b707a9 100644 --- a/partftpy/TftpStates.py +++ b/partftpy/TftpStates.py @@ -1,4 +1,7 @@ +# coding: utf-8 # vim: ts=4 sw=4 et ai: +from __future__ import print_function, unicode_literals + """This module implements all state handling during uploads and downloads, the main interface to which being the TftpState base class. @@ -25,7 +28,7 @@ ############################################################################### -class TftpState: +class TftpState(object): """The base class for the states.""" def __init__(self, context): @@ -48,7 +51,7 @@ def handleOACK(self, pkt): # Set options to OACK options self.context.options = pkt.options for key in self.context.options: - log.info(f" {key} = {self.context.options[key]}") + log.info(" %s = %s", key, self.context.options[key]) else: log.error("Failed to negotiate options") raise TftpException("Failed to negotiate options") @@ -168,7 +171,7 @@ def sendOACK(self): def resendLast(self): """Resend the last sent packet due to a timeout.""" assert( self.context.last_pkt is not None ) - log.warning(f"Resending packet {self.context.last_pkt} on sessions {self}") + log.warning("Resending packet %s on sessions %s", self.context.last_pkt, self) self.context.metrics.resent_bytes += len(self.context.last_pkt.buffer) self.context.metrics.add_dup(self.context.last_pkt) sendto_port = self.context.tidport @@ -335,7 +338,7 @@ def handle(self, pkt, raddress, rport): else: log.warning("File not found: %s", path) self.sendError(TftpErrors.FileNotFound) - raise TftpException(f"File not found: {path}") + raise TftpException("File not found: %s" % (path,)) # Options negotiation. if sendoack and "tsize" in self.context.options: @@ -630,7 +633,7 @@ def handle(self, pkt, raddress, rport): if pkt.errorcode == TftpErrors.FileNotFound: raise TftpFileNotFoundError("File not found") else: - raise TftpException(f"Received ERR from server: {pkt}") + raise TftpException("Received ERR from server: %s" % (pkt,)) else: self.sendError(TftpErrors.IllegalTftpOp) diff --git a/partftpy/__init__.py b/partftpy/__init__.py index 4fd6713..572c100 100644 --- a/partftpy/__init__.py +++ b/partftpy/__init__.py @@ -1,18 +1,14 @@ +# coding: utf-8 # vim: ts=4 sw=4 et ai: +from __future__ import print_function, unicode_literals + """ This library implements the tftp protocol, based on rfc 1350. http://www.faqs.org/rfcs/rfc1350.html """ -import sys - import pkg_resources -# Make sure that this is at least Python 3 -required_version = (3, 0) -if sys.version_info < required_version: - raise ImportError("Requires at least Python 3.0") - from . import __name__ as pkg_name diff --git a/setup.py b/setup.py index 443977c..60ed270 100755 --- a/setup.py +++ b/setup.py @@ -1,4 +1,7 @@ -#!/usr/bin/env python +# coding: utf-8 +# vim: ts=4 sw=4 et ai: +from __future__ import print_function, unicode_literals + # vim: ts=4 sw=4 et ai: import os @@ -27,7 +30,7 @@ def read_file(fname): "setuptools_scm[toml]", "setuptools_scm_git_archive >= 1.0", ], - python_requires=">=3.6", + python_requires=">=2.7", classifiers=[ "Programming Language :: Python :: 3", "Development Status :: 4 - Beta",