-1

I've got a UserDict class with redefined __repr__ and __str__ and I'm debugging some code using it with WinPDB:

class UserDict(dict):
    def __repr__(self):
        return "this is repr"
    def __str__(self):
       return "this is str"

variable = UserDict()
variable["abc"] = 1

Here is a debugging session of that script. Note 2 commands in console: eval(variable) and eval(variable.__repr__()), issued, when the execution of the script reached the last line: enter image description here

If I say eval(variable) in WinPDB console, which should fail in a normal python console, it returns the same as in its "Repr" column.

I wonder, how it fills the contents of that "Repr" column and what it really does, when I say eval(variable)?

Boris Burkov
  • 13,420
  • 17
  • 74
  • 109
  • What `eval` does is to evaluate a string as Python code. It's the exact opposite of what you claim to be looking for. So… what makes you think `eval` is what you want in the first place? – abarnert Oct 15 '13 at 22:00
  • @abarnert I've used a wrong word. I don't necessarily want to change how it works. I want to know, what it does. – Boris Burkov Oct 15 '13 at 22:02
  • Meanwhile, `pdb` does not call `eval` on your object to get its repr; it just calls `repr`. And I'm not sure why you expected defining a `UserDict.__repr__` to affect the representation of some completely unrelated classes that you haven't shown us, but… it won't. – abarnert Oct 15 '13 at 22:02
  • @abarnert you're right, sorry for bad formulation of my question. Edit done. – Boris Burkov Oct 15 '13 at 22:06
  • If you actually did what you claim in the edit, `eval(column)` would raise `TypeError: eval() arg 1 must be a string or code object`. (That's for Python 2.7; the wording is slightly different in 3.x and in very old 2.x, but the basic idea is unchanged.) Please show us an actual [SSCCE](http://sscce.org). – abarnert Oct 15 '13 at 22:07
  • @abarnert Edited. You're right. `eval` wasn't done in the real python console, it was issued in WinPDB command line and strangely it works there. – Boris Burkov Oct 15 '13 at 22:24
  • The Winpdb `eval` command is an entirely separate thing from the Python `eval` function. They do somewhat similar things, hence the name. – abarnert Oct 15 '13 at 22:45

2 Answers2

2

What eval does it to evaluate a string as a Python expression.

You do not want to call eval on your objects to get their representation. pdb/WinPDB does not call eval on your objects to get their representation. In fact, eval is nearly the opposite of repr.

If you want to see the results of foo.__repr__(), you call repr(foo)—or just type foo at the console. Typing any expression at the console causes it to show you repr(that expression).

Of course this means that if you type eval(foo) at the console, what you will see is repr(eval(foo)). But that has nothing to do with eval; it's the same as any other expression.


Meanwhile, at the Winpdb console, you're not running Python code, you're running Winpdb code. Winpdb has a command named eval, which is similar to the Python function eval, but it's not the same thing.

As the documentation says, eval foo effectively evaluates foo in your live debuggee session. Notice that it a fragment that's parseable as a Python expression, not a string holding such a fragment.

So, eval(variable) in the Winpdb console is similar to eval("(variable)") in the interactive interpreter. Which is nearly identical to just (variable) in the interactive interpreter. Which is equivalent to variable.

But if you type variable (or (variable) or eval("(variable)")) in your interactive interpreter, it prints out repr(variable), which calls your __repr__ method. Why isn't that happening in Winpdb?

Because printing out the repr of any expression you type at the interactive interpreter is a feature of the interactive interpreter, not of the language. While the Winpdb console could do the same thing, it doesn't. (This makes it possible to debug problems with __repr__ methods, and it avoids running code from the debuggee in the debugger without making it explicit.)

So, what about eval(variable.__repr__()). As you can probably guess, that's like evaluating the string "(variable.__repr__())" in the debuggee. That .__repr__() ends up being part of the expression you evaluate in the debuggee environment, so of course it gets called in the debuggee environment. The result is not a UserDict object, as in the previous version, but a string.


So, finally, what exactly does Winpdb show in its Repr column and as the result of calling eval? Well, that isn't really documented explicitly, so you can either figure it out through trial and error, or read the source.

abarnert
  • 354,177
  • 51
  • 601
  • 671
0

eval() executes python code passed as a string. If you want your dict to return "foo" then use repr(myUserDictVariable).

cdonts
  • 9,304
  • 4
  • 46
  • 72