This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: getting PyRun_String() true result
Type: Stage:
Components: Interpreter Core Versions:
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: gvanrossum Nosy List: davygrvy, gvanrossum, loewis, nobody
Priority: normal Keywords:

Created on 2001-03-04 14:53 by anonymous, last changed 2022-04-10 16:03 by admin. This issue is now closed.

Messages (9)
msg3684 - (view) Author: Nobody/Anonymous (nobody) Date: 2001-03-04 14:53
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
msg3685 - (view) Author: Martin v. Löwis (loewis) * (Python committer) Date: 2001-03-04 18:22
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.
msg3686 - (view) Author: Nobody/Anonymous (nobody) Date: 2001-03-05 18:51
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"
msg3687 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2001-03-20 18:49
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.
msg3688 - (view) Author: Nobody/Anonymous (nobody) Date: 2001-03-20 21:34
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.
msg3689 - (view) Author: Martin v. Löwis (loewis) * (Python committer) Date: 2001-03-20 21:40
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.
msg3690 - (view) Author: Nobody/Anonymous (nobody) Date: 2001-03-24 16:20
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"?
msg3691 - (view) Author: Martin v. Löwis (loewis) * (Python committer) Date: 2001-03-24 17:51
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?
msg3692 - (view) Author: David Gravereaux (davygrvy) Date: 2001-06-02 00:40
Logged In: YES 
user_id=7549

>> 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__).

But foo() was the last invoked.  Where's it's result?  Is 
eval_input a function, or a start token as in Py_eval_input?

How can the operation of PyRun_String() place into its 
returning PyObject* the result of the operation run?

This is a central theme in Tcl and Perl. such as ->

Tcl_Interp *interp;
int code;

interp = Tcl_CreateInterp();
code = Tcl_Eval(interp, "proc foo {} {}; expr {rand()}");
if (code == TCL_OK) {
  printf("the random number is %s", interp->result);
} else {
  printf("We bombed with %s", interp->result);
}

How is it possible to do the same thing in python to get 
the result of last invoked command as a char*?

>IMO, there is no meaningful result except for
"success or exception".

And upon success, where is the result placed?  POP_TOP case 
in eval_code2() discarding the result object is either a 
bug in the core, or a new start token for return actual 
results of operations needs to added.  Important data is 
being discarded.

>>  my very simple patch

>Which patch?

*** ceval.c.orig	Fri Jun  1 17:11:52 2001
--- ceval.c	Fri Jun  1 17:12:56 2001
***************
*** 771,776 ****
--- 771,777 ----
  
  		case POP_TOP:
  			v = POP();
+ 			PyDict_SetItemString(f-
>f_globals, "_", v); 
  			Py_DECREF(v);
  			continue;
  
History
Date User Action Args
2022-04-10 16:03:48adminsetgithub: 34056
2001-03-04 14:53:29anonymouscreate