4

I am trying to make the following statement more flexible:

for posting in page.findAll(attrs = {"id": re.compile(r'''post\d+''')}):

The following part is retrieved dynamically from a CSV file and stored in a string (for example the string called test). The CSV is stored in a secure location, accessible for admins only.

attrs = {"id": re.compile(r'''post\d+''')}

Can I integrate the variable as following by using an eval(test) or exec(test) in stead of just test?

for posting in page.findAll(test)):
2
  • 2
    @user620007: First. You can omit "Dear," and "Thanks". They don't help. Really. It's not rude to omit this. Second. Please look at your question. the "bold" thing didn't work, did it? Please update your question to make it more clear. Commented Feb 16, 2011 at 16:44
  • 7
    Third, welcome to SO. Fresh blood is good for the community, even if you don't know all of our quirks yet. Commented Feb 16, 2011 at 16:55

4 Answers 4

5

If you want to run code from user input (file contents are input), you'll need eval or exec, by these names or some other (specifically, you need exec for statements - assignment is a statement).

But you don't want to (and shouldn't) do that, because that's evil, insecure, totally unnecessary, etc. Drop the assignment (just store the dict) and the re.compile call, then you can use ast.literal_eval on it and you're quite safe (you should still catch syntax errors and everything else that may go wrong to display a sensible error message, but malicious code should be close to impossible and it's not nearly as dirty). You can apply the re.compile after loading if you thing it's needed.

Sign up to request clarification or add additional context in comments.

Comments

1

Unless you have absolutely no control over the CSV source, avoid, at all cost these kinds of loading.

  • save the regex as seriliazed data using the pickle module (or better, just save the string)
  • Save your data as JSON using the json module
  • write it to a file using the csv module

Then do the opposite to get the data from the file.

If you can't control the CSV generation, try extracting the data manually using split or the re module.

eval and exec are 'last chance solution'. Avoid using them unless you have no other ways.

2 Comments

The CSV is stored in a secure location, accessible for admins only.
@user620007: Are you an admin building the system, or just trying to interface with someone else's system?
1

The most secure is ast.literal_eval():

>>> args = ast.literal_eval('{"a":1}')
>>> args
{'a': 1}

You can use it as:

some_function_or_method(**args)

Comments

0

Neither - this is Python - you can write a eries of named parameters and the desired values to call a function as dictionary. In this case, a dictionary which value fot the key "attrs" is also a dictionary. Just prepend to "**" to the dictionary name when calling the function:

test= {"attrs": {\"id\": re.compile(r'''post\d+''')} }

for posting in page.findAll(**test}):
   (...)

2 Comments

The question is about loading the attrs dynamically from a file, not about unpacking a dictionary.
And so, what is the problem with populating your data as strings in the dictionary from the data on your file?

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.