Mercurial > repos > bcclaywell > argo_navis
annotate venv/lib/python2.7/site-packages/docutils/statemachine.py @ 0:d67268158946 draft
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
| author | bcclaywell | 
|---|---|
| date | Mon, 12 Oct 2015 17:43:33 -0400 | 
| parents | |
| children | 
| rev | line source | 
|---|---|
| 0 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1 # $Id: statemachine.py 7464 2012-06-25 13:16:03Z milde $ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 2 # Author: David Goodger <goodger@python.org> | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 3 # Copyright: This module has been placed in the public domain. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 4 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 5 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 6 A finite state machine specialized for regular-expression-based text filters, | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 7 this module defines the following classes: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 8 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 9 - `StateMachine`, a state machine | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 10 - `State`, a state superclass | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 11 - `StateMachineWS`, a whitespace-sensitive version of `StateMachine` | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 12 - `StateWS`, a state superclass for use with `StateMachineWS` | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 13 - `SearchStateMachine`, uses `re.search()` instead of `re.match()` | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 14 - `SearchStateMachineWS`, uses `re.search()` instead of `re.match()` | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 15 - `ViewList`, extends standard Python lists. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 16 - `StringList`, string-specific ViewList. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 17 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 18 Exception classes: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 19 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 20 - `StateMachineError` | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 21 - `UnknownStateError` | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 22 - `DuplicateStateError` | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 23 - `UnknownTransitionError` | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 24 - `DuplicateTransitionError` | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 25 - `TransitionPatternNotFound` | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 26 - `TransitionMethodNotFound` | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 27 - `UnexpectedIndentationError` | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 28 - `TransitionCorrection`: Raised to switch to another transition. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 29 - `StateCorrection`: Raised to switch to another state & transition. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 30 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 31 Functions: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 32 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 33 - `string2lines()`: split a multi-line string into a list of one-line strings | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 34 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 35 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 36 How To Use This Module | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 37 ====================== | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 38 (See the individual classes, methods, and attributes for details.) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 39 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 40 1. Import it: ``import statemachine`` or ``from statemachine import ...``. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 41 You will also need to ``import re``. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 42 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 43 2. Derive a subclass of `State` (or `StateWS`) for each state in your state | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 44 machine:: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 45 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 46 class MyState(statemachine.State): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 47 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 48 Within the state's class definition: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 49 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 50 a) Include a pattern for each transition, in `State.patterns`:: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 51 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 52 patterns = {'atransition': r'pattern', ...} | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 53 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 54 b) Include a list of initial transitions to be set up automatically, in | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 55 `State.initial_transitions`:: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 56 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 57 initial_transitions = ['atransition', ...] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 58 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 59 c) Define a method for each transition, with the same name as the | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 60 transition pattern:: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 61 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 62 def atransition(self, match, context, next_state): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 63 # do something | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 64 result = [...] # a list | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 65 return context, next_state, result | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 66 # context, next_state may be altered | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 67 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 68 Transition methods may raise an `EOFError` to cut processing short. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 69 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 70 d) You may wish to override the `State.bof()` and/or `State.eof()` implicit | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 71 transition methods, which handle the beginning- and end-of-file. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 72 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 73 e) In order to handle nested processing, you may wish to override the | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 74 attributes `State.nested_sm` and/or `State.nested_sm_kwargs`. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 75 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 76 If you are using `StateWS` as a base class, in order to handle nested | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 77 indented blocks, you may wish to: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 78 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 79 - override the attributes `StateWS.indent_sm`, | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 80 `StateWS.indent_sm_kwargs`, `StateWS.known_indent_sm`, and/or | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 81 `StateWS.known_indent_sm_kwargs`; | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 82 - override the `StateWS.blank()` method; and/or | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 83 - override or extend the `StateWS.indent()`, `StateWS.known_indent()`, | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 84 and/or `StateWS.firstknown_indent()` methods. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 85 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 86 3. Create a state machine object:: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 87 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 88 sm = StateMachine(state_classes=[MyState, ...], | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 89 initial_state='MyState') | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 90 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 91 4. Obtain the input text, which needs to be converted into a tab-free list of | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 92 one-line strings. For example, to read text from a file called | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 93 'inputfile':: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 94 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 95 input_string = open('inputfile').read() | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 96 input_lines = statemachine.string2lines(input_string) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 97 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 98 5. Run the state machine on the input text and collect the results, a list:: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 99 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 100 results = sm.run(input_lines) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 101 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 102 6. Remove any lingering circular references:: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 103 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 104 sm.unlink() | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 105 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 106 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 107 __docformat__ = 'restructuredtext' | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 108 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 109 import sys | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 110 import re | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 111 import types | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 112 import unicodedata | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 113 from docutils import utils | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 114 from docutils.utils.error_reporting import ErrorOutput | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 115 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 116 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 117 class StateMachine: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 118 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 119 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 120 A finite state machine for text filters using regular expressions. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 121 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 122 The input is provided in the form of a list of one-line strings (no | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 123 newlines). States are subclasses of the `State` class. Transitions consist | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 124 of regular expression patterns and transition methods, and are defined in | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 125 each state. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 126 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 127 The state machine is started with the `run()` method, which returns the | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 128 results of processing in a list. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 129 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 130 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 131 def __init__(self, state_classes, initial_state, debug=False): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 132 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 133 Initialize a `StateMachine` object; add state objects. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 134 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 135 Parameters: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 136 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 137 - `state_classes`: a list of `State` (sub)classes. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 138 - `initial_state`: a string, the class name of the initial state. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 139 - `debug`: a boolean; produce verbose output if true (nonzero). | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 140 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 141 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 142 self.input_lines = None | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 143 """`StringList` of input lines (without newlines). | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 144 Filled by `self.run()`.""" | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 145 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 146 self.input_offset = 0 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 147 """Offset of `self.input_lines` from the beginning of the file.""" | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 148 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 149 self.line = None | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 150 """Current input line.""" | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 151 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 152 self.line_offset = -1 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 153 """Current input line offset from beginning of `self.input_lines`.""" | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 154 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 155 self.debug = debug | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 156 """Debugging mode on/off.""" | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 157 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 158 self.initial_state = initial_state | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 159 """The name of the initial state (key to `self.states`).""" | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 160 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 161 self.current_state = initial_state | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 162 """The name of the current state (key to `self.states`).""" | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 163 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 164 self.states = {} | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 165 """Mapping of {state_name: State_object}.""" | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 166 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 167 self.add_states(state_classes) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 168 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 169 self.observers = [] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 170 """List of bound methods or functions to call whenever the current | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 171 line changes. Observers are called with one argument, ``self``. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 172 Cleared at the end of `run()`.""" | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 173 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 174 self._stderr = ErrorOutput() | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 175 """Wrapper around sys.stderr catching en-/decoding errors""" | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 176 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 177 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 178 def unlink(self): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 179 """Remove circular references to objects no longer required.""" | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 180 for state in self.states.values(): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 181 state.unlink() | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 182 self.states = None | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 183 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 184 def run(self, input_lines, input_offset=0, context=None, | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 185 input_source=None, initial_state=None): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 186 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 187 Run the state machine on `input_lines`. Return results (a list). | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 188 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 189 Reset `self.line_offset` and `self.current_state`. Run the | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 190 beginning-of-file transition. Input one line at a time and check for a | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 191 matching transition. If a match is found, call the transition method | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 192 and possibly change the state. Store the context returned by the | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 193 transition method to be passed on to the next transition matched. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 194 Accumulate the results returned by the transition methods in a list. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 195 Run the end-of-file transition. Finally, return the accumulated | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 196 results. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 197 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 198 Parameters: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 199 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 200 - `input_lines`: a list of strings without newlines, or `StringList`. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 201 - `input_offset`: the line offset of `input_lines` from the beginning | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 202 of the file. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 203 - `context`: application-specific storage. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 204 - `input_source`: name or path of source of `input_lines`. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 205 - `initial_state`: name of initial state. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 206 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 207 self.runtime_init() | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 208 if isinstance(input_lines, StringList): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 209 self.input_lines = input_lines | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 210 else: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 211 self.input_lines = StringList(input_lines, source=input_source) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 212 self.input_offset = input_offset | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 213 self.line_offset = -1 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 214 self.current_state = initial_state or self.initial_state | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 215 if self.debug: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 216 print >>self._stderr, ( | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 217 u'\nStateMachine.run: input_lines (line_offset=%s):\n| %s' | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 218 % (self.line_offset, u'\n| '.join(self.input_lines))) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 219 transitions = None | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 220 results = [] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 221 state = self.get_state() | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 222 try: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 223 if self.debug: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 224 print >>self._stderr, '\nStateMachine.run: bof transition' | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 225 context, result = state.bof(context) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 226 results.extend(result) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 227 while True: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 228 try: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 229 try: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 230 self.next_line() | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 231 if self.debug: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 232 source, offset = self.input_lines.info( | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 233 self.line_offset) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 234 print >>self._stderr, ( | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 235 u'\nStateMachine.run: line (source=%r, ' | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 236 u'offset=%r):\n| %s' | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 237 % (source, offset, self.line)) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 238 context, next_state, result = self.check_line( | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 239 context, state, transitions) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 240 except EOFError: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 241 if self.debug: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 242 print >>self._stderr, ( | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 243 '\nStateMachine.run: %s.eof transition' | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 244 % state.__class__.__name__) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 245 result = state.eof(context) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 246 results.extend(result) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 247 break | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 248 else: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 249 results.extend(result) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 250 except TransitionCorrection, exception: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 251 self.previous_line() # back up for another try | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 252 transitions = (exception.args[0],) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 253 if self.debug: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 254 print >>self._stderr, ( | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 255 '\nStateMachine.run: TransitionCorrection to ' | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 256 'state "%s", transition %s.' | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 257 % (state.__class__.__name__, transitions[0])) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 258 continue | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 259 except StateCorrection, exception: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 260 self.previous_line() # back up for another try | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 261 next_state = exception.args[0] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 262 if len(exception.args) == 1: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 263 transitions = None | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 264 else: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 265 transitions = (exception.args[1],) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 266 if self.debug: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 267 print >>self._stderr, ( | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 268 '\nStateMachine.run: StateCorrection to state ' | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 269 '"%s", transition %s.' | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 270 % (next_state, transitions[0])) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 271 else: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 272 transitions = None | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 273 state = self.get_state(next_state) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 274 except: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 275 if self.debug: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 276 self.error() | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 277 raise | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 278 self.observers = [] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 279 return results | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 280 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 281 def get_state(self, next_state=None): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 282 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 283 Return current state object; set it first if `next_state` given. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 284 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 285 Parameter `next_state`: a string, the name of the next state. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 286 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 287 Exception: `UnknownStateError` raised if `next_state` unknown. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 288 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 289 if next_state: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 290 if self.debug and next_state != self.current_state: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 291 print >>self._stderr, ( | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 292 '\nStateMachine.get_state: Changing state from ' | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 293 '"%s" to "%s" (input line %s).' | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 294 % (self.current_state, next_state, | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 295 self.abs_line_number())) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 296 self.current_state = next_state | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 297 try: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 298 return self.states[self.current_state] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 299 except KeyError: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 300 raise UnknownStateError(self.current_state) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 301 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 302 def next_line(self, n=1): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 303 """Load `self.line` with the `n`'th next line and return it.""" | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 304 try: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 305 try: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 306 self.line_offset += n | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 307 self.line = self.input_lines[self.line_offset] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 308 except IndexError: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 309 self.line = None | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 310 raise EOFError | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 311 return self.line | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 312 finally: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 313 self.notify_observers() | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 314 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 315 def is_next_line_blank(self): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 316 """Return 1 if the next line is blank or non-existant.""" | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 317 try: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 318 return not self.input_lines[self.line_offset + 1].strip() | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 319 except IndexError: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 320 return 1 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 321 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 322 def at_eof(self): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 323 """Return 1 if the input is at or past end-of-file.""" | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 324 return self.line_offset >= len(self.input_lines) - 1 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 325 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 326 def at_bof(self): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 327 """Return 1 if the input is at or before beginning-of-file.""" | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 328 return self.line_offset <= 0 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 329 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 330 def previous_line(self, n=1): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 331 """Load `self.line` with the `n`'th previous line and return it.""" | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 332 self.line_offset -= n | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 333 if self.line_offset < 0: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 334 self.line = None | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 335 else: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 336 self.line = self.input_lines[self.line_offset] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 337 self.notify_observers() | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 338 return self.line | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 339 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 340 def goto_line(self, line_offset): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 341 """Jump to absolute line offset `line_offset`, load and return it.""" | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 342 try: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 343 try: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 344 self.line_offset = line_offset - self.input_offset | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 345 self.line = self.input_lines[self.line_offset] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 346 except IndexError: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 347 self.line = None | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 348 raise EOFError | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 349 return self.line | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 350 finally: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 351 self.notify_observers() | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 352 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 353 def get_source(self, line_offset): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 354 """Return source of line at absolute line offset `line_offset`.""" | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 355 return self.input_lines.source(line_offset - self.input_offset) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 356 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 357 def abs_line_offset(self): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 358 """Return line offset of current line, from beginning of file.""" | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 359 return self.line_offset + self.input_offset | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 360 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 361 def abs_line_number(self): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 362 """Return line number of current line (counting from 1).""" | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 363 return self.line_offset + self.input_offset + 1 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 364 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 365 def get_source_and_line(self, lineno=None): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 366 """Return (source, line) tuple for current or given line number. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 367 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 368 Looks up the source and line number in the `self.input_lines` | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 369 StringList instance to count for included source files. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 370 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 371 If the optional argument `lineno` is given, convert it from an | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 372 absolute line number to the corresponding (source, line) pair. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 373 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 374 if lineno is None: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 375 offset = self.line_offset | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 376 else: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 377 offset = lineno - self.input_offset - 1 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 378 try: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 379 src, srcoffset = self.input_lines.info(offset) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 380 srcline = srcoffset + 1 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 381 except (TypeError): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 382 # line is None if index is "Just past the end" | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 383 src, srcline = self.get_source_and_line(offset + self.input_offset) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 384 return src, srcline + 1 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 385 except (IndexError): # `offset` is off the list | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 386 src, srcline = None, None | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 387 # raise AssertionError('cannot find line %d in %s lines' % | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 388 # (offset, len(self.input_lines))) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 389 # # list(self.input_lines.lines()))) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 390 # assert offset == srcoffset, str(self.input_lines) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 391 # print "get_source_and_line(%s):" % lineno, | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 392 # print offset + 1, '->', src, srcline | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 393 # print self.input_lines | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 394 return (src, srcline) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 395 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 396 def insert_input(self, input_lines, source): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 397 self.input_lines.insert(self.line_offset + 1, '', | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 398 source='internal padding after '+source, | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 399 offset=len(input_lines)) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 400 self.input_lines.insert(self.line_offset + 1, '', | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 401 source='internal padding before '+source, | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 402 offset=-1) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 403 self.input_lines.insert(self.line_offset + 2, | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 404 StringList(input_lines, source)) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 405 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 406 def get_text_block(self, flush_left=False): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 407 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 408 Return a contiguous block of text. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 409 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 410 If `flush_left` is true, raise `UnexpectedIndentationError` if an | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 411 indented line is encountered before the text block ends (with a blank | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 412 line). | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 413 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 414 try: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 415 block = self.input_lines.get_text_block(self.line_offset, | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 416 flush_left) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 417 self.next_line(len(block) - 1) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 418 return block | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 419 except UnexpectedIndentationError, err: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 420 block = err.args[0] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 421 self.next_line(len(block) - 1) # advance to last line of block | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 422 raise | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 423 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 424 def check_line(self, context, state, transitions=None): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 425 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 426 Examine one line of input for a transition match & execute its method. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 427 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 428 Parameters: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 429 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 430 - `context`: application-dependent storage. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 431 - `state`: a `State` object, the current state. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 432 - `transitions`: an optional ordered list of transition names to try, | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 433 instead of ``state.transition_order``. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 434 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 435 Return the values returned by the transition method: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 436 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 437 - context: possibly modified from the parameter `context`; | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 438 - next state name (`State` subclass name); | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 439 - the result output of the transition, a list. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 440 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 441 When there is no match, ``state.no_match()`` is called and its return | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 442 value is returned. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 443 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 444 if transitions is None: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 445 transitions = state.transition_order | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 446 state_correction = None | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 447 if self.debug: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 448 print >>self._stderr, ( | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 449 '\nStateMachine.check_line: state="%s", transitions=%r.' | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 450 % (state.__class__.__name__, transitions)) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 451 for name in transitions: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 452 pattern, method, next_state = state.transitions[name] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 453 match = pattern.match(self.line) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 454 if match: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 455 if self.debug: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 456 print >>self._stderr, ( | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 457 '\nStateMachine.check_line: Matched transition ' | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 458 '"%s" in state "%s".' | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 459 % (name, state.__class__.__name__)) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 460 return method(match, context, next_state) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 461 else: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 462 if self.debug: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 463 print >>self._stderr, ( | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 464 '\nStateMachine.check_line: No match in state "%s".' | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 465 % state.__class__.__name__) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 466 return state.no_match(context, transitions) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 467 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 468 def add_state(self, state_class): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 469 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 470 Initialize & add a `state_class` (`State` subclass) object. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 471 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 472 Exception: `DuplicateStateError` raised if `state_class` was already | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 473 added. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 474 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 475 statename = state_class.__name__ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 476 if statename in self.states: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 477 raise DuplicateStateError(statename) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 478 self.states[statename] = state_class(self, self.debug) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 479 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 480 def add_states(self, state_classes): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 481 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 482 Add `state_classes` (a list of `State` subclasses). | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 483 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 484 for state_class in state_classes: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 485 self.add_state(state_class) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 486 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 487 def runtime_init(self): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 488 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 489 Initialize `self.states`. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 490 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 491 for state in self.states.values(): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 492 state.runtime_init() | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 493 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 494 def error(self): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 495 """Report error details.""" | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 496 type, value, module, line, function = _exception_data() | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 497 print >>self._stderr, u'%s: %s' % (type, value) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 498 print >>self._stderr, 'input line %s' % (self.abs_line_number()) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 499 print >>self._stderr, (u'module %s, line %s, function %s' % | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 500 (module, line, function)) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 501 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 502 def attach_observer(self, observer): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 503 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 504 The `observer` parameter is a function or bound method which takes two | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 505 arguments, the source and offset of the current line. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 506 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 507 self.observers.append(observer) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 508 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 509 def detach_observer(self, observer): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 510 self.observers.remove(observer) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 511 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 512 def notify_observers(self): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 513 for observer in self.observers: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 514 try: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 515 info = self.input_lines.info(self.line_offset) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 516 except IndexError: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 517 info = (None, None) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 518 observer(*info) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 519 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 520 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 521 class State: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 522 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 523 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 524 State superclass. Contains a list of transitions, and transition methods. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 525 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 526 Transition methods all have the same signature. They take 3 parameters: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 527 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 528 - An `re` match object. ``match.string`` contains the matched input line, | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 529 ``match.start()`` gives the start index of the match, and | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 530 ``match.end()`` gives the end index. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 531 - A context object, whose meaning is application-defined (initial value | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 532 ``None``). It can be used to store any information required by the state | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 533 machine, and the retured context is passed on to the next transition | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 534 method unchanged. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 535 - The name of the next state, a string, taken from the transitions list; | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 536 normally it is returned unchanged, but it may be altered by the | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 537 transition method if necessary. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 538 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 539 Transition methods all return a 3-tuple: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 540 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 541 - A context object, as (potentially) modified by the transition method. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 542 - The next state name (a return value of ``None`` means no state change). | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 543 - The processing result, a list, which is accumulated by the state | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 544 machine. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 545 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 546 Transition methods may raise an `EOFError` to cut processing short. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 547 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 548 There are two implicit transitions, and corresponding transition methods | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 549 are defined: `bof()` handles the beginning-of-file, and `eof()` handles | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 550 the end-of-file. These methods have non-standard signatures and return | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 551 values. `bof()` returns the initial context and results, and may be used | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 552 to return a header string, or do any other processing needed. `eof()` | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 553 should handle any remaining context and wrap things up; it returns the | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 554 final processing result. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 555 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 556 Typical applications need only subclass `State` (or a subclass), set the | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 557 `patterns` and `initial_transitions` class attributes, and provide | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 558 corresponding transition methods. The default object initialization will | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 559 take care of constructing the list of transitions. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 560 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 561 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 562 patterns = None | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 563 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 564 {Name: pattern} mapping, used by `make_transition()`. Each pattern may | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 565 be a string or a compiled `re` pattern. Override in subclasses. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 566 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 567 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 568 initial_transitions = None | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 569 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 570 A list of transitions to initialize when a `State` is instantiated. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 571 Each entry is either a transition name string, or a (transition name, next | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 572 state name) pair. See `make_transitions()`. Override in subclasses. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 573 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 574 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 575 nested_sm = None | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 576 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 577 The `StateMachine` class for handling nested processing. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 578 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 579 If left as ``None``, `nested_sm` defaults to the class of the state's | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 580 controlling state machine. Override it in subclasses to avoid the default. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 581 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 582 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 583 nested_sm_kwargs = None | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 584 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 585 Keyword arguments dictionary, passed to the `nested_sm` constructor. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 586 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 587 Two keys must have entries in the dictionary: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 588 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 589 - Key 'state_classes' must be set to a list of `State` classes. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 590 - Key 'initial_state' must be set to the name of the initial state class. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 591 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 592 If `nested_sm_kwargs` is left as ``None``, 'state_classes' defaults to the | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 593 class of the current state, and 'initial_state' defaults to the name of | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 594 the class of the current state. Override in subclasses to avoid the | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 595 defaults. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 596 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 597 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 598 def __init__(self, state_machine, debug=False): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 599 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 600 Initialize a `State` object; make & add initial transitions. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 601 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 602 Parameters: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 603 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 604 - `statemachine`: the controlling `StateMachine` object. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 605 - `debug`: a boolean; produce verbose output if true. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 606 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 607 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 608 self.transition_order = [] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 609 """A list of transition names in search order.""" | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 610 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 611 self.transitions = {} | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 612 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 613 A mapping of transition names to 3-tuples containing | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 614 (compiled_pattern, transition_method, next_state_name). Initialized as | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 615 an instance attribute dynamically (instead of as a class attribute) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 616 because it may make forward references to patterns and methods in this | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 617 or other classes. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 618 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 619 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 620 self.add_initial_transitions() | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 621 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 622 self.state_machine = state_machine | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 623 """A reference to the controlling `StateMachine` object.""" | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 624 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 625 self.debug = debug | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 626 """Debugging mode on/off.""" | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 627 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 628 if self.nested_sm is None: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 629 self.nested_sm = self.state_machine.__class__ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 630 if self.nested_sm_kwargs is None: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 631 self.nested_sm_kwargs = {'state_classes': [self.__class__], | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 632 'initial_state': self.__class__.__name__} | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 633 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 634 def runtime_init(self): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 635 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 636 Initialize this `State` before running the state machine; called from | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 637 `self.state_machine.run()`. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 638 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 639 pass | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 640 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 641 def unlink(self): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 642 """Remove circular references to objects no longer required.""" | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 643 self.state_machine = None | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 644 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 645 def add_initial_transitions(self): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 646 """Make and add transitions listed in `self.initial_transitions`.""" | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 647 if self.initial_transitions: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 648 names, transitions = self.make_transitions( | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 649 self.initial_transitions) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 650 self.add_transitions(names, transitions) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 651 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 652 def add_transitions(self, names, transitions): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 653 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 654 Add a list of transitions to the start of the transition list. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 655 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 656 Parameters: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 657 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 658 - `names`: a list of transition names. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 659 - `transitions`: a mapping of names to transition tuples. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 660 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 661 Exceptions: `DuplicateTransitionError`, `UnknownTransitionError`. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 662 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 663 for name in names: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 664 if name in self.transitions: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 665 raise DuplicateTransitionError(name) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 666 if name not in transitions: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 667 raise UnknownTransitionError(name) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 668 self.transition_order[:0] = names | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 669 self.transitions.update(transitions) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 670 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 671 def add_transition(self, name, transition): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 672 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 673 Add a transition to the start of the transition list. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 674 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 675 Parameter `transition`: a ready-made transition 3-tuple. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 676 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 677 Exception: `DuplicateTransitionError`. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 678 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 679 if name in self.transitions: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 680 raise DuplicateTransitionError(name) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 681 self.transition_order[:0] = [name] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 682 self.transitions[name] = transition | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 683 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 684 def remove_transition(self, name): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 685 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 686 Remove a transition by `name`. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 687 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 688 Exception: `UnknownTransitionError`. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 689 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 690 try: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 691 del self.transitions[name] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 692 self.transition_order.remove(name) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 693 except: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 694 raise UnknownTransitionError(name) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 695 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 696 def make_transition(self, name, next_state=None): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 697 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 698 Make & return a transition tuple based on `name`. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 699 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 700 This is a convenience function to simplify transition creation. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 701 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 702 Parameters: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 703 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 704 - `name`: a string, the name of the transition pattern & method. This | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 705 `State` object must have a method called '`name`', and a dictionary | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 706 `self.patterns` containing a key '`name`'. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 707 - `next_state`: a string, the name of the next `State` object for this | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 708 transition. A value of ``None`` (or absent) implies no state change | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 709 (i.e., continue with the same state). | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 710 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 711 Exceptions: `TransitionPatternNotFound`, `TransitionMethodNotFound`. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 712 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 713 if next_state is None: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 714 next_state = self.__class__.__name__ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 715 try: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 716 pattern = self.patterns[name] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 717 if not hasattr(pattern, 'match'): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 718 pattern = re.compile(pattern) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 719 except KeyError: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 720 raise TransitionPatternNotFound( | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 721 '%s.patterns[%r]' % (self.__class__.__name__, name)) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 722 try: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 723 method = getattr(self, name) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 724 except AttributeError: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 725 raise TransitionMethodNotFound( | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 726 '%s.%s' % (self.__class__.__name__, name)) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 727 return (pattern, method, next_state) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 728 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 729 def make_transitions(self, name_list): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 730 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 731 Return a list of transition names and a transition mapping. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 732 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 733 Parameter `name_list`: a list, where each entry is either a transition | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 734 name string, or a 1- or 2-tuple (transition name, optional next state | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 735 name). | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 736 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 737 stringtype = type('') | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 738 names = [] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 739 transitions = {} | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 740 for namestate in name_list: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 741 if type(namestate) is stringtype: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 742 transitions[namestate] = self.make_transition(namestate) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 743 names.append(namestate) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 744 else: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 745 transitions[namestate[0]] = self.make_transition(*namestate) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 746 names.append(namestate[0]) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 747 return names, transitions | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 748 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 749 def no_match(self, context, transitions): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 750 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 751 Called when there is no match from `StateMachine.check_line()`. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 752 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 753 Return the same values returned by transition methods: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 754 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 755 - context: unchanged; | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 756 - next state name: ``None``; | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 757 - empty result list. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 758 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 759 Override in subclasses to catch this event. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 760 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 761 return context, None, [] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 762 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 763 def bof(self, context): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 764 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 765 Handle beginning-of-file. Return unchanged `context`, empty result. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 766 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 767 Override in subclasses. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 768 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 769 Parameter `context`: application-defined storage. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 770 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 771 return context, [] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 772 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 773 def eof(self, context): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 774 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 775 Handle end-of-file. Return empty result. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 776 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 777 Override in subclasses. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 778 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 779 Parameter `context`: application-defined storage. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 780 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 781 return [] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 782 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 783 def nop(self, match, context, next_state): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 784 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 785 A "do nothing" transition method. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 786 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 787 Return unchanged `context` & `next_state`, empty result. Useful for | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 788 simple state changes (actionless transitions). | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 789 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 790 return context, next_state, [] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 791 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 792 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 793 class StateMachineWS(StateMachine): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 794 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 795 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 796 `StateMachine` subclass specialized for whitespace recognition. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 797 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 798 There are three methods provided for extracting indented text blocks: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 799 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 800 - `get_indented()`: use when the indent is unknown. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 801 - `get_known_indented()`: use when the indent is known for all lines. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 802 - `get_first_known_indented()`: use when only the first line's indent is | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 803 known. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 804 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 805 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 806 def get_indented(self, until_blank=False, strip_indent=True): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 807 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 808 Return a block of indented lines of text, and info. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 809 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 810 Extract an indented block where the indent is unknown for all lines. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 811 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 812 :Parameters: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 813 - `until_blank`: Stop collecting at the first blank line if true. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 814 - `strip_indent`: Strip common leading indent if true (default). | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 815 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 816 :Return: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 817 - the indented block (a list of lines of text), | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 818 - its indent, | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 819 - its first line offset from BOF, and | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 820 - whether or not it finished with a blank line. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 821 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 822 offset = self.abs_line_offset() | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 823 indented, indent, blank_finish = self.input_lines.get_indented( | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 824 self.line_offset, until_blank, strip_indent) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 825 if indented: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 826 self.next_line(len(indented) - 1) # advance to last indented line | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 827 while indented and not indented[0].strip(): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 828 indented.trim_start() | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 829 offset += 1 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 830 return indented, indent, offset, blank_finish | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 831 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 832 def get_known_indented(self, indent, until_blank=False, strip_indent=True): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 833 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 834 Return an indented block and info. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 835 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 836 Extract an indented block where the indent is known for all lines. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 837 Starting with the current line, extract the entire text block with at | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 838 least `indent` indentation (which must be whitespace, except for the | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 839 first line). | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 840 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 841 :Parameters: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 842 - `indent`: The number of indent columns/characters. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 843 - `until_blank`: Stop collecting at the first blank line if true. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 844 - `strip_indent`: Strip `indent` characters of indentation if true | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 845 (default). | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 846 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 847 :Return: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 848 - the indented block, | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 849 - its first line offset from BOF, and | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 850 - whether or not it finished with a blank line. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 851 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 852 offset = self.abs_line_offset() | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 853 indented, indent, blank_finish = self.input_lines.get_indented( | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 854 self.line_offset, until_blank, strip_indent, | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 855 block_indent=indent) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 856 self.next_line(len(indented) - 1) # advance to last indented line | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 857 while indented and not indented[0].strip(): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 858 indented.trim_start() | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 859 offset += 1 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 860 return indented, offset, blank_finish | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 861 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 862 def get_first_known_indented(self, indent, until_blank=False, | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 863 strip_indent=True, strip_top=True): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 864 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 865 Return an indented block and info. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 866 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 867 Extract an indented block where the indent is known for the first line | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 868 and unknown for all other lines. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 869 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 870 :Parameters: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 871 - `indent`: The first line's indent (# of columns/characters). | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 872 - `until_blank`: Stop collecting at the first blank line if true | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 873 (1). | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 874 - `strip_indent`: Strip `indent` characters of indentation if true | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 875 (1, default). | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 876 - `strip_top`: Strip blank lines from the beginning of the block. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 877 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 878 :Return: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 879 - the indented block, | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 880 - its indent, | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 881 - its first line offset from BOF, and | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 882 - whether or not it finished with a blank line. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 883 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 884 offset = self.abs_line_offset() | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 885 indented, indent, blank_finish = self.input_lines.get_indented( | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 886 self.line_offset, until_blank, strip_indent, | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 887 first_indent=indent) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 888 self.next_line(len(indented) - 1) # advance to last indented line | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 889 if strip_top: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 890 while indented and not indented[0].strip(): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 891 indented.trim_start() | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 892 offset += 1 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 893 return indented, indent, offset, blank_finish | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 894 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 895 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 896 class StateWS(State): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 897 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 898 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 899 State superclass specialized for whitespace (blank lines & indents). | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 900 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 901 Use this class with `StateMachineWS`. The transitions 'blank' (for blank | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 902 lines) and 'indent' (for indented text blocks) are added automatically, | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 903 before any other transitions. The transition method `blank()` handles | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 904 blank lines and `indent()` handles nested indented blocks. Indented | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 905 blocks trigger a new state machine to be created by `indent()` and run. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 906 The class of the state machine to be created is in `indent_sm`, and the | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 907 constructor keyword arguments are in the dictionary `indent_sm_kwargs`. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 908 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 909 The methods `known_indent()` and `firstknown_indent()` are provided for | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 910 indented blocks where the indent (all lines' and first line's only, | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 911 respectively) is known to the transition method, along with the attributes | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 912 `known_indent_sm` and `known_indent_sm_kwargs`. Neither transition method | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 913 is triggered automatically. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 914 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 915 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 916 indent_sm = None | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 917 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 918 The `StateMachine` class handling indented text blocks. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 919 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 920 If left as ``None``, `indent_sm` defaults to the value of | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 921 `State.nested_sm`. Override it in subclasses to avoid the default. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 922 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 923 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 924 indent_sm_kwargs = None | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 925 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 926 Keyword arguments dictionary, passed to the `indent_sm` constructor. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 927 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 928 If left as ``None``, `indent_sm_kwargs` defaults to the value of | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 929 `State.nested_sm_kwargs`. Override it in subclasses to avoid the default. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 930 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 931 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 932 known_indent_sm = None | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 933 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 934 The `StateMachine` class handling known-indented text blocks. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 935 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 936 If left as ``None``, `known_indent_sm` defaults to the value of | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 937 `indent_sm`. Override it in subclasses to avoid the default. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 938 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 939 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 940 known_indent_sm_kwargs = None | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 941 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 942 Keyword arguments dictionary, passed to the `known_indent_sm` constructor. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 943 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 944 If left as ``None``, `known_indent_sm_kwargs` defaults to the value of | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 945 `indent_sm_kwargs`. Override it in subclasses to avoid the default. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 946 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 947 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 948 ws_patterns = {'blank': ' *$', | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 949 'indent': ' +'} | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 950 """Patterns for default whitespace transitions. May be overridden in | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 951 subclasses.""" | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 952 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 953 ws_initial_transitions = ('blank', 'indent') | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 954 """Default initial whitespace transitions, added before those listed in | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 955 `State.initial_transitions`. May be overridden in subclasses.""" | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 956 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 957 def __init__(self, state_machine, debug=False): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 958 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 959 Initialize a `StateSM` object; extends `State.__init__()`. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 960 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 961 Check for indent state machine attributes, set defaults if not set. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 962 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 963 State.__init__(self, state_machine, debug) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 964 if self.indent_sm is None: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 965 self.indent_sm = self.nested_sm | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 966 if self.indent_sm_kwargs is None: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 967 self.indent_sm_kwargs = self.nested_sm_kwargs | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 968 if self.known_indent_sm is None: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 969 self.known_indent_sm = self.indent_sm | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 970 if self.known_indent_sm_kwargs is None: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 971 self.known_indent_sm_kwargs = self.indent_sm_kwargs | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 972 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 973 def add_initial_transitions(self): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 974 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 975 Add whitespace-specific transitions before those defined in subclass. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 976 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 977 Extends `State.add_initial_transitions()`. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 978 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 979 State.add_initial_transitions(self) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 980 if self.patterns is None: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 981 self.patterns = {} | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 982 self.patterns.update(self.ws_patterns) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 983 names, transitions = self.make_transitions( | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 984 self.ws_initial_transitions) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 985 self.add_transitions(names, transitions) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 986 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 987 def blank(self, match, context, next_state): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 988 """Handle blank lines. Does nothing. Override in subclasses.""" | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 989 return self.nop(match, context, next_state) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 990 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 991 def indent(self, match, context, next_state): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 992 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 993 Handle an indented text block. Extend or override in subclasses. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 994 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 995 Recursively run the registered state machine for indented blocks | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 996 (`self.indent_sm`). | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 997 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 998 indented, indent, line_offset, blank_finish = \ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 999 self.state_machine.get_indented() | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1000 sm = self.indent_sm(debug=self.debug, **self.indent_sm_kwargs) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1001 results = sm.run(indented, input_offset=line_offset) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1002 return context, next_state, results | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1003 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1004 def known_indent(self, match, context, next_state): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1005 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1006 Handle a known-indent text block. Extend or override in subclasses. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1007 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1008 Recursively run the registered state machine for known-indent indented | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1009 blocks (`self.known_indent_sm`). The indent is the length of the | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1010 match, ``match.end()``. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1011 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1012 indented, line_offset, blank_finish = \ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1013 self.state_machine.get_known_indented(match.end()) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1014 sm = self.known_indent_sm(debug=self.debug, | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1015 **self.known_indent_sm_kwargs) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1016 results = sm.run(indented, input_offset=line_offset) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1017 return context, next_state, results | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1018 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1019 def first_known_indent(self, match, context, next_state): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1020 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1021 Handle an indented text block (first line's indent known). | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1022 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1023 Extend or override in subclasses. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1024 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1025 Recursively run the registered state machine for known-indent indented | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1026 blocks (`self.known_indent_sm`). The indent is the length of the | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1027 match, ``match.end()``. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1028 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1029 indented, line_offset, blank_finish = \ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1030 self.state_machine.get_first_known_indented(match.end()) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1031 sm = self.known_indent_sm(debug=self.debug, | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1032 **self.known_indent_sm_kwargs) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1033 results = sm.run(indented, input_offset=line_offset) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1034 return context, next_state, results | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1035 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1036 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1037 class _SearchOverride: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1038 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1039 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1040 Mix-in class to override `StateMachine` regular expression behavior. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1041 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1042 Changes regular expression matching, from the default `re.match()` | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1043 (succeeds only if the pattern matches at the start of `self.line`) to | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1044 `re.search()` (succeeds if the pattern matches anywhere in `self.line`). | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1045 When subclassing a `StateMachine`, list this class **first** in the | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1046 inheritance list of the class definition. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1047 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1048 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1049 def match(self, pattern): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1050 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1051 Return the result of a regular expression search. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1052 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1053 Overrides `StateMachine.match()`. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1054 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1055 Parameter `pattern`: `re` compiled regular expression. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1056 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1057 return pattern.search(self.line) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1058 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1059 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1060 class SearchStateMachine(_SearchOverride, StateMachine): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1061 """`StateMachine` which uses `re.search()` instead of `re.match()`.""" | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1062 pass | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1063 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1064 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1065 class SearchStateMachineWS(_SearchOverride, StateMachineWS): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1066 """`StateMachineWS` which uses `re.search()` instead of `re.match()`.""" | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1067 pass | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1068 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1069 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1070 class ViewList: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1071 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1072 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1073 List with extended functionality: slices of ViewList objects are child | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1074 lists, linked to their parents. Changes made to a child list also affect | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1075 the parent list. A child list is effectively a "view" (in the SQL sense) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1076 of the parent list. Changes to parent lists, however, do *not* affect | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1077 active child lists. If a parent list is changed, any active child lists | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1078 should be recreated. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1079 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1080 The start and end of the slice can be trimmed using the `trim_start()` and | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1081 `trim_end()` methods, without affecting the parent list. The link between | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1082 child and parent lists can be broken by calling `disconnect()` on the | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1083 child list. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1084 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1085 Also, ViewList objects keep track of the source & offset of each item. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1086 This information is accessible via the `source()`, `offset()`, and | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1087 `info()` methods. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1088 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1089 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1090 def __init__(self, initlist=None, source=None, items=None, | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1091 parent=None, parent_offset=None): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1092 self.data = [] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1093 """The actual list of data, flattened from various sources.""" | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1094 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1095 self.items = [] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1096 """A list of (source, offset) pairs, same length as `self.data`: the | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1097 source of each line and the offset of each line from the beginning of | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1098 its source.""" | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1099 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1100 self.parent = parent | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1101 """The parent list.""" | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1102 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1103 self.parent_offset = parent_offset | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1104 """Offset of this list from the beginning of the parent list.""" | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1105 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1106 if isinstance(initlist, ViewList): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1107 self.data = initlist.data[:] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1108 self.items = initlist.items[:] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1109 elif initlist is not None: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1110 self.data = list(initlist) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1111 if items: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1112 self.items = items | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1113 else: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1114 self.items = [(source, i) for i in range(len(initlist))] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1115 assert len(self.data) == len(self.items), 'data mismatch' | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1116 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1117 def __str__(self): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1118 return str(self.data) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1119 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1120 def __repr__(self): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1121 return '%s(%s, items=%s)' % (self.__class__.__name__, | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1122 self.data, self.items) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1123 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1124 def __lt__(self, other): return self.data < self.__cast(other) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1125 def __le__(self, other): return self.data <= self.__cast(other) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1126 def __eq__(self, other): return self.data == self.__cast(other) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1127 def __ne__(self, other): return self.data != self.__cast(other) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1128 def __gt__(self, other): return self.data > self.__cast(other) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1129 def __ge__(self, other): return self.data >= self.__cast(other) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1130 def __cmp__(self, other): return cmp(self.data, self.__cast(other)) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1131 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1132 def __cast(self, other): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1133 if isinstance(other, ViewList): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1134 return other.data | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1135 else: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1136 return other | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1137 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1138 def __contains__(self, item): return item in self.data | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1139 def __len__(self): return len(self.data) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1140 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1141 # The __getitem__()/__setitem__() methods check whether the index | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1142 # is a slice first, since indexing a native list with a slice object | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1143 # just works. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1144 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1145 def __getitem__(self, i): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1146 if isinstance(i, types.SliceType): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1147 assert i.step in (None, 1), 'cannot handle slice with stride' | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1148 return self.__class__(self.data[i.start:i.stop], | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1149 items=self.items[i.start:i.stop], | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1150 parent=self, parent_offset=i.start or 0) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1151 else: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1152 return self.data[i] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1153 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1154 def __setitem__(self, i, item): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1155 if isinstance(i, types.SliceType): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1156 assert i.step in (None, 1), 'cannot handle slice with stride' | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1157 if not isinstance(item, ViewList): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1158 raise TypeError('assigning non-ViewList to ViewList slice') | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1159 self.data[i.start:i.stop] = item.data | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1160 self.items[i.start:i.stop] = item.items | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1161 assert len(self.data) == len(self.items), 'data mismatch' | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1162 if self.parent: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1163 self.parent[(i.start or 0) + self.parent_offset | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1164 : (i.stop or len(self)) + self.parent_offset] = item | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1165 else: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1166 self.data[i] = item | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1167 if self.parent: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1168 self.parent[i + self.parent_offset] = item | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1169 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1170 def __delitem__(self, i): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1171 try: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1172 del self.data[i] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1173 del self.items[i] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1174 if self.parent: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1175 del self.parent[i + self.parent_offset] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1176 except TypeError: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1177 assert i.step is None, 'cannot handle slice with stride' | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1178 del self.data[i.start:i.stop] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1179 del self.items[i.start:i.stop] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1180 if self.parent: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1181 del self.parent[(i.start or 0) + self.parent_offset | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1182 : (i.stop or len(self)) + self.parent_offset] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1183 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1184 def __add__(self, other): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1185 if isinstance(other, ViewList): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1186 return self.__class__(self.data + other.data, | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1187 items=(self.items + other.items)) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1188 else: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1189 raise TypeError('adding non-ViewList to a ViewList') | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1190 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1191 def __radd__(self, other): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1192 if isinstance(other, ViewList): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1193 return self.__class__(other.data + self.data, | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1194 items=(other.items + self.items)) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1195 else: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1196 raise TypeError('adding ViewList to a non-ViewList') | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1197 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1198 def __iadd__(self, other): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1199 if isinstance(other, ViewList): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1200 self.data += other.data | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1201 else: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1202 raise TypeError('argument to += must be a ViewList') | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1203 return self | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1204 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1205 def __mul__(self, n): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1206 return self.__class__(self.data * n, items=(self.items * n)) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1207 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1208 __rmul__ = __mul__ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1209 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1210 def __imul__(self, n): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1211 self.data *= n | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1212 self.items *= n | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1213 return self | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1214 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1215 def extend(self, other): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1216 if not isinstance(other, ViewList): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1217 raise TypeError('extending a ViewList with a non-ViewList') | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1218 if self.parent: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1219 self.parent.insert(len(self.data) + self.parent_offset, other) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1220 self.data.extend(other.data) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1221 self.items.extend(other.items) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1222 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1223 def append(self, item, source=None, offset=0): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1224 if source is None: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1225 self.extend(item) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1226 else: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1227 if self.parent: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1228 self.parent.insert(len(self.data) + self.parent_offset, item, | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1229 source, offset) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1230 self.data.append(item) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1231 self.items.append((source, offset)) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1232 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1233 def insert(self, i, item, source=None, offset=0): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1234 if source is None: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1235 if not isinstance(item, ViewList): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1236 raise TypeError('inserting non-ViewList with no source given') | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1237 self.data[i:i] = item.data | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1238 self.items[i:i] = item.items | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1239 if self.parent: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1240 index = (len(self.data) + i) % len(self.data) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1241 self.parent.insert(index + self.parent_offset, item) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1242 else: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1243 self.data.insert(i, item) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1244 self.items.insert(i, (source, offset)) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1245 if self.parent: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1246 index = (len(self.data) + i) % len(self.data) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1247 self.parent.insert(index + self.parent_offset, item, | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1248 source, offset) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1249 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1250 def pop(self, i=-1): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1251 if self.parent: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1252 index = (len(self.data) + i) % len(self.data) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1253 self.parent.pop(index + self.parent_offset) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1254 self.items.pop(i) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1255 return self.data.pop(i) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1256 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1257 def trim_start(self, n=1): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1258 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1259 Remove items from the start of the list, without touching the parent. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1260 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1261 if n > len(self.data): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1262 raise IndexError("Size of trim too large; can't trim %s items " | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1263 "from a list of size %s." % (n, len(self.data))) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1264 elif n < 0: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1265 raise IndexError('Trim size must be >= 0.') | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1266 del self.data[:n] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1267 del self.items[:n] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1268 if self.parent: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1269 self.parent_offset += n | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1270 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1271 def trim_end(self, n=1): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1272 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1273 Remove items from the end of the list, without touching the parent. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1274 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1275 if n > len(self.data): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1276 raise IndexError("Size of trim too large; can't trim %s items " | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1277 "from a list of size %s." % (n, len(self.data))) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1278 elif n < 0: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1279 raise IndexError('Trim size must be >= 0.') | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1280 del self.data[-n:] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1281 del self.items[-n:] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1282 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1283 def remove(self, item): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1284 index = self.index(item) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1285 del self[index] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1286 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1287 def count(self, item): return self.data.count(item) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1288 def index(self, item): return self.data.index(item) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1289 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1290 def reverse(self): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1291 self.data.reverse() | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1292 self.items.reverse() | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1293 self.parent = None | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1294 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1295 def sort(self, *args): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1296 tmp = zip(self.data, self.items) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1297 tmp.sort(*args) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1298 self.data = [entry[0] for entry in tmp] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1299 self.items = [entry[1] for entry in tmp] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1300 self.parent = None | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1301 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1302 def info(self, i): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1303 """Return source & offset for index `i`.""" | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1304 try: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1305 return self.items[i] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1306 except IndexError: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1307 if i == len(self.data): # Just past the end | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1308 return self.items[i - 1][0], None | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1309 else: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1310 raise | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1311 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1312 def source(self, i): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1313 """Return source for index `i`.""" | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1314 return self.info(i)[0] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1315 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1316 def offset(self, i): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1317 """Return offset for index `i`.""" | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1318 return self.info(i)[1] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1319 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1320 def disconnect(self): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1321 """Break link between this list and parent list.""" | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1322 self.parent = None | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1323 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1324 def xitems(self): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1325 """Return iterator yielding (source, offset, value) tuples.""" | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1326 for (value, (source, offset)) in zip(self.data, self.items): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1327 yield (source, offset, value) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1328 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1329 def pprint(self): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1330 """Print the list in `grep` format (`source:offset:value` lines)""" | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1331 for line in self.xitems(): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1332 print "%s:%d:%s" % line | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1333 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1334 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1335 class StringList(ViewList): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1336 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1337 """A `ViewList` with string-specific methods.""" | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1338 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1339 def trim_left(self, length, start=0, end=sys.maxint): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1340 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1341 Trim `length` characters off the beginning of each item, in-place, | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1342 from index `start` to `end`. No whitespace-checking is done on the | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1343 trimmed text. Does not affect slice parent. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1344 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1345 self.data[start:end] = [line[length:] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1346 for line in self.data[start:end]] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1347 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1348 def get_text_block(self, start, flush_left=False): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1349 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1350 Return a contiguous block of text. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1351 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1352 If `flush_left` is true, raise `UnexpectedIndentationError` if an | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1353 indented line is encountered before the text block ends (with a blank | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1354 line). | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1355 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1356 end = start | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1357 last = len(self.data) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1358 while end < last: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1359 line = self.data[end] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1360 if not line.strip(): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1361 break | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1362 if flush_left and (line[0] == ' '): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1363 source, offset = self.info(end) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1364 raise UnexpectedIndentationError(self[start:end], source, | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1365 offset + 1) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1366 end += 1 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1367 return self[start:end] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1368 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1369 def get_indented(self, start=0, until_blank=False, strip_indent=True, | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1370 block_indent=None, first_indent=None): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1371 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1372 Extract and return a StringList of indented lines of text. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1373 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1374 Collect all lines with indentation, determine the minimum indentation, | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1375 remove the minimum indentation from all indented lines (unless | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1376 `strip_indent` is false), and return them. All lines up to but not | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1377 including the first unindented line will be returned. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1378 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1379 :Parameters: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1380 - `start`: The index of the first line to examine. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1381 - `until_blank`: Stop collecting at the first blank line if true. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1382 - `strip_indent`: Strip common leading indent if true (default). | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1383 - `block_indent`: The indent of the entire block, if known. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1384 - `first_indent`: The indent of the first line, if known. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1385 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1386 :Return: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1387 - a StringList of indented lines with mininum indent removed; | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1388 - the amount of the indent; | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1389 - a boolean: did the indented block finish with a blank line or EOF? | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1390 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1391 indent = block_indent # start with None if unknown | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1392 end = start | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1393 if block_indent is not None and first_indent is None: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1394 first_indent = block_indent | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1395 if first_indent is not None: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1396 end += 1 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1397 last = len(self.data) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1398 while end < last: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1399 line = self.data[end] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1400 if line and (line[0] != ' ' | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1401 or (block_indent is not None | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1402 and line[:block_indent].strip())): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1403 # Line not indented or insufficiently indented. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1404 # Block finished properly iff the last indented line blank: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1405 blank_finish = ((end > start) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1406 and not self.data[end - 1].strip()) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1407 break | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1408 stripped = line.lstrip() | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1409 if not stripped: # blank line | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1410 if until_blank: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1411 blank_finish = 1 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1412 break | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1413 elif block_indent is None: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1414 line_indent = len(line) - len(stripped) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1415 if indent is None: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1416 indent = line_indent | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1417 else: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1418 indent = min(indent, line_indent) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1419 end += 1 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1420 else: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1421 blank_finish = 1 # block ends at end of lines | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1422 block = self[start:end] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1423 if first_indent is not None and block: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1424 block.data[0] = block.data[0][first_indent:] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1425 if indent and strip_indent: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1426 block.trim_left(indent, start=(first_indent is not None)) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1427 return block, indent or 0, blank_finish | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1428 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1429 def get_2D_block(self, top, left, bottom, right, strip_indent=True): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1430 block = self[top:bottom] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1431 indent = right | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1432 for i in range(len(block.data)): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1433 # get slice from line, care for combining characters | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1434 ci = utils.column_indices(block.data[i]) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1435 try: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1436 left = ci[left] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1437 except IndexError: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1438 left += len(block.data[i]) - len(ci) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1439 try: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1440 right = ci[right] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1441 except IndexError: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1442 right += len(block.data[i]) - len(ci) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1443 block.data[i] = line = block.data[i][left:right].rstrip() | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1444 if line: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1445 indent = min(indent, len(line) - len(line.lstrip())) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1446 if strip_indent and 0 < indent < right: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1447 block.data = [line[indent:] for line in block.data] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1448 return block | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1449 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1450 def pad_double_width(self, pad_char): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1451 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1452 Pad all double-width characters in self by appending `pad_char` to each. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1453 For East Asian language support. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1454 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1455 if hasattr(unicodedata, 'east_asian_width'): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1456 east_asian_width = unicodedata.east_asian_width | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1457 else: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1458 return # new in Python 2.4 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1459 for i in range(len(self.data)): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1460 line = self.data[i] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1461 if isinstance(line, unicode): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1462 new = [] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1463 for char in line: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1464 new.append(char) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1465 if east_asian_width(char) in 'WF': # 'W'ide & 'F'ull-width | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1466 new.append(pad_char) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1467 self.data[i] = ''.join(new) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1468 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1469 def replace(self, old, new): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1470 """Replace all occurrences of substring `old` with `new`.""" | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1471 for i in range(len(self.data)): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1472 self.data[i] = self.data[i].replace(old, new) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1473 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1474 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1475 class StateMachineError(Exception): pass | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1476 class UnknownStateError(StateMachineError): pass | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1477 class DuplicateStateError(StateMachineError): pass | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1478 class UnknownTransitionError(StateMachineError): pass | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1479 class DuplicateTransitionError(StateMachineError): pass | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1480 class TransitionPatternNotFound(StateMachineError): pass | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1481 class TransitionMethodNotFound(StateMachineError): pass | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1482 class UnexpectedIndentationError(StateMachineError): pass | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1483 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1484 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1485 class TransitionCorrection(Exception): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1486 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1487 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1488 Raise from within a transition method to switch to another transition. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1489 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1490 Raise with one argument, the new transition name. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1491 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1492 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1493 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1494 class StateCorrection(Exception): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1495 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1496 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1497 Raise from within a transition method to switch to another state. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1498 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1499 Raise with one or two arguments: new state name, and an optional new | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1500 transition name. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1501 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1502 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1503 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1504 def string2lines(astring, tab_width=8, convert_whitespace=False, | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1505 whitespace=re.compile('[\v\f]')): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1506 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1507 Return a list of one-line strings with tabs expanded, no newlines, and | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1508 trailing whitespace stripped. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1509 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1510 Each tab is expanded with between 1 and `tab_width` spaces, so that the | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1511 next character's index becomes a multiple of `tab_width` (8 by default). | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1512 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1513 Parameters: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1514 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1515 - `astring`: a multi-line string. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1516 - `tab_width`: the number of columns between tab stops. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1517 - `convert_whitespace`: convert form feeds and vertical tabs to spaces? | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1518 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1519 if convert_whitespace: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1520 astring = whitespace.sub(' ', astring) | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1521 return [s.expandtabs(tab_width).rstrip() for s in astring.splitlines()] | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1522 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1523 def _exception_data(): | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1524 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1525 Return exception information: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1526 | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1527 - the exception's class name; | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1528 - the exception object; | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1529 - the name of the file containing the offending code; | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1530 - the line number of the offending code; | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1531 - the function name of the offending code. | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1532 """ | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1533 type, value, traceback = sys.exc_info() | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1534 while traceback.tb_next: | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1535 traceback = traceback.tb_next | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1536 code = traceback.tb_frame.f_code | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1537 return (type.__name__, value, code.co_filename, traceback.tb_lineno, | 
| 
d67268158946
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
 bcclaywell parents: diff
changeset | 1538 code.co_name) | 
