Mercurial > repos > fubar > tool_factory_2
comparison toolfactory/galaxyxml/tool/parameters/__init__.py @ 92:6ce360759c28 draft
Uploaded
author | fubar |
---|---|
date | Thu, 19 Nov 2020 23:59:50 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
91:7176af503cdd | 92:6ce360759c28 |
---|---|
1 from builtins import object | |
2 from builtins import str | |
3 | |
4 from galaxyxml import Util | |
5 | |
6 from lxml import etree | |
7 | |
8 | |
9 | |
10 class XMLParam(object): | |
11 name = "node" | |
12 | |
13 def __init__(self, *args, **kwargs): | |
14 # http://stackoverflow.com/a/12118700 | |
15 self.children = [] | |
16 kwargs = {k: v for k, v in list(kwargs.items()) if v is not None} | |
17 kwargs = Util.coerce(kwargs, kill_lists=True) | |
18 kwargs = Util.clean_kwargs(kwargs, final=True) | |
19 self.node = etree.Element(self.name, **kwargs) | |
20 | |
21 def append(self, sub_node): | |
22 if self.acceptable_child(sub_node): | |
23 # If one of ours, they aren't etree nodes, they're custom objects | |
24 if issubclass(type(sub_node), XMLParam): | |
25 self.node.append(sub_node.node) | |
26 self.children.append(sub_node) | |
27 else: | |
28 raise Exception( | |
29 "Child was unacceptable to parent (%s is not appropriate for %s)" % (type(self), type(sub_node)) | |
30 ) | |
31 else: | |
32 raise Exception( | |
33 "Child was unacceptable to parent (%s is not appropriate for %s)" % (type(self), type(sub_node)) | |
34 ) | |
35 | |
36 def validate(self): | |
37 # Very few need validation, but some nodes we may want to have | |
38 # validation routines on. Should only be called when DONE. | |
39 for child in self.children: | |
40 # If any child fails to validate return false. | |
41 if not child.validate(): | |
42 return False | |
43 return True | |
44 | |
45 def cli(self): | |
46 lines = [] | |
47 for child in self.children: | |
48 lines.append(child.command_line()) | |
49 # lines += child.command_line() | |
50 return "\n".join(lines) | |
51 | |
52 def command_line(self): | |
53 return None | |
54 | |
55 | |
56 class RequestParamTranslation(XMLParam): | |
57 name = "request_param_translation" | |
58 | |
59 def __init__(self, **kwargs): | |
60 self.node = etree.Element(self.name) | |
61 | |
62 def acceptable_child(self, child): | |
63 return isinstance(child, RequestParamTranslation) | |
64 | |
65 | |
66 class RequestParam(XMLParam): | |
67 name = "request_param" | |
68 | |
69 def __init__(self, galaxy_name, remote_name, missing, **kwargs): | |
70 # TODO: bulk copy locals into self.attr? | |
71 self.galaxy_name = galaxy_name | |
72 # http://stackoverflow.com/a/1408860 | |
73 params = Util.clean_kwargs(locals().copy()) | |
74 super(RequestParam, self).__init__(**params) | |
75 | |
76 def acceptable_child(self, child): | |
77 return isinstance(child, AppendParam) and self.galaxy_name == "URL" | |
78 | |
79 | |
80 class AppendParam(XMLParam): | |
81 name = "append_param" | |
82 | |
83 def __init__(self, separator="&", first_separator="?", join="=", **kwargs): | |
84 params = Util.clean_kwargs(locals().copy()) | |
85 super(AppendParam, self).__init__(**params) | |
86 | |
87 def acceptable_child(self, child): | |
88 return isinstance(child, AppendParamValue) | |
89 | |
90 | |
91 class AppendParamValue(XMLParam): | |
92 name = "value" | |
93 | |
94 def __init__(self, name="_export", missing="1", **kwargs): | |
95 params = Util.clean_kwargs(locals().copy()) | |
96 super(AppendParamValue, self).__init__(**params) | |
97 | |
98 def acceptable_child(self, child): | |
99 return False | |
100 | |
101 | |
102 class EdamOperations(XMLParam): | |
103 name = "edam_operations" | |
104 | |
105 def acceptable_child(self, child): | |
106 return issubclass(type(child), EdamOperation) | |
107 | |
108 def has_operation(self, edam_operation): | |
109 """ | |
110 Check the presence of a given edam_operation. | |
111 | |
112 :type edam_operation: STRING | |
113 """ | |
114 for operation in self.children: | |
115 if operation.node.text == edam_operation: | |
116 return True | |
117 return False | |
118 | |
119 | |
120 class EdamOperation(XMLParam): | |
121 name = "edam_operation" | |
122 | |
123 def __init__(self, value): | |
124 super(EdamOperation, self).__init__() | |
125 self.node.text = str(value) | |
126 | |
127 | |
128 class EdamTopics(XMLParam): | |
129 name = "edam_topics" | |
130 | |
131 def acceptable_child(self, child): | |
132 return issubclass(type(child), EdamTopic) | |
133 | |
134 def has_topic(self, edam_topic): | |
135 """ | |
136 Check the presence of a given edam_topic. | |
137 | |
138 :type edam_topic: STRING | |
139 """ | |
140 for topic in self.children: | |
141 if topic.node.text == edam_topic: | |
142 return True | |
143 return False | |
144 | |
145 | |
146 class EdamTopic(XMLParam): | |
147 name = "edam_topic" | |
148 | |
149 def __init__(self, value): | |
150 super(EdamTopic, self).__init__() | |
151 self.node.text = str(value) | |
152 | |
153 | |
154 class Requirements(XMLParam): | |
155 name = "requirements" | |
156 # This bodes to be an issue -__- | |
157 | |
158 def acceptable_child(self, child): | |
159 return issubclass(type(child), Requirement) or issubclass(type(child), Container) | |
160 | |
161 | |
162 class Requirement(XMLParam): | |
163 name = "requirement" | |
164 | |
165 def __init__(self, type, value, version=None, **kwargs): | |
166 params = Util.clean_kwargs(locals().copy()) | |
167 passed_kwargs = {} | |
168 passed_kwargs["version"] = params["version"] | |
169 passed_kwargs["type"] = params["type"] | |
170 super(Requirement, self).__init__(**passed_kwargs) | |
171 self.node.text = str(value) | |
172 | |
173 | |
174 class Container(XMLParam): | |
175 name = "container" | |
176 | |
177 def __init__(self, type, value, **kwargs): | |
178 params = Util.clean_kwargs(locals().copy()) | |
179 passed_kwargs = {} | |
180 passed_kwargs["type"] = params["type"] | |
181 super(Container, self).__init__(**passed_kwargs) | |
182 self.node.text = str(value) | |
183 | |
184 | |
185 class Configfiles(XMLParam): | |
186 name = "configfiles" | |
187 | |
188 def acceptable_child(self, child): | |
189 return issubclass(type(child), Configfile) or issubclass(type(child), ConfigfileDefaultInputs) | |
190 | |
191 | |
192 class Configfile(XMLParam): | |
193 name = "configfile" | |
194 | |
195 def __init__(self, name, text, **kwargs): | |
196 params = Util.clean_kwargs(locals().copy()) | |
197 passed_kwargs = {} | |
198 passed_kwargs["name"] = params["name"] | |
199 super(Configfile, self).__init__(**passed_kwargs) | |
200 self.node.text = etree.CDATA(str(text)) | |
201 | |
202 | |
203 class ConfigfileDefaultInputs(XMLParam): | |
204 name = "inputs" | |
205 | |
206 def __init__(self, name, **kwargs): | |
207 params = Util.clean_kwargs(locals().copy()) | |
208 passed_kwargs = {} | |
209 passed_kwargs["name"] = params["name"] | |
210 super(ConfigfileDefaultInputs, self).__init__(**passed_kwargs) | |
211 | |
212 | |
213 class Inputs(XMLParam): | |
214 name = "inputs" | |
215 # This bodes to be an issue -__- | |
216 | |
217 def __init__(self, action=None, check_value=None, method=None, target=None, nginx_upload=None, **kwargs): | |
218 params = Util.clean_kwargs(locals().copy()) | |
219 super(Inputs, self).__init__(**params) | |
220 | |
221 def acceptable_child(self, child): | |
222 return issubclass(type(child), InputParameter) | |
223 | |
224 | |
225 class InputParameter(XMLParam): | |
226 def __init__(self, name, **kwargs): | |
227 # TODO: look at | |
228 self.mako_identifier = name | |
229 # We use kwargs instead of the usual locals(), so manually copy the | |
230 # name to kwargs | |
231 if name is not None: | |
232 kwargs["name"] = name | |
233 | |
234 # Handle positional parameters | |
235 if "positional" in kwargs and kwargs["positional"]: | |
236 self.positional = True | |
237 else: | |
238 self.positional = False | |
239 | |
240 if "num_dashes" in kwargs: | |
241 self.num_dashes = kwargs["num_dashes"] | |
242 del kwargs["num_dashes"] | |
243 else: | |
244 self.num_dashes = 0 | |
245 | |
246 self.space_between_arg = " " | |
247 | |
248 # Not sure about this :( | |
249 # https://wiki.galaxyproject.org/Tools/BestPractices#Parameter_help | |
250 if "label" in kwargs: | |
251 # TODO: replace with positional attribute | |
252 if len(self.flag()) > 0: | |
253 if kwargs["label"] is None: | |
254 kwargs["label"] = "Author did not provide help for this parameter... " | |
255 if not self.positional: | |
256 kwargs["argument"] = self.flag() | |
257 | |
258 super(InputParameter, self).__init__(**kwargs) | |
259 | |
260 def command_line(self): | |
261 before = self.command_line_before() | |
262 cli = self.command_line_actual() | |
263 after = self.command_line_after() | |
264 | |
265 complete = [x for x in (before, cli, after) if x is not None] | |
266 return "\n".join(complete) | |
267 | |
268 def command_line_before(self): | |
269 try: | |
270 return self.command_line_before_override | |
271 except Exception: | |
272 return None | |
273 | |
274 def command_line_after(self): | |
275 try: | |
276 return self.command_line_after_override | |
277 except Exception: | |
278 return None | |
279 | |
280 def command_line_actual(self): | |
281 try: | |
282 return self.command_line_override | |
283 except Exception: | |
284 if self.positional: | |
285 return self.mako_name() | |
286 else: | |
287 return "%s%s%s" % (self.flag(), self.space_between_arg, self.mako_name()) | |
288 | |
289 def mako_name(self): | |
290 # TODO: enhance logic to check up parents for things like | |
291 # repeat>condotion>param | |
292 return "$" + self.mako_identifier | |
293 | |
294 def flag(self): | |
295 flag = "-" * self.num_dashes | |
296 return flag + self.mako_identifier | |
297 | |
298 | |
299 class Section(InputParameter): | |
300 name = "section" | |
301 | |
302 def __init__(self, name, title, expanded=None, help=None, **kwargs): | |
303 params = Util.clean_kwargs(locals().copy()) | |
304 super(Section, self).__init__(**params) | |
305 | |
306 def acceptable_child(self, child): | |
307 return issubclass(type(child), InputParameter) | |
308 | |
309 | |
310 class Repeat(InputParameter): | |
311 name = "repeat" | |
312 | |
313 def __init__(self, name, title, min=None, max=None, default=None, **kwargs): | |
314 params = Util.clean_kwargs(locals().copy()) | |
315 # Allow overriding | |
316 self.command_line_before_override = "#for $i in $%s:" % name | |
317 self.command_line_after_override = "#end for" | |
318 # self.command_line_override | |
319 super(Repeat, self).__init__(**params) | |
320 | |
321 def acceptable_child(self, child): | |
322 return issubclass(type(child), InputParameter) | |
323 | |
324 def command_line_actual(self): | |
325 if hasattr(self, "command_line_override"): | |
326 return self.command_line_override | |
327 else: | |
328 return "%s" % self.mako_name() | |
329 | |
330 | |
331 class Conditional(InputParameter): | |
332 name = "conditional" | |
333 | |
334 def __init__(self, name, **kwargs): | |
335 params = Util.clean_kwargs(locals().copy()) | |
336 super(Conditional, self).__init__(**params) | |
337 | |
338 def acceptable_child(self, child): | |
339 return issubclass(type(child), InputParameter) and not isinstance(child, Conditional) | |
340 | |
341 def validate(self): | |
342 # Find a way to check if one of the kids is a WHEN | |
343 pass | |
344 | |
345 | |
346 class When(InputParameter): | |
347 name = "when" | |
348 | |
349 def __init__(self, value): | |
350 params = Util.clean_kwargs(locals().copy()) | |
351 super(When, self).__init__(None, **params) | |
352 | |
353 def acceptable_child(self, child): | |
354 return issubclass(type(child), InputParameter) | |
355 | |
356 | |
357 class Param(InputParameter): | |
358 name = "param" | |
359 | |
360 # This...isn't really valid as-is, and shouldn't be used. | |
361 def __init__(self, name, optional=None, label=None, help=None, **kwargs): | |
362 params = Util.clean_kwargs(locals().copy()) | |
363 params["type"] = self.type | |
364 super(Param, self).__init__(**params) | |
365 | |
366 if type(self) == Param: | |
367 raise Exception("Param class is not an actual parameter type, use a subclass of Param") | |
368 | |
369 def acceptable_child(self, child): | |
370 return issubclass(type(child, InputParameter) or isinstance(child), ValidatorParam) | |
371 | |
372 | |
373 class TextParam(Param): | |
374 type = "text" | |
375 | |
376 def __init__(self, name, optional=None, label=None, help=None, value=None, **kwargs): | |
377 params = Util.clean_kwargs(locals().copy()) | |
378 super(TextParam, self).__init__(**params) | |
379 | |
380 def command_line_actual(self): | |
381 try: | |
382 return self.command_line_override | |
383 except Exception: | |
384 if self.positional: | |
385 return self.mako_name() | |
386 else: | |
387 return f"{self.flag}{self.space_between_arg}'{self.mako_name()}'" | |
388 | |
389 | |
390 class _NumericParam(Param): | |
391 def __init__(self, name, value, optional=None, label=None, help=None, min=None, max=None, **kwargs): | |
392 params = Util.clean_kwargs(locals().copy()) | |
393 super(_NumericParam, self).__init__(**params) | |
394 | |
395 | |
396 class IntegerParam(_NumericParam): | |
397 type = "integer" | |
398 | |
399 | |
400 class FloatParam(_NumericParam): | |
401 type = "float" | |
402 | |
403 | |
404 class BooleanParam(Param): | |
405 type = "boolean" | |
406 | |
407 def __init__( | |
408 self, name, optional=None, label=None, help=None, checked=False, truevalue=None, falsevalue=None, **kwargs | |
409 ): | |
410 params = Util.clean_kwargs(locals().copy()) | |
411 | |
412 super(BooleanParam, self).__init__(**params) | |
413 if truevalue is None: | |
414 # If truevalue and falsevalue are None, then we use "auto", the IUC | |
415 # recommended default. | |
416 # | |
417 # truevalue is set to the parameter's value, and falsevalue is not. | |
418 # | |
419 # Unfortunately, mako_identifier is set as a result of the super | |
420 # call, which we shouldn't call TWICE, so we'll just hack around this :( | |
421 # params['truevalue'] = '%s%s' % (self.) | |
422 self.node.attrib["truevalue"] = self.flag() | |
423 | |
424 if falsevalue is None: | |
425 self.node.attrib["falsevalue"] = "" | |
426 | |
427 def command_line_actual(self): | |
428 if hasattr(self, "command_line_override"): | |
429 return self.command_line_override | |
430 else: | |
431 return "%s" % self.mako_name() | |
432 | |
433 | |
434 class DataParam(Param): | |
435 type = "data" | |
436 | |
437 def __init__(self, name, optional=None, label=None, help=None, format=None, multiple=None, **kwargs): | |
438 params = Util.clean_kwargs(locals().copy()) | |
439 super(DataParam, self).__init__(**params) | |
440 | |
441 | |
442 class SelectParam(Param): | |
443 type = "select" | |
444 | |
445 def __init__( | |
446 self, | |
447 name, | |
448 optional=None, | |
449 label=None, | |
450 help=None, | |
451 data_ref=None, | |
452 display=None, | |
453 multiple=None, | |
454 options=None, | |
455 default=None, | |
456 **kwargs | |
457 ): | |
458 params = Util.clean_kwargs(locals().copy()) | |
459 del params["options"] | |
460 del params["default"] | |
461 | |
462 super(SelectParam, self).__init__(**params) | |
463 | |
464 if options is not None and default is not None: | |
465 if default not in options: | |
466 raise Exception("Specified a default that isn't in options") | |
467 | |
468 if options: | |
469 for k, v in list(sorted(options.items())): | |
470 selected = k == default | |
471 self.append(SelectOption(k, v, selected=selected)) | |
472 | |
473 def acceptable_child(self, child): | |
474 return issubclass(type(child), SelectOption) or issubclass(type(child), Options) | |
475 | |
476 | |
477 class SelectOption(InputParameter): | |
478 name = "option" | |
479 | |
480 def __init__(self, value, text, selected=False, **kwargs): | |
481 params = Util.clean_kwargs(locals().copy()) | |
482 | |
483 passed_kwargs = {} | |
484 if selected: | |
485 passed_kwargs["selected"] = "true" | |
486 passed_kwargs["value"] = params["value"] | |
487 | |
488 super(SelectOption, self).__init__(None, **passed_kwargs) | |
489 self.node.text = str(text) | |
490 | |
491 | |
492 class Options(InputParameter): | |
493 name = "options" | |
494 | |
495 def __init__(self, from_dataset=None, from_file=None, from_data_table=None, from_parameter=None, **kwargs): | |
496 params = Util.clean_kwargs(locals().copy()) | |
497 super(Options, self).__init__(None, **params) | |
498 | |
499 def acceptable_child(self, child): | |
500 return issubclass(type(child), Column) or issubclass(type(child), Filter) | |
501 | |
502 | |
503 class Column(InputParameter): | |
504 name = "column" | |
505 | |
506 def __init__(self, name, index, **kwargs): | |
507 params = Util.clean_kwargs(locals().copy()) | |
508 super(Column, self).__init__(**params) | |
509 | |
510 | |
511 class Filter(InputParameter): | |
512 name = "filter" | |
513 | |
514 def __init__( | |
515 self, | |
516 type, | |
517 column=None, | |
518 name=None, | |
519 ref=None, | |
520 key=None, | |
521 multiple=None, | |
522 separator=None, | |
523 keep=None, | |
524 value=None, | |
525 ref_attribute=None, | |
526 index=None, | |
527 **kwargs | |
528 ): | |
529 params = Util.clean_kwargs(locals().copy()) | |
530 super(Filter, self).__init__(**params) | |
531 | |
532 | |
533 class ValidatorParam(InputParameter): | |
534 name = "validator" | |
535 | |
536 def __init__( | |
537 self, | |
538 type, | |
539 message=None, | |
540 filename=None, | |
541 metadata_name=None, | |
542 metadata_column=None, | |
543 line_startswith=None, | |
544 min=None, | |
545 max=None, | |
546 **kwargs | |
547 ): | |
548 params = Util.clean_kwargs(locals().copy()) | |
549 super(ValidatorParam, self).__init__(**params) | |
550 | |
551 | |
552 class Outputs(XMLParam): | |
553 name = "outputs" | |
554 | |
555 def acceptable_child(self, child): | |
556 return isinstance(child, OutputData) or isinstance(child, OutputCollection) | |
557 | |
558 | |
559 class OutputData(XMLParam): | |
560 """Copypasta of InputParameter, needs work | |
561 """ | |
562 | |
563 name = "data" | |
564 | |
565 def __init__( | |
566 self, | |
567 name, | |
568 format, | |
569 format_source=None, | |
570 metadata_source=None, | |
571 label=None, | |
572 from_work_dir=None, | |
573 hidden=False, | |
574 **kwargs | |
575 ): | |
576 # TODO: validate format_source&metadata_source against something in the | |
577 # XMLParam children tree. | |
578 self.mako_identifier = name | |
579 if "num_dashes" in kwargs: | |
580 self.num_dashes = kwargs["num_dashes"] | |
581 del kwargs["num_dashes"] | |
582 else: | |
583 self.num_dashes = 0 | |
584 self.space_between_arg = " " | |
585 params = Util.clean_kwargs(locals().copy()) | |
586 | |
587 super(OutputData, self).__init__(**params) | |
588 | |
589 def command_line(self): | |
590 if hasattr(self, "command_line_override"): | |
591 return self.command_line_override | |
592 else: | |
593 return "%s%s%s" % (self.flag(), self.space_between_arg, self.mako_name()) | |
594 | |
595 def mako_name(self): | |
596 return "$" + self.mako_identifier | |
597 | |
598 def flag(self): | |
599 flag = "-" * self.num_dashes | |
600 return flag + self.mako_identifier | |
601 | |
602 def acceptable_child(self, child): | |
603 return isinstance(child, OutputFilter) or isinstance(child, ChangeFormat) or isinstance(child, DiscoverDatasets) | |
604 | |
605 | |
606 class OutputFilter(XMLParam): | |
607 name = "filter" | |
608 | |
609 def __init__(self, text, **kwargs): | |
610 params = Util.clean_kwargs(locals().copy()) | |
611 del params["text"] | |
612 super(OutputFilter, self).__init__(**params) | |
613 self.node.text = text | |
614 | |
615 def acceptable_child(self, child): | |
616 return False | |
617 | |
618 | |
619 class ChangeFormat(XMLParam): | |
620 name = "change_format" | |
621 | |
622 def __init__(self, **kwargs): | |
623 params = Util.clean_kwargs(locals().copy()) | |
624 super(ChangeFormat, self).__init__(**params) | |
625 | |
626 def acceptable_child(self, child): | |
627 return isinstance(child, ChangeFormatWhen) | |
628 | |
629 | |
630 class ChangeFormatWhen(XMLParam): | |
631 name = "when" | |
632 | |
633 def __init__(self, input, format, value, **kwargs): | |
634 params = Util.clean_kwargs(locals().copy()) | |
635 super(ChangeFormatWhen, self).__init__(**params) | |
636 | |
637 def acceptable_child(self, child): | |
638 return False | |
639 | |
640 | |
641 class OutputCollection(XMLParam): | |
642 name = "collection" | |
643 | |
644 def __init__( | |
645 self, | |
646 name, | |
647 type=None, | |
648 label=None, | |
649 format_source=None, | |
650 type_source=None, | |
651 structured_like=None, | |
652 inherit_format=None, | |
653 **kwargs | |
654 ): | |
655 params = Util.clean_kwargs(locals().copy()) | |
656 super(OutputCollection, self).__init__(**params) | |
657 | |
658 def acceptable_child(self, child): | |
659 return isinstance(child, OutputData) or isinstance(child, OutputFilter) or isinstance(child, DiscoverDatasets) | |
660 | |
661 | |
662 class DiscoverDatasets(XMLParam): | |
663 name = "discover_datasets" | |
664 | |
665 def __init__(self, pattern, directory=None, format=None, ext=None, visible=None, **kwargs): | |
666 params = Util.clean_kwargs(locals().copy()) | |
667 super(DiscoverDatasets, self).__init__(**params) | |
668 | |
669 | |
670 class Tests(XMLParam): | |
671 name = "tests" | |
672 | |
673 def acceptable_child(self, child): | |
674 return issubclass(type(child), Test) | |
675 | |
676 | |
677 class Test(XMLParam): | |
678 name = "test" | |
679 | |
680 def acceptable_child(self, child): | |
681 return isinstance(child, TestParam) or isinstance(child, TestOutput) | |
682 | |
683 | |
684 class TestParam(XMLParam): | |
685 name = "param" | |
686 | |
687 def __init__(self, name, value=None, ftype=None, dbkey=None, **kwargs): | |
688 params = Util.clean_kwargs(locals().copy()) | |
689 super(TestParam, self).__init__(**params) | |
690 | |
691 | |
692 class TestOutput(XMLParam): | |
693 name = "output" | |
694 | |
695 def __init__( | |
696 self, | |
697 name=None, | |
698 file=None, | |
699 ftype=None, | |
700 sort=None, | |
701 value=None, | |
702 md5=None, | |
703 checksum=None, | |
704 compare=None, | |
705 lines_diff=None, | |
706 delta=None, | |
707 **kwargs | |
708 ): | |
709 params = Util.clean_kwargs(locals().copy()) | |
710 super(TestOutput, self).__init__(**params) | |
711 | |
712 | |
713 class Citations(XMLParam): | |
714 name = "citations" | |
715 | |
716 def acceptable_child(self, child): | |
717 return issubclass(type(child), Citation) | |
718 | |
719 def has_citation(self, type, value): | |
720 """ | |
721 Check the presence of a given citation. | |
722 | |
723 :type type: STRING | |
724 :type value: STRING | |
725 """ | |
726 for citation in self.children: | |
727 if citation.node.attrib["type"] == type and citation.node.text == value: | |
728 return True | |
729 return False | |
730 | |
731 | |
732 class Citation(XMLParam): | |
733 name = "citation" | |
734 | |
735 def __init__(self, type, value): | |
736 passed_kwargs = {} | |
737 passed_kwargs["type"] = type | |
738 super(Citation, self).__init__(**passed_kwargs) | |
739 self.node.text = str(value) |