Fix AttributeError when node.id is accessed on non-Node objects#911
Fix AttributeError when node.id is accessed on non-Node objects#911
Conversation
When construct_scalar, construct_sequence, construct_mapping, construct_pairs, construct_yaml_omap, or construct_yaml_pairs receive a non-Node object, the error handling code would fail with AttributeError when trying to access node.id or node.start_mark attributes. This fix uses getattr() to safely access these attributes, falling back to type(node).__name__ for the id and None for start_mark when the attributes don't exist. Fixes yaml#907
Manual Test ResultsI've verified the fix works correctly with various test cases: Test 1: Original reproduction case (Null type) import yaml
class Null:
pass
obj = yaml.loader.SafeLoader("")
ret = obj.construct_yaml_float(Null)Result: ✅ Test 2: None object obj = yaml.loader.SafeLoader("")
ret = obj.construct_scalar(None)Result: ✅ Test 3: String instead of SequenceNode obj = yaml.loader.SafeLoader("")
ret = obj.construct_sequence("not a node")Result: ✅ Test 4: Custom object instead of MappingNode class CustomObject:
pass
obj = yaml.loader.SafeLoader("")
ret = obj.construct_mapping(CustomObject())Result: ✅ Test 5: Integer instead of MappingNode obj = yaml.loader.SafeLoader("")
ret = obj.construct_pairs(42)Result: ✅ Test 6: Normal YAML parsing data = yaml.safe_load("key: value")Result: ✅ Works correctly, returns All tests pass. The fix ensures proper |
|
Friendly ping - any chance someone could take a look at this when they get a chance? Happy to make any changes if needed. |
Summary
Fixes #907 by safely accessing
node.idandnode.start_markattributes in error handling code.Problem
When constructor methods like
construct_scalar(),construct_sequence(), etc. receive a non-Node object (e.g.,None, a type object, or any arbitrary Python object), the error handling code unconditionally accessesnode.idandnode.start_mark, which causes anAttributeErrorbefore the intendedConstructorErrorcan be raised.Solution
Use
getattr()to safely access these attributes:node.id: fall back totype(node).__name__to still provide useful type information in the error messagenode.start_mark: fall back toNonesince position information isn't available for non-Node objectsTesting
Tested with the reproduction case from the issue:
Before:
AttributeError: type object 'Null' has no attribute 'id'After:
ConstructorError: expected a scalar node, but found typeAlso verified that normal YAML parsing continues to work correctly.