Install & Compatibility
Where this runs
tested against v0.5.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.920 runs
installs and imports cleanly · install 0.0s · import 0.029s · 17.8MB
glibcpy 3.10–3.920 runs
installs and imports cleanly · install 1.5s · import 0.028s · 18MB
16MB installed
● package 16MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
XMODEM
✓ from xmodem import XMODEM
✗ from modem import XMODEM
The `modem` package refers to an older or different library; the correct import path for this specific library (tehmaze/xmodem) is `from xmodem import XMODEM`.
This quickstart demonstrates how to initialize the `XMODEM` class by providing `getc` and `putc` callback functions, which handle reading from and writing to a communication channel (e.g., a serial port). It shows the basic structure for sending and receiving data streams using the `send()` and `recv()` methods. Note that a full XMODEM transfer requires a cooperating sender and receiver, and a dummy serial port is used here for illustrative purposes.
import serial
from xmodem import XMODEM
# Configure your serial port here
# For example, using a dummy serial port for demonstration
# In a real application, replace with an actual serial port like '/dev/ttyUSB0'
class DummySerial:
def __init__(self, timeout=0):
self.buffer = b''
def read(self, size):
if not self.buffer:
return b''
data = self.buffer[:size]
self.buffer = self.buffer[size:]
return data
def write(self, data):
# In a real scenario, this would send data over serial
# For this dummy example, we just 'receive' it instantly
# Or, you could print it to simulate output.
# print(f"DummySerial sent: {data!r}")
self.buffer += data # Simulate loopback or immediate reception
return len(data)
# Replace DummySerial() with serial.Serial('/dev/ttyUSB0', timeout=0) for actual use
ser = DummySerial(timeout=0)
def getc(size, timeout=1):
return ser.read(size) or None
def putc(data, timeout=1):
return ser.write(data)
modem = XMODEM(getc, putc)
# --- Example: Sending a file ---
print("Attempting to send data...")
# Create a dummy stream for demonstration
import io
stream_to_send = io.BytesIO(b"Hello, XMODEM world! This is a test file.\n")
# In a real scenario, this would be `open('/path/to/file', 'rb')`
# status = modem.send(stream_to_send)
# print(f"Send status: {status}")
# Due to the complexity of XMODEM handshakes in a simple script
# without a cooperating receiver, the send/recv calls are commented out.
# A successful transfer requires a matching XMODEM receiver on the other end.
print("To send a file: modem.send(file_stream_object)")
print("To receive a file: modem.recv(file_stream_object)")
print("Note: A full XMODEM transfer requires a corresponding receiver/sender.")
# --- Example: Receiving a file ---
# stream_to_receive = io.BytesIO()
# received_bytes = modem.recv(stream_to_receive)
# if received_bytes is not None:
# print(f"Received {received_bytes} bytes: {stream_to_receive.getvalue()!r}")
# else:
# print("Failed to receive data.")
Debug
Known issues
breakingVersion 0.4.0 introduced a critical bug that caused `recv()` to raise an `AssertionError` due to a bogus `assert False` statement. This was fixed in version 0.4.5.fixUpgrade to `xmodem` version 0.4.5 or newer (`pip install --upgrade xmodem`).
affects: 0.4.0 - 0.4.4
gotchaThe `retry` parameter in `send()` and `recv()` methods was incorrectly implemented in versions prior to 0.4.4. For `send()`, it was treated as total failures instead of failures per block, and `retry=n` would only retry `n-1` times instead of `n` times. This could lead to premature transfer failures, especially for large files or when `retry=1` was used.fixUpgrade to `xmodem` version 0.4.4 or newer to ensure correct `retry` behavior (`pip install --upgrade xmodem`).
affects: < 0.4.4
gotchaPrior to version 0.4.7, `recv()` could stall under certain error conditions or when receiving empty files. This could cause programs to hang indefinitely.fixUpgrade to `xmodem` version 0.4.7 or newer to resolve stalling issues in `recv()` (`pip install --upgrade xmodem`).
affects: < 0.4.7
gotchaIn versions prior to 0.4.3, the `putc()` callback was invoked multiple times for each part of an XMODEM block's header, data, and checksum. This behavior could cause issues when integrating with microcontrollers or hardware sensitive to timing at stream boundaries.fixUpgrade to `xmodem` version 0.4.3 or newer. The fix ensures all three data blocks are sent by a single `putc()` call, improving compatibility.
affects: < 0.4.3
gotchaIn version 0.5.0, a bug was fixed where `retry_limit` was not correctly triggered during the data transfer phase because errors were not properly accumulated. This means retry mechanisms might not have functioned as expected in versions where this issue was present.fixEnsure you are using `xmodem` version 0.5.0 or newer to benefit from the corrected `retry_limit` logic (`pip install --upgrade xmodem`).
affects: Likely < 0.5.0 (fixed in 0.5.0)
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'xmodem'
The 'xmodem' library is not installed in the current Python environment or interpreter.
fixInstall the library using pip: `pip install xmodem`
TypeError: 'NoneType' object is not callable
The 'getc' or 'putc' callback functions passed to the 'xmodem.XMODEM' constructor were 'None' or not valid callable objects, leading to an attempt to call a 'None' value during protocol execution.
fixDefine and pass proper callable functions (e.g., wrappers around 'serial.Serial.read' and 'serial.Serial.write') as 'getc' and 'putc' to the 'XMODEM' constructor. Example: `modem = xmodem.XMODEM(getc_func, putc_func)`
AttributeError: 'XMODEM' object has no attribute 'receive'
An attempt was made to call a non-existent method, such as 'receive()', on an 'xmodem.XMODEM' object instead of the correct method 'recv()'.
fixUse the correct method names as defined by the 'xmodem' API: 'send()' for sending data and 'recv()' for receiving data. Example: `data = modem.recv()`
xmodem.errors.RetryExceeded: No successful transmission after N retries.
The XMODEM protocol failed to complete successfully after multiple retries due to persistent communication issues, such as timeouts, corrupted data packets, or the remote device not responding as expected.
fixVerify the physical serial connection, baud rate, and other serial port settings. Ensure the remote device is properly configured for XMODEM communication and is ready to send/receive. Consider increasing the timeout or retry parameters if the communication link is slow or unreliable.
Upgrade
Version history
0.5.0latest on PyPI · released Mar 4, 2026
Audit
Dependencies
No dependency data recorded yet.