66import os
77import socket
88import struct
9+ import sys
910import threading
1011import xml .etree .ElementTree as ET_xml
1112from collections import namedtuple
1213from typing import Optional
1314from warnings import warn
1415
15- import defusedxml .ElementTree as ET_secure_xml
16-
1716import irods .exception as ex
1817
1918from . import quasixml as ET_quasi_xml
@@ -97,24 +96,22 @@ class BadXMLSpec(RuntimeError):
9796
9897def current_XML_parser (get_module = False ):
9998 d = getattr (_thrlocal , "xml_type" , _default_XML )
100- return d if not get_module else _XML_parsers [ d ]
99+ return d if not get_module else _get_XML_parser_for ( d )
101100
102101
103102def default_XML_parser (get_module = False ):
104103 d = _default_XML
105- return d if not get_module else _XML_parsers [d ]
104+ return d if not get_module else _get_XML_parser_for (d )
105+
106+
107+ def _get_XML_parser_for (d ):
108+ return sys .modules [__name__ ]._XML_parser [d ]
106109
107110
108111def string_for_XML_parser (parser_enum ):
109112 return PARSER_TYPE_STRINGS [parser_enum ]
110113
111114
112- _XML_parsers = {
113- XML_Parser_Type .STANDARD_XML : ET_xml ,
114- XML_Parser_Type .QUASI_XML : ET_quasi_xml ,
115- XML_Parser_Type .SECURE_XML : ET_secure_xml ,
116- }
117-
118115_reversed_XML_strings_lookup = {v : k for k , v in _XML_strings .items ()}
119116
120117
@@ -168,9 +165,9 @@ def ET(xml_type=(), server_version=None):
168165 _thrlocal .irods_server_version = tuple (
169166 server_version
170167 ) # A default server version for Quasi-XML parsing is set (from the environment) and
171- return _XML_parsers [
168+ return _get_XML_parser_for (
172169 current_XML_parser ()
173- ] # applies to all threads in which ET() has not been called to update the value.
170+ ) # applies to all threads in which ET() has not been called to update the value.
174171
175172
176173logger = logging .getLogger (__name__ )
@@ -188,7 +185,23 @@ def __getattr__(name):
188185 if name in _deprecated_names :
189186 warn (f"{ name } is deprecated" , DeprecationWarning , stacklevel = 2 )
190187 return _deprecated_names [name ]
191- raise AttributeError (f"module { __name__ !r} has no attribute { name !r} " )
188+
189+ global __XML_parser
190+ # Define the _XML_parser module variable only when accessed (#802).
191+ if name == '_XML_parser' :
192+ impl = globals ().get ('__XML_parser' )
193+ if not impl :
194+ import defusedxml .ElementTree as ET_secure_xml
195+
196+ impl = __XML_parser = {
197+ XML_Parser_Type .STANDARD_XML : ET_xml ,
198+ XML_Parser_Type .QUASI_XML : ET_quasi_xml ,
199+ XML_Parser_Type .SECURE_XML : ET_secure_xml ,
200+ }
201+ return impl
202+
203+ message = f"module { __name__ !r} has no attribute { name !r} "
204+ raise AttributeError (message )
192205
193206
194207UNICODE = str
0 commit comments