Files
nuitka-mirror/nuitka/TreeXML.py
Kay Hayen bf8c074cbc Cleanups
* Avoid imports of whole modules and instead import only select names
  from them.

* For the nuitka.Options module we split off the states into a separate
  "nuitka.States" module that provides an object that is also faster
  to access that module attributes. This is a micro optimization that
  allows their use to be faster.

* Renamed XML reading/creating functions for clearer names when used
  with out the module name, same for source code references objects.
2025-11-26 11:19:43 +00:00

152 lines
4.0 KiB
Python

# Copyright 2025, Kay Hayen, mailto:kay.hayen@gmail.com find license text at end of file
""" XML node tree handling
Means to create XML elements from Nuitka tree nodes and to convert the
XML tree to ASCII or output it.
"""
import os
from nuitka.__past__ import BytesIO, StringIO, basestring
def _indent(elem, level=0, more_sibs=False):
i = "\n"
if level:
i += (level - 1) * " "
num_kids = len(elem)
if num_kids:
if not elem.text or not elem.text.strip():
elem.text = i + " "
if level:
elem.text += " "
count = 0
for kid in elem:
_indent(kid, level + 1, count < num_kids - 1)
count += 1
if not elem.tail or not elem.tail.strip():
elem.tail = i
if more_sibs:
elem.tail += " "
else:
if level and (not elem.tail or not elem.tail.strip()):
elem.tail = i
if more_sibs:
elem.tail += " "
return elem
def _dedent(elem, level=0):
if not elem.text or not elem.text.strip():
elem.text = ""
for child in elem:
_dedent(child, level + 1)
if not elem.tail or not elem.tail.strip():
elem.tail = ""
return elem
try:
import xml.etree.ElementTree
xml_module = xml.etree.ElementTree
Element = xml.etree.ElementTree.Element
def xml_tostring(tree, indent=True, encoding=None):
if indent:
_indent(tree)
elif not indent:
_dedent(tree)
return xml_module.tostring(tree, encoding=encoding)
except ImportError:
xml_module = None
Element = None
xml_tostring = None
# TODO: Use the writer to create the XML we output. That should be more
# scalable and/or faster.
# try:
# from lxml import (
# xmlfile as xml_writer, # pylint: disable=I0021,import-error,unused-import
# )
# except ImportError:
# xml_writer = None
def convertXmlToBytes(tree, indent=True, encoding=None):
return xml_tostring(tree, indent=indent, encoding=encoding)
def convertXmlToString(tree):
result = convertXmlToBytes(tree, encoding="utf8")
if str is not bytes:
result = result.decode("utf8")
return result
def convertStringToXML(text, use_lxml=False):
if type(text) is str:
return convertFileToXML(StringIO(text), use_lxml=use_lxml)
else:
return convertFileToXML(BytesIO(text), use_lxml=use_lxml)
def convertFileToXML(file_handle, use_lxml=False):
if isinstance(file_handle, basestring):
if not os.path.isfile(file_handle):
return None
if use_lxml:
from lxml import etree # pylint: disable=I0021,import-error
# TODO: Catch parse error exception to return None as well.
return etree.parse(file_handle).getroot()
else:
try:
return xml_module.parse(file_handle).getroot()
except xml.etree.ElementTree.ParseError:
return None
def appendTreeElement(parent, *args, **kwargs):
element = Element(*args, **kwargs)
parent.append(element)
return element
def dumpTreeXMLToFile(tree, output_file):
"""Write an XML node tree to a file."""
value = convertXmlToBytes(tree).rstrip()
output_file.write(value)
output_file.write(b"\n")
# Part of "Nuitka", an optimizing Python compiler that is compatible and
# integrates with CPython, but also works on its own.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.