f



0 + not 0

>>> 0 + not 0
  File "<stdin>", line 1
    0 + not 0
          ^
SyntaxError: invalid syntax
>>>


What is syntactically wrong with 0 + not 0?
0
candide
7/11/2015 10:26:32 AM
comp.lang.python 77058 articles. 6 followers. Post Follow

17 Replies
1100 Views

Similar Articles

[PageSpeed] 27

On Sat, Jul 11, 2015 at 8:26 PM, candide <c.candide@laposte.net> wrote:
>>>> 0 + not 0
>   File "<stdin>", line 1
>     0 + not 0
>           ^
> SyntaxError: invalid syntax
>>>>
>
>
> What is syntactically wrong with 0 + not 0?

I'm actually not sure why this can't be handled. Possibly it's a
limitation of the parser. Certainly 0 + (not 0) works just fine. This
suggests that the exponentiation operator may have been special-cased
to cope with this:

https://docs.python.org/3/reference/expressions.html#id21

So maybe there's just no corresponding special case for this - which,
I have to say, is not exactly a common construct.

ChrisA
0
Chris
7/11/2015 10:38:52 AM
On 11-7-2015 12:26, candide wrote:
>>>> 0 + not 0
>   File "<stdin>", line 1
>     0 + not 0
>           ^
> SyntaxError: invalid syntax
>>>>
> 
> 
> What is syntactically wrong with 0 + not 0?
> 

I would say that the boolean operator 'not' cannot occur in an arithmetic expression.
Maybe you meant to use the bitwise not:

>>> 0 + ~0
-1


Irmen
0
Irmen
7/11/2015 10:38:57 AM
On 11-7-2015 12:38, Irmen de Jong wrote:
> On 11-7-2015 12:26, candide wrote:
>>>>> 0 + not 0
>>    File "<stdin>", line 1
>>      0 + not 0
>>            ^
>> SyntaxError: invalid syntax
>>>>>
>>
>>
>> What is syntactically wrong with 0 + not 0?
>>
>
> I would say that the boolean operator 'not' cannot occur in an arithmetic expression.
> Maybe you meant to use the bitwise not:
>
>>>> 0 + ~0
> -1
>
>
> Irmen
>

