File tree 6 files changed +43
-6
lines changed
6 files changed +43
-6
lines changed Original file line number Diff line number Diff line change 106
106
function, the graph cannot be modified, and therefore no more nodes can be
107
107
added using :meth: `~TopologicalSorter.add `.
108
108
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
+
109
117
.. method :: is_active()
110
118
111
119
Returns ``True `` if more progress can be made and ``False `` otherwise.
Original file line number Diff line number Diff line change @@ -607,6 +607,15 @@ getopt
607
607
* Add support for returning intermixed options and non-option arguments in order.
608
608
(Contributed by Serhiy Storchaka in :gh: `126390 `.)
609
609
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
+
610
619
http
611
620
----
612
621
Original file line number Diff line number Diff line change @@ -90,13 +90,17 @@ def prepare(self):
90
90
still be used to obtain as many nodes as possible until cycles block more
91
91
progress. After a call to this function, the graph cannot be modified and
92
92
therefore no more nodes can be added using "add".
93
+
94
+ Raise ValueError if nodes have already been passed out of the sorter.
95
+
93
96
"""
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 " )
96
99
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
+ ]
100
104
# ready_nodes is set before we look for cycles on purpose:
101
105
# if the user wants to catch the CycleError, that's fine,
102
106
# they can continue using the instance to grab as many
Original file line number Diff line number Diff line change @@ -140,9 +140,21 @@ def test_calls_before_prepare(self):
140
140
def test_prepare_multiple_times (self ):
141
141
ts = graphlib .TopologicalSorter ()
142
142
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" ):
144
150
ts .prepare ()
145
151
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
+
146
158
def test_invalid_nodes_in_done (self ):
147
159
ts = graphlib .TopologicalSorter ()
148
160
ts .add (1 , 2 , 3 , 4 )
Original file line number Diff line number Diff line change @@ -1483,6 +1483,7 @@ Michael Pomraning
1483
1483
Martin Pool
1484
1484
Iustin Pop
1485
1485
Claudiu Popa
1486
+ Daniel Pope
1486
1487
Nick Pope
1487
1488
John Popplewell
1488
1489
Matheus Vieira Portela
Original file line number Diff line number Diff line change
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.
You can’t perform that action at this time.
0 commit comments