Mailing List Archive

Why doesn't Python (error msg) tell me WHAT the actual (arg) values are ?
> py bug.py
Traceback (most recent call last):
File "C:\Usenet\bug.py", line 5, in <module>
print( a + 12 )
TypeError: can only concatenate str (not "int") to str


Why doesn't Python (error msg) do the obvious thing and tell me
WHAT the actual (offending, arg) values are ?

In many cases, it'd help to know what string the var A had , when the error occurred.
------------ i wouldn't have to put print(a) just above, to see.




( pypy doesn't do that either, but Python makes programming (debugging) so easy that i hardly feel any inconvenience.)
--
https://mail.python.org/mailman/listinfo/python-list
RE: Why doesn't Python (error msg) tell me WHAT the actual (arg) values are ? [ In reply to ]
Hen or Hanna,

You keep asking WHY which may be reasonable but hard or irrelevant in many
cases.

I find the traceback perfectly informative.

It says you asked it to print NOT just "a" but "a + 12" and the error is
coming not from PRINT but from trying to invoke addition between two objects
that have not provided instructions on how to do so. Specifically, an object
of type str has not specified anything to do if asked to concatenate an
object of type int to it. And, an object of type int has not specified what
to do if asked to add itself to an object of type str to the left of it.
Deeper in python, the objects have dunder methods like __ADD__() and
___RADD__() to invoke for those situations that do some logic and decide
they cannot handle it and return an exception of sorts that ends up
generating your message.

If you want to know what "a" has at the moment, ask for just it, not adding
twelve to it. Perhaps you should add a line above your print asking to just
print(a).

Before you suggest what might be helpful, consider what it might mean in a
complex case with lots of variables and what work the interpreter might have
to do to dump the current values of anything relevant or just ANYTHING.

The way forward is less about asking why but asking what to do to get what
you want, or realize it is not attained the way you thought.

Avi

-----Original Message-----
From: Python-list <python-list-bounces+avi.e.gross=gmail.com@python.org> On
Behalf Of Hen Hanna
Sent: Wednesday, February 22, 2023 3:05 PM
To: python-list@python.org
Subject: Why doesn't Python (error msg) tell me WHAT the actual (arg) values
are ?


> py bug.py
Traceback (most recent call last):
File "C:\Usenet\bug.py", line 5, in <module>
print( a + 12 )
TypeError: can only concatenate str (not "int") to str


Why doesn't Python (error msg) do the obvious thing and tell me
WHAT the actual (offending, arg) values are ?

In many cases, it'd help to know what string the var A had , when the
error occurred.
------------ i wouldn't have to put print(a) just
above, to see.




( pypy doesn't do that either, but Python makes programming (debugging)
so easy that i hardly feel any inconvenience.)
--
https://mail.python.org/mailman/listinfo/python-list

--
https://mail.python.org/mailman/listinfo/python-list
Re: Why doesn't Python (error msg) tell me WHAT the actual (arg) values are ? [ In reply to ]
On 22/02/2023 20:05, Hen Hanna wrote:
> Python makes programming (debugging) so easy
I agree with that!
Rob Cliffe
--
https://mail.python.org/mailman/listinfo/python-list
Re: Why doesn't Python (error msg) tell me WHAT the actual (arg) values are ? [ In reply to ]
On Wednesday, February 22, 2023 at 12:05:34 PM UTC-8, Hen Hanna wrote:
> > py bug.py
> Traceback (most recent call last):
> File "C:\Usenet\bug.py", line 5, in <module>
> print( a + 12 )
> TypeError: can only concatenate str (not "int") to str
>
>
> Why doesn't Python (error msg) do the obvious thing and tell me
> WHAT the actual (offending, arg) values are ?
>
> In many cases, it'd help to know what string the var A had , when the error occurred.
> ------------ i wouldn't have to put print(a) just above, to see.
>
>
>
>
> ( pypy doesn't do that either, but Python makes programming (debugging) so easy that i hardly feel any inconvenience.)



i see that my example would be clearER with this one-line change:


> py bug.py

Traceback (most recent call last):

File "C:\Usenet\bug.py", line 5, in <module>
map( Func, fooBar( X, Y, X + Y ))

TypeError: can only concatenate str (not "int") to str


i hope that NOW a few of you can see this as a genuine, (reasonable) question.

--
https://mail.python.org/mailman/listinfo/python-list
Re: Why doesn't Python (error msg) tell me WHAT the actual (arg) values are ? [ In reply to ]
On 2/22/2023 6:46 PM, Hen Hanna wrote:
> On Wednesday, February 22, 2023 at 12:05:34 PM UTC-8, Hen Hanna wrote:
>>> py bug.py
>> Traceback (most recent call last):
>> File "C:\Usenet\bug.py", line 5, in <module>
>> print( a + 12 )
>> TypeError: can only concatenate str (not "int") to str
>>
>>
>> Why doesn't Python (error msg) do the obvious thing and tell me
>> WHAT the actual (offending, arg) values are ?
>>
>> In many cases, it'd help to know what string the var A had , when the error occurred.
>> ------------ i wouldn't have to put print(a) just above, to see.
>>
>>
>>
>>
>> ( pypy doesn't do that either, but Python makes programming (debugging) so easy that i hardly feel any inconvenience.)
>
>
>
> i see that my example would be clearER with this one-line change:
>
>
> > py bug.py
>
> Traceback (most recent call last):
>
> File "C:\Usenet\bug.py", line 5, in <module>
> map( Func, fooBar( X, Y, X + Y ))
>
> TypeError: can only concatenate str (not "int") to str
>
>
> i hope that NOW a few of you can see this as a genuine, (reasonable) question.

It tells me to go look at the function definition and how it's being
invoked. Even if I knew which of (X, Y) was an int and which a str, I'd
still need to do that.

Or you could add type annotations to your code and run mypy on it...


--
https://mail.python.org/mailman/listinfo/python-list
Re: Why doesn't Python (error msg) tell me WHAT the actual (arg) values are ? [ In reply to ]
On Wednesday, February 22, 2023 at 3:46:21 PM UTC-8, Hen Hanna wrote:
> On Wednesday, February 22, 2023 at 12:05:34 PM UTC-8, Hen Hanna wrote:
> > > py bug.py
> > Traceback (most recent call last):
> > File "C:\Usenet\bug.py", line 5, in <module>
> > print( a + 12 )
> > TypeError: can only concatenate str (not "int") to str
> >
> >
> > Why doesn't Python (error msg) do the obvious thing and tell me
> > WHAT the actual (offending, arg) values are ?
> >
> > In many cases, it'd help to know what string the var A had , when the error occurred.
> > ------------ i wouldn't have to put print(a) just above, to see.
> >
> >
> >
> >
> > ( pypy doesn't do that either, but Python makes programming (debugging) so easy that i hardly feel any inconvenience.)


i see that my example would be (even) clearER with this one-line change:

py bug.py

Traceback (most recent call last):

File "C:\Usenet\bug.py", line 5, in <module>
map( Func, fooBar( X, Y, X + Y ))

TypeError: can only concatenate str (not "int") to str
attempt to call + with 'abc' , 123.45 <--------------

> i hope that NOW a few of you can see this as a genuine, (reasonable) question.

Python seems so perfectly User-friendly that
i 'm so curious (puzzled) that it doesn't do the very obvious and easy thing
of giving me this info:

attempt to call + with 'abc' , 123.45 <--------------
--
https://mail.python.org/mailman/listinfo/python-list
Re: Why doesn't Python (error msg) tell me WHAT the actual (arg) values are ? [ In reply to ]
> On 23 Feb 2023, at 01:39, Hen Hanna <henhanna@gmail.com> wrote:
>
> ?On Wednesday, February 22, 2023 at 3:46:21 PM UTC-8, Hen Hanna wrote:
>> On Wednesday, February 22, 2023 at 12:05:34 PM UTC-8, Hen Hanna wrote:
>>>> py bug.py
>>> Traceback (most recent call last):
>>> File "C:\Usenet\bug.py", line 5, in <module>
>>> print( a + 12 )
>>> TypeError: can only concatenate str (not "int") to str
>>>
>>>
>>> Why doesn't Python (error msg) do the obvious thing and tell me
>>> WHAT the actual (offending, arg) values are ?
>>>
>>> In many cases, it'd help to know what string the var A had , when the error occurred.
>>> ------------ i wouldn't have to put print(a) just above, to see.
>>>
>>>
>>>
>>>
>>> ( pypy doesn't do that either, but Python makes programming (debugging) so easy that i hardly feel any inconvenience.)
>
>
> i see that my example would be (even) clearER with this one-line change:
>
> py bug.py
>
> Traceback (most recent call last):
>
> File "C:\Usenet\bug.py", line 5, in <module>
> map( Func, fooBar( X, Y, X + Y ))
>
> TypeError: can only concatenate str (not "int") to str
> attempt to call + with 'abc' , 123.45 <--------------
>
>> i hope that NOW a few of you can see this as a genuine, (reasonable) question.
>
> Python seems so perfectly User-friendly that
> i 'm so curious (puzzled) that it doesn't do the very obvious and easy thing
> of giving me this info:
>
> attempt to call + with 'abc' , 123.45 <--------------

It is not easy to do that in a robust and reliable way for any object.
You can end up in the code to generate the error message itself breaking.
For example using unbounded CPU time when attempting to get the string repr of the variable.

Barry

> --
> https://mail.python.org/mailman/listinfo/python-list
>

--
https://mail.python.org/mailman/listinfo/python-list
Re: Why doesn't Python (error msg) tell me WHAT the actual (arg) values are ? [ In reply to ]
On Wednesday, February 22, 2023 at 11:57:45 PM UTC-8, Barry wrote:
> > On 23 Feb 2023, at 01:39, Hen Hanna <henh...@gmail.com> wrote:
> >
> > ?On Wednesday, February 22, 2023 at 3:46:21 PM UTC-8, Hen Hanna wrote:
> >> On Wednesday, February 22, 2023 at 12:05:34 PM UTC-8, Hen Hanna wrote:
> >>>> py bug.py
> >>> Traceback (most recent call last):
> >>> File "C:\Usenet\bug.py", line 5, in <module>
> >>> print( a + 12 )
> >>> TypeError: can only concatenate str (not "int") to str
> >>>
> >>>
> >>> Why doesn't Python (error msg) do the obvious thing and tell me
> >>> WHAT the actual (offending, arg) values are ?
> >>>
> >>> In many cases, it'd help to know what string the var A had , when the error occurred.
> >>> ------------ i wouldn't have to put print(a) just above, to see.
> >>>
> >>>
> >>>
> >>>
> >>> ( pypy doesn't do that either, but Python makes programming (debugging) so easy that i hardly feel any inconvenience.)
> >
> >
> > i see that my example would be (even) clearER with this one-line change:
> >
> > py bug.py
> >
> > Traceback (most recent call last):
> >
> > File "C:\Usenet\bug.py", line 5, in <module>
> > map( Func, fooBar( X, Y, X + Y ))
> >
> > TypeError: can only concatenate str (not "int") to str
> > attempt to call + with 'abc', 123 <--------------
> >
> >> i hope that NOW a few of you can see this as a genuine, (reasonable) question.
> >
> > Python seems so perfectly User-friendly that
> > i 'm so curious (puzzled) that it doesn't do the very obvious and easy thing
> > of giving me this info:
> >
> > attempt to call + with 'abc', 123 <--------------

> It is not easy to do that in a robust and reliable way for any object.
> You can end up in the code to generate the error message itself breaking.
> For example using unbounded CPU time when attempting to get the string repr of the variable.
>
> Barry
>


Python VM is seeing an "int" object (123) (and telling me that) ... so it should be easy to print that "int" object


What does Python VM know ? and when does it know it ?


it seems like it is being playful, teasing (or mean), and hiding the ball from me
--
https://mail.python.org/mailman/listinfo/python-list
RE: Why doesn't Python (error msg) tell me WHAT the actual (arg) values are ? [ In reply to ]
Rob,

There are lots of nifty features each of us might like and insist make much
more sense than what others say they want.

Sometimes the answer is to not satisfy most of those demands but provide
TOOLS they can use to do things for themselves.

As you agree, many of us have found all kinds of tools that help with
debugging and frankly, some of them use it to the point of annoying others
who would rather avoid them. An example is type hints that can get quite
detailed and obscure the outline of your program and are ignored by the
parser and only relevant for some linter or other such program.

I am thinking of what would happen if I created several fairly long or
complex data structures and tried to add them. Say I have a dictionary
containing millions of entries including every conceivable UNICODE character
as well as very complex values such as other dictionaries or strings
containing entire books. My other data structure might be a forest
containing many smaller trees, such as the output of some machine learning
models or perhaps showing every possible game of chess up to 50 moves deep
along with an evaluation of the relative strength of the board to one
player.

I then accidentally write code that contains:

big_dic + forest_trees

Would I like my error message consume all the paper in my city (or scroll my
screen for a week) as it tells me a dict cannot be added to a forest and by
the way, here is a repr of each of them showing the current (highly
recursive) contents.

Now people have written functions that take something long and truncate it
so a list containing [1, 2, 3, ... 1_000_000] is shown in this condensed
form with the rest missing, but then someone will complain they are not
seeing all of it!

So the deal is to use your TOOLS. You can run a debugger or add print
statements or enclose it in a try/catch to keep it from stopping the program
and other techniques. You can examine the objects carefully just before, or
even after and do cautious things like ask for the length and then maybe ask
for the first few and last few items, or whatever makes sense.

In the original example, we were first asked about print(a + b) and later
given a somewhat weirder func(x, y, x +y) as examples. Now ask what order
things are evaluated and where the error happens. What is known by the party
handling the error?

If you put the offending statement in a try/catch scenario, then when the
error is triggered, YOU wrote the code that catches the exception and you
can often examine the payload of the exception, or know that the arguments
of a or b or x or y were involved and you can craft your own output to be
more clear. Or, you can even sometimes fix the problem and redo the code
using something like float(x) or str(y).

My impression here is that the error is not on the surface but caught
deeper. The symbols used may be x and y but what if we work with "12" + 13
and follow what happens?

Since the interpreter in python evaluates x+y before calling the function
using the result as an argument, the function never sees anything. What
should happen is that the interpreter sees a "12" which is normally an
object of a class of str and then it sees a "+" and then it sees anything
that follows as a second object it ignores for now. Python does not have a
fully defined operator that it invokes when it sees a "+" as the meaning
depends on what object is being asked to do whatever plus means to it. For a
string argument, it means concatenate to your current content and return a
new str object. The way that happens is that the class (or a relative) has
defined a method called __add__() or it hasn't. If it has, it takes an
argument of the second object and in this case it gets the integer object
containing 13.

So it runs the function and it has not been programmed on how to append an
integer to a string of characters and it returns without an answer but an
exception. The interpreter evaluator does not admit defeat yet and
reasonable tries to see if the integer 13 has a __iadd__() which is similar
but different and again, an integer has not been programmed to append itself
to an object of type str. Could it have been? Sure. If you make your own
(sub)class you can create a kind of integer that will make a str version of
itself and append it o the "12" to make "1213" BUT in this case, that is not
an option. So the integer method fails and returns an exception too.

Now the parser functionality knows it has failed. "12" and 13 have both
refused to implement the plus sign and either it catches the exception OR is
does not and lets it flow upstream till any other functions in a chain catch
it. Any one can then generate some error message, or it can reach the top
level of the interpreter and it has to decide what to do.

But some errors are not fatal. If str had no __add__() that is not an error.
If it returns that it cannot do it, that is not a fatal error but a
temporary drawback. Only when int fails too is there a likely error but int
is not programmed to do anything lie reporting in __iadd__() and nor should
it except if you are debugging new functionality.

Can we get better error messages in many cases? Sure. Clearly the
interpreter level sees a call like func(x, y, x+y) and if evaluating it
causes an error, it could type out what all the variables were.

But if you are running code at the console and it aborts like this, you
usually have the variables at your fingertips and can say print(x) or
print(y) but you cannot properly say print(x+y) yet. The error message did
specify you were trying to work with incompatible objects as one was of type
this and the other of type that. That suggests the values of both could have
been accessed and shown in this case ad perhaps the code could be modified
so it returns some semblance of the values at least for built-in objects.
All that though adds code and complexity and often slows things down.



-----Original Message-----
From: Python-list <python-list-bounces+avi.e.gross=gmail.com@python.org> On
Behalf Of Rob Cliffe via Python-list
Sent: Wednesday, February 22, 2023 4:31 PM
To: python-list@python.org
Subject: Re: Why doesn't Python (error msg) tell me WHAT the actual (arg)
values are ?



On 22/02/2023 20:05, Hen Hanna wrote:
> Python makes programming (debugging) so easy
I agree with that!
Rob Cliffe
--
https://mail.python.org/mailman/listinfo/python-list

--
https://mail.python.org/mailman/listinfo/python-list
Re: Why doesn't Python (error msg) tell me WHAT the actual (arg) values are ? [ In reply to ]
On 23/02/2023 09.05, Hen Hanna wrote:
>
> > py bug.py
> Traceback (most recent call last):
> File "C:\Usenet\bug.py", line 5, in <module>
> print( a + 12 )
> TypeError: can only concatenate str (not "int") to str
>
>
> Why doesn't Python (error msg) do the obvious thing and tell me
> WHAT the actual (offending, arg) values are ?
>
> In many cases, it'd help to know what string the var A had , when the error occurred.
> ------------ i wouldn't have to put print(a) just above, to see.

In some ways, providing this information seems appropriate. Curiously,
this does not even occur during an assert exception - despite the
value/relationship being the whole point of using the command!

x = 1
assert x == 2

AssertionError (and that's it)

Then again, remember that exceptions can be 'caught'. So, such data
would need to be added to the exception-instance. This could become
quite costly.



What are the appropriate tools for the job?


Don't add an extra print(), use a debugger.

Not only does this allow you to breakpoint critical points in the code,
but identifiers can be watch-ed and changes noted. The other handy
feature is being able to correct the current erroneous value of the
identifier and continue execution.

For us, memory-challenged coders, there is no need to remember to remove
the print() again, afterwards.


The TypeError indicates a problem between the programmer's ears. What
was thought to be a string or an integer was the opposite. This seems to
be playing fast-and-loose with Python's dynamic-typing. To quote: "we're
all adults here". Thus, I wouldn't recommend 're-cycling' an identifier
to represent two different (types of) data-point in the same code - but
there's nothing to stop you/anyone!

The other possibility is that it was an accident. Sounds more like
something I would do, but... In this case, the tool which is your/my
friend is typing. The IDE should catch most of the situations where an
int would be used as an str, or v-v. Remember though, Python's typing is
(a) not part of the language, and (b) probably won't help at run-time.


PS are you aware that there is a Python-Tutor list for the use of people
learning Python?
--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list
Re: Why doesn't Python (error msg) tell me WHAT the actual (arg) values are ? [ In reply to ]
On 2/23/23 01:08, Hen Hanna wrote:
> Python VM is seeing an "int" object (123) (and telling me that) ... so it should be easy to print that "int" object
> What does Python VM know ? and when does it know it ?
It knows there is an object and its name and type. It knows this from
the first moment you create the object and bind a name to it.
> it seems like it is being playful, teasing (or mean), and hiding the ball from me

Sorry you aren't understanding. Whenever you print() out an object,
python calls the object's __repr__() method to generate the string to
display. For built-in objects this is obviously trivial. But if you
were dealing an object of some arbitrary class, there may not be a
__repr__() method which would cause an exception, or if the __repr__()
method itself raised an exception, you'd lose the original error message
and the stack trace would be all messed up and of no value to you. Does
that make sense? Remember that Python is a very dynamic language and
what might be common sense for a built-in type makes no sense at all for
a custom type. Thus there's no consistent way for Python to print out
the information you think is so simple.
--
https://mail.python.org/mailman/listinfo/python-list
RE: Why doesn't Python (error msg) tell me WHAT the actual (arg) values are ? [ In reply to ]
We have been supplying many possible reasons or consequences for why the
implementation of python does not do what the OP wants and even DEMANDS.

I am satisfied with knowing it was because they CHOSE NOT TO in some places
and maybe not in others. It is nice to see some possible reasons, but
something as simple as efficiency or needing to complicate the code in
something used regularly, might be enough for now.

But to comment on what Michael T. and Dave N. have been saying, newcomers
often have no clue of what can happen so their questions may sound quite
reasonable.

So what happens if you create a large data structure, so some operation that
fails, catch the error and save the variables involved in an exception and
throw that onward and perhaps the program keeps running? There is now a
pointer to the large data structure in the exception object, or even a copy.
If that exception is not discarded or garbage collected, it can remain in
memory indefinitely even if the original string was expected to be removed,
replaced, or garbage collected. Some modern features in R such as generators
will stay alive infinitely and retain their state in between calls for a
next item.

You can end up with memory leaks that are not trivial to solve or that may
mysteriously disappear when an iterable has finally been consumed and all
the storage it used or pointed at can be retrieved, as one example.

A more rational approach is to realize that python has multiple levels of
debugging and exceptions are one among many. They are not meant to solve the
entire problem but just enough to be helpful or point you in some direction.
Yes, they can do more.

And, FYI, I too pointed this person at the Tutor list and I see no sign they
care how many people they make waste their time with so many mainly gripes.
I personally now ignore any post by them.
-----Original Message-----
From: Python-list <python-list-bounces+avi.e.gross=gmail.com@python.org> On
Behalf Of Michael Torrie
Sent: Thursday, February 23, 2023 10:32 PM
To: python-list@python.org
Subject: Re: Why doesn't Python (error msg) tell me WHAT the actual (arg)
values are ?

On 2/23/23 01:08, Hen Hanna wrote:
> Python VM is seeing an "int" object (123) (and telling me that) ...
so it should be easy to print that "int" object
> What does Python VM know ? and when does it know it ?
It knows there is an object and its name and type. It knows this from the
first moment you create the object and bind a name to it.
> it seems like it is being playful, teasing (or mean), and hiding
the ball from me

Sorry you aren't understanding. Whenever you print() out an object, python
calls the object's __repr__() method to generate the string to display. For
built-in objects this is obviously trivial. But if you were dealing an
object of some arbitrary class, there may not be a
__repr__() method which would cause an exception, or if the __repr__()
method itself raised an exception, you'd lose the original error message and
the stack trace would be all messed up and of no value to you. Does that
make sense? Remember that Python is a very dynamic language and what might
be common sense for a built-in type makes no sense at all for a custom type.
Thus there's no consistent way for Python to print out the information you
think is so simple.
--
https://mail.python.org/mailman/listinfo/python-list

--
https://mail.python.org/mailman/listinfo/python-list
Re: Why doesn't Python (error msg) tell me WHAT the actual (arg) values are ? [ In reply to ]
On 2023-02-22 15:46:09 -0800, Hen Hanna wrote:
> On Wednesday, February 22, 2023 at 12:05:34 PM UTC-8, Hen Hanna wrote:
> > > py bug.py
> > Traceback (most recent call last):
> > File "C:\Usenet\bug.py", line 5, in <module>
> > print( a + 12 )
> > TypeError: can only concatenate str (not "int") to str
> >
> >
> > Why doesn't Python (error msg) do the obvious thing and tell me
> > WHAT the actual (offending, arg) values are ?
> >
> > In many cases, it'd help to know what string the var A had , when the error occurred.
> > ------------ i wouldn't have to put print(a) just above, to see.
> >
> > ( pypy doesn't do that either, but Python makes programming
> > (debugging) so easy that i hardly feel any inconvenience.)

That seems like a non-sequitur to me. If you hardly feel any
inconvenience, why argue so forcefully?
And why is pypy relevant here?


> i see that my example would be clearER with this one-line change:
>
>
> > py bug.py
>
> Traceback (most recent call last):
>
> File "C:\Usenet\bug.py", line 5, in <module>
> map( Func, fooBar( X, Y, X + Y ))
>
> TypeError: can only concatenate str (not "int") to str
>
>
> i hope that NOW a few of you can see this as a genuine, (reasonable) question.

That doesn't seem a better example to me. There is still only one
subexpression (X + Y) where that error can come from, so I know that X
is a str and Y is an int.

A better example would be something like

x = (a + b) * (c + d)

In this case it could be either (a + b) or (c + d) which caused the
error. But what I really want to know here is the names of the involved
variables, NOT the values. If the error message told me that the values
were 'foo' and 12.3, I still wouldn't be any wiser. The problem here of
course is that the operands aren't necessarily simple variables as in
this example - they may be arbitrarily complex expressions. However, it
might be sufficient to mark the operator which caused the exception:

| ...
| File "/home/hjp/tmp/./foo", line 4, in f
| return (a + b) * (c + d)
| ^
| TypeError: can only concatenate str (not "int") to str

would tell me that (c + d) caused the problem and therefore that c must
be a str which it obviously shouldn't be.

hp

--
_ | Peter J. Holzer | Story must make more sense than reality.
|_|_) | |
| | | hjp@hjp.at | -- Charles Stross, "Creative writing
__/ | http://www.hjp.at/ | challenge!"
Re: Why doesn't Python (error msg) tell me WHAT the actual (arg) values are ? [ In reply to ]
On 2023-02-23 20:32:26 -0700, Michael Torrie wrote:
> On 2/23/23 01:08, Hen Hanna wrote:
> > Python VM is seeing an "int" object (123) (and telling me that)
> > ... so it should be easy to print that "int" object What does
> > Python VM know ? and when does it know it ?
> It knows there is an object and its name and type. It knows this from
> the first moment you create the object and bind a name to it.
> > it seems like it is being playful, teasing (or mean), and
> > hiding the ball from me
>
> Sorry you aren't understanding. Whenever you print() out an object,
> python calls the object's __repr__() method to generate the string to
> display. For built-in objects this is obviously trivial. But if you
> were dealing an object of some arbitrary class, there may not be a
> __repr__() method

Is this even possible? object has a __repr__ method, so all other
classes would inherit that if they don't define one themselves. I guess
it's possible to explicitely remove it ...

> which would cause an exception, or if the __repr__()
> method itself raised an exception,

Yup. That is possible and has happened to me several times - of course
always in a situation where I really needed that output ...

hp

--
_ | Peter J. Holzer | Story must make more sense than reality.
|_|_) | |
| | | hjp@hjp.at | -- Charles Stross, "Creative writing
__/ | http://www.hjp.at/ | challenge!"
Re: Why doesn't Python (error msg) tell me WHAT the actual (arg) values are ? [ In reply to ]
On 2023-02-24 16:12:10 +1300, dn via Python-list wrote:
> In some ways, providing this information seems appropriate. Curiously, this
> does not even occur during an assert exception - despite the
> value/relationship being the whole point of using the command!
>
> x = 1
> assert x == 2
>
> AssertionError (and that's it)

Pytest is great there. If an assertion in a test case fails it analyzes
the expression to give you various levels of details:

======================================== test session starts ========================================
platform linux -- Python 3.10.6, pytest-6.2.5, py-1.10.0, pluggy-0.13.0
rootdir: /home/hjp/tmp/t
plugins: cov-3.0.0, anyio-3.6.1
collected 1 item

test_a.py F [100%]

============================================= FAILURES ==============================================
______________________________________________ test_a _______________________________________________

def test_a():
a = [1, 2, 3]
b = {"a": a, "b": 2}

> assert len(a) == len(b)
E AssertionError: assert 3 == 2
E + where 3 = len([1, 2, 3])
E + and 2 = len({'a': [1, 2, 3], 'b': 2})

test_a.py:7: AssertionError
====================================== short test summary info ======================================
FAILED test_a.py::test_a - AssertionError: assert 3 == 2
========================================= 1 failed in 0.09s =========================================

hp

--
_ | Peter J. Holzer | Story must make more sense than reality.
|_|_) | |
| | | hjp@hjp.at | -- Charles Stross, "Creative writing
__/ | http://www.hjp.at/ | challenge!"
Re: Why doesn't Python (error msg) tell me WHAT the actual (arg) values are ? [ In reply to ]
On 25/02/2023 08.12, Peter J. Holzer wrote:
> On 2023-02-24 16:12:10 +1300, dn via Python-list wrote:
>> In some ways, providing this information seems appropriate. Curiously, this
>> does not even occur during an assert exception - despite the
>> value/relationship being the whole point of using the command!
>>
>> x = 1
>> assert x == 2
>>
>> AssertionError (and that's it)
>
> Pytest is great there. If an assertion in a test case fails it analyzes
> the expression to give you various levels of details:
>
> ======================================== test session starts ========================================
> platform linux -- Python 3.10.6, pytest-6.2.5, py-1.10.0, pluggy-0.13.0
> rootdir: /home/hjp/tmp/t
> plugins: cov-3.0.0, anyio-3.6.1
> collected 1 item
>
> test_a.py F [100%]
>
> ============================================= FAILURES ==============================================
> ______________________________________________ test_a _______________________________________________
>
> def test_a():
> a = [1, 2, 3]
> b = {"a": a, "b": 2}
>
>> assert len(a) == len(b)
> E AssertionError: assert 3 == 2
> E + where 3 = len([1, 2, 3])
> E + and 2 = len({'a': [1, 2, 3], 'b': 2})
>
> test_a.py:7: AssertionError
> ====================================== short test summary info ======================================
> FAILED test_a.py::test_a - AssertionError: assert 3 == 2
> ========================================= 1 failed in 0.09s =========================================

+1
and hence the tone of slight surprise in the observation - because only
ever use assert within pytests, and as observed, pytest amplifies the
report-back to provide actionable-intelligence. See also: earlier
contribution about using a debugger.


That said, have observed coders 'graduating' from other languages,
making wider use of assert - assumed to be more data (value)
sanity-checks than typing, but ...

Do you use assert frequently?


The OP seems wedded to his?her ways, complaining that Python does not
work the way it 'should'. In turn, gives rise to the impression that
expounding the advantages of TDD, and thus anticipating such unit and
integration error-possibilities, might be considered an insult or unhelpful.
(sigh!)

Personally, I struggled a bit to adapt from the more-strictured (if not
more-structured) languages of my past, to Python - particularly the
different philosophies or emphases of what happens at 'compile-time' cf
'execution-time'; and how such required marked changes in attitudes to
design, time-allocation, work-flow, and tool-set. Two related-activities
which made the language-change more workable and unleashed greater than
step-change advantage, were: increased use of TDD, and actively learning
the facilities within Python-oriented IDEs.

--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list
Re: Why doesn't Python (error msg) tell me WHAT the actual (arg) values are ? [ In reply to ]
On 2023-02-25 08:47:00 +1300, dn via Python-list wrote:
> That said, have observed coders 'graduating' from other languages, making
> wider use of assert - assumed to be more data (value) sanity-checks than
> typing, but ...
>
> Do you use assert frequently?

Not very often, but I do use it. Sometimes for its intended purpose
(i.e. to guard against bugs or wrong assumptions), sometimes just to
guard incomplete or sloppy code (e.g. browsing through some projects I
find
assert len(data["structure"]["dimensions"]["observation"]) == 1
(incomplete code - I didn't bother to implement multiple observations)
and
assert(header[0] == "Monat (JJJJMM)")
(the code below is sloppy. Instead of fixing it I just made the original
programmer's assumptions explicit)
and of course
assert False
(this point should never be reached)).

hp

--
_ | Peter J. Holzer | Story must make more sense than reality.
|_|_) | |
| | | hjp@hjp.at | -- Charles Stross, "Creative writing
__/ | http://www.hjp.at/ | challenge!"
Re: Why doesn't Python (error msg) tell me WHAT the actual (arg) values are ? [ In reply to ]
On 2/24/2023 2:47 PM, dn via Python-list wrote:
> On 25/02/2023 08.12, Peter J. Holzer wrote:
>> On 2023-02-24 16:12:10 +1300, dn via Python-list wrote:
>>> In some ways, providing this information seems appropriate.
>>> Curiously, this
>>> does not even occur during an assert exception - despite the
>>> value/relationship being the whole point of using the command!
>>>
>>>      x = 1
>>>      assert x == 2
>>>
>>> AssertionError (and that's it)

Sometimes you can use a second parameter to assert if you know what kind
of error to expect:

>>> a = [1,2,3]
>>> b = [4,5]
>>> assert len(a) == len(b), f'len(a): {len(a)} != len(b): {len(b)}'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError: len(a): 3 != len(b): 2

With type errors, assert may actually give you the information needed:

>>> c = {"a": a, "b": 2}
>>> assert a > c
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: '>' not supported between instances of 'list' and 'dict'

So now we know that a is a list and c is a dictionary.

>> Pytest is great there. If an assertion in a test case fails it analyzes
>> the expression to give you various levels of details:
>>
>> ======================================== test session starts
>> ========================================
>> platform linux -- Python 3.10.6, pytest-6.2.5, py-1.10.0, pluggy-0.13.0
>> rootdir: /home/hjp/tmp/t
>> plugins: cov-3.0.0, anyio-3.6.1
>> collected 1 item
>>
>> test_a.py
>> F                                                                                   [100%]
>>
>> ============================================= FAILURES
>> ==============================================
>> ______________________________________________ test_a
>> _______________________________________________
>>
>>      def test_a():
>>          a = [1, 2, 3]
>>          b = {"a": a, "b": 2}
>>
>>>        assert len(a) == len(b)
>> E       AssertionError: assert 3 == 2
>> E        +  where 3 = len([1, 2, 3])
>> E        +  and   2 = len({'a': [1, 2, 3], 'b': 2})
>>
>> test_a.py:7: AssertionError
>> ====================================== short test summary info
>> ======================================
>> FAILED test_a.py::test_a - AssertionError: assert 3 == 2
>> ========================================= 1 failed in 0.09s
>> =========================================
>
> +1
> and hence the tone of slight surprise in the observation - because only
> ever use assert within pytests, and as observed, pytest amplifies the
> report-back to provide actionable-intelligence. See also: earlier
> contribution about using a debugger.
>
>
> That said, have observed coders 'graduating' from other languages,
> making wider use of assert - assumed to be more data (value)
> sanity-checks than typing, but ...
>
> Do you use assert frequently?
>
>
> The OP seems wedded to his?her ways, complaining that Python does not
> work the way it 'should'. In turn, gives rise to the impression that
> expounding the advantages of TDD, and thus anticipating such unit and
> integration error-possibilities, might be considered an insult or
> unhelpful.
> (sigh!)
>
> Personally, I struggled a bit to adapt from the more-strictured (if not
> more-structured) languages of my past, to Python - particularly the
> different philosophies or emphases of what happens at 'compile-time' cf
> 'execution-time'; and how such required marked changes in attitudes to
> design, time-allocation, work-flow, and tool-set. Two related-activities
> which made the language-change more workable and unleashed greater than
> step-change advantage, were: increased use of TDD, and actively learning
> the facilities within Python-oriented IDEs.
>

--
https://mail.python.org/mailman/listinfo/python-list
Re: Why doesn't Python (error msg) tell me WHAT the actual (arg) values are ? [ In reply to ]
On 2023-02-24 18:19:52 -0500, Thomas Passin wrote:
> On 2/24/2023 2:47 PM, dn via Python-list wrote:
> > On 25/02/2023 08.12, Peter J. Holzer wrote:
> > > On 2023-02-24 16:12:10 +1300, dn via Python-list wrote:
> > > > In some ways, providing this information seems appropriate.
> > > > Curiously, this does not even occur during an assert exception -
> > > > despite the value/relationship being the whole point of using
> > > > the command!
> > > >
> > > > ???? x = 1
> > > > ???? assert x == 2
> > > >
> > > > AssertionError (and that's it)
>
> Sometimes you can use a second parameter to assert if you know what kind of
> error to expect:
>
> >>> a = [1,2,3]
> >>> b = [4,5]
> >>> assert len(a) == len(b), f'len(a): {len(a)} != len(b): {len(b)}'
> Traceback (most recent call last):
> File "<stdin>", line 1, in <module>
> AssertionError: len(a): 3 != len(b): 2

Yup. That's very useful (but I tend to forget that).


> With type errors, assert may actually give you the information needed:
>
> >>> c = {"a": a, "b": 2}
> >>> assert a > c
> Traceback (most recent call last):
> File "<stdin>", line 1, in <module>
> TypeError: '>' not supported between instances of 'list' and 'dict'

Actually in this case it isn't assert which gives you the information,
it's evaluating the expression itself. You get the same error with just
a > c
on a line by its own.

hp

--
_ | Peter J. Holzer | Story must make more sense than reality.
|_|_) | |
| | | hjp@hjp.at | -- Charles Stross, "Creative writing
__/ | http://www.hjp.at/ | challenge!"
Re: Why doesn't Python (error msg) tell me WHAT the actual (arg) values are ? [ In reply to ]
On 2/25/2023 1:13 AM, Peter J. Holzer wrote:
> On 2023-02-24 18:19:52 -0500, Thomas Passin wrote:
>> On 2/24/2023 2:47 PM, dn via Python-list wrote:
>>> On 25/02/2023 08.12, Peter J. Holzer wrote:
>>>> On 2023-02-24 16:12:10 +1300, dn via Python-list wrote:
>>>>> In some ways, providing this information seems appropriate.
>>>>> Curiously, this does not even occur during an assert exception -
>>>>> despite the value/relationship being the whole point of using
>>>>> the command!
>>>>>
>>>>>      x = 1
>>>>>      assert x == 2
>>>>>
>>>>> AssertionError (and that's it)
>>
>> Sometimes you can use a second parameter to assert if you know what kind of
>> error to expect:
>>
>>>>> a = [1,2,3]
>>>>> b = [4,5]
>>>>> assert len(a) == len(b), f'len(a): {len(a)} != len(b): {len(b)}'
>> Traceback (most recent call last):
>> File "<stdin>", line 1, in <module>
>> AssertionError: len(a): 3 != len(b): 2
>
> Yup. That's very useful (but I tend to forget that).
>
>
>> With type errors, assert may actually give you the information needed:
>>
>>>>> c = {"a": a, "b": 2}
>>>>> assert a > c
>> Traceback (most recent call last):
>> File "<stdin>", line 1, in <module>
>> TypeError: '>' not supported between instances of 'list' and 'dict'
>
> Actually in this case it isn't assert which gives you the information,
> it's evaluating the expression itself. You get the same error with just
> a > c
> on a line by its own.

In some cases. For my example with an explanatory string, you wouldn't
want to write code like that after an ordinary line of code, at least
not very often. The assert statement allows it syntactically.

--
https://mail.python.org/mailman/listinfo/python-list
Re: Why doesn't Python (error msg) tell me WHAT the actual (arg) values are ? [ In reply to ]
On 2023-02-25 09:10:06 -0500, Thomas Passin wrote:
> On 2/25/2023 1:13 AM, Peter J. Holzer wrote:
> > On 2023-02-24 18:19:52 -0500, Thomas Passin wrote:
> > > Sometimes you can use a second parameter to assert if you know what kind of
> > > error to expect:
[...]
> > > With type errors, assert may actually give you the information needed:
> > >
> > > > > > c = {"a": a, "b": 2}
> > > > > > assert a > c
> > > Traceback (most recent call last):
> > > File "<stdin>", line 1, in <module>
> > > TypeError: '>' not supported between instances of 'list' and 'dict'
> >
> > Actually in this case it isn't assert which gives you the information,
> > it's evaluating the expression itself. You get the same error with just
> > a > c
> > on a line by its own.
>
> In some cases. For my example with an explanatory string, you wouldn't want
> to write code like that after an ordinary line of code, at least not very
> often. The assert statement allows it syntactically.

Yes, but if an error in the expression triggers an exception (as in this
case) the explanatory string will never be displayed.

hp

--
_ | Peter J. Holzer | Story must make more sense than reality.
|_|_) | |
| | | hjp@hjp.at | -- Charles Stross, "Creative writing
__/ | http://www.hjp.at/ | challenge!"
Re: Why doesn't Python (error msg) tell me WHAT the actual (arg) values are ? [ In reply to ]
I only use asserts for things I know to be true. Nothing is harder to debug than when something you know to be true turns out to be? not True. Because I?ll check everything else instead of the cause of the bug.

In other words, a failing assert means I have a hole in my program logic.

For that use, the default behavior ?telling me which line the assert is on, is more than sufficient. Depending on the circumstance, I?ll re-run the code with a breakpoint or replace the assert with an informative f-string Exception.



From: Python-list <python-list-bounces+gweatherby=uchc.edu@python.org> on behalf of Peter J. Holzer <hjp-python@hjp.at>
Date: Saturday, February 25, 2023 at 9:22 AM
To: python-list@python.org <python-list@python.org>
Subject: Re: Why doesn't Python (error msg) tell me WHAT the actual (arg) values are ?
On 2023-02-25 09:10:06 -0500, Thomas Passin wrote:
> On 2/25/2023 1:13 AM, Peter J. Holzer wrote:
> > On 2023-02-24 18:19:52 -0500, Thomas Passin wrote:
> > > Sometimes you can use a second parameter to assert if you know what kind of
> > > error to expect:
[...]
> > > With type errors, assert may actually give you the information needed:
> > >
> > > > > > c = {"a": a, "b": 2}
> > > > > > assert a > c
> > > Traceback (most recent call last):
> > > File "<stdin>", line 1, in <module>
> > > TypeError: '>' not supported between instances of 'list' and 'dict'
> >
> > Actually in this case it isn't assert which gives you the information,
> > it's evaluating the expression itself. You get the same error with just
> > a > c
> > on a line by its own.
>
> In some cases. For my example with an explanatory string, you wouldn't want
> to write code like that after an ordinary line of code, at least not very
> often. The assert statement allows it syntactically.

Yes, but if an error in the expression triggers an exception (as in this
case) the explanatory string will never be displayed.

hp

--
_ | Peter J. Holzer | Story must make more sense than reality.
|_|_) | |
| | | hjp@hjp.at | -- Charles Stross, "Creative writing
__/ | http://www.hjp.at/ | challenge!"
--
https://mail.python.org/mailman/listinfo/python-list
Re: Why doesn't Python (error msg) tell me WHAT the actual (arg) values are ? [ In reply to ]
On 2023-02-25 21:58:18 +0000, Weatherby,Gerard wrote:
> I only use asserts for things I know to be true.

Yeah, that's what assers are for. Or rather for things that you *think*
are true.

> In other words, a failing assert means I have a hole in my program
> logic.

Yes, if you include your assumptions in your definition of "logic".


> For that use, the default behavior –telling me which line the assert
> is on, is more than sufficient. Depending on the circumstance, I’ll
> re-run the code with a breakpoint or replace the assert with an
> informative f-string Exception.

That may not always be practical. Things that we know (or think) are
true often have *are* true in most cases (otherwise we wouldn't think
so). So the case where the assumption fails may not be easily
reproducable and the more information you can get post-mortem the
better. For example, in C on Linux a failed assertion causes a core
dump. So you can inspect the complete state of the program.

hp

--
_ | Peter J. Holzer | Story must make more sense than reality.
|_|_) | |
| | | hjp@hjp.at | -- Charles Stross, "Creative writing
__/ | http://www.hjp.at/ | challenge!"
Re: Why doesn't Python (error msg) tell me WHAT the actual (arg) values are ? [ In reply to ]
?So the case where the assumption fails may not be easily
reproducable and the more information you can get post-mortem the
better?

That?s true for rare corner cases or esoteric race conditions. Usually, when I see asserts it's just because I was just plain stupid.

From: Python-list <python-list-bounces+gweatherby=uchc.edu@python.org> on behalf of Peter J. Holzer <hjp-python@hjp.at>
Date: Saturday, February 25, 2023 at 5:21 PM
To: python-list@python.org <python-list@python.org>
Subject: Re: Why doesn't Python (error msg) tell me WHAT the actual (arg) values are ?
On 2023-02-25 21:58:18 +0000, Weatherby,Gerard wrote:
> I only use asserts for things I know to be true.

Yeah, that's what assers are for. Or rather for things that you *think*
are true.

> In other words, a failing assert means I have a hole in my program
> logic.

Yes, if you include your assumptions in your definition of "logic".


> For that use, the default behavior ?telling me which line the assert
> is on, is more than sufficient. Depending on the circumstance, I?ll
> re-run the code with a breakpoint or replace the assert with an
> informative f-string Exception.

That may not always be practical. Things that we know (or think) are
true often have *are* true in most cases (otherwise we wouldn't think
so). So the case where the assumption fails may not be easily
reproducable and the more information you can get post-mortem the
better. For example, in C on Linux a failed assertion causes a core
dump. So you can inspect the complete state of the program.

hp

--
_ | Peter J. Holzer | Story must make more sense than reality.
|_|_) | |
| | | hjp@hjp.at | -- Charles Stross, "Creative writing
__/ | http://www.hjp.at/ | challenge!"
--
https://mail.python.org/mailman/listinfo/python-list