It can occur in an arithmetic expression, and 'not' has a higher 
precedence than '+'
(https://docs.python.org/2/reference/expressions.html#operator-precedence)

0 + not 0
should evalutate to
0 + True
1

just like this does:
0 + (not 0)
1


True + True
2

But, it gets confusing......
 >>> not 0 + 1
False
 >>> not 0
True
 >>> True + 1
2
 >>>

i would expect 'not 0 + 1' to return the same value as 'True + 1'


0
Luuk
7/11/2015 11:12:54 AM
On Sat, Jul 11, 2015 at 9:12 PM, Luuk <luuk@invalid.lan> wrote:
> It can occur in an arithmetic expression, and 'not' has a higher precedence
> than '+'
> (https://docs.python.org/2/reference/expressions.html#operator-precedence)
>

I think you're misreading the table; 'not' has *lower* precedence than '+'.

> But, it gets confusing......
>>>> not 0 + 1
> False
>>>> not 0
> True
>>>> True + 1
> 2
>>>>
>
> i would expect 'not 0 + 1' to return the same value as 'True + 1'

(not 0 + 1) == (not (0 + 1))

ChrisA
0
Chris
7/11/2015 11:20:13 AM
On 11-7-2015 13:20, Chris Angelico wrote:
> On Sat, Jul 11, 2015 at 9:12 PM, Luuk <luuk@invalid.lan> wrote:
>> It can occur in an arithmetic expression, and 'not' has a higher precedence
>> than '+'
>> (https://docs.python.org/2/reference/expressions.html#operator-precedence)
>>
>
> I think you're misreading the table; 'not' has *lower* precedence than '+'.
>
>> But, it gets confusing......
>>>>> not 0 + 1
>> False
>>>>> not 0
>> True
>>>>> True + 1
>> 2
>>>>>
>>
>> i would expect 'not 0 + 1' to return the same value as 'True + 1'
>
> (not 0 + 1) == (not (0 + 1))
>
> ChrisA
>

But operator precedence of 'not' is higher than of '+' ????
0
Luuk
7/11/2015 11:30:29 AM
Le samedi 11 juillet 2015 13:21:03 UTC+2, Chris Angelico a =E9crit=A0:
> I think you're misreading the table; 'not' has *lower* precedence than '+=
'.
>=20


Right but Python docs helps a lot in misreading ;) Following the iconicity =
principle, it's pretty obvious that one has to display table priority begin=
ning with items having the highest priority, cf. for instance table operato=
r precedence for Java provided by oracle tutorial or for the C language as =
given by the K&R book.
0
candide
7/11/2015 11:48:26 AM
Le samedi 11 juillet 2015 13:31:03 UTC+2, Luuk a =E9crit=A0:

>=20
> But operator precedence of 'not' is higher than of '+' ????


Right but what does this prove? For instance, unary minus has higher preced=
ence than exponentiation but the expression

2 ** -1

doesn't raise a syntax error.
0
candide
7/11/2015 11:54:30 AM
On Sat, Jul 11, 2015 at 9:54 PM, candide <c.candide@laposte.net> wrote:
> Le samedi 11 juillet 2015 13:31:03 UTC+2, Luuk a =C3=A9crit :
>
>>
>> But operator precedence of 'not' is higher than of '+' ????
>
>
> Right but what does this prove? For instance, unary minus has higher prec=
edence than exponentiation but the expression
>
> 2 ** -1
>
> doesn't raise a syntax error.

You'll see down below a footnote referring to this as a special case.
But I don't know the details of how it all works, so short of digging
into the source code, I can't explain this any better. There are
others on this list who can, I believe.

ChrisA
0
Chris
7/11/2015 12:05:03 PM
Le samedi 11 juillet 2015 14:05:58 UTC+2, Chris Angelico a =E9crit=A0:

> You'll see down below a footnote referring to this as a special case.

I didn't spot the footnote and I don't regard it as dealing with a "special=
 case": the footnote is paraphrasing the precedence hierarchy given by the =
table. I  see it more as a glose (operator exponentiation is not so common =
in programming languages) or, better, a warning because precedence of unary=
 minus is "between" two "multiplicative" operators (** and *).

By the way, example provided by the doc in this footnote doesnt't properly =
illustrate the precedence of ** versus unary minus : whatever the precedenc=
e is, there is only one way to evaluate 2**-1. On the opposite, -1**2 (for =
instance) leads to two evaluations : (-1)**2 and -(1**2) and would provide =
an appropriate and better example.




0
candide
7/11/2015 1:22:51 PM
On 11.07.15 13:26, candide wrote:
>>>> 0 + not 0
>    File "<stdin>", line 1
>      0 + not 0
>            ^
> SyntaxError: invalid syntax
>>>>
>
>
> What is syntactically wrong with 0 + not 0?

This looks as a bug to me. Please file a report on http://bugs.python.org.


0
Serhiy
7/11/2015 1:38:26 PM
Le samedi 11 juillet 2015 15:38:51 UTC+2, Serhiy Storchaka a =E9crit=A0:

> This looks as a bug to me. Please file a report on http://bugs.python.org=
..


OK, I'll report.
0
candide
7/11/2015 3:07:12 PM
Serhiy Storchaka <storchaka@gmail.com> writes:
>On 11.07.15 13:26, candide wrote:
>>>>> 0 + not 0
>>    File "<stdin>", line 1
>>      0 + not 0
>>            ^
>> SyntaxError: invalid syntax
>> What is syntactically wrong with 0 + not 0?
>This looks as a bug to me. Please file a report

  I look at Python 3.4.3:

a_expr ::=  m_expr | a_expr "+" m_expr | a_expr "-" m_expr

  So, �not 0� must be an �m_expr� when used as the right operand of �+�.

m_expr ::=  u_expr | m_expr "*" u_expr | m_expr "//" u_expr | m_expr "/" u_expr | m_expr "%" u_expr
u_expr ::=  power | "-" u_expr | "+" u_expr | "~" u_expr
power ::=  primary ["**" u_expr]
primary ::=  atom | attributeref | subscription | slicing | call
atom      ::=  identifier | literal | enclosure
enclosure ::=  parenth_form | list_display | dict_display | set_display | generator_expression | yield_atom

  How can there be a �not�?

  �not� is used in

not_test ::=  comparison | "not" not_test
and_test ::=  not_test | and_test "and" not_test
or_test  ::=  and_test | or_test "or" and_test
conditional_expression ::=  or_test ["if" or_test "else" expression]
expression_nocond      ::=  or_test | lambda_expr_nocond
expression             ::=  conditional_expression | lambda_expr

  , but an �expression� is not an �m_expr�.

0
ram
7/11/2015 4:02:09 PM
On 2015-07-11 17:02, Stefan Ram wrote:
> Serhiy Storchaka <storchaka@gmail.com> writes:
>>On 11.07.15 13:26, candide wrote:
>>>>>> 0 + not 0
>>>    File "<stdin>", line 1
>>>      0 + not 0
>>>            ^
>>> SyntaxError: invalid syntax
>>> What is syntactically wrong with 0 + not 0?
>>This looks as a bug to me. Please file a report
>
>    I look at Python 3.4.3:
>
> a_expr ::=  m_expr | a_expr "+" m_expr | a_expr "-" m_expr
>
>    So, »not 0« must be an »m_expr« when used as the right operand of »+«.
>
> m_expr ::=  u_expr | m_expr "*" u_expr | m_expr "//" u_expr | m_expr "/" u_expr | m_expr "%" u_expr
> u_expr ::=  power | "-" u_expr | "+" u_expr | "~" u_expr
> power ::=  primary ["**" u_expr]
> primary ::=  atom | attributeref | subscription | slicing | call
> atom      ::=  identifier | literal | enclosure
> enclosure ::=  parenth_form | list_display | dict_display | set_display | generator_expression | yield_atom
>
>    How can there be a »not«?
>
>    »not« is used in
>
> not_test ::=  comparison | "not" not_test
> and_test ::=  not_test | and_test "and" not_test
> or_test  ::=  and_test | or_test "or" and_test
> conditional_expression ::=  or_test ["if" or_test "else" expression]
> expression_nocond      ::=  or_test | lambda_expr_nocond
> expression             ::=  conditional_expression | lambda_expr
>
>    , but an »expression« is not an »m_expr«.
>
If "not" had the high priority of unary "-", then:

     not a < b

would be parsed as:

     (not a) < b

If you extended the OP's example to:

     0 + not 0 + 0

and permitted "not" in that position, it wouldn't be parsed as:

     0 + (not 0) + 0

but as:

     0 + (not (0 + 0))

0
MRAB
7/11/2015 4:20:58 PM
On Sat, Jul 11, 2015 at 10:02 AM, Stefan Ram <ram@zedat.fu-berlin.de> wrote=
:
>   I look at Python 3.4.3:
>
> a_expr ::=3D  m_expr | a_expr "+" m_expr | a_expr "-" m_expr
>
>   So, =C2=BBnot 0=C2=AB must be an =C2=BBm_expr=C2=AB when used as the ri=
ght operand of =C2=BB+=C2=AB.
>
> m_expr ::=3D  u_expr | m_expr "*" u_expr | m_expr "//" u_expr | m_expr "/=
" u_expr | m_expr "%" u_expr
> u_expr ::=3D  power | "-" u_expr | "+" u_expr | "~" u_expr
> power ::=3D  primary ["**" u_expr]
> primary ::=3D  atom | attributeref | subscription | slicing | call
> atom      ::=3D  identifier | literal | enclosure
> enclosure ::=3D  parenth_form | list_display | dict_display | set_display=
 | generator_expression | yield_atom
>
>   How can there be a =C2=BBnot=C2=AB?
>
>   =C2=BBnot=C2=AB is used in
>
> not_test ::=3D  comparison | "not" not_test
> and_test ::=3D  not_test | and_test "and" not_test
> or_test  ::=3D  and_test | or_test "or" and_test
> conditional_expression ::=3D  or_test ["if" or_test "else" expression]
> expression_nocond      ::=3D  or_test | lambda_expr_nocond
> expression             ::=3D  conditional_expression | lambda_expr
>
>   , but an =C2=BBexpression=C2=AB is not an =C2=BBm_expr=C2=AB.

I must concur. The grammar as written does not actually produce 1 +
not 0. I think it's still worthwhile opening a bug, because the
behavior is surprising and possibly not intentional.
0
Ian
7/11/2015 4:56:04 PM
On 11/07/2015 17:56, Ian Kelly wrote:
> On Sat, Jul 11, 2015 at 10:02 AM, Stefan Ram <ram@zedat.fu-berlin.de> wrote:
>>    I look at Python 3.4.3:
>>
>> a_expr ::=  m_expr | a_expr "+" m_expr | a_expr "-" m_expr
>>
>>    So, »not 0« must be an »m_expr« when used as the right operand of »+«.
>>
>> m_expr ::=  u_expr | m_expr "*" u_expr | m_expr "//" u_expr | m_expr "/" u_expr | m_expr "%" u_expr
>> u_expr ::=  power | "-" u_expr | "+" u_expr | "~" u_expr
>> power ::=  primary ["**" u_expr]
>> primary ::=  atom | attributeref | subscription | slicing | call
>> atom      ::=  identifier | literal | enclosure
>> enclosure ::=  parenth_form | list_display | dict_display | set_display | generator_expression | yield_atom
>>
>>    How can there be a »not«?
>>
>>    »not« is used in
>>
>> not_test ::=  comparison | "not" not_test
>> and_test ::=  not_test | and_test "and" not_test
>> or_test  ::=  and_test | or_test "or" and_test
>> conditional_expression ::=  or_test ["if" or_test "else" expression]
>> expression_nocond      ::=  or_test | lambda_expr_nocond
>> expression             ::=  conditional_expression | lambda_expr
>>
>>    , but an »expression« is not an »m_expr«.
>
> I must concur. The grammar as written does not actually produce 1 +
> not 0. I think it's still worthwhile opening a bug, because the
> behavior is surprising and possibly not intentional.
>

http://bugs.python.org/issue24612

-- 
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.

Mark Lawrence

0
Mark
7/11/2015 8:05:13 PM
On Sat, Jul 11, 2015, at 07:20, Chris Angelico wrote:
> On Sat, Jul 11, 2015 at 9:12 PM, Luuk <luuk@invalid.lan> wrote:
> > It can occur in an arithmetic expression, and 'not' has a higher precedence
> > than '+'
> > (https://docs.python.org/2/reference/expressions.html#operator-precedence)
> >
> 
> I think you're misreading the table; 'not' has *lower* precedence than
> '+'.

Precedence shouldn't actually matter when resolving a unary prefix
operator on the right of a binary operator. I don't understand how this
could possibly be interpreted in a different valid way rather than being
spuriously rejected as a syntax error.
0
random832
7/11/2015 8:46:29 PM
Ian Kelly wrote:
> I must concur. The grammar as written does not actually produce 1 +
> not 0. I think it's still worthwhile opening a bug, because the
> behavior is surprising and possibly not intentional.

It's almost certainly intentional. If you want

    not a + b > c

to be interpreted as

    not (a + b > c)

rather than

    (not a) + b > c

then 'not' has to be higher up in the chain of
grammar productions than the arithmetic operations.
Maintaining that while allowing 'a + not b' would
require contortions in the grammar that wouldn't be
worth the very small benefit that would be obtained.

-- 
Greg
0
Gregory
7/12/2015 6:12:00 AM
Reply: