[Python-ideas] Re: [Python-Dev] Re: Inadequate error reporting during function call setup stage

2021-02-22 Thread Paul Sokolovsky
Hello,

On Tue, 23 Feb 2021 17:52:20 +1100
Chris Angelico  wrote:

[]

> That's why I dispute that this is an "astonishing oversight". It would
> be nice to have the extra information, but given that Python and
> Python programmers have survived for thirty years without it, I don't
> think it's nearly as serious as you're implying.

Ah, missed to reply to that one. Can judge it by myself: that's
definitely not the first time I see that issue, where there was
"something wrong" when getting exceptions when dealing with first-class
function values. But I didn't even have a good understanding of what's
wrong, and cases were either simple and obvious, or I reduced to print
debugging.

But now I'm working on a project where I consider UX to be important.
And I consider a good UX for Python project not when it catch-all's
exceptions and obfuscates the problem with a generic error message, and
likewise not when there're 5 screenfuls of chained exceptions. I
consider it's when there's human-sized backtrace, clearly pointing at
the problem.

And for that case, I figured that the backtrace is senseless and
doesn't give a user of my program enough information to understand the
issue.

So, I stopped with writing my program, sat and scratched my head to
understand what's wrong, then sat again to try a few different
solutions (the original post should mirror that), until finally came
to one which makes sense to the end user, and doesn't require any
crutches.


I won't be surprised if that's how other Python programmers dealt with
it over decades - some didn't even dig into "what's wrong", "something
is wrong" was enough for them to do in-mind-debugging. The other
gritted teeth and recursed to print debugging, again without thinking
too much what's wrong on the meta-level. And the remaining? Well, they
now curse Python for poor error reporting on reddits and hackernewses.


You can also see that on this very thread - at first, the issue was at
all unclear (even though I tried to write a detailed message, packing
different sides into it). Now issue becomes clear, but (besides the
usual "never heard" response), the thinking is along the lines of
"additional info hacks", which was my first motion either.

Let's see where that leads us. (And that's why I posted to the mailing
list first - chances, a bugs.p.o report would be closed with "discuss
first on the mailing list" suggestion).

[]

-- 
Best regards,
 Paul  mailto:pmis...@gmail.com
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/OIENWJYHNEUNTU67MLKVRNK4SRPOSIEE/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: [Python-Dev] Re: Inadequate error reporting during function call setup stage

2021-02-22 Thread Paul Sokolovsky
Hello,

On Tue, 23 Feb 2021 17:52:20 +1100
Chris Angelico  wrote:

> On Tue, Feb 23, 2021 at 5:33 PM Paul Sokolovsky 
> wrote:
> > Because that's the right analogy of what happens with a function -
> > in the function "prolog", there's a series of assignments:
> > "formal_paramX = actual_argX". Conceptually, those *are* in the
> > function context (or you would not be able to reference function's
> > formal params).  
> 
> But they aren't actual lines of code. Your analogy breaks down because
> you're trying to put a line into a backtrace for a mythical and
> conceptual action that happens as part of the function call.

But that's the whole point - the externally visible behavior should
correspond to the conceptual model, even if a particular implementation
does something different underlyingly.

So again, it's CPython's implementation detail that, for bytecode
functions only, it implements:

def foo(params):  # foo takes care of its params
...

foo(args)

as:

param_check_and_call(foo, __param_meta__[foo], *args)

And due to this implementation detail raises exceptions from
param_check_and_call().

[]

> The way I see it, this is perfect as an "additional information"
> field.

I started there, and proceeded to where no "additional information"
hacks are needed, and everything fits well into the existing framework.
Come along with me.


[]


-- 
Best regards,
 Paul  mailto:pmis...@gmail.com
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/CBWMQQYKMOL6JYAESTHFWCJ3Y7H53CDK/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: [Python-Dev] Re: Inadequate error reporting during function call setup stage

2021-02-22 Thread Chris Angelico
On Tue, Feb 23, 2021 at 5:33 PM Paul Sokolovsky  wrote:
> Because that's the right analogy of what happens with a function - in
> the function "prolog", there's a series of assignments:
> "formal_paramX = actual_argX". Conceptually, those *are* in the
> function context (or you would not be able to reference function's
> formal params).

But they aren't actual lines of code. Your analogy breaks down because
you're trying to put a line into a backtrace for a mythical and
conceptual action that happens as part of the function call.

That's why I dispute that this is an "astonishing oversight". It would
be nice to have the extra information, but given that Python and
Python programmers have survived for thirty years without it, I don't
think it's nearly as serious as you're implying.

> For another analogy, you can look at how native functions are defined
> and where they check params, and from where exceptions originate there
> (by obvious reasons, Python backtraces don't show C source code
> function/linenos ;-)).

