Why does `if None.__eq__(“a”)` seem to evaluate to True (but not quite)?





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







141















If you execute the following statement in Python 3.7, it will (from my testing) print b:



if None.__eq__("a"):
print("b")


However, None.__eq__("a") evaluates to NotImplemented.



Naturally, "a".__eq__("a") evaluates to True, and "b".__eq__("a") evaluates to False.



I initially discovered this when testing the return value of a function, but didn't return anything in the second case -- so, the function returned None.



What's going on here?










share|improve this question































    141















    If you execute the following statement in Python 3.7, it will (from my testing) print b:



    if None.__eq__("a"):
    print("b")


    However, None.__eq__("a") evaluates to NotImplemented.



    Naturally, "a".__eq__("a") evaluates to True, and "b".__eq__("a") evaluates to False.



    I initially discovered this when testing the return value of a function, but didn't return anything in the second case -- so, the function returned None.



    What's going on here?










    share|improve this question



























      141












      141








      141


      23






      If you execute the following statement in Python 3.7, it will (from my testing) print b:



      if None.__eq__("a"):
      print("b")


      However, None.__eq__("a") evaluates to NotImplemented.



      Naturally, "a".__eq__("a") evaluates to True, and "b".__eq__("a") evaluates to False.



      I initially discovered this when testing the return value of a function, but didn't return anything in the second case -- so, the function returned None.



      What's going on here?










      share|improve this question
















      If you execute the following statement in Python 3.7, it will (from my testing) print b:



      if None.__eq__("a"):
      print("b")


      However, None.__eq__("a") evaluates to NotImplemented.



      Naturally, "a".__eq__("a") evaluates to True, and "b".__eq__("a") evaluates to False.



      I initially discovered this when testing the return value of a function, but didn't return anything in the second case -- so, the function returned None.



      What's going on here?







      python python-3.x string equivalence






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Apr 21 at 19:06









      Mark Amery

      65.9k31260307




      65.9k31260307










      asked Dec 31 '18 at 6:03









      The AI ArchitectThe AI Architect

      9192918




      9192918
























          4 Answers
          4






          active

          oldest

          votes


















          172














          This is a great example of why the __dunder__ methods should not be used directly as they are quite often not appropriate replacements for their equivalent operators; you should use the == operator instead for equality comparisons, or in this special case, when checking for None, use is (skip to the bottom of the answer for more information).



          You've done



          None.__eq__('a')
          # NotImplemented


          Which returns NotImplemented since the types being compared are different. Consider another example where two objects with different types are being compared in this fashion, such as 1 and 'a'. Doing (1).__eq__('a') is also not correct, and will return NotImplemented. The right way to compare these two values for equality would be



          1 == 'a'
          # False


          What happens here is




          1. First, (1).__eq__('a') is tried, which returns NotImplemented. This indicates that the operation is not supported, so


          2. 'a'.__eq__(1) is called, which also returns the same NotImplemented. So,

          3. The objects are treated as if they are not the same, and False is returned.


          Here's a nice little MCVE using some custom classes to illustrate how this happens:



          class A:
          def __eq__(self, other):
          print('A.__eq__')
          return NotImplemented

          class B:
          def __eq__(self, other):
          print('B.__eq__')
          return NotImplemented

          class C:
          def __eq__(self, other):
          print('C.__eq__')
          return True

          a = A()
          b = B()
          c = C()

          print(a == b)
          # A.__eq__
          # B.__eq__
          # False

          print(a == c)
          # A.__eq__
          # C.__eq__
          # True

          print(c == a)
          # C.__eq__
          # True




          Of course, that doesn't explain why the operation returns true. This is because NotImplemented is actually a truthy value:



          bool(None.__eq__("a"))
          # True


          Same as,



          bool(NotImplemented)
          # True


          For more information on what values are considered truthy and falsey, see the docs section on Truth Value Testing, as well as this answer. It is worth noting here that NotImplemented is truthy, but it would have been a different story had the class defined a __bool__ or __len__ method that returned False or 0 respectively.





          If you want the functional equivalent of the == operator, use operator.eq:



          import operator
          operator.eq(1, 'a')
          # False


          However, as mentioned earlier, for this specific scenario, where you are checking for None, use is:



          var = 'a'
          var is None
          # False

          var2 = None
          var2 is None
          # True


          The functional equivalent of this is using operator.is_:



          operator.is_(var2, None)
          # True


          None is a special object, and only 1 version exists in memory at any point of time. IOW, it is the sole singleton of the NoneType class (but the same object may have any number of references). The PEP8 guidelines make this explicit:




          Comparisons to singletons like None should always be done with is or
          is not, never the equality operators.




          In summary, for singletons like None, a reference check with is is more appropriate, although both == and is will work just fine.






          share|improve this answer

































            33














            The result you are seeing is caused by that fact that



            None.__eq__("a") # evaluates to NotImplemented


            evaluates to NotImplemented, and NotImplemented's truth value is documented to be True:



            https://docs.python.org/3/library/constants.html




            Special value which should be returned by the binary special methods (e.g. __eq__(), __lt__(), __add__(), __rsub__(), etc.) to indicate that the operation is not implemented with respect to the other type; may be returned by the in-place binary special methods (e.g. __imul__(), __iand__(), etc.) for the same purpose. Its truth value is true.




            If you call the __eq()__ method manually rather than just using ==, you need to be prepared to deal with the possibility it may return NotImplemented and that its truth value is true.






            share|improve this answer

































              16














              As you already figured None.__eq__("a") evaluates to NotImplemented however if you try something like



              if NotImplemented:
              print("Yes")
              else:
              print("No")


              the result is




              yes




              this mean that the truth value of NotImplemented true



              Therefor the outcome of the question is obvious:



              None.__eq__(something) yields NotImplemented



              And bool(NotImplemented) evaluates to True



              So if None.__eq__("a") is always True






              share|improve this answer

































                1














                Why?



                It returns a NotImplemented, yeah:



                >>> None.__eq__('a')
                NotImplemented
                >>>


                But if you look at this:



                >>> bool(NotImplemented)
                True
                >>>


                NotImplemented is actually a truthy value, so that's why it returns b, anything that is True will pass, anything that is False wouldn't.



                How to solve it?



                You have to check if it is True, so be more suspicious, as you see:



                >>> NotImplemented == True
                False
                >>>


                So you would do:



                >>> if None.__eq__('a') == True:
                print('b')


                >>>


                And as you see, it wouldn't return anything.






                share|improve this answer



















                • 1





                  most visually clear answer - v worthwhile addition - thank you

                  – scharfmn
                  Jan 29 at 19:27











                • @scharfmn Lol, happy that i posted a good answer :-)

                  – U9-Forward
                  Jan 30 at 0:14






                • 1





                  :) “worthwhile addition” doesn’t quite capture what I was trying to say (as you obv see) - maybe “belated excellence” is what I wanted - cheers

                  – scharfmn
                  Jan 30 at 0:25






                • 1





                  @scharfmn Yeah, i was bored, so answer, lol :-) ...

                  – U9-Forward
                  Jan 30 at 0:26











                • @scharfmn yes? I'm curious to know what you think this answer adds that hasn't already been covered before.

                  – cs95
                  Feb 1 at 22:43










                protected by kmario23 Mar 6 at 4:44



                Thank you for your interest in this question.
                Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).



                Would you like to answer one of these unanswered questions instead?














                4 Answers
                4






                active

                oldest

                votes








                4 Answers
                4






                active

                oldest

                votes









                active

                oldest

                votes






                active

                oldest

                votes









                172














                This is a great example of why the __dunder__ methods should not be used directly as they are quite often not appropriate replacements for their equivalent operators; you should use the == operator instead for equality comparisons, or in this special case, when checking for None, use is (skip to the bottom of the answer for more information).



                You've done



                None.__eq__('a')
                # NotImplemented


                Which returns NotImplemented since the types being compared are different. Consider another example where two objects with different types are being compared in this fashion, such as 1 and 'a'. Doing (1).__eq__('a') is also not correct, and will return NotImplemented. The right way to compare these two values for equality would be



                1 == 'a'
                # False


                What happens here is




                1. First, (1).__eq__('a') is tried, which returns NotImplemented. This indicates that the operation is not supported, so


                2. 'a'.__eq__(1) is called, which also returns the same NotImplemented. So,

                3. The objects are treated as if they are not the same, and False is returned.


                Here's a nice little MCVE using some custom classes to illustrate how this happens:



                class A:
                def __eq__(self, other):
                print('A.__eq__')
                return NotImplemented

                class B:
                def __eq__(self, other):
                print('B.__eq__')
                return NotImplemented

                class C:
                def __eq__(self, other):
                print('C.__eq__')
                return True

                a = A()
                b = B()
                c = C()

                print(a == b)
                # A.__eq__
                # B.__eq__
                # False

                print(a == c)
                # A.__eq__
                # C.__eq__
                # True

                print(c == a)
                # C.__eq__
                # True




                Of course, that doesn't explain why the operation returns true. This is because NotImplemented is actually a truthy value:



                bool(None.__eq__("a"))
                # True


                Same as,



                bool(NotImplemented)
                # True


                For more information on what values are considered truthy and falsey, see the docs section on Truth Value Testing, as well as this answer. It is worth noting here that NotImplemented is truthy, but it would have been a different story had the class defined a __bool__ or __len__ method that returned False or 0 respectively.





                If you want the functional equivalent of the == operator, use operator.eq:



                import operator
                operator.eq(1, 'a')
                # False


                However, as mentioned earlier, for this specific scenario, where you are checking for None, use is:



                var = 'a'
                var is None
                # False

                var2 = None
                var2 is None
                # True


                The functional equivalent of this is using operator.is_:



                operator.is_(var2, None)
                # True


                None is a special object, and only 1 version exists in memory at any point of time. IOW, it is the sole singleton of the NoneType class (but the same object may have any number of references). The PEP8 guidelines make this explicit:




                Comparisons to singletons like None should always be done with is or
                is not, never the equality operators.




                In summary, for singletons like None, a reference check with is is more appropriate, although both == and is will work just fine.






                share|improve this answer






























                  172














                  This is a great example of why the __dunder__ methods should not be used directly as they are quite often not appropriate replacements for their equivalent operators; you should use the == operator instead for equality comparisons, or in this special case, when checking for None, use is (skip to the bottom of the answer for more information).



                  You've done



                  None.__eq__('a')
                  # NotImplemented


                  Which returns NotImplemented since the types being compared are different. Consider another example where two objects with different types are being compared in this fashion, such as 1 and 'a'. Doing (1).__eq__('a') is also not correct, and will return NotImplemented. The right way to compare these two values for equality would be



                  1 == 'a'
                  # False


                  What happens here is




                  1. First, (1).__eq__('a') is tried, which returns NotImplemented. This indicates that the operation is not supported, so


                  2. 'a'.__eq__(1) is called, which also returns the same NotImplemented. So,

                  3. The objects are treated as if they are not the same, and False is returned.


                  Here's a nice little MCVE using some custom classes to illustrate how this happens:



                  class A:
                  def __eq__(self, other):
                  print('A.__eq__')
                  return NotImplemented

                  class B:
                  def __eq__(self, other):
                  print('B.__eq__')
                  return NotImplemented

                  class C:
                  def __eq__(self, other):
                  print('C.__eq__')
                  return True

                  a = A()
                  b = B()
                  c = C()

                  print(a == b)
                  # A.__eq__
                  # B.__eq__
                  # False

                  print(a == c)
                  # A.__eq__
                  # C.__eq__
                  # True

                  print(c == a)
                  # C.__eq__
                  # True




                  Of course, that doesn't explain why the operation returns true. This is because NotImplemented is actually a truthy value:



                  bool(None.__eq__("a"))
                  # True


                  Same as,



                  bool(NotImplemented)
                  # True


                  For more information on what values are considered truthy and falsey, see the docs section on Truth Value Testing, as well as this answer. It is worth noting here that NotImplemented is truthy, but it would have been a different story had the class defined a __bool__ or __len__ method that returned False or 0 respectively.





                  If you want the functional equivalent of the == operator, use operator.eq:



                  import operator
                  operator.eq(1, 'a')
                  # False


                  However, as mentioned earlier, for this specific scenario, where you are checking for None, use is:



                  var = 'a'
                  var is None
                  # False

                  var2 = None
                  var2 is None
                  # True


                  The functional equivalent of this is using operator.is_:



                  operator.is_(var2, None)
                  # True


                  None is a special object, and only 1 version exists in memory at any point of time. IOW, it is the sole singleton of the NoneType class (but the same object may have any number of references). The PEP8 guidelines make this explicit:




                  Comparisons to singletons like None should always be done with is or
                  is not, never the equality operators.




                  In summary, for singletons like None, a reference check with is is more appropriate, although both == and is will work just fine.






                  share|improve this answer




























                    172












                    172








                    172







                    This is a great example of why the __dunder__ methods should not be used directly as they are quite often not appropriate replacements for their equivalent operators; you should use the == operator instead for equality comparisons, or in this special case, when checking for None, use is (skip to the bottom of the answer for more information).



                    You've done



                    None.__eq__('a')
                    # NotImplemented


                    Which returns NotImplemented since the types being compared are different. Consider another example where two objects with different types are being compared in this fashion, such as 1 and 'a'. Doing (1).__eq__('a') is also not correct, and will return NotImplemented. The right way to compare these two values for equality would be



                    1 == 'a'
                    # False


                    What happens here is




                    1. First, (1).__eq__('a') is tried, which returns NotImplemented. This indicates that the operation is not supported, so


                    2. 'a'.__eq__(1) is called, which also returns the same NotImplemented. So,

                    3. The objects are treated as if they are not the same, and False is returned.


                    Here's a nice little MCVE using some custom classes to illustrate how this happens:



                    class A:
                    def __eq__(self, other):
                    print('A.__eq__')
                    return NotImplemented

                    class B:
                    def __eq__(self, other):
                    print('B.__eq__')
                    return NotImplemented

                    class C:
                    def __eq__(self, other):
                    print('C.__eq__')
                    return True

                    a = A()
                    b = B()
                    c = C()

                    print(a == b)
                    # A.__eq__
                    # B.__eq__
                    # False

                    print(a == c)
                    # A.__eq__
                    # C.__eq__
                    # True

                    print(c == a)
                    # C.__eq__
                    # True




                    Of course, that doesn't explain why the operation returns true. This is because NotImplemented is actually a truthy value:



                    bool(None.__eq__("a"))
                    # True


                    Same as,



                    bool(NotImplemented)
                    # True


                    For more information on what values are considered truthy and falsey, see the docs section on Truth Value Testing, as well as this answer. It is worth noting here that NotImplemented is truthy, but it would have been a different story had the class defined a __bool__ or __len__ method that returned False or 0 respectively.





                    If you want the functional equivalent of the == operator, use operator.eq:



                    import operator
                    operator.eq(1, 'a')
                    # False


                    However, as mentioned earlier, for this specific scenario, where you are checking for None, use is:



                    var = 'a'
                    var is None
                    # False

                    var2 = None
                    var2 is None
                    # True


                    The functional equivalent of this is using operator.is_:



                    operator.is_(var2, None)
                    # True


                    None is a special object, and only 1 version exists in memory at any point of time. IOW, it is the sole singleton of the NoneType class (but the same object may have any number of references). The PEP8 guidelines make this explicit:




                    Comparisons to singletons like None should always be done with is or
                    is not, never the equality operators.




                    In summary, for singletons like None, a reference check with is is more appropriate, although both == and is will work just fine.






                    share|improve this answer















                    This is a great example of why the __dunder__ methods should not be used directly as they are quite often not appropriate replacements for their equivalent operators; you should use the == operator instead for equality comparisons, or in this special case, when checking for None, use is (skip to the bottom of the answer for more information).



                    You've done



                    None.__eq__('a')
                    # NotImplemented


                    Which returns NotImplemented since the types being compared are different. Consider another example where two objects with different types are being compared in this fashion, such as 1 and 'a'. Doing (1).__eq__('a') is also not correct, and will return NotImplemented. The right way to compare these two values for equality would be



                    1 == 'a'
                    # False


                    What happens here is




                    1. First, (1).__eq__('a') is tried, which returns NotImplemented. This indicates that the operation is not supported, so


                    2. 'a'.__eq__(1) is called, which also returns the same NotImplemented. So,

                    3. The objects are treated as if they are not the same, and False is returned.


                    Here's a nice little MCVE using some custom classes to illustrate how this happens:



                    class A:
                    def __eq__(self, other):
                    print('A.__eq__')
                    return NotImplemented

                    class B:
                    def __eq__(self, other):
                    print('B.__eq__')
                    return NotImplemented

                    class C:
                    def __eq__(self, other):
                    print('C.__eq__')
                    return True

                    a = A()
                    b = B()
                    c = C()

                    print(a == b)
                    # A.__eq__
                    # B.__eq__
                    # False

                    print(a == c)
                    # A.__eq__
                    # C.__eq__
                    # True

                    print(c == a)
                    # C.__eq__
                    # True




                    Of course, that doesn't explain why the operation returns true. This is because NotImplemented is actually a truthy value:



                    bool(None.__eq__("a"))
                    # True


                    Same as,



                    bool(NotImplemented)
                    # True


                    For more information on what values are considered truthy and falsey, see the docs section on Truth Value Testing, as well as this answer. It is worth noting here that NotImplemented is truthy, but it would have been a different story had the class defined a __bool__ or __len__ method that returned False or 0 respectively.





                    If you want the functional equivalent of the == operator, use operator.eq:



                    import operator
                    operator.eq(1, 'a')
                    # False


                    However, as mentioned earlier, for this specific scenario, where you are checking for None, use is:



                    var = 'a'
                    var is None
                    # False

                    var2 = None
                    var2 is None
                    # True


                    The functional equivalent of this is using operator.is_:



                    operator.is_(var2, None)
                    # True


                    None is a special object, and only 1 version exists in memory at any point of time. IOW, it is the sole singleton of the NoneType class (but the same object may have any number of references). The PEP8 guidelines make this explicit:




                    Comparisons to singletons like None should always be done with is or
                    is not, never the equality operators.




                    In summary, for singletons like None, a reference check with is is more appropriate, although both == and is will work just fine.







                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited Dec 31 '18 at 15:04

























                    answered Dec 31 '18 at 6:16









                    cs95cs95

                    144k25165254




                    144k25165254

























                        33














                        The result you are seeing is caused by that fact that



                        None.__eq__("a") # evaluates to NotImplemented


                        evaluates to NotImplemented, and NotImplemented's truth value is documented to be True:



                        https://docs.python.org/3/library/constants.html




                        Special value which should be returned by the binary special methods (e.g. __eq__(), __lt__(), __add__(), __rsub__(), etc.) to indicate that the operation is not implemented with respect to the other type; may be returned by the in-place binary special methods (e.g. __imul__(), __iand__(), etc.) for the same purpose. Its truth value is true.




                        If you call the __eq()__ method manually rather than just using ==, you need to be prepared to deal with the possibility it may return NotImplemented and that its truth value is true.






                        share|improve this answer






























                          33














                          The result you are seeing is caused by that fact that



                          None.__eq__("a") # evaluates to NotImplemented


                          evaluates to NotImplemented, and NotImplemented's truth value is documented to be True:



                          https://docs.python.org/3/library/constants.html




                          Special value which should be returned by the binary special methods (e.g. __eq__(), __lt__(), __add__(), __rsub__(), etc.) to indicate that the operation is not implemented with respect to the other type; may be returned by the in-place binary special methods (e.g. __imul__(), __iand__(), etc.) for the same purpose. Its truth value is true.




                          If you call the __eq()__ method manually rather than just using ==, you need to be prepared to deal with the possibility it may return NotImplemented and that its truth value is true.






                          share|improve this answer




























                            33












                            33








                            33







                            The result you are seeing is caused by that fact that



                            None.__eq__("a") # evaluates to NotImplemented


                            evaluates to NotImplemented, and NotImplemented's truth value is documented to be True:



                            https://docs.python.org/3/library/constants.html




                            Special value which should be returned by the binary special methods (e.g. __eq__(), __lt__(), __add__(), __rsub__(), etc.) to indicate that the operation is not implemented with respect to the other type; may be returned by the in-place binary special methods (e.g. __imul__(), __iand__(), etc.) for the same purpose. Its truth value is true.




                            If you call the __eq()__ method manually rather than just using ==, you need to be prepared to deal with the possibility it may return NotImplemented and that its truth value is true.






                            share|improve this answer















                            The result you are seeing is caused by that fact that



                            None.__eq__("a") # evaluates to NotImplemented


                            evaluates to NotImplemented, and NotImplemented's truth value is documented to be True:



                            https://docs.python.org/3/library/constants.html




                            Special value which should be returned by the binary special methods (e.g. __eq__(), __lt__(), __add__(), __rsub__(), etc.) to indicate that the operation is not implemented with respect to the other type; may be returned by the in-place binary special methods (e.g. __imul__(), __iand__(), etc.) for the same purpose. Its truth value is true.




                            If you call the __eq()__ method manually rather than just using ==, you need to be prepared to deal with the possibility it may return NotImplemented and that its truth value is true.







                            share|improve this answer














                            share|improve this answer



                            share|improve this answer








                            edited Apr 22 at 11:56









                            Mark Amery

                            65.9k31260307




                            65.9k31260307










                            answered Dec 31 '18 at 6:19









                            Mark MeyerMark Meyer

                            42.1k33665




                            42.1k33665























                                16














                                As you already figured None.__eq__("a") evaluates to NotImplemented however if you try something like



                                if NotImplemented:
                                print("Yes")
                                else:
                                print("No")


                                the result is




                                yes




                                this mean that the truth value of NotImplemented true



                                Therefor the outcome of the question is obvious:



                                None.__eq__(something) yields NotImplemented



                                And bool(NotImplemented) evaluates to True



                                So if None.__eq__("a") is always True






                                share|improve this answer






























                                  16














                                  As you already figured None.__eq__("a") evaluates to NotImplemented however if you try something like



                                  if NotImplemented:
                                  print("Yes")
                                  else:
                                  print("No")


                                  the result is




                                  yes




                                  this mean that the truth value of NotImplemented true



                                  Therefor the outcome of the question is obvious:



                                  None.__eq__(something) yields NotImplemented



                                  And bool(NotImplemented) evaluates to True



                                  So if None.__eq__("a") is always True






                                  share|improve this answer




























                                    16












                                    16








                                    16







                                    As you already figured None.__eq__("a") evaluates to NotImplemented however if you try something like



                                    if NotImplemented:
                                    print("Yes")
                                    else:
                                    print("No")


                                    the result is




                                    yes




                                    this mean that the truth value of NotImplemented true



                                    Therefor the outcome of the question is obvious:



                                    None.__eq__(something) yields NotImplemented



                                    And bool(NotImplemented) evaluates to True



                                    So if None.__eq__("a") is always True






                                    share|improve this answer















                                    As you already figured None.__eq__("a") evaluates to NotImplemented however if you try something like



                                    if NotImplemented:
                                    print("Yes")
                                    else:
                                    print("No")


                                    the result is




                                    yes




                                    this mean that the truth value of NotImplemented true



                                    Therefor the outcome of the question is obvious:



                                    None.__eq__(something) yields NotImplemented



                                    And bool(NotImplemented) evaluates to True



                                    So if None.__eq__("a") is always True







                                    share|improve this answer














                                    share|improve this answer



                                    share|improve this answer








                                    edited Dec 31 '18 at 14:54

























                                    answered Dec 31 '18 at 6:30









                                    KanjiuKanjiu

                                    42110




                                    42110























                                        1














                                        Why?



                                        It returns a NotImplemented, yeah:



                                        >>> None.__eq__('a')
                                        NotImplemented
                                        >>>


                                        But if you look at this:



                                        >>> bool(NotImplemented)
                                        True
                                        >>>


                                        NotImplemented is actually a truthy value, so that's why it returns b, anything that is True will pass, anything that is False wouldn't.



                                        How to solve it?



                                        You have to check if it is True, so be more suspicious, as you see:



                                        >>> NotImplemented == True
                                        False
                                        >>>


                                        So you would do:



                                        >>> if None.__eq__('a') == True:
                                        print('b')


                                        >>>


                                        And as you see, it wouldn't return anything.






                                        share|improve this answer



















                                        • 1





                                          most visually clear answer - v worthwhile addition - thank you

                                          – scharfmn
                                          Jan 29 at 19:27











                                        • @scharfmn Lol, happy that i posted a good answer :-)

                                          – U9-Forward
                                          Jan 30 at 0:14






                                        • 1





                                          :) “worthwhile addition” doesn’t quite capture what I was trying to say (as you obv see) - maybe “belated excellence” is what I wanted - cheers

                                          – scharfmn
                                          Jan 30 at 0:25






                                        • 1





                                          @scharfmn Yeah, i was bored, so answer, lol :-) ...

                                          – U9-Forward
                                          Jan 30 at 0:26











                                        • @scharfmn yes? I'm curious to know what you think this answer adds that hasn't already been covered before.

                                          – cs95
                                          Feb 1 at 22:43
















                                        1














                                        Why?



                                        It returns a NotImplemented, yeah:



                                        >>> None.__eq__('a')
                                        NotImplemented
                                        >>>


                                        But if you look at this:



                                        >>> bool(NotImplemented)
                                        True
                                        >>>


                                        NotImplemented is actually a truthy value, so that's why it returns b, anything that is True will pass, anything that is False wouldn't.



                                        How to solve it?



                                        You have to check if it is True, so be more suspicious, as you see:



                                        >>> NotImplemented == True
                                        False
                                        >>>


                                        So you would do:



                                        >>> if None.__eq__('a') == True:
                                        print('b')


                                        >>>


                                        And as you see, it wouldn't return anything.






                                        share|improve this answer



















                                        • 1





                                          most visually clear answer - v worthwhile addition - thank you

                                          – scharfmn
                                          Jan 29 at 19:27











                                        • @scharfmn Lol, happy that i posted a good answer :-)

                                          – U9-Forward
                                          Jan 30 at 0:14






                                        • 1





                                          :) “worthwhile addition” doesn’t quite capture what I was trying to say (as you obv see) - maybe “belated excellence” is what I wanted - cheers

                                          – scharfmn
                                          Jan 30 at 0:25






                                        • 1





                                          @scharfmn Yeah, i was bored, so answer, lol :-) ...

                                          – U9-Forward
                                          Jan 30 at 0:26











                                        • @scharfmn yes? I'm curious to know what you think this answer adds that hasn't already been covered before.

                                          – cs95
                                          Feb 1 at 22:43














                                        1












                                        1








                                        1







                                        Why?



                                        It returns a NotImplemented, yeah:



                                        >>> None.__eq__('a')
                                        NotImplemented
                                        >>>


                                        But if you look at this:



                                        >>> bool(NotImplemented)
                                        True
                                        >>>


                                        NotImplemented is actually a truthy value, so that's why it returns b, anything that is True will pass, anything that is False wouldn't.



                                        How to solve it?



                                        You have to check if it is True, so be more suspicious, as you see:



                                        >>> NotImplemented == True
                                        False
                                        >>>


                                        So you would do:



                                        >>> if None.__eq__('a') == True:
                                        print('b')


                                        >>>


                                        And as you see, it wouldn't return anything.






                                        share|improve this answer













                                        Why?



                                        It returns a NotImplemented, yeah:



                                        >>> None.__eq__('a')
                                        NotImplemented
                                        >>>


                                        But if you look at this:



                                        >>> bool(NotImplemented)
                                        True
                                        >>>


                                        NotImplemented is actually a truthy value, so that's why it returns b, anything that is True will pass, anything that is False wouldn't.



                                        How to solve it?



                                        You have to check if it is True, so be more suspicious, as you see:



                                        >>> NotImplemented == True
                                        False
                                        >>>


                                        So you would do:



                                        >>> if None.__eq__('a') == True:
                                        print('b')


                                        >>>


                                        And as you see, it wouldn't return anything.







                                        share|improve this answer












                                        share|improve this answer



                                        share|improve this answer










                                        answered Jan 28 at 6:15









                                        U9-ForwardU9-Forward

                                        18.7k51744




                                        18.7k51744








                                        • 1





                                          most visually clear answer - v worthwhile addition - thank you

                                          – scharfmn
                                          Jan 29 at 19:27











                                        • @scharfmn Lol, happy that i posted a good answer :-)

                                          – U9-Forward
                                          Jan 30 at 0:14






                                        • 1





                                          :) “worthwhile addition” doesn’t quite capture what I was trying to say (as you obv see) - maybe “belated excellence” is what I wanted - cheers

                                          – scharfmn
                                          Jan 30 at 0:25






                                        • 1





                                          @scharfmn Yeah, i was bored, so answer, lol :-) ...

                                          – U9-Forward
                                          Jan 30 at 0:26











                                        • @scharfmn yes? I'm curious to know what you think this answer adds that hasn't already been covered before.

                                          – cs95
                                          Feb 1 at 22:43














                                        • 1





                                          most visually clear answer - v worthwhile addition - thank you

                                          – scharfmn
                                          Jan 29 at 19:27











                                        • @scharfmn Lol, happy that i posted a good answer :-)

                                          – U9-Forward
                                          Jan 30 at 0:14






                                        • 1





                                          :) “worthwhile addition” doesn’t quite capture what I was trying to say (as you obv see) - maybe “belated excellence” is what I wanted - cheers

                                          – scharfmn
                                          Jan 30 at 0:25






                                        • 1





                                          @scharfmn Yeah, i was bored, so answer, lol :-) ...

                                          – U9-Forward
                                          Jan 30 at 0:26











                                        • @scharfmn yes? I'm curious to know what you think this answer adds that hasn't already been covered before.

                                          – cs95
                                          Feb 1 at 22:43








                                        1




                                        1





                                        most visually clear answer - v worthwhile addition - thank you

                                        – scharfmn
                                        Jan 29 at 19:27





                                        most visually clear answer - v worthwhile addition - thank you

                                        – scharfmn
                                        Jan 29 at 19:27













                                        @scharfmn Lol, happy that i posted a good answer :-)

                                        – U9-Forward
                                        Jan 30 at 0:14





                                        @scharfmn Lol, happy that i posted a good answer :-)

                                        – U9-Forward
                                        Jan 30 at 0:14




                                        1




                                        1





                                        :) “worthwhile addition” doesn’t quite capture what I was trying to say (as you obv see) - maybe “belated excellence” is what I wanted - cheers

                                        – scharfmn
                                        Jan 30 at 0:25





                                        :) “worthwhile addition” doesn’t quite capture what I was trying to say (as you obv see) - maybe “belated excellence” is what I wanted - cheers

                                        – scharfmn
                                        Jan 30 at 0:25




                                        1




                                        1





                                        @scharfmn Yeah, i was bored, so answer, lol :-) ...

                                        – U9-Forward
                                        Jan 30 at 0:26





                                        @scharfmn Yeah, i was bored, so answer, lol :-) ...

                                        – U9-Forward
                                        Jan 30 at 0:26













                                        @scharfmn yes? I'm curious to know what you think this answer adds that hasn't already been covered before.

                                        – cs95
                                        Feb 1 at 22:43





                                        @scharfmn yes? I'm curious to know what you think this answer adds that hasn't already been covered before.

                                        – cs95
                                        Feb 1 at 22:43





                                        protected by kmario23 Mar 6 at 4:44



                                        Thank you for your interest in this question.
                                        Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).



                                        Would you like to answer one of these unanswered questions instead?



                                        Popular posts from this blog

                                        Bundesstraße 106

                                        Verónica Boquete

                                        Ida-Boy-Ed-Garten