Skip to content

ast.Num or visit_Num method in python return a wrong sign number of node #93447

Closed as not planned
@markgwaps04

Description

@markgwaps04

I'am using built in module AST (Abstract Syntax Tress) to manually parse a expression instead using Eval, Exec or Compile. In python 2 is perfectly work fine. However in python 3, it take 3 process of node before parsing the expression and the result is wrong cause it's supposed to be negative but it's returning a positive value.

Python 2

def test(string_value):
    parse_expression = ast.parse(string_value)
    node = parse_expression.body
    
    for per in node:
        
        # return <_ast.Expr object at 0x7fa695c78510>
        print(per)
        
        # return <_ast.Num object at 0x7ff4b0b1de50>
        print(per.value)
        
        # return -890
        print(per.value.n)

        pass
    pass

test("-890")

Python 3

import ast

def test(string_value):
    parse_expression = ast.parse(string_value)
    node = parse_expression.body
    
    for per in node:
        # return <_ast.Expr object at 0x7fe6a0ce34c0>
        print(per)
        
        #return <_ast.UnaryOp object at 0x7f0b92941790>
        print(per.value)
        
        # ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_attributes', '_fields', 'col_offset', 'end_col_offset', 'end_lineno', 'lineno', 'op', 'operand']
        
        print(dir(per.value))
        
        
        print(per.value.col_offset) #0
        print(per.value.end_col_offset) #4
        print(per.value.end_lineno) #1
        print(per.value.lineno) #1
        print(per.value.op) # <_ast.USub object at 0x7f055c489610>
        print(per.value.operand) #<_ast.Constant object at 0x7f055c45d8e0>
        
        # ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_attributes', '_fields']
        
        print(dir(per.value.op))
        
        # ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_attributes', '_fields', 'col_offset', 'end_col_offset', 'end_lineno', 'kind', 'lineno', 'n', 's', 'value']
        
        print(dir(per.value.operand))
        
        print(per.value.operand.col_offset) #1
        print(per.value.operand.end_col_offset) #4
        print(per.value.operand.end_lineno) #1
        print(per.value.operand.kind) #None
        print(per.value.operand.lineno) #1
        
        # it's return a postive value instead negative value
        
        print(per.value.operand.n) #890
        print(per.value.operand.s) #890
        print(per.value.operand.value) #890
        
        # return -890
        # print(per.value.n)
        
        pass
    pass

test("-890")

Metadata

Metadata

Assignees

No one assigned

    Labels

    type-bugAn unexpected behavior, bug, or error

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions