1

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.

12
  • 1
    Your "'/'" vs '/' problem sounds like you're viewing the result in two different ways. Viewing a variable in the interactive prompt by typing its name by itself on a line can give you a different result than if you explicitly use a print function. How are you viewing the contents of arg_list? An MCVE would be just terrific here :-) Commented Jun 5, 2015 at 12:47
  • As input string to functools.partial which fails with "'/'" but not with '/'. And using my IDE as debug tool. Commented Jun 5, 2015 at 12:50
  • So is that a "no" for an MCVE, then...? Commented Jun 5, 2015 at 12:53
  • @ Kevin, you are right, I will make a MCVE. Sorry Kevin. Please wait a few minutes. Commented Jun 5, 2015 at 12:56
  • 1
    Are you looking for a list of arguments in arg_list? ["'\'"] or ["interval=1, percpu=True"] or ["interval=1", "percpu=True"] vs. "'\'" and "interval=1, percpu=True" what about this one line regular expression? re.findall("\((.*?)\)", stm) Commented Jun 5, 2015 at 13:10

1 Answer 1

1

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]
Sign up to request clarification or add additional context in comments.

14 Comments

no there is a difference. I added functools.partial code. '/' does return a correct number (a percent), But " '/ ' " returns an error code.
@Bernard because '/' is not equal to "'/'". The former is a string of 1 character, the latter is a string of 3 characters. You need to modify your regular expression, so it strips single quotes
that is possible. I tried that, (hardcoded) and it works. But then my previous statement But the input is user code, which can be anything. It can also be ' "/" '
But then stm = 'psutil.cpu_percent(interval=1, percpu=True)' will fail. I was searching for a elegant pythonic solution.
@Bernard, before you accept, let me give you two more mean examples. Then tell me if they can occur and if this code properly resolves them. 'someFunc(("mean", "tuple")).meanSecond("function")' and 'someFunc(1, \'4=2*2\', arg1="4,5")'
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.