On 03/27/2020 05:21 PM, Ivan Pozdeev via Python-Dev wrote:
On 26.03.2020 19:24, Ethan Furman wrote:
On 03/25/2020 06:53 PM, Ivan Pozdeev via Python-Dev wrote:

A diagnostic is always done by the same algorithm:

1) Identify the exact place in code where the problem manifests itself
2) Examine the state of the program at that moment to find out which if the 
values are wrong
3) Track the wrong value back to its origin

Seeing an accurate repr() is required for step 2) -- to immediately detect if 
it's wrong or not.

Before Enum, the repr for socket.AF_UNIX was:

1

Not very useful for debugging.

On the contrary, it's perfect. I know everything I need: it's an integer 
constant, end of story.

So if it was a 3 you'd still be happy?  1 vs 3 gives you no information as to 
what the value should be, while blahblah.AF_UNIX vs blahblah.AF_AX25 could 
point out that that is the wrong value for the function you found it in.

When examining some live object, I would probably see that "1" and won't even 
need to look anything up to know what I'm dealing with.

If all you care about is the value, then blahblah.AF_UNIX isn't going to hurt you 
because the repr() displays it:  <socket.AF_UNIX: 1>.  Hopefully that's 
immediately recognizable as an Enum, and a `type()` or `isinstance()` will tell you 
if it's also an `int`.

[...]

I would rather search for "AddressFamily" (case-sensitive), and in the entire codebase, 
not just "*.py".

Yeah, looks like I messed up that example -- I must have switched directories 
in between the two.  The actual results for my simple grep:

$ grep AddressFamily *.py
socket.py:           "has_dualstack_ipv6", "AddressFamily", "SocketKind"]
socket.py:        'AddressFamily',
socket.py:        return _intenum_converter(super().family, AddressFamily)
socket.py:        addrlist.append((_intenum_converter(af, AddressFamily),

So, more useful for finding the source, still not useful for finding other uses.

Long story short, this is a type name and looks like a very distinctive one.

Yup, it's an Enum.

 So that search is very likely going to readily find me anything directly 
related to that type, including its definition, with negligible noise -- 
however and wherever it's done.

Well, there are less than two dozen lines using your search, but the definition 
location is non-obvious -- all you see is

  `AddressFamily`

Still, it's something.

I hope this serves as yet another demonstration why knowing the exact type is 
so crucial.

Not so much in this case -- if it says <socket.AF_UNIX: 1>, then hopefully it's 
not a far stretch to look in the socket module.

  --> help(socket.AF_UNIX)
  Help on AddressFamily in module socket object:

  class AddressFamily(enum.IntEnum)
   |  AddressFamily(value, names=None, *, module=None, qualname=None, 
type=None, start=1)
   |
   |  An enumeration.
   |
   |  ...

Examining repr() of a large number of objects (think dozens to hundreds) vs 
help() of each of them? I think we have a winner...

Well, the repr in question, whether `socket.*` or `AddressFamily.*`, is still 
distinctive and still contains the value, the thing you are saying you want.

And help() doesn't even show the value!

I had snipped the output for brevity.  Here's the whole thing:

Help on AddressFamily in module socket object:

class AddressFamily(enum.IntEnum)
 |  AddressFamily(value, names=None, *, module=None, qualname=None, type=None, 
start=1)
 |
 |  An enumeration.
 |
 |  Method resolution order:
 |      AddressFamily
 |      enum.IntEnum
 |      builtins.int
 |      enum.Enum
 |      builtins.object
 |
 |  Data and other attributes defined here:
 |
 |  AF_ALG = <socket.AF_ALG: 38>
 |
 |  AF_APPLETALK = <socket.AF_APPLETALK: 5>
 |
 |  AF_ASH = <socket.AF_ASH: 18>
 |
 |  AF_ATMPVC = <socket.AF_ATMPVC: 8>
 |
 |  AF_ATMSVC = <socket.AF_ATMSVC: 20>
 |
 |  AF_AX25 = <socket.AF_AX25: 3>
 |
 |  AF_BLUETOOTH = <socket.AF_BLUETOOTH: 31>
 |
 |  AF_BRIDGE = <socket.AF_BRIDGE: 7>
 |
 |  AF_CAN = <socket.AF_CAN: 29>
 |
 |  AF_ECONET = <socket.AF_ECONET: 19>
 |
 |  AF_INET = <socket.AF_INET: 2>
 |
 |  AF_INET6 = <socket.AF_INET6: 10>
 |
 |  AF_IPX = <socket.AF_IPX: 4>
 |
 |  AF_IRDA = <socket.AF_IRDA: 23>
 |
 |  AF_KEY = <socket.AF_KEY: 15>
 |
 |  AF_LLC = <socket.AF_LLC: 26>
 |
 |  AF_NETBEUI = <socket.AF_NETBEUI: 13>
 |
 |  AF_NETLINK = <socket.AF_NETLINK: 16>
 |
 |  AF_NETROM = <socket.AF_NETROM: 6>
 |
 |  AF_PACKET = <socket.AF_PACKET: 17>
 |
 |  AF_PPPOX = <socket.AF_PPPOX: 24>
 |
 |  AF_QIPCRTR = <socket.AF_QIPCRTR: 42>
 |
 |  AF_RDS = <socket.AF_RDS: 21>
 |
 |  AF_ROSE = <socket.AF_ROSE: 11>
 |
 |  AF_SECURITY = <socket.AF_SECURITY: 14>
 |
 |  AF_SNA = <socket.AF_SNA: 22>
 |
 |  AF_TIPC = <socket.AF_TIPC: 30>
 |
 |  AF_UNIX = <socket.AF_UNIX: 1>
 |
 |  AF_UNSPEC = <socket.AF_UNSPEC: 0>
 |
 |  AF_VSOCK = <socket.AF_VSOCK: 40>
 |
 |  AF_WANPIPE = <socket.AF_WANPIPE: 25>
 |
 |  AF_X25 = <socket.AF_X25: 9>
 |
 |  ----------------------------------------------------------------------
 |  Data descriptors inherited from enum.Enum:
 |
 |  name
 |      The name of the Enum member.
 |
 |  value
 |      The value of the Enum member.
 |
 |  ----------------------------------------------------------------------
 |  Readonly properties inherited from enum.EnumMeta:
 |
 |  __members__
 |      Returns a mapping of member name->value.
 |
 |      This mapping lists all enum members, including aliases. Note that this
 |      is a read-only view of the internal mapping.

You'll note that all the members, and their values, are listed.  (They say 
`socket`  instead of `AddressFamily` as I was testing the change.)

You can't be serious suggesting me to do all this extra work (i.e. 
single-handedly increase diagnostic's labor intensity about 5x -- while problem 
diagnostic is a key activity during both development and ongoing use) just 
because someone wishes to playfully ignore an established standard specifically 
invented to make it unnecessary.

module.function
module.class
module.attribute

are all common access patterns.  It should not be a far stretch to see 
<socket.AF_UNIX: 1> and think to look in the socket module.

Pardon me if I misunderstood you, but I also find the offhand remarks: "adding this 
and that to your debugging list would also be, um, helpful" -- highly condescending 
and insulting and showing that you probably don't do much problem diagnostic and don't 
care at all about anyone who does -- i.e. about software developers and maintainers, your 
core audience.

I was trying to be humorous -- my apologies.  In fact, a large portion of my 
time is spent debugging.  I also recognize Enums when I see them, so they 
aren't big mysteries to me -- admittedly, I am probably more familiar with 
Enums and their repr()s than most, but hopefully once you know what they look 
like they're easy to spot.

All the while yourself being a Python core developer (if your StackOverflow 
profile is to be believed) -- a spokesperson for the dev team and a shining 
example of what every Python developer should strive to be.

Well, yes to my Stackoverflow profile being correct, no, I was not made a spokesperson 
(my opinions are not necessarily shared by any other core developer, nor by the PSF), and 
do you expect every developer of every open source project to be "shining 
examples"?  Hopefully you were just frustrated, and not serious.

If this is any representation of the prevalent attitude in the core team now, 
I'm probably wasting my time arguing here as well as supporting Python in 
general since our values clearly don't match anymore.

Well, my attitude is "ask on python-dev to get wide exposure and feedback to 
proposed changes since bugs on bpo are not widely seen."

As a reminder, the change under discussion only affects enums created from 
globally unique constants using the Enum._convert helper utility.

I know. But it sets a precedent of screwing users over with poorly thought 
cosmetic changes done without thinking of them.

That's offensive.  I started this thread precisely because I'm thinking of them.

--
~Ethan~
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/5PDUZRFXVBHCGVA3I4NMQAHRNODAQJBD/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to