Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 7d2a7a0

Browse filesBrowse files
authored
Merge pull request #5731 from arihant2math/pprint-313
2 parents 494918d + 92e72aa commit 7d2a7a0
Copy full SHA for 7d2a7a0

11 files changed

+750
-228
lines changed

‎Lib/colorsys.py

Copy file name to clipboardExpand all lines: Lib/colorsys.py
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
__all__ = ["rgb_to_yiq","yiq_to_rgb","rgb_to_hls","hls_to_rgb",
2525
"rgb_to_hsv","hsv_to_rgb"]
2626

27-
# Some floating point constants
27+
# Some floating-point constants
2828

2929
ONE_THIRD = 1.0/3.0
3030
ONE_SIXTH = 1.0/6.0

‎Lib/graphlib.py

Copy file name to clipboardExpand all lines: Lib/graphlib.py
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ def done(self, *nodes):
154154
This method unblocks any successor of each node in *nodes* for being returned
155155
in the future by a call to "get_ready".
156156
157-
Raises :exec:`ValueError` if any node in *nodes* has already been marked as
157+
Raises ValueError if any node in *nodes* has already been marked as
158158
processed by a previous call to this method, if a node was not added to the
159159
graph by using "add" or if called without calling "prepare" previously or if
160160
node has not yet been returned by "get_ready".

‎Lib/linecache.py

Copy file name to clipboardExpand all lines: Lib/linecache.py
+70-21Lines changed: 70 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,13 @@
55
that name.
66
"""
77

8-
import functools
9-
import sys
10-
import os
11-
import tokenize
12-
138
__all__ = ["getline", "clearcache", "checkcache", "lazycache"]
149

1510

1611
# The cache. Maps filenames to either a thunk which will provide source code,
1712
# or a tuple (size, mtime, lines, fullname) once loaded.
1813
cache = {}
14+
_interactive_cache = {}
1915

2016

2117
def clearcache():
@@ -49,28 +45,54 @@ def getlines(filename, module_globals=None):
4945
return []
5046

5147

48+
def _getline_from_code(filename, lineno):
49+
lines = _getlines_from_code(filename)
50+
if 1 <= lineno <= len(lines):
51+
return lines[lineno - 1]
52+
return ''
53+
54+
def _make_key(code):
55+
return (code.co_filename, code.co_qualname, code.co_firstlineno)
56+
57+
def _getlines_from_code(code):
58+
code_id = _make_key(code)
59+
if code_id in _interactive_cache:
60+
entry = _interactive_cache[code_id]
61+
if len(entry) != 1:
62+
return _interactive_cache[code_id][2]
63+
return []
64+
65+
5266
def checkcache(filename=None):
5367
"""Discard cache entries that are out of date.
5468
(This is not checked upon each call!)"""
5569

5670
if filename is None:
57-
filenames = list(cache.keys())
58-
elif filename in cache:
59-
filenames = [filename]
71+
# get keys atomically
72+
filenames = cache.copy().keys()
6073
else:
61-
return
74+
filenames = [filename]
6275

6376
for filename in filenames:
64-
entry = cache[filename]
77+
try:
78+
entry = cache[filename]
79+
except KeyError:
80+
continue
81+
6582
if len(entry) == 1:
6683
# lazy cache entry, leave it lazy.
6784
continue
6885
size, mtime, lines, fullname = entry
6986
if mtime is None:
7087
continue # no-op for files loaded via a __loader__
88+
try:
89+
# This import can fail if the interpreter is shutting down
90+
import os
91+
except ImportError:
92+
return
7193
try:
7294
stat = os.stat(fullname)
73-
except OSError:
95+
except (OSError, ValueError):
7496
cache.pop(filename, None)
7597
continue
7698
if size != stat.st_size or mtime != stat.st_mtime:
@@ -82,6 +104,17 @@ def updatecache(filename, module_globals=None):
82104
If something's wrong, print a message, discard the cache entry,
83105
and return an empty list."""
84106

