File tree Expand file tree Collapse file tree 6 files changed +43
-6
lines changed Expand file tree Collapse file tree 6 files changed +43
-6
lines changed Original file line number Diff line number Diff line change 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.
Original file line number Diff line number Diff 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+
610619http
611620----
612621
Original file line number Diff line number Diff 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
Original file line number Diff line number Diff 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 )
Original file line number Diff line number Diff line change @@ -1483,6 +1483,7 @@ Michael Pomraning
14831483Martin Pool
14841484Iustin Pop
14851485Claudiu Popa
1486+ Daniel Pope
14861487Nick Pope
14871488John Popplewell
14881489Matheus 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