patternpythonModerate
Python preprocesser that allows "until" and "unless" statements
Viewed 0 times
allowsunlessuntilpreprocesserstatementsthatpythonand
Problem
I've implemented the beginnings of a Python preprocesser I plan to implement sometime in the future, and the below code is my simple prototype. At the moment, it only converts
py_preproc.py
For reference, here's an example of a code file using
```
iterator = 10
until iterator == 0:
print(iterator)
iterator -= 1
unless iterator != 0:
until and unless statements.py_preproc.py
"""
A simple Python utility that converts
non-valid Python code, like `until`,
and `unless` blocks to valid Python
code.
"""
from sys import argv
try:
file_path = argv[1]
execute_results = argv[2]
except IndexError:
raise Exception("Two argv arguments are required, file_path, and execute_results.")
def open_code_file():
"""
Opens the code file to do the conversion
on, and returns the read version as a
string.
"""
with open(file_path, "r+") as code_file:
return code_file.read()
def replace_items(file_string):
"""
Replace specific pieces of the code_file
with valid Python code. Currently only
`until`, and `unless` blocks are replaced.
"""
return file_string.replace(
"until", "while not"
).replace(
"unless", "if not"
)
def evaluate_result(result_string):
"""
Evaluates the converted result, after
the code has been converted to valid
Python code.
"""
py_string_compiled = compile(result_string, "fakemodule", "exec")
exec(py_string_compiled)
def main():
file_string = open_code_file()
new_file_string = replace_items(file_string)
if execute_results == "-true":
evaluate_result(new_file_string)
elif execute_results == "-false":
with open(file_path) as file_to_write:
file_to_write.truncate()
file_to_write.write(new_file_string)
else:
raise Exception("Invalid argument \"{argument}\".".format(argument=execute_results))
if __name__ == '__main__':
main()For reference, here's an example of a code file using
until and unless, before it's preprocessed.```
iterator = 10
until iterator == 0:
print(iterator)
iterator -= 1
unless iterator != 0:
Solution
-
Remco Gerlich is quite right to point out that this preprocessor does not work on general Python code, because it uses string replacement. Thus
-
Additionally, Bakuriu is quite right to point out that the transformation of
which would be changed to:
where the condition is wrong, because
This problem makes it hopeless to attempt this preprocessing at the level of text, or even of tokens: you need a parser to find the end of the condition. Consider an expression like:
which needs to be transformed into:
Remco Gerlich is quite right to point out that this preprocessor does not work on general Python code, because it uses string replacement. Thus
unless will be changed to if not in strings (such as regular expressions, templates, and docstrings), potentially breaking the code. The preprocessor itself is just one example of the kind of code which will be broken: it is not good enough to respond that this concern is "silly".-
Additionally, Bakuriu is quite right to point out that the transformation of
unless to if not is inadequate: it only works on very simple examples. But consider:a unless b or c else dwhich would be changed to:
a if not b or c else dwhere the condition is wrong, because
not b or c parses as (not b) or c. The correct transformation is:a if not (b or c) else dThis problem makes it hopeless to attempt this preprocessing at the level of text, or even of tokens: you need a parser to find the end of the condition. Consider an expression like:
a unless b or (c unless d and e else f) else gwhich needs to be transformed into:
a if not (b or (c if not (d and e) else f)) else gCode Snippets
a unless b or c else da if not b or c else da if not (b or c) else da unless b or (c unless d and e else f) else ga if not (b or (c if not (d and e) else f)) else gContext
StackExchange Code Review Q#95055, answer score: 14
Revisions (0)
No revisions yet.