> Are there other such classes? from the top of my head, Pandas:
In [13]: pd.DataFrame([[1,2], [3, 4]]) == None Out[13]: 0 1 0 False False 1 False False and any zarr container, or xarray will behave like numpy and broadcast. Ah, that means probably Dask, and Ray. Also maybe CuPy ? But I'm not going to list all that behave like numpy or pandas, but that's a big chunk of things that return non boolean values. Let's grep into my dev folder for other weird __eq__ $ rg 'def __eq__' -A3 ... stuff, let's pick a few: sympy.physics.optics.Medium: def __eq__(self, other): return self.refractive_index == other.refractive_index Will crash with None has no attribute refractive_index, IPython's internal Completions objects around Jedi also assume they are compared against instances of the same class and will crash, but likely with 'NoneType' object is not subscriptable. matplotlib FontProperties have a small but non-zero change of telling you that the current (object == None) is True as it compares hashes, so if the hash of the FontProp is the same as None... well. Basically anything that implements __eq__ and assumes it will be compared only against things that are of the same type will not be happy to be compared with None using ==. or implement broadcasting like abilities. -- Matthias On Tue, 31 Aug 2021 at 16:22, Nick Parlante <n...@cs.stanford.edu> wrote: > > To argue that == is unreliable, I think Matthias has the best, non-contrived > example with numpy, which I did not know about: > > >>> x = np.array([1, 2, 3]) > >>> x == None > array([False, False, False]) > > This certainly is a good example of == not being reliable. Point taken there. > > Are there other such classes? Like if I write code that just uses Python and > its standard library classes, can I get a value where == None is flaky like > the numpy example? I wouldn't think so, just as a matter of > principle-of-least-surprise API design. Anyway, that would be very > interesting example to argue against my claim that == None is reliable. > > Best, > > Nick > > On Mon, Aug 30, 2021 at 12:06 PM Matthias Bussonnier > <bussonniermatth...@gmail.com> wrote: >> >> From my point of view as someone who sometimes help Scientist write >> Python, this is a no go, there are too many cases where == and is are >> different. >> >> $ ipython >> Python 3.8.5 | packaged by conda-forge | (default, Sep 16 2020, 17:43:11) >> Type 'copyright', 'credits' or 'license' for more information >> IPython 7.25.0 -- An enhanced Interactive Python. Type '?' for help. >> >> In [1]: import numpy as np >> >> In [2]: a = np.array([True, False, None]) >> >> In [3]: a == True, a == False, a == None >> Out[3]: >> (array([ True, False, False]), >> array([False, True, False]), >> array([False, False, True])) >> >> In [4]: a is True, a is False, a is None >> Out[4]: (False, False, False) >> >> if `a == True` can even raise errors when in ifs: >> >> In [5]: if a == True: >> ...: pass >> ...: >> --------------------------------------------------------------------------- >> ValueError Traceback (most recent call last) >> <ipython-input-5-59a850ef5f8d> in <module> >> ----> 1 if a == True: >> 2 pass >> 3 >> >> ValueError: The truth value of an array with more than one element is >> ambiguous. Use a.any() or a.all() >> >> Basic types are just too simple to expose the real need between `==` >> and `is`, but that's not a reason not to give the right advice from >> the start. >> IMHO It would be like teaching English and saying that it's ok not to >> put s after nouns when there is a number in front as it's obvious >> there are many. >> >> I do understand your concern, but I believe that would be just pushing >> the problem to later, when it would be much more difficult to explain >> and have students get a wrong mental model from the start, which is >> really hard to overcome. >> >> -- >> Matthias >> >> On Mon, 30 Aug 2021 at 11:45, Nick Parlante <n...@cs.stanford.edu> wrote: >> > >> > Hi there python-ideas - I've been teaching Python as a first >> > programming language for a few years, and from that experience I want >> > to propose a change to PEP8. I'm sure the default position for PEP8 is >> > to avoid changing it. However, for this one rule I think a good case >> > can be made to make it optional, so let me know what you think. >> > >> > Let me start with what I've learned from teaching students in Java and >> > now in Python. In Java, you use == for ints, but you need to use >> > equals() for strings. Of course students screw this up constantly, >> > using == in a context that calls for equals() and their code does not >> > work right. Then for Java arrays a different comparison function is >> > required, and so it goes. To teach comparisons in Python, I simply say >> > "just use ==" - it works for ints, for strings, even for lists. >> > Students are blown away by how nice and simple this is. This is how >> > things should work. Python really gets this right. >> > >> > So what is the problem? >> > >> > The problem for Python is what I will call the "mandatory-is" rule in >> > PEP8, which reads: >> > >> > Comparisons to singletons like None should always be done with is or >> > is not, never the equality operators. >> > >> > For the students, this comes up in the first week of the course with >> > lines like "if x == None:" which work perfectly with == but should use >> > is/is-not for PEP8 conformance. >> > >> > My guess is that this rule is in PEP8 because, within a Python >> > implementation, it is within the programmer's mental model that, say, >> > False is a singleton. The mandatory-is rule is in PEP8 to reinforce >> > that mental model by requiring the is operator. Plus it probably runs >> > a tiny bit faster. >> > >> > However, for "regular" Python code, not implementing Python, forcing >> > the use of is instead of the simpler == is unneeded and unhelpful (and >> > analogously forcing "is not" when != works correctly). What is the >> > benefit of forcing the is operator there? I would say it spreads an >> > awareness of the details of how certain values are allocated within >> > Python. That's not much of a benefit, and it's kind of circular. Like >> > if programmers were permitted to use ==, they wouldn't need to know >> > the details of how Python allocates those values. Being shielded from >> > implementation details is a Python strength - think of the Java vs. >> > Python story above. Is Java better because it builds an awareness in >> > the programmer of the different comparison functions for different >> > types? Of course not! Python is better in that case because it lets >> > the programmer simply use == and not think about those details. >> > Understanding the singleton strategy is important in some corners of >> > coding, but forcing the is operator on all Python code is way out of >> > proportion to the benefit. >> > >> > As a practical matter, the way this comes up for my students is that >> > IDEs by default will put warning marks around PEP8 violations in their >> > code. Mostly this IDE-coaching is very helpful for students learning >> > Python. For example, It's great that beginning Python programmers >> > learn to put one space around operators right from the first day. >> > Having taught thousands of introductory Python students, the one PEP8 >> > rule that causes problems is this mandatory-is rule. >> > >> > As a teacher, this is especially jarring since the "just use ==" rule >> > is so effortless to use correctly. In contrast, the mandatory-is rule >> > adds a little pause where the programmer should think about which >> > comparison operator is the correct one to use. It's not hard, but it >> > feels unnecessary. >> > >> > As a contrasting example, in the language C, programmers need to >> > understand == vs. is right from the first day. You can't get anything >> > done in C without understanding that distinction. However that is just >> > not true for regular (not-Python-implementation) Python code, where == >> > works correctly for the great majority of cases. >> > >> > Here is my proposal: >> > >> > Add the following parenthetical to the mandatory-is rule: (this rule >> > is optional for code that is not part of an implementation of Python). >> > >> > So in effect, programmers outside of a Python implementation can >> > choose to use == or is for the "if x == None:" case. In this way, PEP8 >> > conforming code before the change is still conforming. Moving forward, >> > I would expect that regular code will trend towards using == in such a >> > case, reserving is for the rare cases where it is needed for >> > correctness. >> > >> > PEP8 was originally just for Python implementations, so why is this >> > change needed? Because as a practical matter, the vast majority of >> > code that is using PEP8 is not part of a Python implementation. This >> > may not have been the original mission of PEP8, but it is how things >> > have worked out. >> > >> > Now we are in a situation where the rules in PEP8 are sent out to this >> > ocean of Python programmers of many different ability levels writing >> > regular code that is not a Python implementation. One could imagine a >> > separate PEP800 style guide for regular code, but we don't need to do >> > that, because in almost all cases PEP8 works great for regular code. I >> > have taught thousands of new Python programmers, and the only place >> > where PEP8 serves them poorly is this mandatory-is rule. Therefore >> > instead of a separate style guide for regular code, I propose an >> > exception for this one problem rule. >> > >> > Ultimately this comes down to the question - should PEP8 push regular, >> > not-Python-implementation code to use is for singletons in cases where >> > == works perfectly? Seeing how effortless it is for programmers to use >> > == as their first choice, I think PEP8 should allow that practice. >> > >> > Best, >> > >> > Nick >> > _______________________________________________ >> > 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/JWLKBT2YYDGFS76Z37FZJNZPEDVXOLCW/ >> > 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/XTQX5F652WBU2LKMNFWQ3LVRQDKHX4B4/ Code of Conduct: http://python.org/psf/codeofconduct/