Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IDLE: Module warnings misplaced. #79038

Open
terryjreedy opened this issue Sep 30, 2018 · 8 comments
Open

IDLE: Module warnings misplaced. #79038

terryjreedy opened this issue Sep 30, 2018 · 8 comments
Assignees
Labels
3.7 (EOL) end of life 3.8 only security fixes 3.9 only security fixes topic-IDLE type-bug An unexpected behavior, bug, or error

Comments

@terryjreedy
Copy link
Member

BPO 34857
Nosy @rhettinger, @terryjreedy, @taleinat, @serhiy-storchaka

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields:

assignee = 'https://github.com/terryjreedy'
closed_at = None
created_at = <Date 2018-09-30.20:10:30.440>
labels = ['3.8', 'expert-IDLE', 'type-bug', '3.7', '3.9']
title = 'IDLE: Module warnings misplaced.'
updated_at = <Date 2019-08-16.05:23:48.410>
user = 'https://github.com/terryjreedy'

bugs.python.org fields:

activity = <Date 2019-08-16.05:23:48.410>
actor = 'terry.reedy'
assignee = 'terry.reedy'
closed = False
closed_date = None
closer = None
components = ['IDLE']
creation = <Date 2018-09-30.20:10:30.440>
creator = 'terry.reedy'
dependencies = []
files = []
hgrepos = []
issue_num = 34857
keywords = []
message_count = 7.0
messages = ['326745', '334316', '349394', '349417', '349431', '349434', '349845']
nosy_count = 4.0
nosy_names = ['rhettinger', 'terry.reedy', 'taleinat', 'serhiy.storchaka']
pr_nums = []
priority = 'normal'
resolution = None
stage = 'test needed'
status = 'open'
superseder = None
type = 'behavior'
url = 'https://bugs.python.org/issue34857'
versions = ['Python 3.7', 'Python 3.8', 'Python 3.9']

@terryjreedy
Copy link
Member Author

In 3.6.6, """compile("assert (0, 'bad')", '', 'single')""" in Python or IDLE emits "SyntaxWarning: assertion is always true, perhaps remove parentheses?".

In Python,
>>> assert (0, 'bad')
<stdin>:1: SyntaxWarning: assertion is always true, perhaps remove parentheses?

In IDLE's Shell, the same statement is effectively treated as incomplete in that newlines are echoed and IDLE waits for input until something is entered. KeyboardInterrupt (^C) or any text terminate the loop. In the latter case, "SyntaxError: multiple statements found while compiling a single statement" is printed.

In a file, the statement has no effect, but the warning should be printed in the shell.

@terryjreedy terryjreedy added 3.7 (EOL) end of life 3.8 only security fixes labels Sep 30, 2018
@terryjreedy terryjreedy self-assigned this Sep 30, 2018
@terryjreedy terryjreedy added topic-IDLE type-bug An unexpected behavior, bug, or error labels Sep 30, 2018
@terryjreedy
Copy link
Member Author

In 3.7.2, the statement in a file results in the SyntaxError being printed in Shell *before* the restart. It should be after, but before the code object is sent to the restarted execution process.

@serhiy-storchaka
Copy link
Member

I cannot reproduce this behavior in 3.7+. assert (0, 'bad') does not have any effect. But in 3.6 it outputs a traceback to the stderr.

$ ./python -m idlelib
Exception in Tkinter callback
Traceback (most recent call last):
  File "/home/serhiy/py/cpython3.6/Lib/tkinter/__init__.py", line 1705, in __call__
    return self.func(*args)
  File "/home/serhiy/py/cpython3.6/Lib/idlelib/multicall.py", line 176, in handler
    r = l[i](event)
  File "/home/serhiy/py/cpython3.6/Lib/idlelib/pyshell.py", line 1205, in enter_callback
    self.runit()
  File "/home/serhiy/py/cpython3.6/Lib/idlelib/pyshell.py", line 1246, in runit
    self.interp.runsource(line)
  File "/home/serhiy/py/cpython3.6/Lib/idlelib/pyshell.py", line 684, in runsource
    return InteractiveInterpreter.runsource(self, source, filename)
  File "/home/serhiy/py/cpython3.6/Lib/code.py", line 64, in runsource
    code = self.compile(source, filename, symbol)
  File "/home/serhiy/py/cpython3.6/Lib/codeop.py", line 168, in __call__
    return _maybe_compile(self.compiler, source, filename, symbol)
  File "/home/serhiy/py/cpython3.6/Lib/codeop.py", line 82, in _maybe_compile
    code = compiler(source, filename, symbol)
  File "/home/serhiy/py/cpython3.6/Lib/codeop.py", line 133, in __call__
    codeob = compile(source, filename, symbol, self.flags, 1)
SyntaxWarning: assertion is always true, perhaps remove parentheses?

But other syntax warnings are converted to errors in IDLE (reported by Raymond in https://bugs.python.org/issue15248#msg349375).

In the regular interactive interpreter:

>>> 0 is 0
<stdin>:1: SyntaxWarning: "is" with a literal. Did you mean "=="?
True
>>> data = [
...          (1, 2, 3) # oops, missing comma!
...          (4, 5, 6)
...      ]
<stdin>:2: SyntaxWarning: 'tuple' object is not callable; perhaps you missed a comma?
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
TypeError: 'tuple' object is not callable

In IDLE:

>>> 0 is 0
SyntaxError: "is" with a literal. Did you mean "=="?
>>> data = [
         (1, 2, 3) # oops, missing comma!
         (4, 5, 6)
     ]

SyntaxError: 'tuple' object is not callable; perhaps you missed a comma?

@serhiy-storchaka serhiy-storchaka added the 3.9 only security fixes label Aug 11, 2019
@rhettinger
Copy link
Contributor

See: https://bugs.python.org/msg349375

Because new SyntaxWarnings were added in 3.8, I expect this problem to become more prevalent. Hopefully, this gets fixed for the 3.8 release.

@terryjreedy
Copy link
Member Author

Treating a SyntaxWarning as an error is intentional, since 2001 in a Kurt Kaiser patch. IDLE's ModifiedInterpreter subclasses code.InteractiveInterpreter. The subclass .runsource turns a SyntaxWarning into an error, before calling the superclass method, with

    warnings.filterwarnings(action="error", category=SyntaxWarning)

As long as this is true, it should be documented. It is included in bpo-37825.

In interactive python (as opposed to IDLE), code is executed after a SyntaxWarning. In the non-callable call examples, minimally "()()", "", "1()", and "''()", the result is a traceback that repeats the warning message. I think the repetition is mostly noise and is better omitted. I don't know what SyntaxWarnings were present in 2001, but I presume that Kurt had the same impression, whatever it or they were.

The non-callable calls violate the 'ideal' Python grammar, which would have a production like "call = possible_callable '(', args, ')'. Violations are caught by the compiler rather than the parser. But they could plausibly be called a (subclass of) SyntaxError and execution avoided everywhere.

The situation is quite different with "literal is (not) something", where 'literal' includes constant tuples. The expression is valid, normally runs without exception, and should be executed. To me, this is not a syntax issue, so SyntaxWarning seems wrong. But as long as is used for this situation, the conversion to error must cease. (If I knew how, I would prefer to still not call known non-callables in Shell.)

There are two subcases with different reasons for pinging users.

  1. The result is obvious ("0 is ''", "0 is ()") and unchanged when 'is' is replaced with '=='. The advice is useless. It should instead, it seems to me, be to use True or False. I suspect that this case is rare.

  2. The result using 'is' is implementation dependent ("0 is 0", "0 is a", "1000 is 1000"). For production code, the advice to change 'is' to '==' is correct. For exploration of 'is' in a shell, which many beginners like to do, it likely is not, at least not immediately.
    --

My initial messsage above is moot since compile("assert (0, 'bad')", '', 'single') no longer emit a SyntaxWarning, and the new warnings do not show the same behavior, even for similarly legal code such as "0 is 0".

My second message, about when a SyntaxWarning for a file is displayed, is still relevant, and I agree that it is a higher priority than before.

But it is more complex than reported above. First, there are other warnings than SyntaxWarning, and we might decide to optionally enable them. Second, Run Module does Check Module first. If Check Module is selected directly, there is no restart line. Third, there will be no restart line if there is a SyntaxError, or a Tabnanny but there might be prior warnings. I think I know how to deal with all of the above.

Module SyntaxErrors and Tabnanny errors are displayed in a popup error box, with the cursor moved to the line and maybe column of the error. Warnings could be put in a separate box unless there is a restart. I would prefer to not shift focus to Shell unless and until a module is run.

@rhettinger
Copy link
Contributor

Terry, thanks for the thorough analysis and explanation.

@terryjreedy
Copy link
Member Author

I moved leaving SyntaxWarnings as warnings to bpo-37824, as that is mostly about editing pyshell.

Changing the ordering of warnings and RESTART involves run.show_warnings. I believe the latter should collect lines in a warnings list and print
''.join(warnings) at the appropriate time.

@terryjreedy terryjreedy changed the title IDLE: SyntaxWarning not handled properly IDLE: Module warnings misplaced. Aug 16, 2019
@ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
@snoopyjc
Copy link

Not sure if this is the same issue, but I'm getting the same SyntaxWarning in Python 3.10.6 on the following:

assert ((sub_with_output_parameter(output), (output:=perllib.fetch_out_parameter(0)))[0] == 'expected value', 'Unexpected return value')

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.7 (EOL) end of life 3.8 only security fixes 3.9 only security fixes topic-IDLE type-bug An unexpected behavior, bug, or error
Projects
Status: No status
Development

No branches or pull requests

4 participants