[Python-bugs-list] [ python-Bugs-405837 ] getting PyRun_String() true result

noreply@sourceforge.net noreply@sourceforge.net
Sat, 24 Mar 2001 09:51:43 -0800


Bugs item #405837, was updated on 2001-03-04 06:53
You can respond by visiting: 
http://sourceforge.net/tracker/?func=detail&atid=105470&aid=405837&group_id=5470

Category: Python Interpreter Core
Group: Not a Bug
Status: Closed
Priority: 5
Submitted By: Nobody/Anonymous (nobody)
Assigned to: Guido van Rossum (gvanrossum)
Summary: getting PyRun_String() true result

Initial Comment:
It seems impossible to build am embedded Python
interpreter extension which actually allows getting
the result of the evaluation of a string from the
interpreter, as it is done in interactive mode, as in
the following:
  def f: pass
  f
prints:
  <function f at 0x8069694>

But in C (called twice with the 2 above strings):
  PyRun_String(string, Py_file_input, globals, globals)
returns None.

I found a workaround by patching the core in ceval.c,
eval_code2() (inspired by the PRINT_EXPR case):

...
case POP_TOP:
  v = POP();
PyDict_SetItemString(f->f_globals, "_", v); /* added */
  Py_DECREF(v);
  continue;
...

and then:
  PyRun_String(string, Py_file_input, globals, globals)
  result =PyDict_GetItemString(globals, "_")
returns the '<function f at 0x8069694>' correct result.


My goal is to allow the tclpython extension (at
http://jfontain.free.fr/) to work without having to
insert print statements on the Python side to be able
to pass data to the Tcl interpreter.

Please forgive me if there is an obvious way to do the
above without patching the core, but I am new to Python
(I like it already though :-)

Jean-Luc Fontaine

----------------------------------------------------------------------

>Comment By: Martin v. Löwis (loewis)
Date: 2001-03-24 09:51

Message:
Logged In: YES 
user_id=21627

> But maybe Python is not meant to be also used as a C
extension?

Nonsense. You just have to use it properly.

> Once loaded in the embedded interpreter, how do you get
the 
> result of the library Python functions that you invoke?

You load it using file_input (up to the end of foo), then
you evaluate the expressions (e.g. foo()) using eval_input
(passing the same locals and globals). This is also
(roughly) what the interactive interpreter does (it always
passes the dictionary of __main__).

>  my very simple patch

Which patch?

----------------------------------------------------------------------

Comment By: Nobody/Anonymous (nobody)
Date: 2001-03-24 08:20

Message:
Logged In: NO 

>i = 1
>def foo():
>    return i
>class C:
>    pass
>What should be the result of executing this statement list
>(i.e. suite)? IMO, there is no meaningful result except for
>"success or exception".

True.
But you want to go further than that: actually calling a
function and getting its result, as it is done in
interactive mode.
Let us say that you have a nice library written in Python,
that you want to invoke from C. Once loaded in the embedded
interpreter, how do you get the result of the library Python
functions that you invoke?

Again, that is something that is readily done in other
interpreted languages. But maybe Python is not meant to be
also used as a C extension?

I think my very simple patch demonstrates otherwise, and
furthermore, that Python when run in interactive mode
behaves as I (and I guess most people) expect. For example,
when typing:
  i = 1
  def foo():
      return i
  foo()
one gets 1 as result.

Now if you pass the following C string to an embedded
interpreter:
char *code = "i = 1\ndef foo()\n    return i\nfoo()";
how to you get the result "1"?

----------------------------------------------------------------------

Comment By: Martin v. Löwis (loewis)
Date: 2001-03-20 13:40

Message:
Logged In: YES 
user_id=21627

What kind of result would you expect from evaluating a
file_input? E.g. given

i = 1
def foo():
  return i
class C:
  pass

What should be the result of executing this statement list
(i.e. suite)? IMO, there is no meaningful result except for
"success or exception".

You may also consider discussing this on
python-list@python.org.

----------------------------------------------------------------------

Comment By: Nobody/Anonymous (nobody)
Date: 2001-03-20 13:34

Message:
Logged In: NO 

I agree that this is not a bug per se.
I am puzzled though, that other scripting languages, such as
Perl and Tcl can readily do this.
I still have no answer to my request, so I guess I will try
help@python.org as you recommend.

----------------------------------------------------------------------

Comment By: Guido van Rossum (gvanrossum)
Date: 2001-03-20 10:49

Message:
Logged In: YES 
user_id=6380

This is not a bug.   Closing the bug report now.

If you need more help still, wrote help@python.org.


----------------------------------------------------------------------

Comment By: Nobody/Anonymous (nobody)
Date: 2001-03-05 10:51

Message:
Logged In: NO 

> To evaluate a string, use Py_RunString with Py_eval_input,
> or perhaps Py_single_input.

Py_eval_input is for "isolated expressions", and
Py_single_input "for a single statement", so how do I
execute whole modules except by using Py_file_input, the
only remaining option?

I actually tested all the above options thoroughly and found
that only Py_file_input did the job, but without a way to
get at the result.

Please let me know whether there is something that I missed,
as I am stuck at the moment. If needed, I will be happy to
send you sample code that illustrates the problem.

Thank you very much for your prompt response.

Jean-Luc

PS: passing "def f(): pass\n" to Py_eval_input returns a
"SyntaxError: invalid syntax"


----------------------------------------------------------------------

Comment By: Martin v. Löwis (loewis)
Date: 2001-03-04 10:22

Message:
Logged In: YES 
user_id=21627

Sure there is. PyRun_SimpleString executes a string in "file
mode"; this has no result. The interactive interpreter, when
it prints a result, runs the string in "eval mode" - only
evaluation gives a result.

To evaluate a string, use Py_RunString with Py_eval_input,
or perhaps Py_single_input.

----------------------------------------------------------------------

You can respond by visiting: 
http://sourceforge.net/tracker/?func=detail&atid=105470&aid=405837&group_id=5470