UnboundLocalError in from_xml() when XML element name does not map to any property
Summary
py_serializable.from_xml() raises an UnboundLocalError instead of a meaningful exception when deserializing nested XML elements that do not match any registered property.
The error originates from an uninitialized local variable (k) inside the library.
This makes deserialization failures hard to diagnose and hides the real cause (XML ↔ property name mismatch).
Environment
py_serializable: current PyPI version (as of 2026-01)
Python: 3.11 / 3.12 / 3.13 (reproducible across versions)
OS: Windows (also reproducible on Linux)
Minimal Reproducible Example
Python code
import io
import py_serializable
from py_serializable import xml_array, XmlArraySerializationType
@py_serializable.serializable_class
class Trade:
def __init__(self, price: float = 0.0):
self.price = price
@py_serializable.serializable_class
class TradeBook:
def __init__(self):
self._trades = []
@property
@xml_array(XmlArraySerializationType.NESTED, "trade")
def trades(self):
return self._trades
@trades.setter
def trades(self, value):
self._trades = value
XML input (note the mismatching element name)
<TradeBook>
<trades>
<Trade>
<price>100.0</price>
</Trade>
</trades>
</TradeBook>
How to trigger the bug
xml = """<TradeBook>
<trades>
<Trade>
<price>100.0</price>
</Trade>
</trades>
</TradeBook>"""
TradeBook.from_xml(io.StringIO(xml))
Actual behavior
The library crashes with:
UnboundLocalError: cannot access local variable 'k' where it is not associated with a value
Full traceback excerpt:
File ".../py_serializable/__init__.py", line 678, in from_xml
_data[decoded_k].append(prop_info.concrete_type.from_xml(
File ".../py_serializable/__init__.py", line 657, in from_xml
k, decoded_k, cls.__module__, cls.__qualname__)
UnboundLocalError: cannot access local variable 'k'
Expected behavior
A clear, user-facing exception, e.g.:
- ValueError: Unknown XML element for property 'trades'
- or ValueError: XML element 'Trade' does not match expected item name 'trade'
- or any error that explains the mapping mismatch
The library should never raise UnboundLocalError for invalid input.
Root cause analysis
Inside py_serializable.from_xml():
- Variable k is only conditionally assigned
- In the error path (else: branch), k is referenced without initialization
- This causes an UnboundLocalError instead of the intended error
This is a pure internal bug unrelated to user code correctness.
Why this matters
- The error hides the real cause (XML ↔ property mismatch)
- Users cannot diagnose deserialization issues
- It breaks debugging and test feedback loops
- This situation is very common when working with nested XML
Suggested fix (high level)
Ensure k is always initialized before use
Or raise a meaningful exception directly when no property matches
Add a unit test covering mismatched XML element names
Additional notes
- This issue is not related to enums, typing, or user-defined setters
- The crash happens before user code can handle the error
- Fixing this would greatly improve developer experience
Conclusion
This is a library bug in py_serializable.from_xml() caused by an uninitialized local variable.
It should be fixed to raise a meaningful exception instead of crashing with UnboundLocalError.
✅ Fix for UnboundLocalError in from_xml()
Problem recap (one sentence)
When an XML element cannot be mapped to any property, from_xml() raises UnboundLocalError because local variable k is referenced before assignment.
🔧 Minimal, correct fix
Location
py_serializable/init.py, inside BaseXmlModel.from_xml()
(around the block that handles nested elements)
❌ Current buggy code (simplified)
for prop_info in props:
if decoded_k == prop_info.xml_name:
k = prop_info.attr_name
...
break
else:
raise ValueError(
k, decoded_k, cls.__module__, cls.__qualname__
)
If no property matches, k is undefined.
✅ Fixed version (safe + informative)
matched_prop = None
for prop_info in props:
if decoded_k == prop_info.xml_name:
matched_prop = prop_info
break
if matched_prop is None:
raise ValueError(
f"Unknown XML element '{decoded_k}' while deserializing "
f"{cls.__module__}.{cls.__qualname__}"
)
k = matched_prop.attr_name
prop_info = matched_prop
✅ Why this fix is correct
- k is never referenced before assignment
- The error message is clear and actionable
- Behavior is unchanged for valid XML
- No API changes
- No backward compatibility break
🧪 Unit test (reproduces bug, validates fix)
This test fails on current main and passes with the fix.
Test file: tests/test_unknown_nested_element.py
import io
import pytest
import py_serializable
from py_serializable import xml_array, XmlArraySerializationType
@py_serializable.serializable_class
class Trade:
def __init__(self, price: float = 0.0):
self.price = price
@py_serializable.serializable_class
class TradeBook:
def __init__(self):
self._trades = []
@property
@xml_array(XmlArraySerializationType.NESTED, "trade")
def trades(self):
return self._trades
@trades.setter
def trades(self, value):
self._trades = value
def test_unknown_nested_element_raises_meaningful_error():
xml = """
<TradeBook>
<trades>
<Trade>
<price>100.0</price>
</Trade>
</trades>
</TradeBook>
"""
with pytest.raises(ValueError) as exc:
TradeBook.from_xml(io.StringIO(xml))
msg = str(exc.value)
assert "Unknown XML element" in msg
assert "Trade" in msg
assert "TradeBook" in msg
🧠 Why this test matters
- Covers a real-world failure mode
- Ensures no internal exceptions leak out
- Validates error message quality
- Guards against regressions
📌 Optional (nice-to-have improvement)
If you want to be extra helpful, you can include expected XML names:
expected = ", ".join(p.xml_name for p in props)
raise ValueError(
f"Unknown XML element '{decoded_k}' while deserializing "
f"{cls.__qualname__}. Expected one of: {expected}"
)
UnboundLocalError in from_xml() when XML element name does not map to any property
Summary
py_serializable.from_xml() raises an UnboundLocalError instead of a meaningful exception when deserializing nested XML elements that do not match any registered property.
The error originates from an uninitialized local variable (k) inside the library.
This makes deserialization failures hard to diagnose and hides the real cause (XML ↔ property name mismatch).
Environment
py_serializable: current PyPI version (as of 2026-01)
Python: 3.11 / 3.12 / 3.13 (reproducible across versions)
OS: Windows (also reproducible on Linux)
Minimal Reproducible Example
Python code
XML input (note the mismatching element name)
How to trigger the bug
Actual behavior
The library crashes with:
UnboundLocalError: cannot access local variable 'k' where it is not associated with a valueFull traceback excerpt:
Expected behavior
A clear, user-facing exception, e.g.:
The library should never raise UnboundLocalError for invalid input.
Root cause analysis
Inside py_serializable.from_xml():
This is a pure internal bug unrelated to user code correctness.
Why this matters
Suggested fix (high level)
Ensure k is always initialized before use
Or raise a meaningful exception directly when no property matches
Add a unit test covering mismatched XML element names
Additional notes
Conclusion
This is a library bug in py_serializable.from_xml() caused by an uninitialized local variable.
It should be fixed to raise a meaningful exception instead of crashing with UnboundLocalError.
✅ Fix for UnboundLocalError in from_xml()
Problem recap (one sentence)
When an XML element cannot be mapped to any property, from_xml() raises UnboundLocalError because local variable k is referenced before assignment.
🔧 Minimal, correct fix
Location
py_serializable/init.py, inside BaseXmlModel.from_xml()
(around the block that handles nested elements)
❌ Current buggy code (simplified)
If no property matches, k is undefined.
✅ Fixed version (safe + informative)
✅ Why this fix is correct
🧪 Unit test (reproduces bug, validates fix)
This test fails on current main and passes with the fix.
Test file: tests/test_unknown_nested_element.py
🧠 Why this test matters
📌 Optional (nice-to-have improvement)
If you want to be extra helpful, you can include expected XML names: