pFad - Phone/Frame/Anonymizer/Declutterfier! Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

URL: http://github.com/python/cpython/commit/c1b42db9e47b76fca3c2993cb172cc4991b04839

gh-130914: Make graphlib.TopologicalSorter.prepare() idempotent (#131… · python/cpython@c1b42db · GitHub
Skip to content

Commit c1b42db

Browse files
authored
gh-130914: Make graphlib.TopologicalSorter.prepare() idempotent (#131317)
Closes #130914: Make graphlib.TopologicalSorter.prepare() idempotent Relax the rules so that `.prepare()` can be called multiple times, provided that no work has been passed out by `.get_ready()` yet.
1 parent f819900 commit c1b42db

6 files changed

Lines changed: 43 additions & 6 deletions

File tree

Doc/library/graphlib.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,14 @@
106106
function, the graph cannot be modified, and therefore no more nodes can be
107107
added using :meth:`~TopologicalSorter.add`.
108108

109+
A :exc:`ValueError` will be raised if the sort has been started by
110+
:meth:`~.static_order` or :meth:`~.get_ready`.
111+
112+
.. versionchanged:: next
113+
114+
``prepare()`` can now be called more than once as long as the sort has
115+
not started. Previously this raised :exc:`ValueError`.
116+
109117
.. method:: is_active()
110118

111119
Returns ``True`` if more progress can be made and ``False`` otherwise.

Doc/whatsnew/3.14.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -607,6 +607,15 @@ getopt
607607
* Add support for returning intermixed options and non-option arguments in order.
608608
(Contributed by Serhiy Storchaka in :gh:`126390`.)
609609

610+
611+
graphlib
612+
--------
613+
614+
* Allow :meth:`graphlib.TopologicalSorter.prepare` to be called more than once
615+
as long as sorting has not started.
616+
(Contributed by Daniel Pope in :gh:`130914`)
617+
618+
610619
http
611620
----
612621

Lib/graphlib.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -90,13 +90,17 @@ def prepare(self):
9090
still be used to obtain as many nodes as possible until cycles block more
9191
progress. After a call to this function, the graph cannot be modified and
9292
therefore no more nodes can be added using "add".
93+
94+
Raise ValueError if nodes have already been passed out of the sorter.
95+
9396
"""
94-
if self._ready_nodes is not None:
95-
raise ValueError("cannot prepare() more than once")
97+
if self._npassedout > 0:
98+
raise ValueError("cannot prepare() after starting sort")
9699

97-
self._ready_nodes = [
98-
i.node for i in self._node2info.values() if i.npredecessors == 0
99-
]
100+
if self._ready_nodes is None:
101+
self._ready_nodes = [
102+
i.node for i in self._node2info.values() if i.npredecessors == 0
103+
]
100104
# ready_nodes is set before we look for cycles on purpose:
101105
# if the user wants to catch the CycleError, that's fine,
102106
# they can continue using the instance to grab as many

Lib/test/test_graphlib.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,9 +140,21 @@ def test_calls_before_prepare(self):
140140
def test_prepare_multiple_times(self):
141141
ts = graphlib.TopologicalSorter()
142142
ts.prepare()
143-
with self.assertRaisesRegex(ValueError, r"cannot prepare\(\) more than once"):
143+
ts.prepare()
144+
145+
def test_prepare_after_pass_out(self):
146+
ts = graphlib.TopologicalSorter({'a': 'bc'})
147+
ts.prepare()
148+
self.assertEqual(set(ts.get_ready()), {'b', 'c'})
149+
with self.assertRaisesRegex(ValueError, r"cannot prepare\(\) after starting sort"):
144150
ts.prepare()
145151

152+
def test_prepare_cycleerror_each_time(self):
153+
ts = graphlib.TopologicalSorter({'a': 'b', 'b': 'a'})
154+
for attempt in range(1, 4):
155+
with self.assertRaises(graphlib.CycleError, msg=f"{attempt=}"):
156+
ts.prepare()
157+
146158
def test_invalid_nodes_in_done(self):
147159
ts = graphlib.TopologicalSorter()
148160
ts.add(1, 2, 3, 4)

Misc/ACKS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1483,6 +1483,7 @@ Michael Pomraning
14831483
Martin Pool
14841484
Iustin Pop
14851485
Claudiu Popa
1486+
Daniel Pope
14861487
Nick Pope
14871488
John Popplewell
14881489
Matheus Vieira Portela
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Allow :meth:`graphlib.TopologicalSorter.prepare` to be called more than once
2+
as long as sorting has not started.
3+
Patch by Daniel Pope.

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad © 2024 Your Company Name. All rights reserved.





Check this box to remove all script contents from the fetched content.



Check this box to remove all images from the fetched content.


Check this box to remove all CSS styles from the fetched content.


Check this box to keep images inefficiently compressed and original size.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy