Exceptions and results
tftp.exceptions
Every exception the package raises on its own account, and the mapping from OS errors to TFTP error codes.
:class:TFTPError is the one base. It plays three roles, told apart by the
subclass:
- what a server handler raises to refuse a request: the code and message
become the ERROR packet the client receives (:class:
TFTPErroritself, or :class:TFTPProtocolError); - what a client raises for an ERROR the server sent: :class:
RemoteErrorand its leaves, one per defined error code; - what a transfer that failed reports in
TransferResult.error, whichever of these it was, including :class:TransferTimeoutError, :class:TransferAbortedErrorand :class:TransferTooLargeErrorfor a local deadline, anabort()or a client'smax_size.
Text that is not the value it was asked to become raises
:class:TFTPValueError, which is also a :class:ValueError:
:class:TFTPDecodeError for bytes that are not a packet. A caller's own
mistake, a wrong argument type or an option out of range, is plain
:class:TypeError or :class:ValueError, not one of these. A file that is not
a capture raises pktcap.CaptureFormatError and a filter expression that does
not compile pktcap.CaptureFilterError, each a :class:ValueError of that
library.
:class:WouldBlock is a signal that a source or sink has nothing ready, not a
failure, so it is a :class:BlockingIOError and not a :class:TFTPError.
Every class is rebuilt by type(*args), so each one copies and pickles.
AccessViolation(code=None, message='')
Bases: RemoteError
ERROR 2.
Source code in src/tftp/exceptions.py
146 147 | |
DiskFull(code=None, message='')
Bases: RemoteError
ERROR 3: disk full or allocation exceeded.
Source code in src/tftp/exceptions.py
146 147 | |
FileAlreadyExists(code=None, message='')
Bases: RemoteError
ERROR 6.
Source code in src/tftp/exceptions.py
146 147 | |
FileNotFound(code=None, message='')
Bases: RemoteError
ERROR 1.
Source code in src/tftp/exceptions.py
146 147 | |
IllegalOperation(code=None, message='')
Bases: RemoteError
ERROR 4.
Source code in src/tftp/exceptions.py
146 147 | |
NoSuchUser(code=None, message='')
Bases: RemoteError
ERROR 7.
Source code in src/tftp/exceptions.py
146 147 | |
OptionNegotiationError(code=None, message='')
Bases: RemoteError
ERROR 8: the peer refused option negotiation.
Source code in src/tftp/exceptions.py
146 147 | |
RemoteError(code=None, message='')
Bases: TFTPError
The peer sent an ERROR packet.
Raised as the subclass for its code (:class:FileNotFound,
:class:AccessViolation, ...) so callers can catch by kind; code and
message hold exactly what the peer sent. The leaves describe the
server's file, so none is also a FileNotFoundError or
PermissionError: :mod:tftp.path translates where a path caller
expects the builtin.
Source code in src/tftp/exceptions.py
146 147 | |
from_code(code, message='')
classmethod
The :class:RemoteError subclass instance for code (cls itself for a code with no leaf).
Source code in src/tftp/exceptions.py
149 150 151 152 | |
TFTPDecodeError(message='')
Bases: TFTPValueError
The bytes do not form a valid TFTP packet.
Carries ERROR 4 (illegal operation), the code a peer is answered with.
Source code in src/tftp/exceptions.py
265 266 | |
TFTPError(code=TFTPErrorCode.NOT_DEFINED, message='')
Bases: Exception
A TFTP failure carrying the ERROR code that describes it.
A server handler raises this to refuse a request: the code and message become the ERROR packet the client receives.
:param code: an int in 0..65535 (unknown codes are kept: the wire
carries any 16-bit value). TypeError for anything else, which
catches TFTPError("message"); ValueError outside the range.
:param message: text; TypeError for anything else. A NUL is replaced
and a long text cut when the ERROR is encoded.
Source code in src/tftp/exceptions.py
73 74 75 76 77 78 79 80 81 82 83 84 | |
from_exception(exc)
classmethod
The ERROR to send for exc, always a plain :class:TFTPError or exc itself.
A :class:TFTPError is used as is. An OSError maps by errno
(ENOENT -> file not found, EACCES -> access violation,
ENOSPC -> disk full, ...). Its message is the generic one for the
code, never the OS text, which would disclose server paths.
Source code in src/tftp/exceptions.py
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | |
TFTPProtocolError(message, code=TFTPErrorCode.ILLEGAL_OPERATION)
Bases: TFTPError
The peer broke the protocol (malformed packet, bad option ack...).
Source code in src/tftp/exceptions.py
126 127 | |
TFTPValueError(message='')
Bases: TFTPError, ValueError
Text that is not the value it was asked to become: a malformed
tftp:// URL, for one.
Also a :class:ValueError, so except ValueError keeps catching it.
Source code in src/tftp/exceptions.py
265 266 | |
TransferAbortedError(message='transfer aborted')
Bases: TFTPError
Cancelled locally (abort(), a server shutting down).
Source code in src/tftp/exceptions.py
235 236 | |
TransferTimeoutError(message='timed out')
Bases: TFTPError, TimeoutError
The peer stopped answering, or the transfer ran out of time.
Also a :class:TimeoutError; errno is None, since no OS call
failed.
Source code in src/tftp/exceptions.py
225 226 | |
TransferTooLargeError(message='transfer too large')
Bases: TFTPError
A download would bring more than the client's max_size.
Raised, and sent to the server as ERROR 3, before the octet that passes the
bound is written; code is DISK_FULL.
Source code in src/tftp/exceptions.py
249 250 | |
UnknownTransferID(code=None, message='')
Bases: RemoteError
ERROR 5.
Source code in src/tftp/exceptions.py
146 147 | |
WouldBlock
Bases: BlockingIOError
Raised by a source or sink that has nothing ready yet.
A sender whose read raises it stops after the blocks it has, and a
receiver whose write (or complete) raises it holds the block
unacknowledged; both carry on when the driver calls Transfer.resume.
This is how a slow backend (an upstream server, an HTTP fetch) applies
backpressure without blocking the loop that serves every other transfer.
tftp.TransferResult(filename, operation, mode, peer, local, bytes, blocks, retransmits, duration, negotiated, error=None)
The outcome of one transfer, on either side.
:ivar filename: as requested.
:ivar operation: "read" for an RRQ, "write" for a WRQ, whichever
side reports it.
:ivar mode: "octet" or "netascii".
:ivar peer: the other side's (host, port, ...) transfer address.
:ivar local: this side's transfer address.
:ivar bytes: payload bytes moved (netascii-encoded size on the wire).
:ivar blocks: DATA blocks moved, excluding retransmissions.
:ivar retransmits: packets sent again after a timeout or a lost block.
:ivar duration: seconds from request to completion.
:ivar negotiated: the parameters the transfer ran with.
:ivar error: the failure, or None on success.
Source code in src/tftp/_result.py
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | |
throughput
property
Payload bytes per second.
to_dict()
The result as a dictionary of JSON types, one object per transfer.
ok is :attr:is_ok; peer is [host, port]; duration is
seconds to the microsecond; blksize, windowsize, tsize and
options come from :attr:negotiated; error is the failure's
text, or None.
Source code in src/tftp/_result.py
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | |