@@ -75,7 +75,7 @@ def _mjcf_property(self):
7575 err_with_next_tb = err .with_traceback (tb .tb_next )
7676 if isinstance (err , AttributeError ):
7777 self ._last_attribute_error = err_with_next_tb # pylint: disable=protected-access
78- raise err_with_next_tb
78+ raise err_with_next_tb # pylint: disable=raise-missing-from
7979 return _raw_property (_mjcf_property )
8080
8181
@@ -182,7 +182,7 @@ def __init__(self, spec, parent, attributes=None):
182182 attribute_obj ._force_clear () # pylint: disable=protected-access
183183 # Then raise a meaningful error
184184 err_type , err , tb = sys .exc_info ()
185- raise err_type (
185+ raise err_type ( # pylint: disable=raise-missing-from
186186 f'during initialization of attribute { attribute_spec .name !r} of '
187187 f'element <{ self ._spec .name } >: { err } ' ).with_traceback (tb )
188188
@@ -507,9 +507,14 @@ def _get_attribute(self, attribute_name):
507507 self ._check_valid_attribute (attribute_name )
508508 return self ._attributes [attribute_name ].value
509509
510- def get_attribute_xml_string (self , attribute_name , prefix_root = None ):
510+ def get_attribute_xml_string (self ,
511+ attribute_name ,
512+ prefix_root = None ,
513+ * ,
514+ precision = constants .XML_DEFAULT_PRECISION ):
511515 self ._check_valid_attribute (attribute_name )
512- return self ._attributes [attribute_name ].to_xml_string (prefix_root )
516+ return self ._attributes [attribute_name ].to_xml_string (
517+ prefix_root , precision = precision )
513518
514519 def get_attributes (self ):
515520 fix_attribute_name = (
@@ -541,7 +546,7 @@ def set_attributes(self, **kwargs):
541546 self ._set_attribute (name , old_value )
542547 # Then raise a meaningful error.
543548 err_type , err , tb = sys .exc_info ()
544- raise err_type (
549+ raise err_type ( # pylint: disable=raise-missing-from
545550 f'during assignment to attribute { attribute_name !r} of '
546551 f'element <{ self ._spec .name } >: { err } ' ).with_traceback (tb )
547552
@@ -554,7 +559,7 @@ def _check_valid_child(self, element_name):
554559 try :
555560 return self ._spec .children [element_name ]
556561 except KeyError :
557- raise AttributeError (
562+ raise AttributeError ( # pylint: disable=raise-missing-from
558563 '<{}> is not a valid child of <{}>'
559564 .format (element_name , self ._spec .name ))
560565
@@ -690,7 +695,8 @@ def all_children(self):
690695 if child .spec .repeated ]
691696 return all_children
692697
693- def to_xml (self , prefix_root = None , debug_context = None ):
698+ def to_xml (self , prefix_root = None , debug_context = None ,
699+ * , precision = constants .XML_DEFAULT_PRECISION ):
694700 """Generates an etree._Element corresponding to this MJCF element.
695701
696702 Args:
@@ -701,30 +707,37 @@ def to_xml(self, prefix_root=None, debug_context=None):
701707 the debugging information associated with the generated XML is written.
702708 This is intended for internal use within PyMJCF; users should never need
703709 manually pass this argument.
710+ precision: (optional) Number of digits to output for floating point
711+ quantities.
704712
705713 Returns:
706714 An etree._Element object.
707715 """
708716 prefix_root = prefix_root or self .namescope
709717 xml_element = etree .Element (self ._spec .name )
710- self ._attributes_to_xml (xml_element , prefix_root , debug_context )
711- self ._children_to_xml (xml_element , prefix_root , debug_context )
718+ self ._attributes_to_xml (xml_element , prefix_root , debug_context ,
719+ precision = precision )
720+ self ._children_to_xml (xml_element , prefix_root , debug_context ,
721+ precision = precision )
712722 return xml_element
713723
714- def _attributes_to_xml (self , xml_element , prefix_root , debug_context = None ):
724+ def _attributes_to_xml (self , xml_element , prefix_root , debug_context = None ,
725+ * , precision ):
715726 del debug_context # Unused.
716727 for attribute_name , attribute in self ._attributes .items ():
717- attribute_value = attribute .to_xml_string (prefix_root )
728+ attribute_value = attribute .to_xml_string (prefix_root ,
729+ precision = precision )
718730 if attribute_name == self ._spec .identifier and attribute_value is None :
719731 xml_element .set (attribute_name , self .full_identifier )
720732 elif attribute_value is None :
721733 continue
722734 else :
723735 xml_element .set (attribute_name , attribute_value )
724736
725- def _children_to_xml (self , xml_element , prefix_root , debug_context = None ):
737+ def _children_to_xml (self , xml_element , prefix_root , debug_context = None ,
738+ * , precision ):
726739 for child in self .all_children ():
727- child_xml = child .to_xml (prefix_root , debug_context )
740+ child_xml = child .to_xml (prefix_root , debug_context , precision = precision )
728741 if (child_xml .attrib or len (child_xml ) # pylint: disable=g-explicit-length-test
729742 or child .spec .repeated or child .spec .on_demand ):
730743 xml_element .append (child_xml )
@@ -735,7 +748,8 @@ def _children_to_xml(self, xml_element, prefix_root, debug_context=None):
735748 child_xml .insert (0 , copy .deepcopy (debug_comment ))
736749
737750 def to_xml_string (self , prefix_root = None ,
738- self_only = False , pretty_print = True , debug_context = None ):
751+ self_only = False , pretty_print = True , debug_context = None ,
752+ * , precision = constants .XML_DEFAULT_PRECISION ):
739753 """Generates an XML string corresponding to this MJCF element.
740754
741755 Args:
@@ -750,16 +764,19 @@ def to_xml_string(self, prefix_root=None,
750764 the debugging information associated with the generated XML is written.
751765 This is intended for internal use within PyMJCF; users should never need
752766 manually pass this argument.
767+ precision: (optional) Number of digits to output for floating point
768+ quantities.
753769
754770 Returns:
755771 A string.
756772 """
757- xml_element = self .to_xml (prefix_root , debug_context )
773+ xml_element = self .to_xml (prefix_root , debug_context , precision = precision )
758774 if self_only and len (xml_element ) > 0 : # pylint: disable=g-explicit-length-test
759775 etree .strip_elements (xml_element , '*' )
760776 xml_element .text = '...'
761777 if (self_only and self ._spec .identifier and
762- not self ._attributes [self ._spec .identifier ].to_xml_string (prefix_root )):
778+ not self ._attributes [self ._spec .identifier ].to_xml_string (
779+ prefix_root , precision = precision )):
763780 del xml_element .attrib [self ._spec .identifier ]
764781 xml_string = util .to_native_string (
765782 etree .tostring (xml_element , pretty_print = pretty_print ))
@@ -987,8 +1004,10 @@ def prefixed_identifier(self, prefix_root=None):
9871004 prefix = self .namescope .full_prefix (prefix_root )
9881005 return prefix + self ._attachment .namescope .name + constants .PREFIX_SEPARATOR
9891006
990- def to_xml (self , prefix_root = None , debug_context = None ):
991- xml_element = (super ().to_xml (prefix_root , debug_context ))
1007+ def to_xml (self , prefix_root = None , debug_context = None ,
1008+ * , precision = constants .XML_DEFAULT_PRECISION ):
1009+ xml_element = (super ().to_xml (prefix_root , debug_context ,
1010+ precision = precision ))
9921011 xml_element .set ('name' , self .prefixed_identifier (prefix_root ))
9931012 return xml_element
9941013
@@ -1013,8 +1032,10 @@ class _AttachmentFrameChild(_ElementImpl):
10131032 """
10141033 __slots__ = []
10151034
1016- def to_xml (self , prefix_root = None , debug_context = None ):
1017- xml_element = (super ().to_xml (prefix_root , debug_context ))
1035+ def to_xml (self , prefix_root = None , debug_context = None ,
1036+ * , precision = constants .XML_DEFAULT_PRECISION ):
1037+ xml_element = (super ().to_xml (prefix_root , debug_context ,
1038+ precision = precision ))
10181039 if self .spec .namespace is not None :
10191040 if self .name :
10201041 name = (self ._parent .prefixed_identifier (prefix_root ) +
@@ -1051,14 +1072,17 @@ def _attach(self, other, exclude_worldbody=False, dry_run=False):
10511072 def all_children (self ):
10521073 return [child for child in self ._children ]
10531074
1054- def to_xml (self , prefix_root = None , debug_context = None ):
1075+ def to_xml (self , prefix_root = None , debug_context = None ,
1076+ * , precision = constants .XML_DEFAULT_PRECISION ):
10551077 prefix_root = prefix_root or self .namescope
1056- xml_element = (super ().to_xml (prefix_root , debug_context ))
1078+ xml_element = (super ().to_xml (prefix_root , debug_context ,
1079+ precision = precision ))
10571080 if isinstance (self ._parent , RootElement ):
10581081 root_default = etree .Element (self ._spec .name )
10591082 root_default .append (xml_element )
10601083 for attachment in self ._attachments .values ():
1061- attachment_xml = attachment .to_xml (prefix_root , debug_context )
1084+ attachment_xml = attachment .to_xml (prefix_root , debug_context ,
1085+ precision = precision )
10621086 for attachment_child_xml in attachment_xml :
10631087 root_default .append (attachment_child_xml )
10641088 xml_element = root_default
@@ -1082,12 +1106,13 @@ def _is_third_order_actuator(self, child):
10821106 else :
10831107 return False # No other actuator shortcuts have internal dynamics.
10841108
1085- def _children_to_xml (self , xml_element , prefix_root , debug_context = None ):
1109+ def _children_to_xml (self , xml_element , prefix_root , debug_context = None ,
1110+ * , precision = constants .XML_DEFAULT_PRECISION ):
10861111 second_order = []
10871112 third_order = []
10881113 debug_comments = {}
10891114 for child in self .all_children ():
1090- child_xml = child .to_xml (prefix_root , debug_context )
1115+ child_xml = child .to_xml (prefix_root , debug_context , precision = precision )
10911116 if (child_xml .attrib or len (child_xml ) # pylint: disable=g-explicit-length-test
10921117 or child .spec .repeated or child .spec .on_demand ):
10931118 if self ._is_third_order_actuator (child ):
@@ -1297,7 +1322,7 @@ def __getitem__(self, index):
12971322 return scoped_elements [index [(len (scope_name ) + 1 ):]]
12981323 except KeyError :
12991324 # Re-raise so that the error shows the full, un-stripped index string
1300- raise self ._identifier_not_found_error (index )
1325+ raise self ._identifier_not_found_error (index ) # pylint: disable=raise-missing-from
13011326 elif isinstance (index , slice ) or (isinstance (index , int ) and index < 0 ):
13021327 return self ._full_list ()[index ]
13031328 else :
0 commit comments