Yes, or you could look at CPython byte code and how it does a bunch of
stack operations, but some of them don't actually happen. Looking at
the implementation, especially in a completely different language,
doesn't really help here :)

The way I see it, this is perfect as an "additional information"
field. For instance, when I compile certain buggy C programs, gcc
tells me things like this:

demo.c: In function ‘main’:
demo.c:4:9: warning: passing argument 1 of ‘printf’ makes pointer from
integer without a cast [-Wint-conversion]
  printf(12345);
 ^
In file included from demo.c:1:
/usr/include/stdio.h:332:43: note: expected ‘const char * restrict’
but argument is of type ‘int’
 extern int printf (const char *__restrict __format, ...);
~~~^~~~

It starts by reporting the error, and then says "note: the thing
you're calling came from over here". It's separate from the error
itself, but provides extremely useful information.

Python doesn't currently have a standardized way to report this, but
IMO that would be a far better way than synthesizing a fake backtrace
entry.

Taking your original example, it might look something like this:

Traceback (most recent call last):
  File "pseudoc_tool.py", line 91, in 
first_class_function_value(func, **pass_params)
TypeError: print() got an unexpected keyword argument 'noann'

Note: The function is defined here:
File "whatever.py", line 123, in 
  def print(thingy, thongy, whop):

ChrisA
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/5Z4JLH76N6OL4DGF4CBD3IY7GQQOL2VR/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: [Python-Dev] Re: Inadequate error reporting during function call setup stage

2021-02-22 Thread Paul Sokolovsky
Hello,

On Tue, 23 Feb 2021 12:31:37 +1100
Chris Angelico  wrote:

> On Tue, Feb 23, 2021 at 10:10 AM Stestagg  wrote:
> > So Python has identified that a function 'do_thing' is being called
> > incorrectly, but /where/ is do_thing defined?   This problem gets
> > much harder if there are multiple definitions of 'do_thing' in the
> > codebase, as alluded to in the original mail.
> >
> > Paul's suggestion is that python should add the source location of
> > the function being called into the error message somewhere. 
> 
> Thank you for explaining. I'm glad I wasn't the only one confused by
> the original post :)
> 
> I think this is a nice-to-have, rather than being a serious bug to be
> fixed. 

It's not a serious bug, it's "astonishing overlook". Astonishing, as it
was there for so many years, unpatched. And of course, it's rare
enough. But when it happens, you're in the maze.

I spend much time communicating with Python critics (well, haters), and
sometimes read quite funny criticisms like: error reporting
(stacktraces) in Python is poor. I always considered that "random last
resort nitpick", as error reporting in Python has always been much
better than in other scripting languages (I guess by now everyone
caught up).

But now imagine error like that happens in some 3rd-party library.
Which happened to do some first-class function/higher order
programming. With functions from another 3rd-party library. Which
released a new version with "slightly updated" API. All that happening
in production. Someone who ever caught such (or similar) case would
forever get imprint of "Python has poor error reporting". Because just
imagine what you report to the maintainer of the first 3rd-party lib:
"Your lib calls something wrong in file X line Y" - "Ok, let's look
into that. What does it call?" - "Umm, I don't know, something called
'foo'" (or ""). 

> When you get an error about a function call, it's entirely
> possible that the target function is the problem, or that the wrong
> function is being referenced; but you can get similar problems with
> all kinds of mismatches (like "a, b, c = thing" and getting a
> ValueError - maybe you'd need to check the line where 'thing'
> originated).

Good point. But right analogy here is: suppose error happens in "a, b,
c = thing". But Python doesn't show that line in the backtrace, it stops
1 entry before it. Go figure now.

Because that's the right analogy of what happens with a function - in
the function "prolog", there's a series of assignments:
"formal_paramX = actual_argX". Conceptually, those *are* in the
function context (or you would not be able to reference function's
formal params).

> If this can be done easily, great, but otherwise it might be the
> domain of traceback enhancement tools rather than the core language.

For Pycopy it was easy. I will look into CPython one of these weeks.

> 
> Does execution ever (in the normal case) actually hit the 'def' line?
> If so, I wouldn't be averse to having a traceback line mentioning it.
> But if (as I suspect) tracing successful execution wouldn't hit that
> line, then it doesn't seem right to feign execution of it. My
> understanding of the def statement is that it runs ONLY when the
> function is defined; when the function's called, you go straight into
> the body.

For another analogy, you can look at how native functions are defined
and where they check params, and from where exceptions originate there
(by obvious reasons, Python backtraces don't show C source code
function/linenos ;-)).

> 
> ChrisA

[]
-- 
Best regards,
 Paul  mailto:pmis...@gmail.com
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/FB46HVUMI4KYBQW3URH75WV7VJBI5U3G/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: [Python-Dev] Re: Inadequate error reporting during function call setup stage

2021-02-22 Thread Paul Sokolovsky
Hello,

