Showing
22 changed files
with
179 additions
and
181 deletions
1 | """SNAKES is the Net Algebra Kit for Editors and Simulators | 1 | """SNAKES is the Net Algebra Kit for Editors and Simulators |
2 | 2 | ||
3 | -@author: Franck Pommereau | ||
4 | -@organization: University of Paris 12 | ||
5 | -@copyright: (C) 2005 Franck Pommereau | ||
6 | -@license: GNU Lesser General Public Licence (aka. GNU LGPL), | ||
7 | - see the file C{doc/COPYING} in the distribution or visit U{the GNU | ||
8 | - web site<http://www.gnu.org/licenses/licenses.html#LGPL>} | ||
9 | -@contact: pommereau@univ-paris12.fr | ||
10 | - | ||
11 | SNAKES is a Python library allowing to model all sorts of Petri nets | 3 | SNAKES is a Python library allowing to model all sorts of Petri nets |
12 | and to execute them. It is very general as most Petri nets annotations | 4 | and to execute them. It is very general as most Petri nets annotations |
13 | can be arbitrary Python expressions while most values can be arbitrary | 5 | can be arbitrary Python expressions while most values can be arbitrary |
... | @@ -16,6 +8,14 @@ Python objects. | ... | @@ -16,6 +8,14 @@ Python objects. |
16 | SNAKES can be further extended with plugins, several ones being | 8 | SNAKES can be further extended with plugins, several ones being |
17 | already provided, in particular two plugins implement the Petri nets | 9 | already provided, in particular two plugins implement the Petri nets |
18 | compositions defined for the Petri Box Calculus and its successors. | 10 | compositions defined for the Petri Box Calculus and its successors. |
11 | + | ||
12 | +@author: Franck Pommereau | ||
13 | +@organization: University of Evry/Paris-Saclay | ||
14 | +@copyright: (C) 2005-2013 Franck Pommereau | ||
15 | +@license: GNU Lesser General Public Licence (aka. GNU LGPL), see the | ||
16 | + file `doc/COPYING` in the distribution or visit [the GNU web | ||
17 | + site](http://www.gnu.org/licenses/licenses.html#LGPL) | ||
18 | +@contact: franck.pommereau@ibisc.univ-evry.fr | ||
19 | """ | 19 | """ |
20 | 20 | ||
21 | version = "0.9.16" | 21 | version = "0.9.16" | ... | ... |
This diff is collapsed. Click to expand it.
1 | """Hashable mutable objets. | 1 | """Hashable mutable objets. |
2 | 2 | ||
3 | This module proposes hashable version of the mutable containers | 3 | This module proposes hashable version of the mutable containers |
4 | -C{list}, C{dict} and C{set}, called respectively C{hlist}, C{hdict} | 4 | +`list`, `dict` and `set`, called respectively `hlist`, `hdict` and |
5 | -and C{hset}. After one object has been hashed, it becomes not mutable | 5 | +`hset`. After one object has been hashed, it becomes not mutable and |
6 | -and raises a ValueError if a method which changes the object (let call | 6 | +raises a ValueError if a method which changes the object (let call a |
7 | -a I{mutation} such a method) is invoqued. The object can be then | 7 | +_mutation_ such a method) is invoqued. The object can be then un- |
8 | -un-hashed by calling C{unhash} on it so that it becomes mutable again. | 8 | +hashed by calling `unhash` on it so that it becomes mutable again. |
9 | Notice that this may cause troubles if the object is stored in a set | 9 | Notice that this may cause troubles if the object is stored in a set |
10 | or dict which uses its hashcode to locate it. Notice also that | 10 | or dict which uses its hashcode to locate it. Notice also that |
11 | hashable containers cannot be hashed if they contain non hashable | 11 | hashable containers cannot be hashed if they contain non hashable |
... | @@ -24,9 +24,9 @@ ValueError: hashed 'hlist' object is not mutable | ... | @@ -24,9 +24,9 @@ ValueError: hashed 'hlist' object is not mutable |
24 | >>> l | 24 | >>> l |
25 | hlist([0, 1, 2, 3, 4, 5]) | 25 | hlist([0, 1, 2, 3, 4, 5]) |
26 | 26 | ||
27 | -Testing if a C{hlist} is in a C{set}, C{dict}, C{hset} or C{hdict} | 27 | +Testing if a `hlist` is in a `set`, `dict`, `hset` or `hdict` causes |
28 | -causes its hashing. If this is not desirable, you should either | 28 | +its hashing. If this is not desirable, you should either compensate |
29 | -compensate with a call to C{unhash}, or test if a copy is in the set: | 29 | +with a call to `unhash`, or test if a copy is in the set: |
30 | 30 | ||
31 | >>> s = set() | 31 | >>> s = set() |
32 | >>> s.add(list(range(4))) | 32 | >>> s.add(list(range(4))) |
... | @@ -54,7 +54,7 @@ from snakes.compat import * | ... | @@ -54,7 +54,7 @@ from snakes.compat import * |
54 | 54 | ||
55 | def unhash (obj) : | 55 | def unhash (obj) : |
56 | """Make the object hashable again. | 56 | """Make the object hashable again. |
57 | - | 57 | + |
58 | >>> l = hlist(range(3)) | 58 | >>> l = hlist(range(3)) |
59 | >>> _ = hash(l) | 59 | >>> _ = hash(l) |
60 | >>> l.append(3) | 60 | >>> l.append(3) |
... | @@ -63,9 +63,9 @@ def unhash (obj) : | ... | @@ -63,9 +63,9 @@ def unhash (obj) : |
63 | ValueError: hashed 'hlist' object is not mutable | 63 | ValueError: hashed 'hlist' object is not mutable |
64 | >>> unhash(l) | 64 | >>> unhash(l) |
65 | >>> l.append(3) | 65 | >>> l.append(3) |
66 | - | 66 | + |
67 | @param obj: any object | 67 | @param obj: any object |
68 | - @type obj: C{object} | 68 | + @type obj: `object` |
69 | """ | 69 | """ |
70 | try : | 70 | try : |
71 | del obj._hash | 71 | del obj._hash |
... | @@ -95,7 +95,7 @@ def hashable (cls) : | ... | @@ -95,7 +95,7 @@ def hashable (cls) : |
95 | __hash__.__doc__ = classdict["__hash__"].__doc__ | 95 | __hash__.__doc__ = classdict["__hash__"].__doc__ |
96 | cls.__hash__ = __hash__ | 96 | cls.__hash__ = __hash__ |
97 | def __mutable__ (self) : | 97 | def __mutable__ (self) : |
98 | - "Raise C{ValueError} if the %s has been hashed." | 98 | + "Raise `ValueError` if the %s has been hashed." |
99 | if self.hashed() : | 99 | if self.hashed() : |
100 | raise ValueError("hashed '%s' object is not mutable" % classname) | 100 | raise ValueError("hashed '%s' object is not mutable" % classname) |
101 | try : | 101 | try : |
... | @@ -123,7 +123,7 @@ def hashable (cls) : | ... | @@ -123,7 +123,7 @@ def hashable (cls) : |
123 | 123 | ||
124 | class hlist (list) : | 124 | class hlist (list) : |
125 | """Hashable lists. | 125 | """Hashable lists. |
126 | - | 126 | + |
127 | >>> l = hlist(range(5)) | 127 | >>> l = hlist(range(5)) |
128 | >>> l | 128 | >>> l |
129 | hlist([0, 1, 2, 3, 4]) | 129 | hlist([0, 1, 2, 3, 4]) |
... | @@ -201,7 +201,7 @@ hlist = hashable(hlist) | ... | @@ -201,7 +201,7 @@ hlist = hashable(hlist) |
201 | 201 | ||
202 | class hdict (dict) : | 202 | class hdict (dict) : |
203 | """Hashable dictionnaries. | 203 | """Hashable dictionnaries. |
204 | - | 204 | + |
205 | >>> l = hlist(range(5)) | 205 | >>> l = hlist(range(5)) |
206 | >>> d = hdict([(l, 0)]) | 206 | >>> d = hdict([(l, 0)]) |
207 | >>> d | 207 | >>> d |
... | @@ -272,7 +272,7 @@ hdict = hashable(hdict) | ... | @@ -272,7 +272,7 @@ hdict = hashable(hdict) |
272 | 272 | ||
273 | class hset (set) : | 273 | class hset (set) : |
274 | """Hashable sets. | 274 | """Hashable sets. |
275 | - | 275 | + |
276 | >>> s = hset() | 276 | >>> s = hset() |
277 | >>> l = hlist(range(5)) | 277 | >>> l = hlist(range(5)) |
278 | >>> s.add(l) | 278 | >>> s.add(l) | ... | ... |
... | @@ -17,7 +17,8 @@ class memoize(object): | ... | @@ -17,7 +17,8 @@ class memoize(object): |
17 | return call | 17 | return call |
18 | 18 | ||
19 | def __get__(self, obj, objtype): | 19 | def __get__(self, obj, objtype): |
20 | - """Support instance methods.""" | 20 | + """Support instance methods. |
21 | + """ | ||
21 | return partial(self.__call__, obj) | 22 | return partial(self.__call__, obj) |
22 | 23 | ||
23 | def component_has_cycle(node, graph, proceeding, visited): | 24 | def component_has_cycle(node, graph, proceeding, visited): |
... | @@ -237,7 +238,8 @@ class CodeGen (asdl.VisitorBase) : | ... | @@ -237,7 +238,8 @@ class CodeGen (asdl.VisitorBase) : |
237 | return "\n".join(python(code, 0)) | 238 | return "\n".join(python(code, 0)) |
238 | 239 | ||
239 | def compile_asdl(infilename, outfilename): | 240 | def compile_asdl(infilename, outfilename): |
240 | - """ Helper function to compile asdl files. """ | 241 | + """Helper function to compile asdl files. |
242 | + """ | ||
241 | 243 | ||
242 | infile = open(infilename, 'r') | 244 | infile = open(infilename, 'r') |
243 | outfile = open(outfilename, 'w') | 245 | outfile = open(outfilename, 'w') | ... | ... |
This diff is collapsed. Click to expand it.
... | @@ -41,7 +41,7 @@ class Token (str) : | ... | @@ -41,7 +41,7 @@ class Token (str) : |
41 | non-mutable object and this __init__ could not assign a str | 41 | non-mutable object and this __init__ could not assign a str |
42 | content. For more information see: | 42 | content. For more information see: |
43 | 43 | ||
44 | - http://docs.python.org/reference/datamodel.html#object.__new__ | 44 | + http://docs.python.org/reference/datamodel.html#object.__new__ |
45 | """ | 45 | """ |
46 | kind = token[0] | 46 | kind = token[0] |
47 | text = token[1] | 47 | text = token[1] |
... | @@ -196,10 +196,8 @@ class Tokenizer (object) : | ... | @@ -196,10 +196,8 @@ class Tokenizer (object) : |
196 | - skip: a collection of tokens that the tokenizer will | 196 | - skip: a collection of tokens that the tokenizer will |
197 | automatically skip (default to [COMMENT, NL]) | 197 | automatically skip (default to [COMMENT, NL]) |
198 | - additional keywords arguments allow to define new tokens, | 198 | - additional keywords arguments allow to define new tokens, |
199 | - for instance, providing | 199 | + for instance, providing DOLLAR='$' defines a new token |
200 | - DOLLAR='$' | 200 | + called 'DOLLAR' (its kind will be automatically computed) |
201 | - defines a new token called 'DOLLAR' (its kind will be | ||
202 | - automatically computed) | ||
203 | 201 | ||
204 | An instance of Tokenizer has the following attributes: | 202 | An instance of Tokenizer has the following attributes: |
205 | - self.opmap: a dict mapping operators token literals to the | 203 | - self.opmap: a dict mapping operators token literals to the | ... | ... |
... | @@ -111,7 +111,7 @@ class ASDLParser(spark.GenericParser, object): | ... | @@ -111,7 +111,7 @@ class ASDLParser(spark.GenericParser, object): |
111 | raise ASDLSyntaxError(tok.lineno, tok) | 111 | raise ASDLSyntaxError(tok.lineno, tok) |
112 | 112 | ||
113 | def p_module_0(self, arg): | 113 | def p_module_0(self, arg): |
114 | - " module ::= Id Id version { } " | 114 | + "module ::= Id Id version { }" |
115 | (module, name, version, _0, _1) = arg | 115 | (module, name, version, _0, _1) = arg |
116 | if module.value != "module": | 116 | if module.value != "module": |
117 | raise ASDLSyntaxError(module.lineno, | 117 | raise ASDLSyntaxError(module.lineno, |
... | @@ -119,7 +119,7 @@ class ASDLParser(spark.GenericParser, object): | ... | @@ -119,7 +119,7 @@ class ASDLParser(spark.GenericParser, object): |
119 | return Module(name, None, version) | 119 | return Module(name, None, version) |
120 | 120 | ||
121 | def p_module(self, arg): | 121 | def p_module(self, arg): |
122 | - " module ::= Id Id version { definitions } " | 122 | + "module ::= Id Id version { definitions }" |
123 | (module, name, version, _0, definitions, _1) = arg | 123 | (module, name, version, _0, definitions, _1) = arg |
124 | if module.value != "module": | 124 | if module.value != "module": |
125 | raise ASDLSyntaxError(module.lineno, | 125 | raise ASDLSyntaxError(module.lineno, |
... | @@ -135,32 +135,32 @@ class ASDLParser(spark.GenericParser, object): | ... | @@ -135,32 +135,32 @@ class ASDLParser(spark.GenericParser, object): |
135 | return V | 135 | return V |
136 | 136 | ||
137 | def p_definition_0(self, arg): | 137 | def p_definition_0(self, arg): |
138 | - " definitions ::= definition " | 138 | + "definitions ::= definition" |
139 | (definition,) = arg | 139 | (definition,) = arg |
140 | return definition | 140 | return definition |
141 | 141 | ||
142 | def p_definition_1(self, arg): | 142 | def p_definition_1(self, arg): |
143 | - " definitions ::= definition definitions " | 143 | + "definitions ::= definition definitions" |
144 | (definitions, definition) = arg | 144 | (definitions, definition) = arg |
145 | return definitions + definition | 145 | return definitions + definition |
146 | 146 | ||
147 | def p_definition(self, arg): | 147 | def p_definition(self, arg): |
148 | - " definition ::= Id = type " | 148 | + "definition ::= Id = type" |
149 | (id, _, type) = arg | 149 | (id, _, type) = arg |
150 | return [Type(id, type)] | 150 | return [Type(id, type)] |
151 | 151 | ||
152 | def p_type_0(self, arg): | 152 | def p_type_0(self, arg): |
153 | - " type ::= product " | 153 | + "type ::= product" |
154 | (product,) = arg | 154 | (product,) = arg |
155 | return product | 155 | return product |
156 | 156 | ||
157 | def p_type_1(self, arg): | 157 | def p_type_1(self, arg): |
158 | - " type ::= sum " | 158 | + "type ::= sum" |
159 | (sum,) = arg | 159 | (sum,) = arg |
160 | return Sum(sum) | 160 | return Sum(sum) |
161 | 161 | ||
162 | def p_type_2(self, arg): | 162 | def p_type_2(self, arg): |
163 | - " type ::= sum Id ( fields ) " | 163 | + "type ::= sum Id ( fields )" |
164 | (sum, id, _0, attributes, _1) = arg | 164 | (sum, id, _0, attributes, _1) = arg |
165 | if id.value != "attributes": | 165 | if id.value != "attributes": |
166 | raise ASDLSyntaxError(id.lineno, | 166 | raise ASDLSyntaxError(id.lineno, |
... | @@ -170,74 +170,74 @@ class ASDLParser(spark.GenericParser, object): | ... | @@ -170,74 +170,74 @@ class ASDLParser(spark.GenericParser, object): |
170 | return Sum(sum, attributes) | 170 | return Sum(sum, attributes) |
171 | 171 | ||
172 | def p_product(self, arg): | 172 | def p_product(self, arg): |
173 | - " product ::= ( fields ) " | 173 | + "product ::= ( fields )" |
174 | (_0, fields, _1) = arg | 174 | (_0, fields, _1) = arg |
175 | fields.reverse() | 175 | fields.reverse() |
176 | return Product(fields) | 176 | return Product(fields) |
177 | 177 | ||
178 | def p_sum_0(self, arg): | 178 | def p_sum_0(self, arg): |
179 | - " sum ::= constructor """ | 179 | + "sum ::= constructor""" |
180 | (constructor,) = arg | 180 | (constructor,) = arg |
181 | return [constructor] | 181 | return [constructor] |
182 | 182 | ||
183 | def p_sum_1(self, arg): | 183 | def p_sum_1(self, arg): |
184 | - " sum ::= constructor | sum " | 184 | + "sum ::= constructor | sum" |
185 | (constructor, _, sum) = arg | 185 | (constructor, _, sum) = arg |
186 | return [constructor] + sum | 186 | return [constructor] + sum |
187 | 187 | ||
188 | def p_sum_2(self, arg): | 188 | def p_sum_2(self, arg): |
189 | - " sum ::= constructor | sum " | 189 | + "sum ::= constructor | sum" |
190 | (constructor, _, sum) = arg | 190 | (constructor, _, sum) = arg |
191 | return [constructor] + sum | 191 | return [constructor] + sum |
192 | 192 | ||
193 | def p_constructor_0(self, arg): | 193 | def p_constructor_0(self, arg): |
194 | - " constructor ::= Id " | 194 | + "constructor ::= Id" |
195 | (id,) = arg | 195 | (id,) = arg |
196 | return Constructor(id) | 196 | return Constructor(id) |
197 | 197 | ||
198 | def p_constructor_1(self, arg): | 198 | def p_constructor_1(self, arg): |
199 | - " constructor ::= Id ( fields ) " | 199 | + "constructor ::= Id ( fields )" |
200 | (id, _0, fields, _1) = arg | 200 | (id, _0, fields, _1) = arg |
201 | fields.reverse() | 201 | fields.reverse() |
202 | return Constructor(id, fields) | 202 | return Constructor(id, fields) |
203 | 203 | ||
204 | def p_fields_0(self, arg): | 204 | def p_fields_0(self, arg): |
205 | - " fields ::= field " | 205 | + "fields ::= field" |
206 | (field,) = arg | 206 | (field,) = arg |
207 | return [field] | 207 | return [field] |
208 | 208 | ||
209 | def p_fields_1(self, arg): | 209 | def p_fields_1(self, arg): |
210 | - " fields ::= field , fields " | 210 | + "fields ::= field , fields" |
211 | (field, _, fields) = arg | 211 | (field, _, fields) = arg |
212 | return fields + [field] | 212 | return fields + [field] |
213 | 213 | ||
214 | def p_field_0(self, arg): | 214 | def p_field_0(self, arg): |
215 | - " field ::= Id " | 215 | + "field ::= Id" |
216 | (type,) = arg | 216 | (type,) = arg |
217 | return Field(type) | 217 | return Field(type) |
218 | 218 | ||
219 | def p_field_1(self, arg): | 219 | def p_field_1(self, arg): |
220 | - " field ::= Id Id " | 220 | + "field ::= Id Id" |
221 | (type, name) = arg | 221 | (type, name) = arg |
222 | return Field(type, name) | 222 | return Field(type, name) |
223 | 223 | ||
224 | def p_field_2(self, arg): | 224 | def p_field_2(self, arg): |
225 | - " field ::= Id * Id " | 225 | + "field ::= Id * Id" |
226 | (type, _, name) = arg | 226 | (type, _, name) = arg |
227 | return Field(type, name, seq=1) | 227 | return Field(type, name, seq=1) |
228 | 228 | ||
229 | def p_field_3(self, arg): | 229 | def p_field_3(self, arg): |
230 | - " field ::= Id ? Id " | 230 | + "field ::= Id ? Id" |
231 | (type, _, name) = arg | 231 | (type, _, name) = arg |
232 | return Field(type, name, opt=1) | 232 | return Field(type, name, opt=1) |
233 | 233 | ||
234 | def p_field_4(self, arg): | 234 | def p_field_4(self, arg): |
235 | - " field ::= Id * " | 235 | + "field ::= Id *" |
236 | (type, _) = arg | 236 | (type, _) = arg |
237 | return Field(type, seq=1) | 237 | return Field(type, seq=1) |
238 | 238 | ||
239 | def p_field_5(self, arg): | 239 | def p_field_5(self, arg): |
240 | - " field ::= Id ? " | 240 | + "field ::= Id ?" |
241 | (type, _) = arg | 241 | (type, _) = arg |
242 | return Field(type, opt=1) | 242 | return Field(type, opt=1) |
243 | 243 | ... | ... |
... | @@ -1623,7 +1623,7 @@ class Translator (object) : | ... | @@ -1623,7 +1623,7 @@ class Translator (object) : |
1623 | return self.ST.Set(lineno=st.srow, col_offset=st.scol, | 1623 | return self.ST.Set(lineno=st.srow, col_offset=st.scol, |
1624 | elts=[self.do(st[0], ctx)]) | 1624 | elts=[self.do(st[0], ctx)]) |
1625 | elif st[1].text == ":" : | 1625 | elif st[1].text == ":" : |
1626 | - if st[3].text == "," : | 1626 | + if len(st) < 4 or st[3].text == "," : |
1627 | return self.ST.Dict(lineno=st.srow, col_offset=st.scol, | 1627 | return self.ST.Dict(lineno=st.srow, col_offset=st.scol, |
1628 | keys=[self.do(child, ctx) | 1628 | keys=[self.do(child, ctx) |
1629 | for child in st[::4]], | 1629 | for child in st[::4]], | ... | ... |
... | @@ -17,13 +17,16 @@ def interleave(inter, f, seq): | ... | @@ -17,13 +17,16 @@ def interleave(inter, f, seq): |
17 | f(x) | 17 | f(x) |
18 | 18 | ||
19 | class Unparser: | 19 | class Unparser: |
20 | - """Methods in this class recursively traverse an AST and | 20 | + """Methods in this class recursively traverse an AST and output |
21 | - output source code for the abstract syntax; original formatting | 21 | + source code for the abstract syntax; original formatting is |
22 | - is disregarged. """ | 22 | + disregarged. |
23 | + """ | ||
23 | 24 | ||
24 | def __init__(self, tree, file = sys.stdout): | 25 | def __init__(self, tree, file = sys.stdout): |
25 | """Unparser(tree, file=sys.stdout) -> None. | 26 | """Unparser(tree, file=sys.stdout) -> None. |
26 | - Print the source for tree to file.""" | 27 | + |
28 | + Print the source for tree to file. | ||
29 | + """ | ||
27 | self.f = file | 30 | self.f = file |
28 | self._indent = 0 | 31 | self._indent = 0 |
29 | self.dispatch(tree) | 32 | self.dispatch(tree) |
... | @@ -31,7 +34,9 @@ class Unparser: | ... | @@ -31,7 +34,9 @@ class Unparser: |
31 | self.f.flush() | 34 | self.f.flush() |
32 | 35 | ||
33 | def fill(self, text = ""): | 36 | def fill(self, text = ""): |
34 | - "Indent a piece of text, according to the current indentation level" | 37 | + """Indent a piece of text, according to the current indentation |
38 | + level | ||
39 | + """ | ||
35 | self.f.write("\n" + " "*self._indent + text) | 40 | self.f.write("\n" + " "*self._indent + text) |
36 | 41 | ||
37 | def write(self, text): | 42 | def write(self, text): | ... | ... |
This diff could not be displayed because it is too large.
1 | """A plugins system. | 1 | """A plugins system. |
2 | 2 | ||
3 | The first example shows how to load a plugin: we load | 3 | The first example shows how to load a plugin: we load |
4 | -C{snakes.plugins.hello} and plug it into C{snakes.nets}, which results | 4 | +`snakes.plugins.hello` and plug it into `snakes.nets`, which results |
5 | -in a new module that actually C{snakes.nets} extended by | 5 | +in a new module that actually `snakes.nets` extended by |
6 | -C{snakes.plugins.hello}. | 6 | +`snakes.plugins.hello`. |
7 | 7 | ||
8 | >>> import snakes.plugins as plugins | 8 | >>> import snakes.plugins as plugins |
9 | >>> hello_nets = plugins.load('hello', 'snakes.nets') | 9 | >>> hello_nets = plugins.load('hello', 'snakes.nets') |
... | @@ -14,14 +14,14 @@ Hello from N | ... | @@ -14,14 +14,14 @@ Hello from N |
14 | >>> n.hello() | 14 | >>> n.hello() |
15 | Hi, this is N! | 15 | Hi, this is N! |
16 | 16 | ||
17 | -The next example shows how to simulate the effect of C{import module}: | 17 | +The next example shows how to simulate the effect of `import module`: |
18 | -we give to C{load} a thrid argument that is the name of the created | 18 | +we give to `load` a thrid argument that is the name of the created |
19 | -module, from which it becomes possible to import names or C{*}. | 19 | +module, from which it becomes possible to import names or `*`. |
20 | 20 | ||
21 | -B{Warning:} this feature will not work C{load} is not called from the | 21 | +**Warning:** this feature will not work `load` is not called from the |
22 | -module where we then do the C{from ... import ...}. This is exactly | 22 | +module where we then do the `from ... import ...`. This is exactly the |
23 | -the same when, from a module C{foo} that you load a module C{bar}: if | 23 | +same when, from a module `foo` that you load a module `bar`: if `bar` |
24 | -C{bar} loads other modules they will not be imported in C{foo}. | 24 | +loads other modules they will not be imported in `foo`. |
25 | 25 | ||
26 | >>> plugins.load('hello', 'snakes.nets', 'another_version') | 26 | >>> plugins.load('hello', 'snakes.nets', 'another_version') |
27 | <module ...> | 27 | <module ...> |
... | @@ -33,7 +33,7 @@ Hello from another net | ... | @@ -33,7 +33,7 @@ Hello from another net |
33 | >>> n.hello() | 33 | >>> n.hello() |
34 | Hi, this is yet another net! | 34 | Hi, this is yet another net! |
35 | 35 | ||
36 | -How to define a plugin is explained in the example C{hello}. | 36 | +How to define a plugin is explained in the example `hello`. |
37 | """ | 37 | """ |
38 | 38 | ||
39 | import imp, sys, inspect | 39 | import imp, sys, inspect |
... | @@ -56,21 +56,20 @@ def update (module, objects) : | ... | @@ -56,21 +56,20 @@ def update (module, objects) : |
56 | 56 | ||
57 | def build (name, module, *objects) : | 57 | def build (name, module, *objects) : |
58 | """Builds an extended module. | 58 | """Builds an extended module. |
59 | - | 59 | + |
60 | - The parameter C{module} is exactly that taken by the function | 60 | + The parameter `module` is exactly that taken by the function |
61 | - C{extend} of a plugin. This list argument C{objects} holds all the | 61 | + `extend` of a plugin. This list argument `objects` holds all the |
62 | - objects, constructed in C{extend}, that are extensions of objects | 62 | + objects, constructed in `extend`, that are extensions of objects |
63 | - from C{module}. The resulting value should be returned by | 63 | + from `module`. The resulting value should be returned by `extend`. |
64 | - C{extend}. | 64 | + |
65 | - | ||
66 | @param name: the name of the constructed module | 65 | @param name: the name of the constructed module |
67 | - @type name: C{str} | 66 | + @type name: `str` |
68 | @param module: the extended module | 67 | @param module: the extended module |
69 | - @type module: C{module} | 68 | + @type module: `module` |
70 | @param objects: the sub-objects | 69 | @param objects: the sub-objects |
71 | @type objects: each is a class object | 70 | @type objects: each is a class object |
72 | @return: the new module | 71 | @return: the new module |
73 | - @rtype: C{module} | 72 | + @rtype: `module` |
74 | """ | 73 | """ |
75 | result = imp.new_module(name) | 74 | result = imp.new_module(name) |
76 | result.__dict__.update(module.__dict__) | 75 | result.__dict__.update(module.__dict__) |
... | @@ -85,22 +84,22 @@ def build (name, module, *objects) : | ... | @@ -85,22 +84,22 @@ def build (name, module, *objects) : |
85 | 84 | ||
86 | def load (plugins, base, name=None) : | 85 | def load (plugins, base, name=None) : |
87 | """Load plugins. | 86 | """Load plugins. |
88 | - | 87 | + |
89 | - C{plugins} can be a single plugin name or module or a list of such | 88 | + `plugins` can be a single plugin name or module or a list of such |
90 | - values. If C{name} is not C{None}, the extended module is loaded | 89 | + values. If `name` is not `None`, the extended module is loaded ad |
91 | - ad C{name} in C{sys.modules} as well as in the global environment | 90 | + `name` in `sys.modules` as well as in the global environment from |
92 | - from which C{load} was called. | 91 | + which `load` was called. |
93 | - | 92 | + |
94 | - @param plugins: the module that implements the plugin, or its name, | 93 | + @param plugins: the module that implements the plugin, or its |
95 | - or a collection of such values | 94 | + name, or a collection of such values |
96 | - @type plugins: C{str} or C{module}, or a C{list}/C{tuple}/... of | 95 | + @type plugins: `str` or `module`, or a `list`/`tuple`/... of such |
97 | - such values | 96 | + values |
98 | @param base: the module being extended or its name | 97 | @param base: the module being extended or its name |
99 | - @type base: C{str} or C{module} | 98 | + @type base: `str` or `module` |
100 | @param name: the name of the created module | 99 | @param name: the name of the created module |
101 | - @type name: C{str} | 100 | + @type name: `str` |
102 | @return: the extended module | 101 | @return: the extended module |
103 | - @rtype: C{module} | 102 | + @rtype: `module` |
104 | """ | 103 | """ |
105 | if type(base) is str : | 104 | if type(base) is str : |
106 | result = __import__(base, fromlist=["__name__"]) | 105 | result = __import__(base, fromlist=["__name__"]) |
... | @@ -128,7 +127,7 @@ def load (plugins, base, name=None) : | ... | @@ -128,7 +127,7 @@ def load (plugins, base, name=None) : |
128 | 127 | ||
129 | def plugin (base, depends=[], conflicts=[]) : | 128 | def plugin (base, depends=[], conflicts=[]) : |
130 | """Decorator for extension functions | 129 | """Decorator for extension functions |
131 | - | 130 | + |
132 | @param base: name of base module (usually 'snakes.nets') | 131 | @param base: name of base module (usually 'snakes.nets') |
133 | @type base: str | 132 | @type base: str |
134 | @param depends: list of plugins on which this one depends | 133 | @param depends: list of plugins on which this one depends |
... | @@ -166,7 +165,7 @@ def plugin (base, depends=[], conflicts=[]) : | ... | @@ -166,7 +165,7 @@ def plugin (base, depends=[], conflicts=[]) : |
166 | return wrapper | 165 | return wrapper |
167 | 166 | ||
168 | def new_instance (cls, obj) : | 167 | def new_instance (cls, obj) : |
169 | - """Create a copy of C{obj} which is an instance of C{cls} | 168 | + """Create a copy of `obj` which is an instance of `cls` |
170 | """ | 169 | """ |
171 | result = object.__new__(cls) | 170 | result = object.__new__(cls) |
172 | result.__dict__.update(obj.__dict__) | 171 | result.__dict__.update(obj.__dict__) | ... | ... |
... | @@ -12,7 +12,6 @@ class Cluster (object) : | ... | @@ -12,7 +12,6 @@ class Cluster (object) : |
12 | ... Cluster(['3', '4', '5'], | 12 | ... Cluster(['3', '4', '5'], |
13 | ... [Cluster(['C', 'D'])])]) | 13 | ... [Cluster(['C', 'D'])])]) |
14 | Cluster(...) | 14 | Cluster(...) |
15 | - | ||
16 | """ | 15 | """ |
17 | self._nodes = set(nodes) | 16 | self._nodes = set(nodes) |
18 | self._children = [] | 17 | self._children = [] |
... | @@ -160,7 +159,6 @@ class Cluster (object) : | ... | @@ -160,7 +159,6 @@ class Cluster (object) : |
160 | [Cluster(['A'], [])]), | 159 | [Cluster(['A'], [])]), |
161 | Cluster(['...', '...'], | 160 | Cluster(['...', '...'], |
162 | [Cluster(['...', '...'], [])])]) | 161 | [Cluster(['...', '...'], [])])]) |
163 | - | ||
164 | """ | 162 | """ |
165 | if name in self._cluster : | 163 | if name in self._cluster : |
166 | self._cluster[name].remove_node(name) | 164 | self._cluster[name].remove_node(name) | ... | ... |
1 | """Draw Petri nets using PyGraphViz | 1 | """Draw Petri nets using PyGraphViz |
2 | 2 | ||
3 | - - adds a method C{draw} to C{PetriNet} and C{StateGraph} that creates | 3 | + * adds a method `draw` to `PetriNet` and `StateGraph` that creates |
4 | - a drawing of the object in a file. | 4 | + a drawing of the object in a file. |
5 | 5 | ||
6 | >>> import snakes.plugins | 6 | >>> import snakes.plugins |
7 | >>> snakes.plugins.load('gv', 'snakes.nets', 'nets') | 7 | >>> snakes.plugins.load('gv', 'snakes.nets', 'nets') |
... | @@ -16,14 +16,11 @@ | ... | @@ -16,14 +16,11 @@ |
16 | >>> n.add_output('p11', 't10', Expression('x+1')) | 16 | >>> n.add_output('p11', 't10', Expression('x+1')) |
17 | >>> n.add_input('p11', 't01', Variable('y')) | 17 | >>> n.add_input('p11', 't01', Variable('y')) |
18 | >>> n.add_output('p00', 't01', Expression('y-1')) | 18 | >>> n.add_output('p00', 't01', Expression('y-1')) |
19 | - | ||
20 | >>> for engine in ('neato', 'dot', 'circo', 'twopi', 'fdp') : | 19 | >>> for engine in ('neato', 'dot', 'circo', 'twopi', 'fdp') : |
21 | ... n.draw(',test-gv-%s.png' % engine, engine=engine) | 20 | ... n.draw(',test-gv-%s.png' % engine, engine=engine) |
22 | - | ||
23 | >>> s = StateGraph(n) | 21 | >>> s = StateGraph(n) |
24 | >>> s.build() | 22 | >>> s.build() |
25 | >>> s.draw(',test-gv-graph.png') | 23 | >>> s.draw(',test-gv-graph.png') |
26 | - | ||
27 | >>> for node in sorted(n.node(), key=str) : | 24 | >>> for node in sorted(n.node(), key=str) : |
28 | ... node.pos.moveto(-100, -100) | 25 | ... node.pos.moveto(-100, -100) |
29 | >>> n.layout() | 26 | >>> n.layout() |
... | @@ -151,36 +148,37 @@ class Graph (Cluster) : | ... | @@ -151,36 +148,37 @@ class Graph (Cluster) : |
151 | "snakes.plugins.pos"]) | 148 | "snakes.plugins.pos"]) |
152 | def extend (module) : | 149 | def extend (module) : |
153 | class PetriNet (module.PetriNet) : | 150 | class PetriNet (module.PetriNet) : |
154 | - "An extension with a method C{draw}" | 151 | + "An extension with a method `draw`" |
155 | def draw (self, filename=None, engine="dot", debug=False, | 152 | def draw (self, filename=None, engine="dot", debug=False, |
156 | graph_attr=None, cluster_attr=None, | 153 | graph_attr=None, cluster_attr=None, |
157 | place_attr=None, trans_attr=None, arc_attr=None) : | 154 | place_attr=None, trans_attr=None, arc_attr=None) : |
158 | """ | 155 | """ |
159 | @param filename: the name of the image file to create or | 156 | @param filename: the name of the image file to create or |
160 | - C{None} if only the computed graph is needed | 157 | + `None` if only the computed graph is needed |
161 | - @type filename: C{None} or C{str} | 158 | + @type filename: `None` or `str` |
162 | @param engine: the layout engine to use: 'dot' (default), | 159 | @param engine: the layout engine to use: 'dot' (default), |
163 | - 'neato', 'circo', 'twopi' or 'fdp' | 160 | + 'neato', 'circo', 'twopi' or 'fdp' |
164 | - @type engine: C{str} | 161 | + @type engine: `str` |
165 | @param place_attr: a function to format places, it will be | 162 | @param place_attr: a function to format places, it will be |
166 | - called with the place and its attributes dict as | 163 | + called with the place and its attributes dict as |
167 | - parameters | 164 | + parameters |
168 | - @type place_attr: C{function(Place,dict)->None} | 165 | + @type place_attr: `function(Place,dict)->None` |
169 | @param trans_attr: a function to format transitions, it | 166 | @param trans_attr: a function to format transitions, it |
170 | - will be called with the transition and its attributes dict | 167 | + will be called with the transition and its attributes |
171 | - as parameters | 168 | + dict as parameters |
172 | - @type trans_attr: C{function(Transition,dict)->None} | 169 | + @type trans_attr: `function(Transition,dict)->None` |
173 | - @param arc_attr: a function to format arcs, it will be | 170 | + @param arc_attr: a function to format arcs, it will be |
174 | - called with the label and its attributes dict as | 171 | + called with the label and its attributes dict as |
175 | - parameters | 172 | + parameters |
176 | - @type arc_attr: C{function(ArcAnnotation,dict)->None} | 173 | + @type arc_attr: `function(ArcAnnotation,dict)->None` |
177 | @param cluster_attr: a function to format clusters of | 174 | @param cluster_attr: a function to format clusters of |
178 | - nodes, it will be called with the cluster and its | 175 | + nodes, it will be called with the cluster and its |
179 | - attributes dict as parameters | 176 | + attributes dict as parameters |
180 | - @type cluster_attr: C{function(snakes.plugins.clusters.Cluster,dict)->None} | 177 | + @type cluster_attr: |
181 | - @return: C{None} if C{filename} is not C{None}, the | 178 | + `function(snakes.plugins.clusters.Cluster,dict)->None` |
182 | - computed graph otherwise | 179 | + @return: `None` if `filename` is not `None`, the computed |
183 | - @rtype: C{None} or C{pygraphviz.AGraph} | 180 | + graph otherwise |
181 | + @rtype: `None` or `pygraphviz.AGraph` | ||
184 | """ | 182 | """ |
185 | nodemap = dict((node.name, "node_%s" % num) | 183 | nodemap = dict((node.name, "node_%s" % num) |
186 | for num, node in enumerate(self.node())) | 184 | for num, node in enumerate(self.node())) |
... | @@ -243,31 +241,31 @@ def extend (module) : | ... | @@ -243,31 +241,31 @@ def extend (module) : |
243 | self.node(node[n]).pos.moveto(x*xscale, y*yscale) | 241 | self.node(node[n]).pos.moveto(x*xscale, y*yscale) |
244 | 242 | ||
245 | class StateGraph (module.StateGraph) : | 243 | class StateGraph (module.StateGraph) : |
246 | - "An extension with a method C{draw}" | 244 | + "An extension with a method `draw`" |
247 | def draw (self, filename=None, engine="dot", debug=False, | 245 | def draw (self, filename=None, engine="dot", debug=False, |
248 | node_attr=None, edge_attr=None, graph_attr=None) : | 246 | node_attr=None, edge_attr=None, graph_attr=None) : |
249 | - """ | 247 | + """@param filename: the name of the image file to create or |
250 | - @param filename: the name of the image file to create or | 248 | + `None` if only the computed graph is needed |
251 | - C{None} if only the computed graph is needed | 249 | + @type filename: `None` or `str` |
252 | - @type filename: C{None} or C{str} | ||
253 | @param engine: the layout engine to use: 'dot' (default), | 250 | @param engine: the layout engine to use: 'dot' (default), |
254 | - 'neato', 'circo', 'twopi' or 'fdp' | 251 | + 'neato', 'circo', 'twopi' or 'fdp' |
255 | - @type engine: C{str} | 252 | + @type engine: `str` |
256 | @param node_attr: a function to format nodes, it will be | 253 | @param node_attr: a function to format nodes, it will be |
257 | - called with the state number, the C{StateGraph} object | 254 | + called with the state number, the `StateGraph` object |
258 | - and attributes dict as parameters | 255 | + and attributes dict as parameters |
259 | - @type node_attr: C{function(int,StateGraph,dict)->None} | 256 | + @type node_attr: `function(int,StateGraph,dict)->None` |
260 | - @param edge_attr: a function to format edges, it | 257 | + @param edge_attr: a function to format edges, it will be |
261 | - will be called with the transition, its mode and | 258 | + called with the transition, its mode and attributes |
262 | - attributes dict as parameters | 259 | + dict as parameters |
263 | - @type trans_attr: C{function(Transition,Substitution,dict)->None} | 260 | + @type trans_attr: |
264 | - @param graph_attr: a function to format grapg, it | 261 | + `function(Transition,Substitution,dict)->None` |
265 | - will be called with the state graphe and attributes dict | 262 | + @param graph_attr: a function to format grapg, it will be |
266 | - as parameters | 263 | + called with the state graphe and attributes dict as |
267 | - @type graph_attr: C{function(StateGraph,dict)->None} | 264 | + parameters |
268 | - @return: C{None} if C{filename} is not C{None}, the | 265 | + @type graph_attr: `function(StateGraph,dict)->None` |
269 | - computed graph otherwise | 266 | + @return: `None` if `filename` is not `None`, the computed |
270 | - @rtype: C{None} or C{pygraphviz.AGraph} | 267 | + graph otherwise |
268 | + @rtype: `None` or `pygraphviz.AGraph` | ||
271 | """ | 269 | """ |
272 | attr = dict(style="invis", | 270 | attr = dict(style="invis", |
273 | splines="true") | 271 | splines="true") | ... | ... |
1 | -"""An example plugin that allows instances class C{PetriNet} to say hello. | 1 | +"""An example plugin that allows instances class `PetriNet` to say hello. |
2 | 2 | ||
3 | -A new method C{hello} is added. The constructor is added a keyword | 3 | +A new method `hello` is added. The constructor is added a keyword |
4 | -argument C{hello} that must be the C{str} to print when calling | 4 | +argument `hello` that must be the `str` to print when calling `hello`, |
5 | -C{hello}, with one C{%s} that will be replaced by the name of the net | 5 | +with one `%s` that will be replaced by the name of the net when |
6 | -when C{hello} is called. | 6 | +`hello` is called. |
7 | 7 | ||
8 | Defining a plugins need writing a module with a single function called | 8 | Defining a plugins need writing a module with a single function called |
9 | -C{extend} that takes a single argument that is the module to be | 9 | +`extend` that takes a single argument that is the module to be |
10 | extended. | 10 | extended. |
11 | 11 | ||
12 | Inside the function, extensions of the classes in the module are | 12 | Inside the function, extensions of the classes in the module are |
13 | defined as normal sub-classes. | 13 | defined as normal sub-classes. |
14 | 14 | ||
15 | -The function C{extend} should return the extended module created by | 15 | +The function `extend` should return the extended module created by |
16 | -C{snakes.plugins.build} that takes as arguments: the name of the | 16 | +`snakes.plugins.build` that takes as arguments: the name of the |
17 | extended module, the module taken as argument and the sub-classes | 17 | extended module, the module taken as argument and the sub-classes |
18 | -defined (expected as a list argument C{*args} in no special order). | 18 | +defined (expected as a list argument `*args` in no special order). |
19 | 19 | ||
20 | -If the plugin depends on other plugins, for instance C{foo} and | 20 | +If the plugin depends on other plugins, for instance `foo` and `bar`, |
21 | -C{bar}, the function C{extend} should be decorated by | 21 | +the function `extend` should be decorated by `@depends('foo', 'bar')`. |
22 | -C{@depends('foo', 'bar')}. | ||
23 | 22 | ||
24 | Read the source code of this module to have an example | 23 | Read the source code of this module to have an example |
25 | """ | 24 | """ |
... | @@ -28,34 +27,34 @@ import snakes.plugins | ... | @@ -28,34 +27,34 @@ import snakes.plugins |
28 | 27 | ||
29 | @snakes.plugins.plugin("snakes.nets") | 28 | @snakes.plugins.plugin("snakes.nets") |
30 | def extend (module) : | 29 | def extend (module) : |
31 | - """Extends C{module} | 30 | + """Extends `module` |
32 | """ | 31 | """ |
33 | class PetriNet (module.PetriNet) : | 32 | class PetriNet (module.PetriNet) : |
34 | - """Extension of the class C{PetriNet} in C{module} | 33 | + """Extension of the class `PetriNet` in `module` |
35 | """ | 34 | """ |
36 | def __init__ (self, name, **args) : | 35 | def __init__ (self, name, **args) : |
37 | - """When extending an existing method, take care that you | 36 | + """When extending an existing method, take care that you may |
38 | - may be working on an already extended class, so you so not | 37 | + be working on an already extended class, so you so not |
39 | know how its arguments have been changed. So, always use | 38 | know how its arguments have been changed. So, always use |
40 | - those from the unextended class plus C{**args}, remove | 39 | + those from the unextended class plus `**args`, remove from |
41 | - from it what your plugin needs and pass it to the method | 40 | + it what your plugin needs and pass it to the method of the |
42 | - of the extended class if you need to call it. | 41 | + extended class if you need to call it. |
43 | - | 42 | + |
44 | >>> PetriNet('N').hello() | 43 | >>> PetriNet('N').hello() |
45 | Hello from N | 44 | Hello from N |
46 | >>> PetriNet('N', hello='Hi! This is %s...').hello() | 45 | >>> PetriNet('N', hello='Hi! This is %s...').hello() |
47 | Hi! This is N... | 46 | Hi! This is N... |
48 | - | 47 | + |
49 | @param args: plugin options | 48 | @param args: plugin options |
50 | - @keyword hello: the message to print, with C{%s} where the | 49 | + @keyword hello: the message to print, with `%s` where the |
51 | - net name should appear. | 50 | + net name should appear. |
52 | - @type hello: C{str} | 51 | + @type hello: `str` |
53 | """ | 52 | """ |
54 | self._hello = args.pop("hello", "Hello from %s") | 53 | self._hello = args.pop("hello", "Hello from %s") |
55 | module.PetriNet.__init__(self, name, **args) | 54 | module.PetriNet.__init__(self, name, **args) |
56 | def hello (self) : | 55 | def hello (self) : |
57 | - """A new method C{hello} | 56 | + """A new method `hello` |
58 | - | 57 | + |
59 | >>> n = PetriNet('N') | 58 | >>> n = PetriNet('N') |
60 | >>> n.hello() | 59 | >>> n.hello() |
61 | Hello from N | 60 | Hello from N | ... | ... |
1 | """A plugin to add positions to the nodes. | 1 | """A plugin to add positions to the nodes. |
2 | 2 | ||
3 | - - C{Place} and C{Transition} constructors are added an optional | 3 | + * `Place` and `Transition` constructors are added an optional argument |
4 | - argument C{pos=(x,y)} to set their position | 4 | + `pos=(x,y)` to set their position |
5 | - | 5 | + * `Place` and `Transition` are added an attribute `pos` that is pair |
6 | - - C{Place} and C{Transition} are added an attribute C{pos} that is | 6 | + of numbers with attributes `x` and `y` and methods `shift(dx, dy)` |
7 | - pair of numbers with attributes C{x} and C{y} and methods | 7 | + and `moveto(x, y)` |
8 | - C{shift(dx, dy)} and C{moveto(x, y)} | 8 | + * Petri nets are added methods `bbox()` that returns a pair of |
9 | - | 9 | + extrema `((xmin, ymin), (xmax, ymax))`, a method `shift(dx, dy)` |
10 | - - Petri nets are added methods C{bbox()} that returns a pair of | 10 | + that shift all the nodes, and a method `transpose()` that rotates |
11 | - extrema C{((xmin, ymin), (xmax, ymax))}, a method C{shift(dx, dy)} | ||
12 | - that shift all the nodes, and a method C{transpose()} that rotates | ||
13 | the net in such a way that the top-down direction becomes | 11 | the net in such a way that the top-down direction becomes |
14 | left-right | 12 | left-right |
15 | 13 | ... | ... |
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
... | @@ -40,7 +40,8 @@ class Decl (object) : | ... | @@ -40,7 +40,8 @@ class Decl (object) : |
40 | setattr(self, key, val) | 40 | setattr(self, key, val) |
41 | 41 | ||
42 | class GetInstanceArgs (object) : | 42 | class GetInstanceArgs (object) : |
43 | - """Bind arguments for a net instance""" | 43 | + """Bind arguments for a net instance |
44 | + """ | ||
44 | def __init__ (self, node) : | 45 | def __init__ (self, node) : |
45 | self.argspec = [] | 46 | self.argspec = [] |
46 | self.arg = {} | 47 | self.arg = {} | ... | ... |
-
Please register or login to post a comment