Re: Returning a value from exec or a better solution

2011-08-31 Thread Arnaud Delobelle
On 30 August 2011 22:48, Rob Williscroft r...@rtw.me.uk wrote:
 Arnaud Delobelle wrote in
 news:CAJ6cK1YVi3NQgdZOUdhAESf133pUkdazM1PkSP=p6xfayvo...@mail.gmail.com in
 gmane.comp.python.general:

 On 30 August 2011 13:31, Jack Trades jacktradespub...@gmail.com wrote:


 On Tue, Aug 30, 2011 at 2:37 AM, Rob Williscroft r...@rtw.me.uk wrote:


  That's brilliant and works flawlessly. ś˙Thank you very much!

 If an impementation (as you say up thread) can populate globals
 or locals with whatever they want, then how do you know that last
 item added was the function definition the user supplied ?

 That's not an issue. The last statement that is executed will be the
 def statement.

 You don't know that, an implementation may for example set __bultins__
 to None, prior to returning, its not an unreasonable thing to do and
 the docs don't say they can't.

I haven't studied the docs but I'm certain that such an implementation
would break a lot of code.

-- 
Arnaud
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Returning a value from exec or a better solution

2011-08-31 Thread Ian Kelly
On Wed, Aug 31, 2011 at 12:35 AM, Arnaud Delobelle arno...@gmail.com wrote:
 You don't know that, an implementation may for example set __bultins__
 to None, prior to returning, its not an unreasonable thing to do and
 the docs don't say they can't.

 I haven't studied the docs but I'm certain that such an implementation
 would break a lot of code.

For example:

a = 42
exec a += 1729
print(a)

...since print would no longer be available in the global namespace.

Cheers,
Ian
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Returning a value from exec or a better solution

2011-08-30 Thread Rob Williscroft
Jack Trades wrote in
news:CAG5udOh1+oE4g9Frjp3pucbHUtWcN34KK35a-Xs2YqkZH9X5=w...@mail.gmail.com
in gmane.comp.python.general: 

 def test():
  src = (
   def double(x):
return x * 2
 )
  globals  = {}
  exec( src, globals )
  return globals[ double ]

 print( test() )

 
 I looked into doing it that way but it still requires that the user
 use a specific name for the function they are defining.  The docs on
 exec say that an implementation may populate globals or locals with
 whatever they want so that also rules out doing a simple for item in
 globals, as there may be more than just the one function in there
 (though I suppose I may be able to work around that).
 
 

Why not just get the name from the user, or use a regular expression
to extract the first (or last, maybe) definition from the source string.

Rob.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Returning a value from exec or a better solution

2011-08-30 Thread Rob Williscroft
Jack Trades wrote in news:CAG5udOiOAge3uHrGSDTZ412GAg+CC-
6u8igoyj0lnf3hnwu...@mail.gmail.com in gmane.comp.python.general:

  class CapturingDict(dict):
 ... def __setitem__(self, key, val):
 ... self.key, self.val = key, val
 ... dict.__setitem__(self, key, val)
 ...
  c = CapturingDict()
  exec(def myfunction(x): return 1, c)
  c.key
 'myfunction'
  c.val
 function myfunction at 0x100634d10

 HTH,

 --
 Arnaud

 
 That's brilliant and works flawlessly.  Thank you very much!

If an impementation (as you say up thread) can populate globals 
or locals with whatever they want, then how do you know that last 
item added was the function definition the user supplied ?

Rob.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Returning a value from exec or a better solution

2011-08-30 Thread Jack Trades
On Tue, Aug 30, 2011 at 2:37 AM, Rob Williscroft r...@rtw.me.uk wrote:


  That's brilliant and works flawlessly.  Thank you very much!

 If an impementation (as you say up thread) can populate globals
 or locals with whatever they want, then how do you know that last
 item added was the function definition the user supplied ?

 Rob.

 --
 http://mail.python.org/mailman/listinfo/python-list



I spoke a bit too soon with the works flawlessly post.  In addition to
your issue, there is also the problem that supplying an empty environment
does not allow the user to call necessary functions (like scheme_eval).


Why not just get the name from the user


That's probably what I'll end up doing, something similar to:

special_forms = {}

def exec_func_def(symbol, def_string, name=None):
  exec(def_string)
  if name is None:
special_forms[symbol] = f
  else:
special_forms[symbol] = eval(name)

It just feels kind of hackish to me, when what I really want to do here is
eval an anonymous function.

-- 
Nick Zarczynski http://www.rentageekit.com
Pointless Programming Blog http://pointlessprogramming.wordpress.com
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Returning a value from exec or a better solution

2011-08-30 Thread Ethan Furman

Jack Trades wrote:

On Tue, Aug 30, 2011 at 2:37 AM, Rob Williscroft wrote:

If an impementation (as you say up thread) can populate globals
or locals with whatever they want, then how do you know that last
item added was the function definition the user supplied ?


Because the implementation will add things before the exec is processed. 
 Then when the exec actually runs, any assignments, definitions, etc, 
from the user supplied string will be added.



I spoke a bit too soon with the works flawlessly post.  In addition to 
your issue, there is also the problem that supplying an empty 
environment does not allow the user to call necessary functions (like 
scheme_eval).


So, just like an implementation, add the functions to the CapturingDict 
before the exec.


One thing to keep in mind:  the CapturingDict only remembers the *last* 
thing created/assigned... so if the user code has more than one 
def/class/name assignment, you won't have ready access to the first 
items, only that last one.


~Ethan~
--
http://mail.python.org/mailman/listinfo/python-list


Re: Returning a value from exec or a better solution

2011-08-30 Thread Rob Williscroft
Ethan Furman wrote in news:4e5d29c8.8010...@stoneleaf.us in 
gmane.comp.python.general:

 Jack Trades wrote:
 On Tue, Aug 30, 2011 at 2:37 AM, Rob Williscroft wrote:
 If an impementation (as you say up thread) can populate globals
 or locals with whatever they want, then how do you know that last
 item added was the function definition the user supplied ?
 
 Because the implementation will add things before the exec is processed. 

How do you know this ?, it isn't what the docs say.

http://docs.python.org/reference/simple_stmts.html#the-exec-statement

Rob.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Returning a value from exec or a better solution

2011-08-30 Thread Ethan Furman

Rob Williscroft wrote:
Ethan Furman wrote in news:4e5d29c8.8010...@stoneleaf.us in 
gmane.comp.python.general:



Jack Trades wrote:

On Tue, Aug 30, 2011 at 2:37 AM, Rob Williscroft wrote:

If an impementation (as you say up thread) can populate globals
or locals with whatever they want, then how do you know that last
item added was the function definition the user supplied ?
Because the implementation will add things before the exec is processed. 


How do you know this ?, it isn't what the docs say.

http://docs.python.org/reference/simple_stmts.html#the-exec-statement


The docs don't say when, true -- so I don't know for sure that all 
additions happen before the exec since I haven't delved into the source 
code...


Okay, just perused builtin_exec in bltinmodule.c, and I can say that 
cPython (somewhere in 3.2-3.3 land) only adds __builtins__ if not 
already there, and that it does it first.


Which makes sense -- after all, what's the point of adding stuff to 
globals() *after* the code has been run?


~Ethan~
--
http://mail.python.org/mailman/listinfo/python-list


Re: Returning a value from exec or a better solution

2011-08-30 Thread Arnaud Delobelle
On 30 August 2011 13:31, Jack Trades jacktradespub...@gmail.com wrote:


 On Tue, Aug 30, 2011 at 2:37 AM, Rob Williscroft r...@rtw.me.uk wrote:


  That's brilliant and works flawlessly.  Thank you very much!

 If an impementation (as you say up thread) can populate globals
 or locals with whatever they want, then how do you know that last
 item added was the function definition the user supplied ?

That's not an issue. The last statement that is executed will be the
def statement.

 Rob.

 I spoke a bit too soon with the works flawlessly post.  In addition to
 your issue, there is also the problem that supplying an empty environment
 does not allow the user to call necessary functions (like scheme_eval).

You could simply prepend the function definition string with whatever
imports are needed.

-- 
Arnaud
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Returning a value from exec or a better solution

2011-08-30 Thread Rob Williscroft
Arnaud Delobelle wrote in 
news:CAJ6cK1YVi3NQgdZOUdhAESf133pUkdazM1PkSP=p6xfayvo...@mail.gmail.com in 
gmane.comp.python.general:

 On 30 August 2011 13:31, Jack Trades jacktradespub...@gmail.com wrote:


 On Tue, Aug 30, 2011 at 2:37 AM, Rob Williscroft r...@rtw.me.uk wrote:


  That's brilliant and works flawlessly. ¶ÿThank you very much!

 If an impementation (as you say up thread) can populate globals
 or locals with whatever they want, then how do you know that last
 item added was the function definition the user supplied ?

 That's not an issue. The last statement that is executed will be the
 def statement.

You don't know that, an implementation may for example set __bultins__ 
to None, prior to returning, its not an unreasonable thing to do and
the docs don't say they can't.

Rob.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Returning a value from exec or a better solution

2011-08-30 Thread Ethan Furman

Rob Williscroft wrote:

Arnaud Delobelle wrote:

That's not an issue. The last statement that is executed will be the
def statement.


You don't know that, an implementation may for example set __bultins__ 
to None, prior to returning, its not an unreasonable thing to do and

the docs don't say they can't.


Yet another excellent reason to have unit tests!

~Ethan~
--
http://mail.python.org/mailman/listinfo/python-list


Re: Returning a value from exec or a better solution

2011-08-30 Thread Ethan Furman

Rob Williscroft wrote:

Arnaud Delobelle wrote:


That's not an issue. The last statement that is executed will be the
def statement.


You don't know that, an implementation may for example set __bultins__ 
to None, prior to returning, its not an unreasonable thing to do and

the docs don't say they can't.


Actually, I think it is unreasonable -- by modifying the globals or 
locals objects *after* the code has been exec'd, information is being 
removed about the environment the code ran in, making introspection (if 
nothing else) more difficult.


Good reasons are required to make life difficult (at least with Python).

~Ethan~
--
http://mail.python.org/mailman/listinfo/python-list


Re: Returning a value from exec or a better solution

2011-08-30 Thread Jack Trades
On Tue, Aug 30, 2011 at 1:19 PM, Ethan Furman et...@stoneleaf.us wrote:


 I spoke a bit too soon with the works flawlessly post.  In addition to
 your issue, there is also the problem that supplying an empty environment
 does not allow the user to call necessary functions (like scheme_eval).



 So, just like an implementation, add the functions to the CapturingDict
 before the exec.


I will probably do that a bit down the road, that also allows exporting only
the things that are absolutely necessary, which is a huge plus.  Right now
I'm trying to keep the code as simple as possible as this Scheme interpreter
is being written as a tutorial in a similar fashion to An Incremental
Approach to Compiler Construction.  I'll add a note about this method of
implementation and link to this discussion.

In the off chance anyone is interested, the series is
herehttp://nickzarr.com/blog4/series/scheme-in-python/and the github
is
here https://github.com/jacktrades/Scheme-in-Python.  It's still very much
in draft form and will probably undergo a number of rewrites, but criticism
is always welcome.

-- 
Nick Zarczynski
Pointless Programming Blog http://pointlessprogramming.wordpress.com
-- 
http://mail.python.org/mailman/listinfo/python-list


Returning a value from exec or a better solution

2011-08-29 Thread Jack Trades
I'm writing a Scheme interpreter and I need to be able to create and return
a Python function from a string.

This is a port of another Scheme interpreter I wrote in Scheme.  What I'm
trying to do looked like this:

