@@ -294,9 +294,7 @@ def get_docstring(node, clean=True):
294
294
if not (node .body and isinstance (node .body [0 ], Expr )):
295
295
return None
296
296
node = node .body [0 ].value
297
- if isinstance (node , Str ):
298
- text = node .s
299
- elif isinstance (node , Constant ) and isinstance (node .value , str ):
297
+ if isinstance (node , Constant ) and isinstance (node .value , str ):
300
298
text = node .value
301
299
else :
302
300
return None
@@ -499,27 +497,66 @@ def generic_visit(self, node):
499
497
return node
500
498
501
499
500
+ _DEPRECATED_VALUE_ALIAS_MESSAGE = (
501
+ "{name} is deprecated and will be removed in Python {remove}; use value instead"
502
+ )
503
+ _DEPRECATED_CLASS_MESSAGE = (
504
+ "{name} is deprecated and will be removed in Python {remove}; "
505
+ "use ast.Constant instead"
506
+ )
507
+
508
+
502
509
# If the ast module is loaded more than once, only add deprecated methods once
503
510
if not hasattr (Constant , 'n' ):
504
511
# The following code is for backward compatibility.
505
512
# It will be removed in future.
506
513
507
- def _getter (self ):
514
+ def _n_getter (self ):
515
+ """Deprecated. Use value instead."""
516
+ import warnings
517
+ warnings ._deprecated (
518
+ "Attribute n" , message = _DEPRECATED_VALUE_ALIAS_MESSAGE , remove = (3 , 14 )
519
+ )
520
+ return self .value
521
+
522
+ def _n_setter (self , value ):
523
+ import warnings
524
+ warnings ._deprecated (
525
+ "Attribute n" , message = _DEPRECATED_VALUE_ALIAS_MESSAGE , remove = (3 , 14 )
526
+ )
527
+ self .value = value
528
+
529
+ def _s_getter (self ):
508
530
"""Deprecated. Use value instead."""
531
+ import warnings
532
+ warnings ._deprecated (
533
+ "Attribute s" , message = _DEPRECATED_VALUE_ALIAS_MESSAGE , remove = (3 , 14 )
534
+ )
509
535
return self .value
510
536
511
- def _setter (self , value ):
537
+ def _s_setter (self , value ):
538
+ import warnings
539
+ warnings ._deprecated (
540
+ "Attribute s" , message = _DEPRECATED_VALUE_ALIAS_MESSAGE , remove = (3 , 14 )
541
+ )
512
542
self .value = value
513
543
514
- Constant .n = property (_getter , _setter )
515
- Constant .s = property (_getter , _setter )
544
+ Constant .n = property (_n_getter , _n_setter )
545
+ Constant .s = property (_s_getter , _s_setter )
516
546
517
547
class _ABC (type ):
518
548
519
549
def __init__ (cls , * args ):
520
550
cls .__doc__ = """Deprecated AST node class. Use ast.Constant instead"""
521
551
522
552
def __instancecheck__ (cls , inst ):
553
+ if cls in _const_types :
554
+ import warnings
555
+ warnings ._deprecated (
556
+ f"ast.{ cls .__qualname__ } " ,
557
+ message = _DEPRECATED_CLASS_MESSAGE ,
558
+ remove = (3 , 14 )
559
+ )
523
560
if not isinstance (inst , Constant ):
524
561
return False
525
562
if cls in _const_types :
@@ -543,6 +580,10 @@ def _new(cls, *args, **kwargs):
543
580
if pos < len (args ):
544
581
raise TypeError (f"{ cls .__name__ } got multiple values for argument { key !r} " )
545
582
if cls in _const_types :
583
+ import warnings
584
+ warnings ._deprecated (
585
+ f"ast.{ cls .__qualname__ } " , message = _DEPRECATED_CLASS_MESSAGE , remove = (3 , 14 )
586
+ )
546
587
return Constant (* args , ** kwargs )
547
588
return Constant .__new__ (cls , * args , ** kwargs )
548
589
@@ -565,10 +606,19 @@ class Ellipsis(Constant, metaclass=_ABC):
565
606
_fields = ()
566
607
567
608
def __new__ (cls , * args , ** kwargs ):
568
- if cls is Ellipsis :
609
+ if cls is _ast_Ellipsis :
610
+ import warnings
611
+ warnings ._deprecated (
612
+ "ast.Ellipsis" , message = _DEPRECATED_CLASS_MESSAGE , remove = (3 , 14 )
613
+ )
569
614
return Constant (..., * args , ** kwargs )
570
615
return Constant .__new__ (cls , * args , ** kwargs )
571
616
617
+ # Keep another reference to Ellipsis in the global namespace
618
+ # so it can be referenced in Ellipsis.__new__
619
+ # (The original "Ellipsis" name is removed from the global namespace later on)
620
+ _ast_Ellipsis = Ellipsis
621
+
572
622
_const_types = {
573
623
Num : (int , float , complex ),
574
624
Str : (str ,),
@@ -1699,6 +1749,22 @@ def unparse(ast_obj):
1699
1749
return unparser .visit (ast_obj )
1700
1750
1701
1751
1752
+ _deprecated_globals = {
1753
+ name : globals ().pop (name )
1754
+ for name in ('Num' , 'Str' , 'Bytes' , 'NameConstant' , 'Ellipsis' )
1755
+ }
1756
+
1757
+ def __getattr__ (name ):
1758
+ if name in _deprecated_globals :
1759
+ globals ()[name ] = value = _deprecated_globals [name ]
1760
+ import warnings
1761
+ warnings ._deprecated (
1762
+ f"ast.{ name } " , message = _DEPRECATED_CLASS_MESSAGE , remove = (3 , 14 )
1763
+ )
1764
+ return value
1765
+ raise AttributeError (f"module 'ast' has no attribute '{ name } '" )
1766
+
1767
+
1702
1768
def main ():
1703
1769
import argparse
1704
1770
0 commit comments