Mercurial > repos > shellac > guppy_basecaller
comparison env/lib/python3.7/site-packages/boto/ec2/instance.py @ 2:6af9afd405e9 draft
"planemo upload commit 0a63dd5f4d38a1f6944587f52a8cd79874177fc1"
author | shellac |
---|---|
date | Thu, 14 May 2020 14:56:58 -0400 |
parents | 26e78fe6e8c4 |
children |
comparison
equal
deleted
inserted
replaced
1:75ca89e9b81c | 2:6af9afd405e9 |
---|---|
1 # Copyright (c) 2006-2012 Mitch Garnaat http://garnaat.org/ | |
2 # Copyright (c) 2010, Eucalyptus Systems, Inc. | |
3 # Copyright (c) 2012 Amazon.com, Inc. or its affiliates. All Rights Reserved | |
4 # | |
5 # Permission is hereby granted, free of charge, to any person obtaining a | |
6 # copy of this software and associated documentation files (the | |
7 # "Software"), to deal in the Software without restriction, including | |
8 # without limitation the rights to use, copy, modify, merge, publish, dis- | |
9 # tribute, sublicense, and/or sell copies of the Software, and to permit | |
10 # persons to whom the Software is furnished to do so, subject to the fol- | |
11 # lowing conditions: | |
12 # | |
13 # The above copyright notice and this permission notice shall be included | |
14 # in all copies or substantial portions of the Software. | |
15 # | |
16 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |
17 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- | |
18 # ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT | |
19 # SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | |
20 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
21 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | |
22 # IN THE SOFTWARE. | |
23 | |
24 """ | |
25 Represents an EC2 Instance | |
26 """ | |
27 import boto | |
28 from boto.ec2.ec2object import EC2Object, TaggedEC2Object | |
29 from boto.resultset import ResultSet | |
30 from boto.ec2.address import Address | |
31 from boto.ec2.blockdevicemapping import BlockDeviceMapping | |
32 from boto.ec2.image import ProductCodes | |
33 from boto.ec2.networkinterface import NetworkInterface | |
34 from boto.ec2.group import Group | |
35 import base64 | |
36 | |
37 | |
38 class InstanceState(object): | |
39 """ | |
40 The state of the instance. | |
41 | |
42 :ivar code: The low byte represents the state. The high byte is an | |
43 opaque internal value and should be ignored. Valid values: | |
44 | |
45 * 0 (pending) | |
46 * 16 (running) | |
47 * 32 (shutting-down) | |
48 * 48 (terminated) | |
49 * 64 (stopping) | |
50 * 80 (stopped) | |
51 | |
52 :ivar name: The name of the state of the instance. Valid values: | |
53 | |
54 * "pending" | |
55 * "running" | |
56 * "shutting-down" | |
57 * "terminated" | |
58 * "stopping" | |
59 * "stopped" | |
60 """ | |
61 def __init__(self, code=0, name=None): | |
62 self.code = code | |
63 self.name = name | |
64 | |
65 def __repr__(self): | |
66 return '%s(%d)' % (self.name, self.code) | |
67 | |
68 def startElement(self, name, attrs, connection): | |
69 pass | |
70 | |
71 def endElement(self, name, value, connection): | |
72 if name == 'code': | |
73 self.code = int(value) | |
74 elif name == 'name': | |
75 self.name = value | |
76 else: | |
77 setattr(self, name, value) | |
78 | |
79 | |
80 class InstancePlacement(object): | |
81 """ | |
82 The location where the instance launched. | |
83 | |
84 :ivar zone: The Availability Zone of the instance. | |
85 :ivar group_name: The name of the placement group the instance is | |
86 in (for cluster compute instances). | |
87 :ivar tenancy: The tenancy of the instance (if the instance is | |
88 running within a VPC). An instance with a tenancy of dedicated | |
89 runs on single-tenant hardware. | |
90 """ | |
91 def __init__(self, zone=None, group_name=None, tenancy=None): | |
92 self.zone = zone | |
93 self.group_name = group_name | |
94 self.tenancy = tenancy | |
95 | |
96 def __repr__(self): | |
97 return self.zone | |
98 | |
99 def startElement(self, name, attrs, connection): | |
100 pass | |
101 | |
102 def endElement(self, name, value, connection): | |
103 if name == 'availabilityZone': | |
104 self.zone = value | |
105 elif name == 'groupName': | |
106 self.group_name = value | |
107 elif name == 'tenancy': | |
108 self.tenancy = value | |
109 else: | |
110 setattr(self, name, value) | |
111 | |
112 | |
113 class Reservation(EC2Object): | |
114 """ | |
115 Represents a Reservation response object. | |
116 | |
117 :ivar id: The unique ID of the Reservation. | |
118 :ivar owner_id: The unique ID of the owner of the Reservation. | |
119 :ivar groups: A list of Group objects representing the security | |
120 groups associated with launched instances. | |
121 :ivar instances: A list of Instance objects launched in this | |
122 Reservation. | |
123 """ | |
124 def __init__(self, connection=None): | |
125 super(Reservation, self).__init__(connection) | |
126 self.id = None | |
127 self.owner_id = None | |
128 self.groups = [] | |
129 self.instances = [] | |
130 | |
131 def __repr__(self): | |
132 return 'Reservation:%s' % self.id | |
133 | |
134 def startElement(self, name, attrs, connection): | |
135 if name == 'instancesSet': | |
136 self.instances = ResultSet([('item', Instance)]) | |
137 return self.instances | |
138 elif name == 'groupSet': | |
139 self.groups = ResultSet([('item', Group)]) | |
140 return self.groups | |
141 else: | |
142 return None | |
143 | |
144 def endElement(self, name, value, connection): | |
145 if name == 'reservationId': | |
146 self.id = value | |
147 elif name == 'ownerId': | |
148 self.owner_id = value | |
149 else: | |
150 setattr(self, name, value) | |
151 | |
152 def stop_all(self, dry_run=False): | |
153 for instance in self.instances: | |
154 instance.stop(dry_run=dry_run) | |
155 | |
156 | |
157 class Instance(TaggedEC2Object): | |
158 """ | |
159 Represents an instance. | |
160 | |
161 :ivar id: The unique ID of the Instance. | |
162 :ivar groups: A list of Group objects representing the security | |
163 groups associated with the instance. | |
164 :ivar public_dns_name: The public dns name of the instance. | |
165 :ivar private_dns_name: The private dns name of the instance. | |
166 :ivar state: The string representation of the instance's current state. | |
167 :ivar state_code: An integer representation of the instance's | |
168 current state. | |
169 :ivar previous_state: The string representation of the instance's | |
170 previous state. | |
171 :ivar previous_state_code: An integer representation of the | |
172 instance's current state. | |
173 :ivar key_name: The name of the SSH key associated with the instance. | |
174 :ivar instance_type: The type of instance (e.g. m1.small). | |
175 :ivar launch_time: The time the instance was launched. | |
176 :ivar image_id: The ID of the AMI used to launch this instance. | |
177 :ivar placement: The availability zone in which the instance is running. | |
178 :ivar placement_group: The name of the placement group the instance | |
179 is in (for cluster compute instances). | |
180 :ivar placement_tenancy: The tenancy of the instance, if the instance | |
181 is running within a VPC. An instance with a tenancy of dedicated | |
182 runs on a single-tenant hardware. | |
183 :ivar kernel: The kernel associated with the instance. | |
184 :ivar ramdisk: The ramdisk associated with the instance. | |
185 :ivar architecture: The architecture of the image (i386|x86_64). | |
186 :ivar hypervisor: The hypervisor used. | |
187 :ivar virtualization_type: The type of virtualization used. | |
188 :ivar product_codes: A list of product codes associated with this instance. | |
189 :ivar ami_launch_index: This instances position within it's launch group. | |
190 :ivar monitored: A boolean indicating whether monitoring is enabled or not. | |
191 :ivar monitoring_state: A string value that contains the actual value | |
192 of the monitoring element returned by EC2. | |
193 :ivar spot_instance_request_id: The ID of the spot instance request | |
194 if this is a spot instance. | |
195 :ivar subnet_id: The VPC Subnet ID, if running in VPC. | |
196 :ivar vpc_id: The VPC ID, if running in VPC. | |
197 :ivar private_ip_address: The private IP address of the instance. | |
198 :ivar ip_address: The public IP address of the instance. | |
199 :ivar platform: Platform of the instance (e.g. Windows) | |
200 :ivar root_device_name: The name of the root device. | |
201 :ivar root_device_type: The root device type (ebs|instance-store). | |
202 :ivar block_device_mapping: The Block Device Mapping for the instance. | |
203 :ivar state_reason: The reason for the most recent state transition. | |
204 :ivar interfaces: List of Elastic Network Interfaces associated with | |
205 this instance. | |
206 :ivar ebs_optimized: Whether instance is using optimized EBS volumes | |
207 or not. | |
208 :ivar instance_profile: A Python dict containing the instance | |
209 profile id and arn associated with this instance. | |
210 """ | |
211 | |
212 def __init__(self, connection=None): | |
213 super(Instance, self).__init__(connection) | |
214 self.id = None | |
215 self.dns_name = None | |
216 self.public_dns_name = None | |
217 self.private_dns_name = None | |
218 self.key_name = None | |
219 self.instance_type = None | |
220 self.launch_time = None | |
221 self.image_id = None | |
222 self.kernel = None | |
223 self.ramdisk = None | |
224 self.product_codes = ProductCodes() | |
225 self.ami_launch_index = None | |
226 self.monitored = False | |
227 self.monitoring_state = None | |
228 self.spot_instance_request_id = None | |
229 self.subnet_id = None | |
230 self.vpc_id = None | |
231 self.private_ip_address = None | |
232 self.ip_address = None | |
233 self.requester_id = None | |
234 self._in_monitoring_element = False | |
235 self.persistent = False | |
236 self.root_device_name = None | |
237 self.root_device_type = None | |
238 self.block_device_mapping = None | |
239 self.state_reason = None | |
240 self.group_name = None | |
241 self.client_token = None | |
242 self.eventsSet = None | |
243 self.groups = [] | |
244 self.platform = None | |
245 self.interfaces = [] | |
246 self.hypervisor = None | |
247 self.virtualization_type = None | |
248 self.architecture = None | |
249 self.instance_profile = None | |
250 self._previous_state = None | |
251 self._state = InstanceState() | |
252 self._placement = InstancePlacement() | |
253 | |
254 def __repr__(self): | |
255 return 'Instance:%s' % self.id | |
256 | |
257 @property | |
258 def state(self): | |
259 return self._state.name | |
260 | |
261 @property | |
262 def state_code(self): | |
263 return self._state.code | |
264 | |
265 @property | |
266 def previous_state(self): | |
267 if self._previous_state: | |
268 return self._previous_state.name | |
269 return None | |
270 | |
271 @property | |
272 def previous_state_code(self): | |
273 if self._previous_state: | |
274 return self._previous_state.code | |
275 return 0 | |
276 | |
277 @property | |
278 def placement(self): | |
279 return self._placement.zone | |
280 | |
281 @property | |
282 def placement_group(self): | |
283 return self._placement.group_name | |
284 | |
285 @property | |
286 def placement_tenancy(self): | |
287 return self._placement.tenancy | |
288 | |
289 def startElement(self, name, attrs, connection): | |
290 retval = super(Instance, self).startElement(name, attrs, connection) | |
291 if retval is not None: | |
292 return retval | |
293 if name == 'monitoring': | |
294 self._in_monitoring_element = True | |
295 elif name == 'blockDeviceMapping': | |
296 self.block_device_mapping = BlockDeviceMapping() | |
297 return self.block_device_mapping | |
298 elif name == 'productCodes': | |
299 return self.product_codes | |
300 elif name == 'stateReason': | |
301 self.state_reason = SubParse('stateReason') | |
302 return self.state_reason | |
303 elif name == 'groupSet': | |
304 self.groups = ResultSet([('item', Group)]) | |
305 return self.groups | |
306 elif name == "eventsSet": | |
307 self.eventsSet = SubParse('eventsSet') | |
308 return self.eventsSet | |
309 elif name == 'networkInterfaceSet': | |
310 self.interfaces = ResultSet([('item', NetworkInterface)]) | |
311 return self.interfaces | |
312 elif name == 'iamInstanceProfile': | |
313 self.instance_profile = SubParse('iamInstanceProfile') | |
314 return self.instance_profile | |
315 elif name == 'currentState': | |
316 return self._state | |
317 elif name == 'previousState': | |
318 self._previous_state = InstanceState() | |
319 return self._previous_state | |
320 elif name == 'instanceState': | |
321 return self._state | |
322 elif name == 'placement': | |
323 return self._placement | |
324 return None | |
325 | |
326 def endElement(self, name, value, connection): | |
327 if name == 'instanceId': | |
328 self.id = value | |
329 elif name == 'imageId': | |
330 self.image_id = value | |
331 elif name == 'dnsName' or name == 'publicDnsName': | |
332 self.dns_name = value # backwards compatibility | |
333 self.public_dns_name = value | |
334 elif name == 'privateDnsName': | |
335 self.private_dns_name = value | |
336 elif name == 'keyName': | |
337 self.key_name = value | |
338 elif name == 'amiLaunchIndex': | |
339 self.ami_launch_index = value | |
340 elif name == 'previousState': | |
341 self.previous_state = value | |
342 elif name == 'instanceType': | |
343 self.instance_type = value | |
344 elif name == 'rootDeviceName': | |
345 self.root_device_name = value | |
346 elif name == 'rootDeviceType': | |
347 self.root_device_type = value | |
348 elif name == 'launchTime': | |
349 self.launch_time = value | |
350 elif name == 'platform': | |
351 self.platform = value | |
352 elif name == 'kernelId': | |
353 self.kernel = value | |
354 elif name == 'ramdiskId': | |
355 self.ramdisk = value | |
356 elif name == 'state': | |
357 if self._in_monitoring_element: | |
358 self.monitoring_state = value | |
359 if value == 'enabled': | |
360 self.monitored = True | |
361 self._in_monitoring_element = False | |
362 elif name == 'spotInstanceRequestId': | |
363 self.spot_instance_request_id = value | |
364 elif name == 'subnetId': | |
365 self.subnet_id = value | |
366 elif name == 'vpcId': | |
367 self.vpc_id = value | |
368 elif name == 'privateIpAddress': | |
369 self.private_ip_address = value | |
370 elif name == 'ipAddress': | |
371 self.ip_address = value | |
372 elif name == 'requesterId': | |
373 self.requester_id = value | |
374 elif name == 'persistent': | |
375 if value == 'true': | |
376 self.persistent = True | |
377 else: | |
378 self.persistent = False | |
379 elif name == 'groupName': | |
380 if self._in_monitoring_element: | |
381 self.group_name = value | |
382 elif name == 'clientToken': | |
383 self.client_token = value | |
384 elif name == "eventsSet": | |
385 self.events = value | |
386 elif name == 'hypervisor': | |
387 self.hypervisor = value | |
388 elif name == 'virtualizationType': | |
389 self.virtualization_type = value | |
390 elif name == 'architecture': | |
391 self.architecture = value | |
392 elif name == 'ebsOptimized': | |
393 self.ebs_optimized = (value == 'true') | |
394 else: | |
395 setattr(self, name, value) | |
396 | |
397 def _update(self, updated): | |
398 self.__dict__.update(updated.__dict__) | |
399 | |
400 def update(self, validate=False, dry_run=False): | |
401 """ | |
402 Update the instance's state information by making a call to fetch | |
403 the current instance attributes from the service. | |
404 | |
405 :type validate: bool | |
406 :param validate: By default, if EC2 returns no data about the | |
407 instance the update method returns quietly. If | |
408 the validate param is True, however, it will | |
409 raise a ValueError exception if no data is | |
410 returned from EC2. | |
411 """ | |
412 rs = self.connection.get_all_reservations([self.id], dry_run=dry_run) | |
413 if len(rs) > 0: | |
414 r = rs[0] | |
415 for i in r.instances: | |
416 if i.id == self.id: | |
417 self._update(i) | |
418 elif validate: | |
419 raise ValueError('%s is not a valid Instance ID' % self.id) | |
420 return self.state | |
421 | |
422 def terminate(self, dry_run=False): | |
423 """ | |
424 Terminate the instance | |
425 """ | |
426 rs = self.connection.terminate_instances([self.id], dry_run=dry_run) | |
427 if len(rs) > 0: | |
428 self._update(rs[0]) | |
429 | |
430 def stop(self, force=False, dry_run=False): | |
431 """ | |
432 Stop the instance | |
433 | |
434 :type force: bool | |
435 :param force: Forces the instance to stop | |
436 | |
437 :rtype: list | |
438 :return: A list of the instances stopped | |
439 """ | |
440 rs = self.connection.stop_instances([self.id], force, dry_run=dry_run) | |
441 if len(rs) > 0: | |
442 self._update(rs[0]) | |
443 | |
444 def start(self, dry_run=False): | |
445 """ | |
446 Start the instance. | |
447 """ | |
448 rs = self.connection.start_instances([self.id], dry_run=dry_run) | |
449 if len(rs) > 0: | |
450 self._update(rs[0]) | |
451 | |
452 def reboot(self, dry_run=False): | |
453 return self.connection.reboot_instances([self.id], dry_run=dry_run) | |
454 | |
455 def get_console_output(self, dry_run=False): | |
456 """ | |
457 Retrieves the console output for the instance. | |
458 | |
459 :rtype: :class:`boto.ec2.instance.ConsoleOutput` | |
460 :return: The console output as a ConsoleOutput object | |
461 """ | |
462 return self.connection.get_console_output(self.id, dry_run=dry_run) | |
463 | |
464 def confirm_product(self, product_code, dry_run=False): | |
465 return self.connection.confirm_product_instance( | |
466 self.id, | |
467 product_code, | |
468 dry_run=dry_run | |
469 ) | |
470 | |
471 def use_ip(self, ip_address, dry_run=False): | |
472 """ | |
473 Associates an Elastic IP to the instance. | |
474 | |
475 :type ip_address: Either an instance of | |
476 :class:`boto.ec2.address.Address` or a string. | |
477 :param ip_address: The IP address to associate | |
478 with the instance. | |
479 | |
480 :rtype: bool | |
481 :return: True if successful | |
482 """ | |
483 | |
484 if isinstance(ip_address, Address): | |
485 ip_address = ip_address.public_ip | |
486 return self.connection.associate_address( | |
487 self.id, | |
488 ip_address, | |
489 dry_run=dry_run | |
490 ) | |
491 | |
492 def monitor(self, dry_run=False): | |
493 return self.connection.monitor_instance(self.id, dry_run=dry_run) | |
494 | |
495 def unmonitor(self, dry_run=False): | |
496 return self.connection.unmonitor_instance(self.id, dry_run=dry_run) | |
497 | |
498 def get_attribute(self, attribute, dry_run=False): | |
499 """ | |
500 Gets an attribute from this instance. | |
501 | |
502 :type attribute: string | |
503 :param attribute: The attribute you need information about | |
504 Valid choices are: | |
505 | |
506 * instanceType | |
507 * kernel | |
508 * ramdisk | |
509 * userData | |
510 * disableApiTermination | |
511 * instanceInitiatedShutdownBehavior | |
512 * rootDeviceName | |
513 * blockDeviceMapping | |
514 * productCodes | |
515 * sourceDestCheck | |
516 * groupSet | |
517 * ebsOptimized | |
518 | |
519 :rtype: :class:`boto.ec2.image.InstanceAttribute` | |
520 :return: An InstanceAttribute object representing the value of the | |
521 attribute requested | |
522 """ | |
523 return self.connection.get_instance_attribute( | |
524 self.id, | |
525 attribute, | |
526 dry_run=dry_run | |
527 ) | |
528 | |
529 def modify_attribute(self, attribute, value, dry_run=False): | |
530 """ | |
531 Changes an attribute of this instance | |
532 | |
533 :type attribute: string | |
534 :param attribute: The attribute you wish to change. | |
535 | |
536 * instanceType - A valid instance type (m1.small) | |
537 * kernel - Kernel ID (None) | |
538 * ramdisk - Ramdisk ID (None) | |
539 * userData - Base64 encoded String (None) | |
540 * disableApiTermination - Boolean (true) | |
541 * instanceInitiatedShutdownBehavior - stop|terminate | |
542 * sourceDestCheck - Boolean (true) | |
543 * groupSet - Set of Security Groups or IDs | |
544 * ebsOptimized - Boolean (false) | |
545 | |
546 :type value: string | |
547 :param value: The new value for the attribute | |
548 | |
549 :rtype: bool | |
550 :return: Whether the operation succeeded or not | |
551 """ | |
552 return self.connection.modify_instance_attribute( | |
553 self.id, | |
554 attribute, | |
555 value, | |
556 dry_run=dry_run | |
557 ) | |
558 | |
559 def reset_attribute(self, attribute, dry_run=False): | |
560 """ | |
561 Resets an attribute of this instance to its default value. | |
562 | |
563 :type attribute: string | |
564 :param attribute: The attribute to reset. Valid values are: | |
565 kernel|ramdisk | |
566 | |
567 :rtype: bool | |
568 :return: Whether the operation succeeded or not | |
569 """ | |
570 return self.connection.reset_instance_attribute( | |
571 self.id, | |
572 attribute, | |
573 dry_run=dry_run | |
574 ) | |
575 | |
576 def create_image(self, name, description=None, no_reboot=False, | |
577 dry_run=False): | |
578 """ | |
579 Will create an AMI from the instance in the running or stopped | |
580 state. | |
581 | |
582 :type name: string | |
583 :param name: The name of the new image | |
584 | |
585 :type description: string | |
586 :param description: An optional human-readable string describing | |
587 the contents and purpose of the AMI. | |
588 | |
589 :type no_reboot: bool | |
590 :param no_reboot: An optional flag indicating that the bundling process | |
591 should not attempt to shutdown the instance before | |
592 bundling. If this flag is True, the responsibility | |
593 of maintaining file system integrity is left to the | |
594 owner of the instance. | |
595 | |
596 :rtype: string | |
597 :return: The new image id | |
598 """ | |
599 return self.connection.create_image( | |
600 self.id, | |
601 name, | |
602 description, | |
603 no_reboot, | |
604 dry_run=dry_run | |
605 ) | |
606 | |
607 | |
608 class ConsoleOutput(object): | |
609 def __init__(self, parent=None): | |
610 self.parent = parent | |
611 self.instance_id = None | |
612 self.timestamp = None | |
613 self.output = None | |
614 | |
615 def startElement(self, name, attrs, connection): | |
616 return None | |
617 | |
618 def endElement(self, name, value, connection): | |
619 if name == 'instanceId': | |
620 self.instance_id = value | |
621 elif name == 'timestamp': | |
622 self.timestamp = value | |
623 elif name == 'output': | |
624 self.output = base64.b64decode(value) | |
625 else: | |
626 setattr(self, name, value) | |
627 | |
628 | |
629 class InstanceAttribute(dict): | |
630 ValidValues = ['instanceType', 'kernel', 'ramdisk', 'userData', | |
631 'disableApiTermination', | |
632 'instanceInitiatedShutdownBehavior', | |
633 'rootDeviceName', 'blockDeviceMapping', 'sourceDestCheck', | |
634 'groupSet'] | |
635 | |
636 def __init__(self, parent=None): | |
637 dict.__init__(self) | |
638 self.instance_id = None | |
639 self.request_id = None | |
640 self._current_value = None | |
641 | |
642 def startElement(self, name, attrs, connection): | |
643 if name == 'blockDeviceMapping': | |
644 self[name] = BlockDeviceMapping() | |
645 return self[name] | |
646 elif name == 'groupSet': | |
647 self[name] = ResultSet([('item', Group)]) | |
648 return self[name] | |
649 else: | |
650 return None | |
651 | |
652 def endElement(self, name, value, connection): | |
653 if name == 'instanceId': | |
654 self.instance_id = value | |
655 elif name == 'requestId': | |
656 self.request_id = value | |
657 elif name == 'value': | |
658 if value == 'true': | |
659 value = True | |
660 elif value == 'false': | |
661 value = False | |
662 self._current_value = value | |
663 elif name in self.ValidValues: | |
664 self[name] = self._current_value | |
665 | |
666 | |
667 class SubParse(dict): | |
668 def __init__(self, section, parent=None): | |
669 dict.__init__(self) | |
670 self.section = section | |
671 | |
672 def startElement(self, name, attrs, connection): | |
673 return None | |
674 | |
675 def endElement(self, name, value, connection): | |
676 if name != self.section: | |
677 self[name] = value |