Install & Compatibility
Where this runs
tested against v0.26.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.210s · 20.4MB
glibcpy 3.10–3.920 runs
installs and imports cleanly · install 2.0s · import 0.193s · 21MB
19MB installed
● package 19MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
parse_ldf
✓ from ldfparser import parse_ldf
The primary function to load and parse an LDF file.
LDF
✓ import ldfparser
ldf = ldfparser.parse_ldf(path='file.ldf')
The LDF object is returned by parse_ldf and provides access to parsed data.
This quickstart demonstrates how to parse an LDF file, retrieve network parameters like baudrate, access specific frames, and then encode and decode LIN messages using defined signals. A temporary LDF file is created for a runnable example.
import ldfparser
import os
import tempfile
import binascii
# Create a dummy LDF file for demonstration
ldf_content = """
LIN_description_file;
LIN_protocol_version = "2.1";
LIN_language_version = "2.1";
LIN_speed = 19.2 kbps;
Nodes {
Master: MasterNode, 5 ms, 0.1 ms;
Slaves: SlaveNode1;
}
Signals {
EngineRPM: 12, 0, MasterNode, MasterNode;
CoolantTemp: 8, 12, MasterNode, MasterNode;
}
Frames {
EngineFrame: 0x10, 8, MasterNode;
Signals {
EngineRPM, 0;
CoolantTemp, 2;
}
}
Signal_encoding_types {
MotorRPM_encoding:
physical_value,
0, 255, 1, 0, "RPM";
}
Signal_representation {
MotorRPM_encoding: EngineRPM;
}
"""
with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.ldf') as temp_ldf_file:
temp_ldf_file.write(ldf_content)
ldf_path = temp_ldf_file.name
try:
# Load LDF
ldf = ldfparser.parse_ldf(path=ldf_path)
print(f"Successfully parsed LDF from: {ldf_path}")
# Get baudrate
print(f"Baudrate: {ldf.get_baudrate()} kbps")
# Get an unconditional frame
frame = ldf.get_unconditional_frame('EngineFrame')
print(f"Frame 'EngineFrame' ID: {frame.frame_id}, Length: {frame.length} bytes")
# Encode signal values
signal_values = {"EngineRPM": 1500, "CoolantTemp": 95}
message = frame.encode(signal_values)
print(f"Encoded message for {signal_values}: 0x{binascii.hexlify(message).decode('utf-8')}")
# Decode message
decoded_values = frame.decode(message)
print(f"Decoded message: {decoded_values}")
except Exception as e:
print(f"An error occurred: {e}")
finally:
# Clean up the temporary LDF file
if os.path.exists(ldf_path):
os.remove(ldf_path)
Debug
Known issues
breakingAs of v0.26.0, `signal.frames` is the new way to determine signal owners for compatibility with signals associated with multiple frames. While `signal.frame` is still set if a signal belongs to only one frame, relying on `signal.frame` directly for multi-frame signals is discouraged.fixMigrate code to use `signal.frames` (which returns a list) instead of `signal.frame` when iterating over signal ownership.
affects: >=0.26.0
breakingIn v0.26.0, physical values are now rounded to the nearest integer during conversion, rather than always rounded down. This can change the output of decoded signals.fixReview any logic that depends on the previous rounding-down behavior for physical value conversions and adjust expectations or implement custom rounding if needed.
affects: >=0.26.0
deprecatedPrior to v0.10.0, several functions like `parseLDF`, `parseLDFtoDict`, `parseComments`, and direct attribute access like `LDF.frame(x)` were common. These have been deprecated in favor of snake_case function names (`parse_ldf`) and proper getter methods.fixUpdate function calls to their snake_case equivalents (e.g., `parse_ldf`) and use getter methods (e.g., `ldf.get_frame('FrameName')`) to ensure future compatibility. affects: <0.10.0
gotchaThe library is in a 'pre-release' state, and features may break between minor versions. This means APIs or internal behaviors can change without a major version increment.fixIt is highly recommended to pin the exact minor version (e.g., `ldfparser==0.26.0`) in production environments and perform thorough integration tests when updating to a new minor version.
affects: All pre-1.0.0 versions
gotchaDue to known ambiguities or errors in LIN standard documentation, `ldfparser` cannot guarantee parsing correctness for *all* LDF files.fixIf parsing issues occur, first verify the LDF file with a commercial tool (e.g., Vector LDF Explorer). If the LDF is valid, consider opening an issue with an anonymized LDF snippet.
affects: All versions
Errors
Common errors & fixes
FileNotFoundError: 'non_existent.ldf' doesn't exist
The path provided to `ldfparser.parse_ldf` does not point to an accessible LDF file.
fixEnsure the LDF file exists at the specified path and that the Python process has read permissions for it. Double-check the file name and directory.
KeyError: 'Frame_X'
Attempted to access a frame (e.g., `ldf.get_unconditional_frame('Frame_X')`) or signal that does not exist or is misspelled in the parsed LDF.
fixVerify the exact name of the frame or signal in the LDF file. Use `ldf.frames` or `ldf.signals` to inspect available names or iterate through them.
AttributeError: 'LinSignal' object has no attribute 'frame'
Attempting to access `signal.frame` when the signal is associated with multiple frames, especially after v0.26.0 which introduced `signal.frames`.
fixUse `signal.frames` (which is a list of frames) to determine the owners of a signal. Iterate over this list if a signal can belong to multiple frames. For signals with a single frame owner, `signal.frame` will still be populated for backward compatibility.
ldfparser.parser.LDFParserException: Error parsing LDF file: ...
The provided LDF file contains syntax errors or deviations from the LIN standard that the parser cannot handle, leading to a parsing failure.
fixReview the LDF file for syntax errors. Validate it with a commercial LDF editor if possible. Consider simplifying the LDF to isolate the problematic section or upgrading `ldfparser` if it's an old version with a known parsing bug.
Upgrade
Version history
0.26.0latest on PyPI · released Jan 27, 2025
Audit
Dependencies
No dependency data recorded yet.