This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: precedence (relational, logical operator)not working with single value
Type: behavior Stage: resolved
Components: Interpreter Core Versions: Python 3.6
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: sangeetamchauhan, steven.daprano, tim.peters
Priority: normal Keywords:

Created on 2019-09-09 03:35 by sangeetamchauhan, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
pythonBug.py sangeetamchauhan, 2019-09-09 03:35 Contains errorneous statements
image.png sangeetamchauhan, 2019-09-09 06:06
Messages (12)
msg351344 - (view) Author: Sangeeta M Chauhan (sangeetamchauhan) Date: 2019-09-09 03:35
precendence betweeen relational and logical operators not working properly if expression contains single values instead of sub expressions. . Please see attached file
msg351345 - (view) Author: Tim Peters (tim.peters) * (Python committer) Date: 2019-09-09 03:55
It's working fine.  What do you expect?  For example,

    9 or 7 > "str"

groups as

    9 or (7 > "str")

9 is evaluated for "truthiness" first, and since it's not 0 it's considered to be true.  That's enough to determine the result of "or", so (7 > "str") isn't evaluated at all.  9 is the result.

This is all working as designed and as documented, so I'm closing this report.
msg351346 - (view) Author: Sangeeta M Chauhan (sangeetamchauhan) Date: 2019-09-09 04:28
i am not satisfied ..with your answer . as in the following expression   9
or 7 > "str" precedence must be given to relational operator . why is is
executing logical operator first??????????????
if we write  4>9 or 7> "str" it works correct but if we replace first
condition(4>9) with a numeric value it is not giving correct output

On Mon, Sep 9, 2019 at 9:25 AM Tim Peters <report@bugs.python.org> wrote:

>
> Tim Peters <tim@python.org> added the comment:
>
> It's working fine.  What do you expect?  For example,
>
>     9 or 7 > "str"
>
> groups as
>
>     9 or (7 > "str")
>
> 9 is evaluated for "truthiness" first, and since it's not 0 it's
> considered to be true.  That's enough to determine the result of "or", so
> (7 > "str") isn't evaluated at all.  9 is the result.
>
> This is all working as designed and as documented, so I'm closing this
> report.
>
> ----------
> nosy: +tim.peters
> resolution:  -> not a bug
> stage:  -> resolved
> status: open -> closed
>
> _______________________________________
> Python tracker <report@bugs.python.org>
> <https://bugs.python.org/issue38060>
> _______________________________________
>
msg351347 - (view) Author: Tim Peters (tim.peters) * (Python committer) Date: 2019-09-09 04:47
I'm sorry you're not satisfied with the answer, but I'm a bona fide expert on this and you're not going to get anyone to agree with your confusion here ;-)

But the bug tracker is not the right place for tutorials.  Please take this up on, e.g., the Python mailing list instead.  There is no bug here.

One hint:  in

    EXPR1 or EXPR2

bool(EXPR1) is _always_ evaluated first.  It makes no difference at all to this whether EXPR1 is "x < y" or "1 + 2 + 3" or "9".  Trying to make a special case out of "a numerical value" is entirely in your own head:  the language does nothing of the sort.

   9 or (ANYTHING_AT_ALL)

always results in 9, for the same reason

   4+5 or (ANYTHING_AT_ALL)

always results in 9.  Whether the left-hand expression evaluating to 9 is a literal or a complex expression is irrelevant.

In the same way, e.g.,

   x = 9
and
   x = 4+6

both bind x to 9.  A numeric literal is just as much "an expression" as any other kind of expression.  "Single value" has nothing to do with this.
msg351350 - (view) Author: Sangeeta M Chauhan (sangeetamchauhan) Date: 2019-09-09 06:06
Sorry to disturb you again. The examples you have explained... I already
knew it and i am satisfied with that... but i think i am not able to
explain you about the problem.. Please see the attached file again for
reference.....pleeeeeaassseeeee.
Please last time answer me....
 first i have mailed this problem but i got answer that i should send it to
python tracker

[image: image.png]

On Mon, Sep 9, 2019 at 10:17 AM Tim Peters <report@bugs.python.org> wrote:

>
> Tim Peters <tim@python.org> added the comment:
>
> I'm sorry you're not satisfied with the answer, but I'm a bona fide expert
> on this and you're not going to get anyone to agree with your confusion
> here ;-)
>
> But the bug tracker is not the right place for tutorials.  Please take
> this up on, e.g., the Python mailing list instead.  There is no bug here.
>
> One hint:  in
>
>     EXPR1 or EXPR2
>
> bool(EXPR1) is _always_ evaluated first.  It makes no difference at all to
> this whether EXPR1 is "x < y" or "1 + 2 + 3" or "9".  Trying to make a
> special case out of "a numerical value" is entirely in your own head:  the
> language does nothing of the sort.
>
>    9 or (ANYTHING_AT_ALL)
>
> always results in 9, for the same reason
>
>    4+5 or (ANYTHING_AT_ALL)
>
> always results in 9.  Whether the left-hand expression evaluating to 9 is
> a literal or a complex expression is irrelevant.
>
> In the same way, e.g.,
>
>    x = 9
> and
>    x = 4+6
>
> both bind x to 9.  A numeric literal is just as much "an expression" as
> any other kind of expression.  "Single value" has nothing to do with this.
>
> ----------
>
> _______________________________________
> Python tracker <report@bugs.python.org>
> <https://bugs.python.org/issue38060>
> _______________________________________
>
msg351390 - (view) Author: Steven D'Aprano (steven.daprano) * (Python committer) Date: 2019-09-09 09:53
Tim is correct, the behaviour is right, however the docs could be clearer.

I think what you are missing is that ``or`` and ``and`` are short-circuiting operators. So in the expression

    9 or (anything)

the "anything" expression never gets evaluated because 9 is a truthy value. You might get a better example of what is happening if you disassemble the byte-code:


py> from dis import dis
py> dis(compile("9 or 7 < 'str'", '', 'eval'))
  1           0 LOAD_CONST               0 (9)
              3 JUMP_IF_TRUE_OR_POP     15
              6 LOAD_CONST               1 (7)
              9 LOAD_CONST               2 ('str')
             12 COMPARE_OP               0 (<)
        >>   15 RETURN_VALUE


Another way to see the order of evaluation is if we make the left hand operand falsey:


py> print("first") or print("second") < 'str'
first
second
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unorderable types: NoneType() < str()

In this case, the order of operations is:

- evaluate ``print("first")`` (returns None)
- since None is falsey, evaluate ``print("second") < 'str'``
- which prints the word "second", then raises an exception.


We can get rid of the exception:

py> print("first") or str(print("second")) < 'str'
first
second
True


I can see how the docs are a little bit confusing if you don't remember that ``or`` and ``and`` are short-circuiting operators. If you would like to propose an improvement to the docs, please suggest something. But the behaviour is correct and is not a bug.

https://docs.python.org/3/reference/expressions.html#operator-precedence
msg351494 - (view) Author: Tim Peters (tim.peters) * (Python committer) Date: 2019-09-09 15:08
@sangeetamchauhan, the reply you got in the image you attached was in error - kind of.  Section "6.16. Operator precedence" defines Python's operator precedence:

https://docs.python.org/3/reference/expressions.html#index-92

"""
The following table summarizes the operator precedence in Python, from lowest precedence (least binding) to highest precedence (most binding).
"""

As you can see there, "and" and "or" are very near the top of the table, so bind very weakly - almost anything else on either side gets evaluated first.  In particular, all comparison operators bind more tightly than "and" and "or".

It's the bitwise operators (| & ^) that bind more tightly than comparisons.

I asked at the start "What do you expect?" but you never answered.  You just keep repeating that it's wrong.  Sorry, but I still have no idea what you think "should" happen instead.

As I also said the start,

    9 or 7 > "str"

groups as

    9 or (7 > "str")

exactly as the operator precedence table says it should, and returns 9, exactly as the docs for "or" say it should do.

What about that do you think is wrong?  Please be very specific, and back your answer with a reference to what the docs actually say.
msg351527 - (view) Author: Tim Peters (tim.peters) * (Python committer) Date: 2019-09-09 16:43
BTW, the docs also spell out that "and" and "or" ALWAYS evaluate their left operand before their right operand, and don't evaluate the right operand at all if the result of evaluating the left operand is true (for "or") or false (for "and").  So, e.g., 

    result = (EXPR1) or (EXPR2)

acts like

    result = EXPR1
    if not bool(result):
        result = EXPR2
msg351720 - (view) Author: Sangeeta M Chauhan (sangeetamchauhan) Date: 2019-09-10 16:07
Sir, I was expecting that the precedence should be given to relational
operator (  7>"str")   and according to that instead of printing 9 it
should give error.

On Mon, Sep 9, 2019 at 8:38 PM Tim Peters <report@bugs.python.org> wrote:

