Re: Returning a value from exec or a better solution
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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