On Mon, 22 Feb 2021 17:32:23 -0500
Ned Batchelder  wrote:

> On 2/22/21 3:06 PM, Paul Sokolovsky wrote:
> >
> > No, I'm proposing to stop faking lack of the last stack frame due to
> > CPython's implementation details. See the original message for more
> > info.  
> 
> I'm trying to understand what last stack frame (or lack of a last
> stack frame, or the faking of a lack of a last stack frame) you are
> talking about.  Your original message shows some tracebacks, but
> doesn't have the code that produced them.  It's hard to understand
> what you are referring to.

Well, if you looked at that stack trace, you saw the code:

Traceback (most recent call last):
  File "pseudoc_tool.py", line 91, in 
first_class_function_value(func, **pass_params)
TypeError: print() got an unexpected keyword argument 'noann'

So yes, the code is:

---
first_class_function_value(func, **pass_params)
---

That's the "calling code". And the rest of the code? But's that's the
whole point, that the current CPython's error reporting doesn't tell me
where it is! It just tells me the function name, and go make a
full-text search thru the entire sys.path to find its location,
especially if there're many functions of that name.



-- 
Best regards,
 Paul  mailto:pmis...@gmail.com
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/6GFRPZSWTRZPJQKMWKBJVVPHD7X2ZMLO/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Deprecate/change the behaviour of ~bool

2021-02-22 Thread Marco Sulla
On Tue, 23 Feb 2021 at 02:13, Soni L.  wrote:
>
> Currently ~False is -1 and ~True is -2. Would be nicer if ~bool was the
> same as not bool.

I suspect this is more for NumPy people. I remember that one of my
bosses used `~a` on a bool because he started with NumPy and had a
limited knowledge of Python.
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/ISG7IASKULB4SP7TW5GC7I5BUIEDYO4E/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Deprecate/change the behaviour of ~bool

2021-02-22 Thread Josh Rosenberg
> You could write it as a ^ (not b), as long as you don't mind it giving
back an integer rather than a bool.

Actually, that'll give back a bool if a is a bool (and (not b) produces a
bool); ^ is overridden for bool/bool operations and itself returns a bool.

On Tue, Feb 23, 2021 at 1:48 AM Chris Angelico  wrote:

> On Tue, Feb 23, 2021 at 12:14 PM Soni L.  wrote:
> >
> > Currently ~False is -1 and ~True is -2. Would be nicer if ~bool was the
> > same as not bool. Hopefully nobody actually relies on this but
> > nevertheless, it would be a backwards-incompatible change so the whole
> > deprecation warnings and whatnot would be required.
>
> There are quite a few ways in which bitwise operators are not the same
> as boolean operators. What would be the advantage of having them be
> the same in just this one case?
>
> > In particular, this is nice for xnor operator: a ^~ b. This currently
> > works on ints, but not on bools, while most other operators, including
> > xor, do successfully work on bools.
>
> You could write it as a ^ (not b), as long as you don't mind it giving
> back an integer rather than a bool. Fundamentally, you're doing
> bitwise operations on integers, and expecting them to behave as if
> they have only a single bit each, so another way to resolve this might
> be to mask it off at the end with "& 1".
>
> If this makes your code horrendously ugly, perhaps it would be better
> to create your own "one-bit integer" class, which responds to all
> bitwise operators by automatically masking down to one bit?
>
> ChrisA
> ___
> Python-ideas mailing list -- python-ideas@python.org
> To unsubscribe send an email to python-ideas-le...@python.org
> https://mail.python.org/mailman3/lists/python-ideas.python.org/
> Message archived at
> https://mail.python.org/archives/list/python-ideas@python.org/message/6HLSLQMMKYNLSEQCIIDVKXIGV2TZFREE/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/QLYII65C56TRVBWPE3NRLC7IBEBECNPO/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Deprecate/change the behaviour of ~bool

2021-02-22 Thread Guido van Rossum
Also, code that is expecting an int should not behave differently when it
receives a bool.

On Mon, Feb 22, 2021 at 17:47 Chris Angelico  wrote:

> On Tue, Feb 23, 2021 at 12:14 PM Soni L.  wrote:
> >
> > Currently ~False is -1 and ~True is -2. Would be nicer if ~bool was the
> > same as not bool. Hopefully nobody actually relies on this but
> > nevertheless, it would be a backwards-incompatible change so the whole
> > deprecation warnings and whatnot would be required.
>
> There are quite a few ways in which bitwise operators are not the same
> as boolean operators. What would be the advantage of having them be
> the same in just this one case?
>
> > In particular, this is nice for xnor operator: a ^~ b. This currently
> > works on ints, but not on bools, while most other operators, including
> > xor, do successfully work on bools.
>
> You could write it as a ^ (not b), as long as you don't mind it giving
> back an integer rather than a bool. Fundamentally, you're doing
> bitwise operations on integers, and expecting them to behave as if
> they have only a single bit each, so another way to resolve this might
> be to mask it off at the end with "& 1".
>
> If this makes your code horrendously ugly, perhaps it would be better
> to create your own "one-bit integer" class, which responds to all
> bitwise operators by automatically masking down to one bit?
>
> ChrisA
> ___
> Python-ideas mailing list -- python-ideas@python.org
> To unsubscribe send an email to python-ideas-le...@python.org
> https://mail.python.org/mailman3/lists/python-ideas.python.org/
> Message archived at
> https://mail.python.org/archives/list/python-ideas@python.org/message/6HLSLQMMKYNLSEQCIIDVKXIGV2TZFREE/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
-- 
--Guido (mobile)
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/CHWNS222IJQQHXBTXXMSSD2GQZ4QAE7A/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Deprecate/change the behaviour of ~bool

2021-02-22 Thread Chris Angelico
On Tue, Feb 23, 2021 at 12:14 PM Soni L.  wrote:
>
> Currently ~False is -1 and ~True is -2. Would be nicer if ~bool was the
> same as not bool. Hopefully nobody actually relies on this but
> nevertheless, it would be a backwards-incompatible change so the whole
> deprecation warnings and whatnot would be required.

There are quite a few ways in which bitwise operators are not the same
as boolean operators. What would be the advantage of having them be
the same in just this one case?

> In particular, this is nice for xnor operator: a ^~ b. This currently
> works on ints, but not on bools, while most other operators, including
> xor, do successfully work on bools.

You could write it as a ^ (not b), as long as you don't mind it giving
back an integer rather than a bool. Fundamentally, you're doing
bitwise operations on integers, and expecting them to behave as if
they have only a single bit each, so another way to resolve this might
be to mask it off at the end with "& 1".

If this makes your code horrendously ugly, perhaps it would be better
to create your own "one-bit integer" class, which responds to all
bitwise operators by automatically masking down to one bit?

ChrisA
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/6HLSLQMMKYNLSEQCIIDVKXIGV2TZFREE/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: [Python-Dev] Re: Inadequate error reporting during function call setup stage

2021-02-22 Thread Chris Angelico
On Tue, Feb 23, 2021 at 10:10 AM Stestagg  wrote:
> So Python has identified that a function 'do_thing' is being called 
> incorrectly, but /where/ is do_thing defined?   This problem gets much harder 
> if there are multiple definitions of 'do_thing' in the codebase, as alluded 
> to in the original mail.
>
> Paul's suggestion is that python should add the source location of the 
> function being called into the error message somewhere.
>

Thank you for explaining. I'm glad I wasn't the only one confused by
the original post :)

I think this is a nice-to-have, rather than being a serious bug to be
fixed. When you get an error about a function call, it's entirely
possible that the target function is the problem, or that the wrong
function is being referenced; but you can get similar problems with
all kinds of mismatches (like "a, b, c = thing" and getting a
ValueError - maybe you'd need to check the line where 'thing'
originated).

If this can be done easily, great, but otherwise it might be the
domain of traceback enhancement tools rather than the core language.

Does execution ever (in the normal case) actually hit the 'def' line?
If so, I wouldn't be averse to having a traceback line mentioning it.
But if (as I suspect) tracing successful execution wouldn't hit that
line, then it doesn't seem right to feign execution of it. My
understanding of the def statement is that it runs ONLY when the
function is defined; when the function's called, you go straight into
the body.

ChrisA
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/6G6Q45XYZOFA7BMHDLJUO4R6AX5UJVDM/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Deprecate/change the behaviour of ~bool

2021-02-22 Thread Soni L.
Currently ~False is -1 and ~True is -2. Would be nicer if ~bool was the 
same as not bool. Hopefully nobody actually relies on this but 
nevertheless, it would be a backwards-incompatible change so the whole 
deprecation warnings and whatnot would be required.


In particular, this is nice for xnor operator: a ^~ b. This currently 
works on ints, but not on bools, while most other operators, including 
xor, do successfully work on bools.

___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/PTIKNJRKI33UEC62UDJOR5N6WOENU6PB/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: [Python-Dev] Re: Inadequate error reporting during function call setup stage

2021-02-22 Thread Stestagg
To avoid confusion, the traceback below has been updated here with correct
names:

On Mon, Feb 22, 2021 at 11:07 PM Stestagg  wrote:

