Dear All, in a ticket (#21254) I recently created with Dylan Rupel I need to explore a (possibly) infinite n-regular tree in a breath-first search. The way it is implemented right now is via iterators. I am writing to you to ask if there is a preferred way to deal with user interaction and KeyboardInterrupt.
At the moment the init function of :class:`ClusterAlgebra` calls :meth:`reset_exploring_iterator` that creates an instance of :meth:`seeds` and stores it in an internal var ``_sd_iter``. The methods that need to explore the tree just call ``next`` on this iterator till they get the data they are looking for. This process is potentially never ending. For this reason the user may specify a maximum depth at which to stop. Since this iterator is computationally intense, it easy to imagine that users will tend to start searching but change their mind in mid computation and send an interrupt. This, unfortunately, leaves ``_sd_iter`` in a corrupted state and all future calls to it will result in a StopIteration. At the moment we have a warning in the docstring of each method accessing _sd_iter to explain that after sending a KeyboardInterrupt the user needs to call :meth:`reset_exploring_iterator`. Do you think we should instead catch the interrupt, reset the iterator and then raise it again like this? @@ -1999,12 +1999,17 @@ class ClusterAlgebra(Parent): sage: len(A.g_vectors_so_far()) 14 """ - while self._explored_depth <= depth: - try: - seed = next(self._sd_iter) - self._explored_depth = seed.depth() - except StopIteration: - break + try: + while self._explored_depth <= depth: + try: + seed = next(self._sd_iter) + self._explored_depth = seed.depth() + except StopIteration: + break + except KeyboardInterrupt: + print("Got a KeyboardInterrupt, cleaning up before returning.") + self.reset_exploring_iterator() + raise KeyboardInterrupt The advantage of this is that the user does not have to remember an extra (unnatural?) step. The drawback is that he/she looses any customization that may have been made by a previous call to :meth:`reset_exploring_iterator`. On a related topic. In the situation just described, the next exploration will have to begin from the root of the tree resulting in a lot of wasted effort. Is there any way around this? Sending a node of the tree back to the iterator does not seem useful because of the breath-first search. Thanks S. -- You received this message because you are subscribed to the Google Groups "sage-devel" group. To unsubscribe from this group and stop receiving emails from it, send an email to sage-devel+unsubscr...@googlegroups.com. To post to this group, send email to sage-devel@googlegroups.com. Visit this group at https://groups.google.com/group/sage-devel. For more options, visit https://groups.google.com/d/optout.