Embedding python code into text document question.

T

Thomas Troeger

Dear all,

I've written a program that parses a string or file for embedded python
commands, executes them and fills in the returned value. The input might
look like this:

process id: $$return os.getpid()$$
current date: $$return time.ctime()$$
superuser: $$
if os.geteuid():
return "Yes"
else:
return "No"$$

I've tried several solutions using eval, execfile or compile, but none
of those would solve my problem. Does anyone have a solution that works?
Any suggestions? Any help will be appreciated :)

Regards,
Thomas.
 
G

grflanagan

Dear all,

I've written a program that parses a string or file for embedded python
commands, executes them and fills in the returned value. The input might
look like this:

process id: $$return os.getpid()$$
current date: $$return time.ctime()$$
superuser: $$
if os.geteuid():
return "Yes"
else:
return "No"$$

I've tried several solutions using eval, execfile or compile, but none
of those would solve my problem. Does anyone have a solution that works?
Any suggestions? Any help will be appreciated :)


AST visitor approach:

http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/440629
 
T

Thomas Troeger

Ok I've written a small example program to clarify matters:

================ [SNIP] ================
#!/usr/bin/python

import os, sys, time

def template(src, dst, sep):
"""
Copy file from src to dst, executing embedded python code.
"""
try:
# read template file.
f=open(src, "rU")
data="".join(f.readlines())
f.close()

# find embedded python code and execute it.
while True:
# find embedded embedded python command.
offset=data.find(sep)
if offset < 0:
break
offset2=data.find(sep, offset+1)
if offset2 < 0:
break
cmd=data[offset+len(sep):eek:ffset2]

# execute command.
try:
ret=""
exec(compile(cmd,
'<from string>', 'exec'))
except:
print "error compiling code `%s'." % cmd

# substitute command with return value.
data=data[:eek:ffset]+str(ret)+\
data[offset2+len(sep):]

# write translated input.
f=open(dst, "w")
f.write(data)
f.close()
except:
print "error processing template file `%s'." % src

# ------------------------------ main -------------------------------

if len(sys.argv) > 2:
template(sys.argv[1], sys.argv[2], '$$')
================ [SNIP] ================

This is the example input that works:

================ [SNIP] ================
process id: $$ret=os.getpid()$$
current date: $$ret=time.ctime()$$
superuser: $$
if os.geteuid():
ret="No"
else:
ret="Yes"$$
================ [SNIP] ================

Now the `ret= ...' mechanism is not nice, I'd prefer to have a return
statement instead.
 
T

tezlo

Thomas Troeger said:
I've written a program that parses a string or file for embedded
python commands, executes them and fills in the returned value.
...
I've tried several solutions using eval, execfile or compile, but
none of those would solve my problem. Does anyone have a solution
that works? Any suggestions? Any help will be appreciated :)

Hi,
first, to quote the manual [1]
Be aware that the return and yield statements may not be used
outside of function definitions even within the context of code
passed to the exec statement.

Once you get rid of those return statements, the first two
substitutions could simpy be eval'ed. Conditions and loops can be
exec'ed, but you need to capture the output somehow. You could
replace sys.stdout with your own StringIO before you exec, and
use 'print' instead of 'return' in your templates.

Two basic approaches: you eval every substitution by itself [2], or you
parse the whole template into one big python chunk, and exec that [3].

[1] http://docs.python.org/ref/exec.html
[2] http://blog.ianbicking.org/templating-via-dict-wrappers.html
[3] http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/464766
 
M

Marc 'BlackJack' Rintsch

I've written a program that parses a string or file for embedded python
commands, executes them and fills in the returned value. The input might
look like this:

process id: $$return os.getpid()$$
current date: $$return time.ctime()$$
superuser: $$
if os.geteuid():
return "Yes"
else:
return "No"$$

I've tried several solutions using eval, execfile or compile, but none
of those would solve my problem. Does anyone have a solution that works?
Any suggestions? Any help will be appreciated :)

My suggestion would be: use one of the many already existing templating
systems.

Ciao,
Marc 'BlackJack' Rintsch
 
M

MRAB

Dear all,

I've written a program that parses a string or file for embedded python
commands, executes them and fills in the returned value. The input might
look like this:

process id: $$return os.getpid()$$
current date: $$return time.ctime()$$
superuser: $$
if os.geteuid():
return "Yes"
else:
return "No"$$

I've tried several solutions using eval, execfile or compile, but none
of those would solve my problem. Does anyone have a solution that works?
Any suggestions? Any help will be appreciated :)
You could wrap the bits of code in a def statement and then exec it:
3904
 
E

Erik Max Francis

Thomas said:
I've written a program that parses a string or file for embedded python
commands, executes them and fills in the returned value. The input might
look like this:

process id: $$return os.getpid()$$
current date: $$return time.ctime()$$
superuser: $$
if os.geteuid():
return "Yes"
else:
return "No"$$

I've tried several solutions using eval, execfile or compile, but none
of those would solve my problem. Does anyone have a solution that works?
Any suggestions? Any help will be appreciated :)

What you're looking for is a templating system for Python. There are
already many with varying degrees of complexity and emphasis, including
one I've put together, EmPy:

http://www.alcyone.com/software/empy/

For more, google around for Python templating.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top