[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.python

Embedding python code into text document question.

Thomas Troeger

1/10/2008 1:10:00 PM

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.
7 Answers

G F

1/10/2008 1:59:00 PM

0

On Jan 10, 2:10 pm, Thomas Troeger <thomas.troeger....@siemens.com>
wrote:
> 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/Rec...

Thomas Troeger

1/10/2008 2:02:00 PM

0

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):offset2]

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

# substitute command with return value.
data=data[:offset]+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.

tezlo

1/10/2008 2:27:00 PM

0

Thomas Troeger <thomas.troeger.ext@siemens.com> wrote:
> 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...
[2] http://blog.ianbicking.org/templating-via-dict-wra...
[3] http://aspn.activestate.com/ASPN/Cookbook/Python/Rec...

Marc 'BlackJack' Rintsch

1/10/2008 2:30:00 PM

0

On Thu, 10 Jan 2008 14:10:05 +0100, Thomas Troeger wrote:

> 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

MRAB

1/10/2008 8:52:00 PM

0

On Jan 10, 1:10 pm, Thomas Troeger <thomas.troeger....@siemens.com>
wrote:
> 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:

>>> print field
return os.getpid()
>>> exec("def field_func():\n" + "".join(" %s\n" % line for line in field.splitlines()))
>>> print field_func()
3904

Erik Max Francis

1/10/2008 10:07:00 PM

0

Thomas Troeger wrote:

> 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/soft...

For more, google around for Python templating.

--
Erik Max Francis && max@alcyone.com && http://www.alcyon...
San Jose, CA, USA && 37 18 N 121 57 W && AIM, Y!M erikmaxfrancis
If the sun comes up / And you're not home / I'll be strong
-- India Arie

Thomas Troeger

1/11/2008 10:12:00 AM

0

Thanks guys, you've helped me very much :) Cheers & happy new year!