> My take on this is that it's actually a valid suggestion, albeit wrapped
> in some unhelpful language.
>
> This is a more common example, in my opinion:
>
> === fileA.py ===
>
> class MyClass:
> def do_thing(self, arg_a, arg_b):
> pass
>
> === fileB.py ===
> ...
> class MySubClass(MyClass):
> pass
>
> === main.py ===
> ...
> MySubclass().do_thing(1)
>
> If you run the above (with trivial imports filled in etc.)
> Then the traceback gives:
>
> Traceback (most recent call last):
>   File "main.py", line 3, in 
> MySubClass().do_thing(1)
> TypeError: do_thing() takes exactly 3 arguments (2 given)
>
> So Python has identified that a function 'do_thing' is being called
> incorrectly, but /where/ is do_thing defined?   This problem gets much
> harder if there are multiple definitions of 'do_thing' in the codebase, as
> alluded to in the original mail.
>
> Paul's suggestion is that python should add the source location of the
> function being called into the error message somewhere.
>
> The "it is/isn't a stack frame" issue is one possible solution, and comes
> down to a potential *semantic only* disagreement on how functions are
> called with python.
>
> If you take traditional runtime-less languages, then the responsibility
> for unpacking and handling arguments is considered part of the function
> being called.
> With C, for example, typically the compiler inserts a header (can't
> remember the better term for this right now)  at the start of a function,
> which moves the function arguments around as needed, so any failure match
> the arguments originates from within the called function (this is even more
> obvious with VA_ARGS for example).
>
> Obviously, in languages with a runtime, such as python, the responsibility
> for matching arguments with function signatures can sit outside of the
> runtime function call context, and runtime-internal machinery information
> is not typically included in stack-traces.  Therefore, it appears (although
> I don't think this was part of any specific plan?) that the error
> originates from the call site (where the function is being called from)
> because this is the last point that was executing any python code.
>
> So, the suggestion, as I understand it, is that a small conceptual shift
> is made in how we think about the mechanics of calling a function within
> python, such that the assignment and binding of function arguments are
> conceptually performed 'inside' the function being called (I assume you
> could equate this to the function 'def' line being executed).  If we do
> this, then it becomes easy to consider the TypeError as originating from
> within the called function, and therefore python will print the exact
> location of the function that's being called *as well as* the location of
> the call site (in the frame above).  Internally, the python runtime would
> have to go out of its way to  enter this 'fake' frame before generating the
> exception as, in reality the frame isn't entered (as I understand it) until
> after the arguments have been assigned correctly to the signature.  But
> this seems like it should be relatively simple and non-invasive to do.
>
> The above makes sense to me, apologies if it's not very understandable to
> others.
>
> Thanks
>
> Steve
>
>
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/PZNJC7UJWGLWU53AQ64CK5TJZMG2ZBN4/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: [Python-Dev] Re: Inadequate error reporting during function call setup stage

2021-02-22 Thread Stestagg
My take on this is that it's actually a valid suggestion, albeit wrapped in
some unhelpful language.

This is a more common example, in my opinion:

=== fileA.py ===

class MyClass:
def do_thing(self, arg_a, arg_b):
pass

=== fileB.py ===
...
class MySubClass(MyClass):
pass

=== main.py ===
...
MySubclass().do_thing(1)

If you run the above (with trivial imports filled in etc.)
Then the traceback gives:

Traceback (most recent call last):
  File "c.py", line 3, in 
B().do_thing()
TypeError: do_thing() takes exactly 3 arguments (1 given)

So Python has identified that a function 'do_thing' is being called
incorrectly, but /where/ is do_thing defined?   This problem gets much
harder if there are multiple definitions of 'do_thing' in the codebase, as
alluded to in the original mail.

Paul's suggestion is that python should add the source location of the
function being called into the error message somewhere.

The "it is/isn't a stack frame" issue is one possible solution, and comes
down to a potential *semantic only* disagreement on how functions are
called with python.

If you take traditional runtime-less languages, then the responsibility for
unpacking and handling arguments is considered part of the function being
called.
With C, for example, typically the compiler inserts a header (can't
remember the better term for this right now)  at the start of a function,
which moves the function arguments around as needed, so any failure match
the arguments originates from within the called function (this is even more
obvious with VA_ARGS for example).

Obviously, in languages with a runtime, such as python, the responsibility
for matching arguments with function signatures can sit outside of the
runtime function call context, and runtime-internal machinery information
is not typically included in stack-traces.  Therefore, it appears (although
I don't think this was part of any specific plan?) that the error
originates from the call site (where the function is being called from)
because this is the last point that was executing any python code.

So, the suggestion, as I understand it, is that a small conceptual shift is
made in how we think about the mechanics of calling a function within
python, such that the assignment and binding of function arguments are
conceptually performed 'inside' the function being called (I assume you
could equate this to the function 'def' line being executed).  If we do
this, then it becomes easy to consider the TypeError as originating from
within the called function, and therefore python will print the exact
location of the function that's being called *as well as* the location of
the call site (in the frame above).  Internally, the python runtime would
have to go out of its way to  enter this 'fake' frame before generating the
exception as, in reality the frame isn't entered (as I understand it) until
after the arguments have been assigned correctly to the signature.  But
this seems like it should be relatively simple and non-invasive to do.

The above makes sense to me, apologies if it's not very understandable to
others.

Thanks

Steve



On Mon, Feb 22, 2021 at 10:39 PM Ned Batchelder 
wrote:

>
> On 2/22/21 3:06 PM, Paul Sokolovsky wrote:
> >
> > No, I'm proposing to stop faking lack of the last stack frame due to
> > CPython's implementation details. See the original message for more
> > info.
>
> I'm trying to understand what last stack frame (or lack of a last stack
> frame, or the faking of a lack of a last stack frame) you are talking
> about.  Your original message shows some tracebacks, but doesn't have
> the code that produced them.  It's hard to understand what you are
> referring to.
>
> --Ned.
> ___
> Python-ideas mailing list -- python-ideas@python.org
> To unsubscribe send an email to python-ideas-le...@python.org
> https://mail.python.org/mailman3/lists/python-ideas.python.org/
> Message archived at
> https://mail.python.org/archives/list/python-ideas@python.org/message/KTBIYQDPHOHNYGTWWXT2KRODRHZDZWQX/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/BJPW734TOJDN3RAUI73CLUFY6LVZCQ7X/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: SimpleNamespace vs object

2021-02-22 Thread Mike Miller

On 2021-02-21 20:51, Chris Angelico wrote:

In my mind, the current front-runners are:

* namespace
* ns
* thing
* mutableobject
* mobject
* attrobject
* bunch



Short and PascalCase please, to avoid collisions:


* Stuff


With credit to George Carlin. ;-)