107+
# These imports are not at top level because linecache is in the critical
108+
# path of the interpreter startup and importing os and sys take a lot of time
109+
# and slows down the startup sequence.
110+
try:
111+
import os
112+
import sys
113+
import tokenize
114+
except ImportError:
115+
# These import can fail if the interpreter is shutting down
116+
return []
117+
85118
if filename in cache:
86119
if len(cache[filename]) != 1:
87120
cache.pop(filename, None)
@@ -128,16 +161,20 @@ def updatecache(filename, module_globals=None):
128161
try:
129162
stat = os.stat(fullname)
130163
break
131-
except OSError:
164+
except (OSError, ValueError):
132165
pass
133166
else:
134167
return []
168+
except ValueError: # may be raised by os.stat()
169+
return []
135170
try:
136171
with tokenize.open(fullname) as fp:
137172
lines = fp.readlines()
138173
except (OSError, UnicodeDecodeError, SyntaxError):
139174
return []
140-
if lines and not lines[-1].endswith('\n'):
175+
if not lines:
176+
lines = ['\n']
177+
elif not lines[-1].endswith('\n'):
141178
lines[-1] += '\n'
142179
size, mtime = stat.st_size, stat.st_mtime
143180
cache[filename] = size, mtime, lines, fullname
@@ -166,17 +203,29 @@ def lazycache(filename, module_globals):
166203
return False
167204
# Try for a __loader__, if available
168205
if module_globals and '__name__' in module_globals:
169-
name = module_globals['__name__']
170-
if (loader := module_globals.get('__loader__')) is None:
171-
if spec := module_globals.get('__spec__'):
172-
try:
173-
loader = spec.loader
174-
except AttributeError:
175-
pass
206+
spec = module_globals.get('__spec__')
207+
name = getattr(spec, 'name', None) or module_globals['__name__']
208+
loader = getattr(spec, 'loader', None)
209+
if loader is None:
210+
loader = module_globals.get('__loader__')
176211
get_source = getattr(loader, 'get_source', None)
177212

178213
if name and get_source:
179-
get_lines = functools.partial(get_source, name)
214+
def get_lines(name=name, *args, **kwargs):
215+
return get_source(name, *args, **kwargs)
180216
cache[filename] = (get_lines,)
181217
return True
182218
return False
219+
220+
def _register_code(code, string, name):
221+
entry = (len(string),
222+
None,
223+
[line + '\n' for line in string.splitlines()],
224+
name)
225+
stack = [code]
226+
while stack:
227+
code = stack.pop()
228+
for const in code.co_consts:
229+
if isinstance(const, type(code)):
230+
stack.append(const)
231+
_interactive_cache[_make_key(code)] = entry

‎Lib/pprint.py

Copy file name to clipboardExpand all lines: Lib/pprint.py
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,9 @@ def __init__(self, indent=1, width=80, depth=None, stream=None, *,
128128
sort_dicts
129129
If true, dict keys are sorted.
130130
131+
underscore_numbers
132+
If true, digit groups are separated with underscores.
133+
131134
"""
132135
indent = int(indent)
133136
width = int(width)

‎Lib/queue.py

Copy file name to clipboardExpand all lines: Lib/queue.py
+59-1Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,15 @@
1010
except ImportError:
1111
SimpleQueue = None
1212

13-
__all__ = ['Empty', 'Full', 'Queue', 'PriorityQueue', 'LifoQueue', 'SimpleQueue']
13+
__all__ = [
14+
'Empty',
15+
'Full',
16+
'ShutDown',
17+
'Queue',
18+
'PriorityQueue',
19+
'LifoQueue',
20+
'SimpleQueue',
21+
]
1422

1523

1624
try:
@@ -25,6 +33,10 @@ class Full(Exception):
2533
pass
2634

2735

36+
class ShutDown(Exception):
37+
'''Raised when put/get with shut-down queue.'''
38+
39+
2840
class Queue:
2941
'''Create a queue object with a given maximum size.
3042
@@ -54,6 +66,9 @@ def __init__(self, maxsize=0):
5466
self.all_tasks_done = threading.Condition(self.mutex)
5567
self.unfinished_tasks = 0
5668

69+
# Queue shutdown state
70+
self.is_shutdown = False
71+
5772
def task_done(self):
5873
'''Indicate that a formerly enqueued task is complete.
5974
@@ -65,6 +80,9 @@ def task_done(self):
6580
have been processed (meaning that a task_done() call was received
6681
for every item that had been put() into the queue).
6782
83+
shutdown(immediate=True) calls task_done() for each remaining item in
84+
the queue.
85+
6886
Raises a ValueError if called more times than there were items
6987
placed in the queue.
7088
'''
@@ -129,15 +147,21 @@ def put(self, item, block=True, timeout=None):
129147
Otherwise ('block' is false), put an item on the queue if a free slot
130148
is immediately available, else raise the Full exception ('timeout'
131149
is ignored in that case).
150+
151+
Raises ShutDown if the queue has been shut down.
132152
'''
133153
with self.not_full:
154+
if self.is_shutdown:
155+
raise ShutDown
134156
if self.maxsize > 0:
135157
if not block:
136158
if self._qsize() >= self.maxsize:
137159
raise Full
138160
elif timeout is None:
139161
while self._qsize() >= self.maxsize:
140162
self.not_full.wait()
163+
if self.is_shutdown:
164+
raise ShutDown
141165
elif timeout < 0:
142166
raise ValueError("'timeout' must be a non-negative number")
143167
else:
@@ -147,6 +171,8 @@ def put(self, item, block=True, timeout=None):
147171
if remaining <= 0.0:
148172
raise Full
149173
self.not_full.wait(remaining)
174+
if self.is_shutdown:
175+
raise ShutDown
150176
self._put(item)
151177
self.unfinished_tasks += 1
152178
self.not_empty.notify()
@@ -161,14 +187,21 @@ def get(self, block=True, timeout=None):
161187
Otherwise ('block' is false), return an item if one is immediately
162188
available, else raise the Empty exception ('timeout' is ignored
163189
in that case).
190+
191+
Raises ShutDown if the queue has been shut down and is empty,
192+
or if the queue has been shut down immediately.
164193
'''
165194
with self.not_empty:
195+
if self.is_shutdown and not self._qsize():
196+
raise ShutDown
166197
if not block:
167198
if not self._qsize():
168199
raise Empty
169200
elif timeout is None:
170201
while not self._qsize():
171202
self.not_empty.wait()
203+
if self.is_shutdown and not self._qsize():
204+
raise ShutDown
172205
elif timeout < 0:
173206
raise ValueError("'timeout' must be a non-negative number")
174207
else:
@@ -178,6 +211,8 @@ def get(self, block=True, timeout=None):
178211
if remaining <= 0.0:
179212
raise Empty
180213
self.not_empty.wait(remaining)
214+
if self.is_shutdown and not self._qsize():
215+
raise ShutDown
181216
item = self._get()
182217
self.not_full.notify()
183218
return item
@@ -198,6 +233,29 @@ def get_nowait(self):
198233
'''
199234
return self.get(block=False)
200235

236+
def shutdown(self, immediate=False):
237+
'''Shut-down the queue, making queue gets and puts raise ShutDown.
238+
239+
By default, gets will only raise once the queue is empty. Set
240+
'immediate' to True to make gets raise immediately instead.
241+
242+
All blocked callers of put() and get() will be unblocked. If
243+
'immediate', a task is marked as done for each item remaining in
244+
the queue, which may unblock callers of join().
245+
'''
246+
with self.mutex:
247+
self.is_shutdown = True
248+
if immediate:
249+
while self._qsize():
250+
self._get()
251+
if self.unfinished_tasks > 0:
252+
self.unfinished_tasks -= 1
253+
# release all blocked threads in `join()`
254+
self.all_tasks_done.notify_all()
255+
# All getters need to re-check queue-empty to raise ShutDown
256+
self.not_empty.notify_all()
257+
self.not_full.notify_all()
258+
201259
# Override these methods to implement other queue organizations
202260
# (e.g. stack or priority queue).
203261
# These will only be called with appropriate locks held

‎Lib/sched.py

Copy file name to clipboardExpand all lines: Lib/sched.py
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
implement simulated time by writing your own functions. This can
1212
also be used to integrate scheduling with STDWIN events; the delay
1313
function is allowed to modify the queue. Time can be expressed as
14-
integers or floating point numbers, as long as it is consistent.
14+
integers or floating-point numbers, as long as it is consistent.
1515
1616
Events are specified by tuples (time, priority, action, argument, kwargs).
1717
As in UNIX, lower priority numbers mean higher priority; in this

‎Lib/test/test_heapq.py

Copy file name to clipboardExpand all lines: Lib/test/test_heapq.py
-1Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import unittest
55
import doctest
66

7-
from test import support
87
from test.support import import_helper
98
from unittest import TestCase, skipUnless
109
from operator import itemgetter

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.