Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main'
Browse files Browse the repository at this point in the history
  • Loading branch information
hugovk committed Apr 27, 2024
2 parents e58a0e4 + 51aefc5 commit 2f7d0a2
Show file tree
Hide file tree
Showing 11 changed files with 75 additions and 8 deletions.
3 changes: 3 additions & 0 deletions Doc/whatsnew/3.13.rst
Original file line number Diff line number Diff line change
Expand Up @@ -791,6 +791,9 @@ tkinter
:class:`tkinter.ttk.Style`.
(Contributed by Serhiy Storchaka in :gh:`68166`.)

* Add the :meth:`!after_info` method for Tkinter widgets.
(Contributed by Cheryl Sabella in :gh:`77020`.)

traceback
---------

Expand Down
3 changes: 3 additions & 0 deletions Grammar/python.gram
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ _PyPegen_parse(Parser *p)
# Fail if e can be parsed, without consuming any input.
# ~
# Commit to the current alternative, even if it fails to parse.
# &&e
# Eager parse e. The parser will not backtrack and will immediately
# fail with SyntaxError if e cannot be parsed.
#

# STARTING RULES
Expand Down
6 changes: 4 additions & 2 deletions Include/internal/pycore_ceval_state.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ struct _pending_call {
int flags;
};

#define PENDINGCALLSARRAYSIZE 32
#define PENDINGCALLSARRAYSIZE 300

#define MAXPENDINGCALLS PENDINGCALLSARRAYSIZE
/* For interpreter-level pending calls, we want to avoid spending too
Expand All @@ -31,7 +31,9 @@ struct _pending_call {
# define MAXPENDINGCALLSLOOP MAXPENDINGCALLS
#endif

#define MAXPENDINGCALLS_MAIN PENDINGCALLSARRAYSIZE
/* We keep the number small to preserve as much compatibility
as possible with earlier versions. */
#define MAXPENDINGCALLS_MAIN 32
/* For the main thread, we want to make sure all pending calls are
run at once, for the sake of prompt signal handling. This is
unlikely to cause any problems since there should be very few
Expand Down
4 changes: 2 additions & 2 deletions Lib/test/test_capi/test_misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -1570,9 +1570,9 @@ def test_max_pending(self):
self.assertEqual(added, maxpending)

with self.subTest('not main-only'):
# Per-interpreter pending calls has the same low limit
# Per-interpreter pending calls has a much higher limit
# on how many may be pending at a time.
maxpending = 32
maxpending = 300

l = []
added = self.pendingcalls_submit(l, 1, main=False)
Expand Down
40 changes: 40 additions & 0 deletions Lib/test/test_tkinter/test_misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,46 @@ def callback():
with self.assertRaises(tkinter.TclError):
root.tk.call('after', 'info', idle1)

def test_after_info(self):
root = self.root

# No events.
self.assertEqual(root.after_info(), ())

# Add timer.
timer = root.after(1, lambda: 'break')

# With no parameter, it returns a tuple of the event handler ids.
self.assertEqual(root.after_info(), (timer, ))
root.after_cancel(timer)

timer1 = root.after(5000, lambda: 'break')
timer2 = root.after(5000, lambda: 'break')
idle1 = root.after_idle(lambda: 'break')
# Only contains new events and not 'timer'.
self.assertEqual(root.after_info(), (idle1, timer2, timer1))

# With a parameter returns a tuple of (script, type).
timer1_info = root.after_info(timer1)
self.assertEqual(len(timer1_info), 2)
self.assertEqual(timer1_info[1], 'timer')
idle1_info = root.after_info(idle1)
self.assertEqual(len(idle1_info), 2)
self.assertEqual(idle1_info[1], 'idle')

root.after_cancel(timer1)
with self.assertRaises(tkinter.TclError):
root.after_info(timer1)
root.after_cancel(timer2)
with self.assertRaises(tkinter.TclError):
root.after_info(timer2)
root.after_cancel(idle1)
with self.assertRaises(tkinter.TclError):
root.after_info(idle1)

# No events.
self.assertEqual(root.after_info(), ())

def test_clipboard(self):
root = self.root
root.clipboard_clear()
Expand Down
3 changes: 2 additions & 1 deletion Lib/test/test_traceback.py
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,7 @@ def f():
])

@requires_subprocess()
@force_not_colorized
def test_encoded_file(self):
# Test that tracebacks are correctly printed for encoded source files:
# - correct line number (Issue2384)
Expand All @@ -410,7 +411,7 @@ def do_test(firstlines, message, charset, lineno):
""".format(firstlines, message))

process = subprocess.Popen([sys.executable, TESTFN],
stdout=subprocess.PIPE, stderr=subprocess.STDOUT, env={})
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
stdout, stderr = process.communicate()
stdout = stdout.decode(output_encoding).splitlines()
finally:
Expand Down
4 changes: 3 additions & 1 deletion Lib/test/test_tracemalloc.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
interpreter_requires_environment)
from test import support
from test.support import os_helper
from test.support import force_not_colorized

try:
import _testcapi
Expand Down Expand Up @@ -938,11 +939,12 @@ def test_env_limit(self):
stdout = stdout.rstrip()
self.assertEqual(stdout, b'10')

@force_not_colorized
def check_env_var_invalid(self, nframe):
with support.SuppressCrashReport():
ok, stdout, stderr = assert_python_failure(
'-c', 'pass',
PYTHONTRACEMALLOC=str(nframe), __cleanenv=True)
PYTHONTRACEMALLOC=str(nframe))

if b'ValueError: the number of frames must be in range' in stderr:
return
Expand Down
15 changes: 15 additions & 0 deletions Lib/tkinter/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -897,6 +897,21 @@ def after_cancel(self, id):
pass
self.tk.call('after', 'cancel', id)

def after_info(self, id=None):
"""Return information about existing event handlers.
With no argument, return a tuple of the identifiers for all existing
event handlers created by the after and after_idle commands for this
interpreter. If id is supplied, it specifies an existing handler; id
must have been the return value from some previous call to after or
after_idle and it must not have triggered yet or been canceled. If the
id doesn't exist, a TclError is raised. Otherwise, the return value is
a tuple containing (script, type) where script is a reference to the
function to be called by the event handler and type is either 'idle'
or 'timer' to indicate what kind of event handler it is.
"""
return self.tk.splitlist(self.tk.call('after', 'info', id))

def bell(self, displayof=0):
"""Ring a display's bell."""
self.tk.call(('bell',) + self._displayof(displayof))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add the :meth:`after_info` method for Tkinter widgets.
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ class was dynamically created, the class held strong references to other
objects which took up a significant amount of memory, and the cache
contained the sole strong reference to the class. The fix for the regression
leads to a slowdown in :func:`getattr_static`, but the function should still
be signficantly faster than it was in Python 3.11. Patch by Alex Waygood.
be significantly faster than it was in Python 3.11. Patch by Alex Waygood.
2 changes: 1 addition & 1 deletion iOS/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ iOS specific arguments to configure

Unless you know what you're doing, changing the name of the Python
framework on iOS is not advised. If you use this option, you won't be able
to run the ``make testios`` target without making signficant manual
to run the ``make testios`` target without making significant manual
alterations, and you won't be able to use any binary packages unless you
compile them yourself using your own framework name.

Expand Down

0 comments on commit 2f7d0a2

Please sign in to comment.