Some of these work as well, Kit is not bad:

https://www.thesaurus.com/browse/stuff

-Mike
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/YCF6B4BI5RHZTL2DFHEO3J7NXM6O7MN7/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: [Python-Dev] Re: Inadequate error reporting during function call setup stage

2021-02-22 Thread Ned Batchelder


On 2/22/21 3:06 PM, Paul Sokolovsky wrote:


No, I'm proposing to stop faking lack of the last stack frame due to
CPython's implementation details. See the original message for more
info.


I'm trying to understand what last stack frame (or lack of a last stack 
frame, or the faking of a lack of a last stack frame) you are talking 
about.  Your original message shows some tracebacks, but doesn't have 
the code that produced them.  It's hard to understand what you are 
referring to.


--Ned.
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/KTBIYQDPHOHNYGTWWXT2KRODRHZDZWQX/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Inadequate error reporting during function call setup stage

2021-02-22 Thread Paul Sokolovsky
Hello,

On Mon, 22 Feb 2021 19:47:04 +
Barry Scott  wrote:

> > On 22 Feb 2021, at 10:15, Paul Sokolovsky  wrote:
> > 
> > It looks like:
> > 
> > Traceback (most recent call last):
> >  File "pseudoc_tool.py", line 91, in 
> >  File ".../xforms.py", line 25, in print
> > TypeError: unexpected keyword argument 'noann'
> > 
> > - that makes clear that it's "print" function of "xforms.py" module,
> > line 25, which got an unexpected keyword argument.  
> 
> You are proposing to fake a stack frame that I have to know is not a
> stack frame but is in fact the location of the function in the
> exception? 

No, I'm proposing to stop faking lack of the last stack frame due to
CPython's implementation details. See the original message for more
info.

> I'm -1 on that as its confusing.
> 
> Having checked that its python code and not a C extension function
> you could use the info in fn.__code__ to get the filename and line of
> where the function is defined and put that info into the exception.

Could use crystal ball, even.

> 
> Example of the info:
> | >>> os.path.join.__code__
>  "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/posixpath.py",
> line 71>
> 
> I use repr(fn.__code__) a lot when debugging complex code.
> 
> Barry
> 



-- 
Best regards,
 Paul  mailto:pmis...@gmail.com
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/FB65TFWGZEBENGT3W2X7RBPY63RINU25/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Inadequate error reporting during function call setup stage

2021-02-22 Thread Barry Scott


> On 22 Feb 2021, at 10:15, Paul Sokolovsky  wrote:
> 
> It looks like:
> 
> Traceback (most recent call last):
>  File "pseudoc_tool.py", line 91, in 
>  File ".../xforms.py", line 25, in print
> TypeError: unexpected keyword argument 'noann'
> 
> - that makes clear that it's "print" function of "xforms.py" module,
> line 25, which got an unexpected keyword argument.

You are proposing to fake a stack frame that I have to know is not a stack 
frame but is in fact the location of the function in the exception?
I'm -1 on that as its confusing.

Having checked that its python code and not a C extension function you could 
use the info
in fn.__code__ to get the filename and line of where the function is defined 
and put that info into the exception.

Example of the info:
| >>> os.path.join.__code__


I use repr(fn.__code__) a lot when debugging complex code.

Barry

___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/YJ3RNTHGZWJ2DG2T5HFGXKTKFYN3CGAN/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: SimpleNamespace vs object

2021-02-22 Thread Steven D'Aprano
On Mon, Feb 22, 2021 at 11:22:09AM +, Rob Cliffe via Python-ideas wrote:

> What's wrong with "namespace"?  None of the other names IMO convey the 
> intended/suggested use nearly as well.

The problem with "namespace" is that the intended us is not as a 
namespace, but as a dict using `.` syntax instead of `["key"]` syntax, 
as in Javascript.

The normal use of a namespace is something that you *implicitly* lookup 
names in, e.g. locals, globals, builtins. Whereas this is more of a 
key:value store where the keys are restricted to identifiers and you use 
attribute syntax to access the values.

I know there's a lot of overlap in functionality and semantics between 
objects, namespaces and dicts, but generally speaking we don't talk 
about an int being a namespace when we look up a method:

(47295).bit_length()

nor do we normally think of a dict as a namespace, unless it's the 
backend data store of globals etc.

So we have the funny situation that *technically* every object is a 
namespace, but the objects that we use as namespaces are usually dicts, 
and we don't use dict attributes as the namespace names/values, we use 
keys/values instead.
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/YAUXWUSOHQ5CKTZPI577HR4BWQY7FK4Q/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: SimpleNamespace vs object

2021-02-22 Thread Rob Cliffe via Python-ideas



On 22/02/2021 04:51, Chris Angelico wrote:

On Mon, Feb 22, 2021 at 1:11 PM Brendan Barnwell  wrote:


 Why not just put SimpleNamespace in the collections module?  The one in
types could be aliased to it (or vice versa if we really don't want to
change anything).  That seems like it's a trivial change that would
greatly increase discoverability of SimpleNamespace without adding
complexity of any kind.

I absolutely agree, and that's going to be the cornerstone of the
proposal :)

Seems sensible.

  But at the same time as putting into collections, we can
also give it a much shorter name. Whatever happens, it's going to be
an exact alias for types.SimpleNamespace, which isn't going away.

In my mind, the current front-runners are:

* namespace
* ns
* thing
* mutableobject
* mobject
* attrobject
* bunch

I
What's wrong with "namespace"?  None of the other names IMO convey the 
intended/suggested use nearly as well.

Rob Cliffe
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/DEAUQM5FBYYU4WK3FY45XMAFMFNBKYIP/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Inadequate error reporting during function call setup stage

2021-02-22 Thread Paul Sokolovsky
Hello,

On Mon, 22 Feb 2021 10:44:19 +0100
Peter Otten <__pete...@web.de> wrote:

> On 21/02/2021 23:06, Terry Reedy wrote:
> > On 2/21/2021 12:04 PM, Paul Sokolovsky wrote:
> >  
> >> Traceback (most recent call last):
> >>    File "pseudoc_tool.py", line 91, in 
> >>  first_class_function_value(func, **pass_params)
> >> TypeError: print() got an unexpected keyword argument 'noann'  
> >
> > This is not typical behavior in current Python (3.8+).  
> 
> The way I understand it's not about print(), it's about
> disambiguating multiple functions with the same name.
> Example:
> 
> PS > type .\ambiguous_names.py
> import random
> 
> def do_stuff():
>  pass
> 
> f = do_stuff
> 
> def do_stuff(a, b):
>  pass
> 
> g = do_stuff
> 
> random.choice([f, g])(42)

Thanks, that's exactly what I meant, and a repro with random "roulette"
is also what I had in mind, I just didn't get to it yet ;-).

> PS > py .\ambiguous_names.py
> Traceback (most recent call last):
>File "...\ambiguous_names.py", line 13, in 
>  random.choice([f, g])(42)
> TypeError: do_stuff() missing 1 required positional argument: 'b'
> 
> The traceback gives no clue which of the two do_stuff() functions
> caused the error, you have to check both implementations.
> 
> If that is a comman problem one might consider including module name
> and co_firstlineno in the message, or at least adding the relevant
> do_stuff() function to the exception's args.

As my original message argues, that's a workaround. Python tracebacks
already have places where they show source file and line number -
namely, the individual traceback entries. So, instead of cramming that
info into the exception message, there should be additional last (latest
in the order of execution) traceback entry, pointing to the exact
function which had parameter mismatch. As I mentioned, I implemented
that in my Python dialect, which happened to have exactly the same
problem (code is not based on CPython).

It looks like:

Traceback (most recent call last):
  File "pseudoc_tool.py", line 91, in 
  File ".../xforms.py", line 25, in print
TypeError: unexpected keyword argument 'noann'

 - that makes clear that it's "print" function of "xforms.py" module,
line 25, which got an unexpected keyword argument.


-- 
Best regards,
 Paul  mailto:pmis...@gmail.com
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/7SJTTAB7TZQYZ6WSRAAPSLLNMRF2OP7F/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: SimpleNamespace vs object

2021-02-22 Thread Steven D'Aprano
On Mon, Feb 22, 2021 at 06:26:28PM +1100, Chris Angelico wrote:

> Ultimately, SimpleNamespace is useless if it can't be found.

"Can't" be found is an exaggeration.

The std lib is full of little gems, and people learn them and use them. 
Generally when people talk about something that "can't be found" they 
mean *undocumented* features, like simplegeneric in pkgutil, which 
became the inspiration for functools.singledispatch. (And even then, 
some people obviously did find it.)


> If people
> looking for this are not going to look in types, then either people
> need to be educated (good luck with that - you can't fight human
> nature), or it needs to be placed where people will find it.

Of course we can fight human nature. That's what education, school, 
manners, coding standards, documentation, codes of conduct, laws and 
community mores are all about. The fact that hardly anyone chased me 
down the street today with an antelope thighbone to bash my head in is, 
I think, good evidence that we have mostly been successful.

We can't force people to look in `types`, but I don't think that the 
problem is that they refuse to. It's that they don't know about it's 
existence. We don't make everything a builtin because people might not 
know glob; "people don't know about the types module and don't think to 
look in there" is likewise a weak argument for moving SimpleNamespace 
into another module.

It is an argument, but a weak one. Given that SimpleNamespace objects 
aren't a collection, they don't meet the collection API, I think that 
I'm -0.5 on that change.

https://docs.python.org/3/library/collections.abc.html

A Collection is sized, iterable, and supports `in`; SimpleNamespace 
supports none of those.
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/IHTUMKGS6HZNMUGCJJKXBIMCJ3C3GTIZ/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Inadequate error reporting during function call setup stage

2021-02-22 Thread Peter Otten

On 21/02/2021 23:06, Terry Reedy wrote:

On 2/21/2021 12:04 PM, Paul Sokolovsky wrote:


Traceback (most recent call last):
   File "pseudoc_tool.py", line 91, in 
 first_class_function_value(func, **pass_params)
TypeError: print() got an unexpected keyword argument 'noann'


This is not typical behavior in current Python (3.8+).


The way I understand it's not about print(), it's about
disambiguating multiple functions with the same name.
Example:

PS > type .\ambiguous_names.py
import random

def do_stuff():
pass

f = do_stuff

def do_stuff(a, b):
pass

g = do_stuff

random.choice([f, g])(42)


PS > py .\ambiguous_names.py
Traceback (most recent call last):
  File "...\ambiguous_names.py", line 13, in 
random.choice([f, g])(42)
TypeError: do_stuff() missing 1 required positional argument: 'b'

The traceback gives no clue which of the two do_stuff() functions caused
the error, you have to check both implementations.

If that is a comman problem one might consider including module name and
co_firstlineno in the message, or at least adding the relevant
do_stuff() function to the exception's args.
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/E7OUHLWXP3NHEM3UZOBWP5AQRSFL5RDO/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: SimpleNamespace vs object

2021-02-22 Thread Steven D'Aprano
On Mon, Feb 22, 2021 at 10:27:55AM +0300, Paul Sokolovsky wrote:

> Such short generic names shouldn't be used for types added so late in
> the language evolution. Those are names for variables. (And lowercase in
> general, with the exception of handful(!) core types).

A handful you say.

int, float, str, list, tuple, dict, bytes, bytearray, set, frozenset, 
bool, memoryview, object, complex; plus some more in the stdlib such as 
deque,; plus some which are technically types but are usually used as if 
they were functions, such as slice, range, map, filter, zip, etc. So by 
my count that makes at least 15, or 20 if you include the function-like 
types.

You must have big hands.

If this bunch-of-attributes object was to move into the std lib, it 
would likely become a "core type" and we'd want it to have a short, 
simple, all-lowercase name, like the other core types.


> A typical use is:
> 
> ns = SimpleNamespace()
> 
> Anyone who doesn't agree always has "import as" in their disposal (as a
> more structured form of "whatever_i_want = official_descriptive_name").

The type is not going to be called "ns", that's too cryptic for a core 
type. We have "dict", not "dt", "int", not "it", "complex, not "cx". So 
you will still be able to say:

ns = obj = o = bunch()

for example.

You always have `from builtins import bunch as MyLongDescriptiveName` if 
you disagree.


[...]
> So, hopefully window for the lower-case types is as closed as anytime
> (last case was indeed adding "odict" as a builtin alias for
> collection.OrderedDict instead of falling for 3.6 mapping algorithmic
> fiasco),

"Fiasco"?


> and all newly added types will follow the established
> naming conventions.

The established naming conversion for built-in standard types other than 
exceptions is all lowercase.


-- 
Steve
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/K6C7DJFMCJAIABQH4ZBA65WFYCKSPDA3/
Code of Conduct: http://python.org/psf/codeofconduct/