(define (scheme-syntax expr)
  (hash-table-set! global-syntax (car expr) (eval (cadr expr

Where expr was of the form (symbol (lambda (exp) ...)).  This added a new
special form handler.

I came up with a very ugly solution in Python:

def add_special_form_handler(expr):
  exec(expr.cdr.car)
  special_forms[expr.car] = f

Where expr.car = the symbol to be dispatched on and expr.cdr.car = a string
of Python code defining a function that must be named f.

I wanted to use an anonymous function here, but with the limitations of
Python's lambda that would probably make things more complicated.  Failing
that I wanted to allow the user to manually return the function from the
string, like this:

a = exec(
def double(x):
  return x * 2
double
)

However it seems that exec does not return a value as it produces a
SyntaxError whenever I try to assign it.

Is there a better way to do this?

-- 
Nick Zarczynski
Pointless Programming Blog http://pointlessprogramming.wordpress.com
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Returning a value from exec or a better solution

2011-08-29 Thread Rob Williscroft
Jack Trades wrote in
news:CAG5udOg=GtFGPmTB=1ojnvnrpdyucxdokn1wjqmomv9gx0+...@mail.gmail.com
in gmane.comp.python.general: 

 ... I wanted to allow the user to manually return the
 function from the string, like this:
 
 a = exec(
 def double(x):
   return x * 2
 double
 )
 
 However it seems that exec does not return a value as it produces a
 SyntaxError whenever I try to assign it.

def test():
  src = (
  def double(x):
return x * 2
)
  globals  = {}
  exec( src, globals )
  return globals[ double ]
  
print( test() )

The a bove works on 2.7 (I tested it) on earlier versions you may need 
to use:

exec src in globals 

Rob.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Returning a value from exec or a better solution

2011-08-29 Thread Jack Trades
On Mon, Aug 29, 2011 at 12:30 PM, Rob Williscroft r...@rtw.me.uk wrote:

 Jack Trades wrote in
  ... I wanted to allow the user to manually return the
  function from the string, like this:
 
  a = exec(
  def double(x):
return x * 2
  double
  )
 
  However it seems that exec does not return a value as it produces a
  SyntaxError whenever I try to assign it.

 def test():
  src = (
   def double(x):
return x * 2
 )
  globals  = {}
  exec( src, globals )
  return globals[ double ]

 print( test() )


I looked into doing it that way but it still requires that the user use a
specific name for the function they are defining.  The docs on exec say that
an implementation may populate globals or locals with whatever they want so
that also rules out doing a simple for item in globals, as there may be
more than just the one function in there (though I suppose I may be able to
work around that).

-- 
Nick Zarczynski
Pointless Programming Blog http://pointlessprogramming.wordpress.com
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Returning a value from exec or a better solution

2011-08-29 Thread Arnaud Delobelle
On 29 August 2011 23:14, Jack Trades jacktradespub...@gmail.com wrote:
 On Mon, Aug 29, 2011 at 12:30 PM, Rob Williscroft r...@rtw.me.uk wrote:

 Jack Trades wrote in
  ... I wanted to allow the user to manually return the
  function from the string, like this:
 
  a = exec(
  def double(x):
    return x * 2
  double
  )
 
  However it seems that exec does not return a value as it produces a
  SyntaxError whenever I try to assign it.

 def test():
  src = (
      def double(x):
        return x * 2
    )
  globals  = {}
  exec( src, globals )
  return globals[ double ]

 print( test() )

 I looked into doing it that way but it still requires that the user use a
 specific name for the function they are defining.  The docs on exec say that
 an implementation may populate globals or locals with whatever they want so
 that also rules out doing a simple for item in globals, as there may be
 more than just the one function in there (though I suppose I may be able to
 work around that).

Hi Jack,

Here is a possible solution for your problem (Python 3):


 class CapturingDict(dict):
... def __setitem__(self, key, val):
... self.key, self.val = key, val
... dict.__setitem__(self, key, val)
...
 c = CapturingDict()
 exec(def myfunction(x): return 1, c)
 c.key
'myfunction'
 c.val
function myfunction at 0x100634d10

HTH,

-- 
Arnaud
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Returning a value from exec or a better solution

2011-08-29 Thread Jack Trades
On Mon, Aug 29, 2011 at 5:50 PM, Arnaud Delobelle arno...@gmail.com wrote:


 Hi Jack,

 Here is a possible solution for your problem (Python 3):


  class CapturingDict(dict):
 ... def __setitem__(self, key, val):
 ... self.key, self.val = key, val
 ... dict.__setitem__(self, key, val)
 ...
  c = CapturingDict()
  exec(def myfunction(x): return 1, c)
  c.key
 'myfunction'
  c.val
 function myfunction at 0x100634d10

 HTH,

 --
 Arnaud


That's brilliant and works flawlessly.  Thank you very much!

-- 
Nick Zarczynski http://www.rentageekit.com
Pointless Programming Blog http://pointlessprogramming.wordpress.com
-- 
http://mail.python.org/mailman/listinfo/python-list