>
> Tim Peters <tim@python.org> added the comment:
>
> @sangeetamchauhan, the reply you got in the image you attached was in
> error - kind of.  Section "6.16. Operator precedence" defines Python's
> operator precedence:
>
> https://docs.python.org/3/reference/expressions.html#index-92
>
> """
> The following table summarizes the operator precedence in Python, from
> lowest precedence (least binding) to highest precedence (most binding).
> """
>
> As you can see there, "and" and "or" are very near the top of the table,
> so bind very weakly - almost anything else on either side gets evaluated
> first.  In particular, all comparison operators bind more tightly than
> "and" and "or".
>
> It's the bitwise operators (| & ^) that bind more tightly than comparisons.
>
> I asked at the start "What do you expect?" but you never answered.  You
> just keep repeating that it's wrong.  Sorry, but I still have no idea what
> you think "should" happen instead.
>
> As I also said the start,
>
>     9 or 7 > "str"
>
> groups as
>
>     9 or (7 > "str")
>
> exactly as the operator precedence table says it should, and returns 9,
> exactly as the docs for "or" say it should do.
>
> What about that do you think is wrong?  Please be very specific, and back
> your answer with a reference to what the docs actually say.
>
> ----------
>
> _______________________________________
> Python tracker <report@bugs.python.org>
> <https://bugs.python.org/issue38060>
> _______________________________________
>
msg351727 - (view) Author: Tim Peters (tim.peters) * (Python committer) Date: 2019-09-10 16:49
Ah, so you were expecting an error!  That helps.

But that's not how the language works, or how it's documented to work, as has been explained in quite some detail already.

In general, precedence _constrains_ evaluation order, but does not _define_ it.  In Python or any other language.  In

     9 or 7 > "str"

the precedence rules say the expression groups as

     9 or (7 > "str")

rather than as, say,

     (9 or 7) > "str"

but says nothing more than just that.  It's a very intentional - and documented - feature of "and" and "or" that they do NOT evaluate their right-hand operands at all if the result of evaluating the left-hand operand first is enough to settle the issue.  The precedence rules only define what the "left-hand" and "right-hand" operand expressions _are_.

I don't think the docs could be materially clearer about this.  For example, from section "6.11. Boolean operations":

"""
The expression `x or y` first evaluates x; if x is true, its value is returned; otherwise, y is evaluated and the resulting value is returned.
"""

Precedence rules alone are too feeble to capture that.
msg351758 - (view) Author: Steven D'Aprano (steven.daprano) * (Python committer) Date: 2019-09-10 23:54
I think that the problem is that the precedence table may be technically 
correct, but it doesn't describe the actual behaviour of expressions 
including the boolean operators ``or`` and ``and`` for exactly the 
reason Tim gives:

> Precedence rules alone are too feeble to capture that.

If I didn't know that boolean operators short-circuited, I too would 
have expected that an expression like ``9 or 7 < "str"`` would have 
raised an exception.

The documentation (precedence table) isn't wrong, it's just incomplete. 
The information needed exists, but it is elsewhere, and if you don't 
already know it, you don't know that you need to look for it.

I think that the precedence table could do with a footnote on the two 
boolean operators describing their interaction with short-circuiting 
behaviour and linking back to the relevant section 6.11.

https://docs.python.org/3/reference/expressions.html#boolean-operations
msg351759 - (view) Author: Tim Peters (tim.peters) * (Python committer) Date: 2019-09-11 03:17
I don't believe that would improve the docs, but suit yourself.  This is hardly a FAQ, but instead a peculiar case where, for whatever reason, someone is saying "I'm puzzled by what `or` does, but didn't read the docs for `or`".  Most people confused by `or` almost certainly _do_ read the docs for `or` ;-)

As is, in the precedence table the word "or" is already a direct hyperlink to the section _about_ "or", and similarly for "and".  It can't be made any easier than that to find the whole story.

If you do want to pursue adding more cruft to the docs, note that the same would be needed for the `- if - else -` operator too.
History
Date User Action Args
2022-04-11 14:59:19adminsetgithub: 82241
2019-09-11 03:17:52tim.peterssetmessages: + msg351759
2019-09-10 23:54:36steven.dapranosetmessages: + msg351758
2019-09-10 16:49:39tim.peterssetmessages: + msg351727
2019-09-10 16:07:51sangeetamchauhansetmessages: + msg351720
2019-09-09 16:43:11tim.peterssetmessages: + msg351527
2019-09-09 15:08:25tim.peterssetmessages: + msg351494
2019-09-09 09:53:49steven.dapranosetnosy: + steven.daprano
messages: + msg351390
2019-09-09 06:06:59sangeetamchauhansetfiles: + image.png

messages: + msg351350
2019-09-09 04:47:48tim.peterssetmessages: + msg351347
2019-09-09 04:28:53sangeetamchauhansetmessages: + msg351346
title: precedence (relational,logical operator)not working with single value -> precedence (relational, logical operator)not working with single value
2019-09-09 03:55:13tim.peterssetstatus: open -> closed

nosy: + tim.peters
messages: + msg351345

resolution: not a bug
stage: resolved
2019-09-09 03:35:45sangeetamchauhancreate