Skip to content

Commit 37d4fe7

Browse files
author
Release Manager
committed
sagemathgh-41032: Fix sageinspect for Python 3.14 1.In Python 3.14, the AST representation was fully unified to use ``ast.Constant`` nodes for all literal values (numbers, strings, booleans, None). Previously, Python 3.8-3.13 still generated legacy node types (``ast.Num``, ``ast.Str``, ``ast.NameConstant``) for backward compatibility. The ``SageArgSpecVisitor`` class had visit methods for the legacy node types but was missing ``visit_Constant()``, causing it to return None for all constant default argument values when parsing function signatures on Python 3.14. This fix adds the ``visit_Constant()`` method to properly handle the unified AST representation, allowing correct extraction of default argument values like base=0 in ``Integer.__init__(self, x=None, base=0)``. 2. In line 464, The output format is changed in python 3.14 - Old format: ``<ast.Assign object at ...>`` contains "Assign" - New format: ``Assign(targets=[...], ...)`` starts with "Assign" 3. Remove the deprecated visit methods from 3.8 and finally deleted in python 3.14. <!-- ^ Please provide a concise and informative title. --> <!-- ^ Don't put issue numbers in the title, do this in the PR description below. --> <!-- ^ For example, instead of "Fixes sagemath#12345" use "Introduce new method to calculate 1 + 2". --> <!-- v Describe your changes below in detail. --> <!-- v Why is this change required? What problem does it solve? --> <!-- v If this PR resolves an open issue, please link to it here. For example, "Fixes sagemath#12345". --> ### 📝 Checklist <!-- Put an `x` in all the boxes that apply. --> - [x] The title is concise and informative. - [x] The description explains in detail what this PR is about. - [x] I have linked a relevant issue or discussion. - [x] I have created tests covering the changes. - [ ] I have updated the documentation and checked the documentation preview. ### ⌛ Dependencies <!-- List all open PRs that this PR logically depends on. For example, --> <!-- - sagemath#12345: short description why this is a dependency --> <!-- - sagemath#34567: ... --> sagemath#41028 (part) URL: sagemath#41032 Reported by: Chenxin Zhong Reviewer(s): Chenxin Zhong, Copilot, Tobias Diez, user202729
2 parents 60ff00e + 95311c9 commit 37d4fe7

File tree

1 file changed

+25
-72
lines changed

1 file changed

+25
-72
lines changed

src/sage/misc/sageinspect.py

Lines changed: 25 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -460,8 +460,9 @@ class SageArgSpecVisitor(ast.NodeVisitor):
460460
sage: v = visitor.visit(ast.parse("{'a':('e',2,[None,({False:True},'pi')]), 37.0:'temp'}").body[0].value)
461461
sage: sorted(v.items(), key=lambda x: str(x[0]))
462462
[(37.0, 'temp'), ('a', ('e', 2, [None, ({False: True}, 'pi')]))]
463-
sage: v = ast.parse("jc = ['veni', 'vidi', 'vici']").body[0]; v
464-
<...ast.Assign object at ...>
463+
sage: v = ast.parse("jc = ['veni', 'vidi', 'vici']").body[0]
464+
sage: isinstance(v, ast.Assign)
465+
True
465466
sage: attrs = [x for x in dir(v) if not x.startswith('__')]
466467
sage: '_attributes' in attrs and '_fields' in attrs and 'col_offset' in attrs
467468
True
@@ -492,31 +493,6 @@ def visit_Name(self, node):
492493
"""
493494
return node.id
494495

495-
def visit_NameConstant(self, node):
496-
"""
497-
Visit a Python AST :class:`ast.NameConstant` node.
498-
499-
This is an optimization added in Python 3.4 for the special cases
500-
of True, False, and None.
501-
502-
INPUT:
503-
504-
- ``node`` -- the node instance to visit
505-
506-
OUTPUT: ``None``, ``True``, ``False``
507-
508-
EXAMPLES::
509-
510-
sage: import ast, sage.misc.sageinspect as sms
511-
sage: visitor = sms.SageArgSpecVisitor()
512-
sage: vis = lambda x: visitor.visit_NameConstant(ast.parse(x).body[0].value)
513-
sage: [vis(n) for n in ['True', 'False', 'None']]
514-
[True, False, None]
515-
sage: [type(vis(n)) for n in ['True', 'False', 'None']]
516-
[<class 'bool'>, <class 'bool'>, <class 'NoneType'>]
517-
"""
518-
return node.value
519-
520496
def visit_arg(self, node):
521497
r"""
522498
Visit a Python AST :class:`ast.arg` node.
@@ -544,51 +520,6 @@ def visit_arg(self, node):
544520
"""
545521
return node.arg
546522

547-
def visit_Num(self, node):
548-
"""
549-
Visit a Python AST :class:`ast.Num` node.
550-
551-
INPUT:
552-
553-
- ``node`` -- the node instance to visit
554-
555-
OUTPUT: the number the ``node`` represents
556-
557-
EXAMPLES::
558-
559-
sage: import ast, sage.misc.sageinspect as sms
560-
sage: visitor = sms.SageArgSpecVisitor()
561-
sage: vis = lambda x: visitor.visit_Num(ast.parse(x).body[0].value)
562-
sage: [vis(n) for n in ['123', '0.0']]
563-
[123, 0.0]
564-
565-
.. NOTE::
566-
567-
On Python 3 negative numbers are parsed first, for some reason, as
568-
a UnaryOp node.
569-
"""
570-
return node.value
571-
572-
def visit_Str(self, node):
573-
r"""
574-
Visit a Python AST :class:`ast.Str` node.
575-
576-
INPUT:
577-
578-
- ``node`` -- the node instance to visit
579-
580-
OUTPUT: the string the ``node`` represents
581-
582-
EXAMPLES::
583-
584-
sage: import ast, sage.misc.sageinspect as sms
585-
sage: visitor = sms.SageArgSpecVisitor()
586-
sage: vis = lambda x: visitor.visit_Str(ast.parse(x).body[0].value)
587-
sage: [vis(s) for s in ['"abstract"', "'syntax'", r'''r"tr\ee"''']]
588-
['abstract', 'syntax', 'tr\\ee']
589-
"""
590-
return node.value
591-
592523
def visit_List(self, node):
593524
"""
594525
Visit a Python AST :class:`ast.List` node.
@@ -820,6 +751,28 @@ def visit_UnaryOp(self, node):
820751
if op == 'USub':
821752
return -self.visit(node.operand)
822753

754+
def visit_Constant(self, node):
755+
"""
756+
Visit a Python AST :class:`ast.Constant` node.
757+
758+
INPUT:
759+
760+
- ``node`` -- the node instance to visit
761+
762+
OUTPUT: the constant value the ``node`` represents
763+
764+
EXAMPLES::
765+
766+
sage: import ast, sage.misc.sageinspect as sms
767+
sage: visitor = sms.SageArgSpecVisitor()
768+
sage: vis = lambda x: visitor.visit_Constant(ast.parse(x).body[0].value)
769+
sage: [vis(n) for n in ['123', '0', '3.14', '"hello"', 'True', 'False', 'None']]
770+
[123, 0, 3.14, 'hello', True, False, None]
771+
sage: [type(vis(n)) for n in ['123', '0', '3.14', '"hello"', 'True', 'False', 'None']]
772+
[<class 'int'>, <class 'int'>, <class 'float'>, <class 'str'>, <class 'bool'>, <class 'bool'>, <class 'NoneType'>]
773+
"""
774+
return node.value
775+
823776

824777
def _grep_first_pair_of_parentheses(s):
825778
r"""

0 commit comments

Comments
 (0)