• Why doesn't Python (error msg) tell me WHAT the actual (arg) values are

    From Hen Hanna@21:1/5 to All on Wed Feb 22 12:05:21 2023
    > 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.)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From avi.e.gross@gmail.com@21:1/5 to All on Wed Feb 22 16:26:05 2023
    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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Hen Hanna@21:1/5 to Hen Hanna on Wed Feb 22 15:46:09 2023
    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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Thomas Passin@21:1/5 to Hen Hanna on Wed Feb 22 19:28:29 2023
    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...

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Hen Hanna@21:1/5 to Hen Hanna on Wed Feb 22 16:52:34 2023
    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 <--------------

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Barry@21:1/5 to All on Thu Feb 23 07:57:09 2023
    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


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Hen Hanna@21:1/5 to Barry on Thu Feb 23 00:08:31 2023
    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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rob Cliffe@21:1/5 to Hen Hanna on Wed Feb 22 21:31:14 2023
    On 22/02/2023 20:05, Hen Hanna wrote:
    Python makes programming (debugging) so easy
    I agree with that!
    Rob Cliffe

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From avi.e.gross@gmail.com@21:1/5 to Hen Hanna on Thu Feb 23 15:08:49 2023
    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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From dn@21:1/5 to Hen Hanna on Fri Feb 24 16:12:10 2023
    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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Michael Torrie@21:1/5 to Hen Hanna on Thu Feb 23 20:32:26 2023
    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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From avi.e.gross@gmail.com@21:1/5 to Hen Hanna on Thu Feb 23 23:09:52 2023
    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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Peter J. Holzer@21:1/5 to Hen Hanna on Fri Feb 24 20:01:44 2023
    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!"

    -----BEGIN PGP SIGNATURE-----

    iQIzBAABCgAdFiEETtJbRjyPwVTYGJ5k8g5IURL+KF0FAmP5CZMACgkQ8g5IURL+ KF2xhg/9GJ33hYdaWzvIyAvYbAwYmfkf5+QpP4It2yNkBIyJkszUgcbp2EsjclbP 3aUNO3C47HOEq1sreuY10rpXQslSwLAhgSje3gggaBflD+xxMbR0DSkMsbbUbkO9 bOD41ERDynRXgzu4/bJfiqAbjO89Y+lGSWhtmDOoVTGplVAyqU1osGipN1fwjY96 TecPPsLrVsv4WsFCRX86+Ta0BAywOt0d/CctMufDPj/gQCFghaj7CzZ4w78nDrMY kYNc/lidwjMO8USGmJaaznh+RbcqyuQGvCzxs/3nmOdrsnB6EubwLi39HtnA3dF3 0eNW84raL79/E0Hzru/fQ5+BRgyOwjrPOwpd7eVuJTukyrJD5SF+I+YaC3qZEl4x bSpC3NiqDYUCx5Wc8xJ0ZOQiO+BNvH4pvqRv2C78rDT4a+rIEi2+VX8Jv99oZBF4 apBgCpUjSBPHluqUwB+PwTOAqL7VXO3rb2MKw5WWzvqBYuYs0VyOes22qg+Q43Cv AOb/GRT5Ik4iSs626kewQhOtzuxaX5eT2eCveXCLicMxC2TKiGTIr0184DeI5E0w DgEbza+rhvKcTseOD7iZKuy53IsIqtljm93Q0MoMsqZhuf+MHVybD7YxeIqF/q8x Av/aSM8E8ZUl12iAlPqF3kC+paRUd4iiB7c0Qx3
  • From Peter J. Holzer@21:1/5 to Michael Torrie on Fri Feb 24 20:06:06 2023
    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!"

    -----BEGIN PGP SIGNATURE-----

    iQIzBAABCgAdFiEETtJbRjyPwVTYGJ5k8g5IURL+KF0FAmP5Cp0ACgkQ8g5IURL+ KF09RQ/7BfbjZ3usbaIgciKmj5Qj7fFWQI0gRi5WkHg3gnzLM901txCabHuzOSXT KxxkUdC41Df7tM3xfYRQ//FVC/qFuuePYJSXaYUVjTep7nw1+jjQo5+kHH8EfqI4 Vgp2PYze0k028esiyoFvod3S+9HjK3FfdAqs7ciQZV6vC0ijGdoW/P735FaUKxhm VHHSk6q+AJKl8/Y90JeW9yG5lvZiaygI7yU4n3+vt5MXMTd/JgF2NuHcwZFVymFI 41uKLtSZPqKZm1oAQ2lChN3MPjtqUY+CU1pbOb8DRHvMn5xhIHsvUb+s1DbPxpmg zcZo2n7/r+QKoOcITvFMyqfgrzVg4Bu84pkByYLl1NvOlTcWpqlwWivtxf/ic0px ISf0+YyaWDU56W5n7G6gpVlsTxiiraQbzq5tIkuQibRgfinXUf0GtjJcjJmca9ze 2Yy5ktBTpOVCQMhLb4+nL85XXrT7ElUVRxvysNVCiKwmN+M0SgaOqKavPd0CsBGZ lJqtfi/eZe+TVzYcsUEmQXxBPDrl04WU5DE1Jx9zji6NgnlcZFdYOjGDwHPSKzKH XVidXrAQ+zJ9ZKFPuMuUyiGZaXk+gvzNj7dNHGM9gsL175HXJhSwbBbQdXTlMpEj OzcgVqYrcr3algwUJwff7Q0l8osSA6BsOVQeCiD
  • From Peter J. Holzer@21:1/5 to dn via Python-list on Fri Feb 24 20:12:44 2023
    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!"

    -----BEGIN PGP SIGNATURE-----

    iQIzBAABCgAdFiEETtJbRjyPwVTYGJ5k8g5IURL+KF0FAmP5DCwACgkQ8g5IURL+ KF2lxA/+NwO24ERjFHpV+FqaqjTgwm/RFf4Lwv8cmoPPwVnfja/4AjBxkxTaTLe9 a+ggq1T9cfFZFMSbEBvCNEHBeDnaNo+kX7Wt43cPsHYR23jTjDfSV4n8QfJcVKxK oGJLlCiU3QjdIzlGuhRLs7YoOHSy/YZsRzpm88dUXpKb090YVNt3WUQE+RpvslsP JgmIKFCsHTbDjK37lOYc5M/vDjelMOGeQInE2zzTbg4fYQtfXCMMeLMnhD6K4cL8 hENGw7rVkx3lJUs2hbNbhyd+3opJ3hvDvzM7Ig2B5dqvP+2eot7QHDf9rG/eNLaI FFKJkuhsjvCg1ML8uX/RdZKz8HMda2FmAooIEQB41sBUIfH2afGzPuj1/EpNmTgw uML+CgOf2hyLvDHqg//GHNUvPoGxTQfSAJBUU0q7u4BIlTeYXvVHLQ6mJTtgxdEe lkglPmsJ3JlDvhA0FODxMVCMfOENoCL1YSotPnUGRJrYf02fhifM07V52226S/yN Wztnfp0HG7UDNlh8/8TPtGcnfvU2SdR19Qp0ojUThbdX6PC/nIEroelL+EESOXN1 Fxrp99Z06JoyCwAGScT67LQnkqNlEenwaEZcwx2oIdbqkh5Wgdm0JfAVXj8JB8xB hdzUA81OQar8T7t3mnxNs6MbowSBtr+8g4k1gbA
  • From Peter J. Holzer@21:1/5 to dn via Python-list on Fri Feb 24 21:13:30 2023
    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!"

    -----BEGIN PGP SIGNATURE-----

    iQIzBAABCgAdFiEETtJbRjyPwVTYGJ5k8g5IURL+KF0FAmP5GmUACgkQ8g5IURL+ KF36tA/8CVI4kZVJrvikZ3pgj+9Z1HUhTcI4+vgf9OlPfe4dTdV97RkP6D/ODCq/ yQVV8kf914j2wiLlH8Z3QUNHtXTmkb+7Pt79Fnvj1HJMrvmeuOvvdxHH23ej0joP MKTTrrl+7silUHSJdVuCA72zTNJUjgazKiO74ilMpPaXbDj6ADpLsW4zwUfJW5W0 IaF0eazz03vQiAISfSR7CXzeI5FYFbalmMSbYdjtsVqeYpuhCDhQmvOxX2K+fqmF mEZmlhhGBEvKHSAV+setRgEJRX1nZejZjVLJSaEh/AGX/ZlrWDcakBbeSpresMur XQmeyoURSOUAKtIO2Z744AzDwhCybVkQXsRTjCB30E2I427f4gMke6Y84tBdat0n l3vbmvVcbE4290iIhEazFsiOO6celm450l3BWT8FAQvvsvZWzevuQzlnw0wjVWZt ts2cfS8JVtTQMX17cXNx6AC+8gnznLfRVeQeK6wEtVoSzZ04/RlrRh9F4nwKF02N 5zdSyeQ7pPq2pDHOFoNvStf0sTkBzWxcFp3YhsV5JSM7JBffJj8UgsgVES+itUsJ zM58KOzYVUrKtSgOc3KYoKpp05IL5KtfKSJ3CUQm1H/P8oookRKo23hBF0+WUCL1 GtyjpKsH8HBjTYBuXerxoLjhOiYS9eVI4Nt+9An
  • From dn@21:1/5 to Peter J. Holzer on Sat Feb 25 08:47:00 2023
    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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Thomas Passin@21:1/5 to dn via Python-list on Fri Feb 24 18:19:52 2023
    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.


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Peter J. Holzer@21:1/5 to Thomas Passin on Sat Feb 25 07:13:07 2023
    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!"

    -----BEGIN PGP SIGNATURE-----

    iQIzBAABCgAdFiEETtJbRjyPwVTYGJ5k8g5IURL+KF0FAmP5pu8ACgkQ8g5IURL+ KF1ZGA//dNrwxP3yVas7Z0TLaqOeRUR7cbH1BQpEeUNlP3nS0FJShjpa6OgIUOMB 3VJ2qSKRzWKsH1vCHPv9DqPoPH56gCFFmzjAJqjD46A0as0Go449Jd3xxG1sFBVA 7newloywTJDFPgvTB3HpNwL+eoOrm8f4TR/u+OI+AhktTs1aGOrOGlVE61nxCB2m mAvrDz0kS7vBsNXIbyeRi0Qpu3ohPq1mallkwrJs/hLNtQWb9A2PxBCgP0bsmpmP NkF1gfO1KtMyYE7PKM7xUmOHgY4zB15ZK7nr4Yqb31X7IcMQEfiIY7MEHofRKqjC lNoC0dFvyDQ0UB5Ei9oIS87N/PkeV43o8KHpyjxAs65BOFTvNJRd3x/HPPG9Lbpm 7GUf3g6c9FdI8fTgCX1uML6pfFi19zlXP66EJQ9/K54gSoOSTwtCMkUSvYBCVVID N3fqMajwa2ZvSudf1zWYdgJjiRgBPxj5BKgoSF9qt+jeu/3hsrhZ15D7ARV3ReU5 GnXkBz6X5v4r3qV1qBDWy/zxkPFgpmVB/gd7IpmMQkxzL8jR+PLdtCZvY+ZO71mp IvjIb12fAqefa6CdKY+WCMsPxUBsI4R2xlBtSClXqiWLU0F3MVOva8hYiEY6Iemu 1S9mhnp9+HAeBwgOwR5x6WTivoEj8mDskjd30bk
  • From Thomas Passin@21:1/5 to Peter J. Holzer on Sat Feb 25 09:10:06 2023
    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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Peter J. Holzer@21:1/5 to Thomas Passin on Sat Feb 25 15:20:31 2023
    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!"

    -----BEGIN PGP SIGNATURE-----

    iQIzBAABCgAdFiEETtJbRjyPwVTYGJ5k8g5IURL+KF0FAmP6GS8ACgkQ8g5IURL+ KF05pA//XLtJF+XAWzuV3ab2Vtf7NDVa9Y5+5W09TJCiCXlIYqbS8wNL28JX5E+d ll/amQKZuYIoOm0VFh25HfVXZ5pLox9TL2oSb/Wu98wuxrQuFvXDhlowQk5DSgx/ NZMdmJbNLVi7A/yoemf+78Rtq6QRH/Oa9kFf32Sx481QfDnPOmaFgXls+/P9ML6M 02Bvhk1lie3W/phQMioRbYKAoKgY5x9ymImp1h69mXMn5MaWDqpQzNiaCY7vv6i8 C0X1rdY5wYq45c09tCOZlk+NbDkFvgdkBhrj+NI2D2apwd7fbf38uXhVb7tWnupK P9WmNENVATDSu8VnbX16X43hYgH2Gnno0cr/K1QYq/q6XkO//UlO7i8niG5j23MZ WuExK8J5xuqmK6MBo03s1DjGNIOgnW61/zG1QBNt3DSZp5dnbvk5qUCg8Bpx8+Ks f9zcJsGOl1rgHytoy+8e9fUUzHnKrkJftZyVb7AZNeY7wCTuglsDupQweEsbFu13 cSopcJysm7ty40ySZ8MzRjaIsg8pjzVP/CHWgpfyfiQJVtwWxptEi9F1ZC5iA5R3 PXNLyWp011290lu8TH+quxZCfrz6H7Q/pmn0MbSnmIPn1IqYmtcjO4No0w3BOuei lBnmCz/zEqtFVNogdZyAoMxj0UdC63MTPzRVJ2W
  • From Weatherby,Gerard@21:1/5 to Thomas Passin on Sat Feb 25 21:58:18 2023
    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!"

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Paul Rubin@21:1/5 to Gerard" on Sat Feb 25 14:21:28 2023
    "Weatherby,Gerard" <gweatherby@uchc.edu> writes:
    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.

    The hole in the logic can be annoying to recreate. You can give an arg
    to the assert statement telling it what to put in the message, and I
    often do that:

    n = count_wobbles(thingy)
    assert n > 3, (n, thingy)

    The argument "(n, thingy)" puts the offending values into the message.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Peter J. Holzer@21:1/5 to Gerard on Sat Feb 25 23:19:43 2023
    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!"

    -----BEGIN PGP SIGNATURE-----

    iQIzBAABCgAdFiEETtJbRjyPwVTYGJ5k8g5IURL+KF0FAmP6iXoACgkQ8g5IURL+ KF0rjRAAjRpqQerjGqfSxRFp13yWYcP4jOBUyn44DpqBg+awOxKdDw5eDXngyAyD zRlOnQls/8JTqdIBPJavyleoWsljfULD5dJMHTd44p7Xz1vRD6rEgOtoQ5HHnplc zeePlP4+iWZSB6topsVUlM6anC54gjBeYEZ7rahsfdCeKFydHnhg0fwMv3hwmefy Y+Qoe7Esms0EY7RdiUD+E3MvjFvoieqjTP1Dv5KaDS2wz71PJcsfaRDdtHswR4CW 8Yr/po5/P0LeR1B2vyzWqXxsyKkZqE05X94AZXEyR7O6LGWp9nQFu+7KdcXwux9+ UOGOqcvvFTtwFaqetUJyBnT3wvfQgBKTkHlYuEgzhE4o57c/eS0CFa2zEFHPjjCl Fg0Dkx17Te+C3AsfbKcE5JQsWjndp3O6+4gS3eU4mo2cST3OYwI7Vg2ia3MlyV/G PCHkrqKS4M+auKxJcHgjLAa0UKjPG+9yWxceWePR686B8JUKOuwjYA8pkmPg7mMO hPDAA4vK11VKXPBdeF9BJt4gbeqVJDUyKQuus+FHRCmEERxgIgzfRcz7FN/e3vIE u7RCds6v0w8eFNgEXSd4BgBm/pjhG4+oYDI4qdeNwUBj5LdYiQMtC7Mct7dqyIHN pQYLU3YkfuOhz4/zLUT+2WfsM3snauZKNwuYsyE
  • From Weatherby,Gerard@21:1/5 to Gerard on Sun Feb 26 02:38:08 2023
    “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!"

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)