Bernard
Bernard

Reputation: 715

parse statement string for arguments using regex in Python

I have user input statements which I would like to parse for arguments. If possible using regex.

I have read much about functools.partial on Stackoverflow where I could not find argument parsing. Also in regex on Stackoverflow I could not find how to check for a match, but exclude the used tokens. The Python tokenizer seems to heavy for my purpose.

import re

def getarguments(statement):      
    prog = re.compile("([(].*[)])")
    result = prog.search(statement) 
    m = result.group()  
    # m = '(interval=1, percpu=True)'
    # or m = "('/')"
    # strip the parentheses, ugly but it works
    return statement[result.start()+1:result.end()-1] 

stm = 'psutil.cpu_percent(interval=1, percpu=True)'
arg_list = getarguments(stm) 
print(arg_list) # returns : interval=1, percpu=True

# But combining single and double quotes like
stm = "psutil.disk_usage('/').percent"
arg_list = getarguments(stm) # in debug value is "'/'"   
print(arg_list) # when printed value is : '/'

callfunction = psutil.disk_usage
args = []
args.append(arg_list)
# args.append('/')
funct1 = functools.partial(callfunction, *args)
perc = funct1().percent
print(perc)  

This results an error : builtins.FileNotFoundError: [Errno 2] No such file or directory: "'/'"

But

callfunction = psutil.disk_usage
args = []
#args.append(arg_list)
args.append('/')
funct1 = functools.partial(callfunction, *args)
perc = funct1().percent
print(perc)  

Does return (for me) 20.3 This is correct. So there is somewhere a difference.

The weird thing is, if I view the content in my IDE (WingIDE) the result is "'/'" and then, if I want to view the details then the result is '/'

I use Python 3.4.0 What is happening here, and how to solve? Your help is really appreciated.

Upvotes: 1

Views: 323

Answers (1)

Konstantin
Konstantin

Reputation: 25339

getarguments("psutil.disk_usage('/').percent") returns '/'. You can check this by printing len(arg_list), for example.

Your IDE adds ", because by default strings are enclosed into single quotes '. Now you have a string which actually contains ', so IDE uses double quotes to enclose the string.

Note, that '/' is not equal to "'/'". The former is a string of 1 character, the latter is a string of 3 characters. So in order to get things right you need to strip quotes (both double and single ones) in getarguments. You can do it with following snippet

if (s.startswith('\'') and s.endswith('\'')) or 
        (s.startswith('\"') and s.endswith('\"')):
   s = s[1:-1]

Upvotes: 1

Related Questions