https://github.com/python/cpython/commit/06822bfbf625e9777813542be0b8a2d10a685f30
commit: 06822bfbf625e9777813542be0b8a2d10a685f30
branch: main
author: Jelle Zijlstra <jelle.zijls...@gmail.com>
committer: AA-Turner <9087854+aa-tur...@users.noreply.github.com>
date: 2025-04-02T18:15:05Z
summary:

gh-118761: Fix star-import of ast (#132025)

Co-authored-by: Adam Turner <9087854+aa-tur...@users.noreply.github.com>

files:
M Lib/_ast_unparse.py
M Lib/ast.py

diff --git a/Lib/_ast_unparse.py b/Lib/_ast_unparse.py
index c03f9bd4c1d40b..56d9e935dd9d87 100644
--- a/Lib/_ast_unparse.py
+++ b/Lib/_ast_unparse.py
@@ -6,8 +6,6 @@
 from contextlib import contextmanager, nullcontext
 from enum import IntEnum, auto, _simple_enum
 
-__all__ = ('unparse',)
-
 # Large float and imaginary literals get turned into infinities in the AST.
 # We unparse those infinities to INFSTR.
 _INFSTR = "1e" + repr(sys.float_info.max_10_exp + 1)
@@ -48,7 +46,7 @@ def next(self):
 _MULTI_QUOTES = ('"""', "'''")
 _ALL_QUOTES = (*_SINGLE_QUOTES, *_MULTI_QUOTES)
 
-class _Unparser(NodeVisitor):
+class Unparser(NodeVisitor):
     """Methods in this class recursively traverse an AST and
     output source code for the abstract syntax; original formatting
     is disregarded."""
@@ -1142,9 +1140,3 @@ def visit_MatchOr(self, node):
         with self.require_parens(_Precedence.BOR, node):
             self.set_precedence(_Precedence.BOR.next(), *node.patterns)
             self.interleave(lambda: self.write(" | "), self.traverse, 
node.patterns)
-
-
-def unparse(ast_obj):
-    unparser = _Unparser()
-    return unparser.visit(ast_obj)
-unparse.__module__ = 'ast'  # backwards compatibility
diff --git a/Lib/ast.py b/Lib/ast.py
index 8be4f68455150a..507fec5f2d3890 100644
--- a/Lib/ast.py
+++ b/Lib/ast.py
@@ -24,7 +24,6 @@
     :copyright: Copyright 2008 by Armin Ronacher.
     :license: Python License.
 """
-import sys
 from _ast import *
 
 
@@ -621,8 +620,19 @@ class Param(expr_context):
     """Deprecated AST node class.  Unused in Python 3."""
 
 
+def unparse(ast_obj):
+    global _Unparser
+    try:
+        unparser = _Unparser()
+    except NameError:
+        from _ast_unparse import Unparser as _Unparser
+        unparser = _Unparser()
+    return unparser.visit(ast_obj)
+
+
 def main():
     import argparse
+    import sys
 
     parser = argparse.ArgumentParser()
     parser.add_argument('infile', nargs='?', default='-',
@@ -651,15 +661,3 @@ def main():
 
 if __name__ == '__main__':
     main()
-
-def __dir__():
-    dir_ = {n for n in globals() if not n.startswith('_') and n != 'sys'}
-    return sorted(dir_ | {'unparse'})
-
-def __getattr__(name):
-    if name == 'unparse':
-        global unparse
-        from _ast_unparse import unparse
-        return unparse
-
-    raise AttributeError(f'module {__name__!r} has no attribute {name!r}')

_______________________________________________
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com

Reply via email to