554 |
554 |
555 The part `type` is used to route the part to the application level |
555 The part `type` is used to route the part to the application level |
556 handler. |
556 handler. |
557 |
557 |
558 The part payload is contained in ``part.data``. It could be raw bytes or a |
558 The part payload is contained in ``part.data``. It could be raw bytes or a |
559 generator of byte chunks. The data attribute cannot be modified after the |
559 generator of byte chunks. |
560 generation has begun. |
560 |
|
561 You can add parameters to the part using the ``addparam`` method. |
|
562 Parameters can be either mandatory (default) or advisory. Remote side |
|
563 should be able to safely ignore the advisory ones. |
|
564 |
|
565 Both data and parameters cannot be modified after the generation has begun. |
561 """ |
566 """ |
562 |
567 |
563 def __init__(self, parttype, mandatoryparams=(), advisoryparams=(), |
568 def __init__(self, parttype, mandatoryparams=(), advisoryparams=(), |
564 data=''): |
569 data=''): |
565 self.id = None |
570 self.id = None |
566 self.type = parttype |
571 self.type = parttype |
567 self._data = data |
572 self._data = data |
568 self.mandatoryparams = mandatoryparams |
573 self._mandatoryparams = list(mandatoryparams) |
569 self.advisoryparams = advisoryparams |
574 self._advisoryparams = list(advisoryparams) |
570 # status of the part's generation: |
575 # status of the part's generation: |
571 # - None: not started, |
576 # - None: not started, |
572 # - False: currently generated, |
577 # - False: currently generated, |
573 # - True: generation done. |
578 # - True: generation done. |
574 self._generated = None |
579 self._generated = None |
579 raise ReadOnlyPartError('part is being generated') |
584 raise ReadOnlyPartError('part is being generated') |
580 self._data = data |
585 self._data = data |
581 def __getdata(self): |
586 def __getdata(self): |
582 return self._data |
587 return self._data |
583 data = property(__getdata, __setdata) |
588 data = property(__getdata, __setdata) |
|
589 |
|
590 @property |
|
591 def mandatoryparams(self): |
|
592 # make it an immutable tuple to force people through ``addparam`` |
|
593 return tuple(self._mandatoryparams) |
|
594 |
|
595 @property |
|
596 def advisoryparams(self): |
|
597 # make it an immutable tuple to force people through ``addparam`` |
|
598 return tuple(self._advisoryparams) |
|
599 |
|
600 def addparam(self, name, value='', mandatory=True): |
|
601 if self._generated is not None: |
|
602 raise ReadOnlyPartError('part is being generated') |
|
603 params = self._advisoryparams |
|
604 if mandatory: |
|
605 params = self._mandatoryparams |
|
606 params.append((name, value)) |
584 |
607 |
585 # methods used to generates the bundle2 stream |
608 # methods used to generates the bundle2 stream |
586 def getchunks(self): |
609 def getchunks(self): |
587 if self._generated is not None: |
610 if self._generated is not None: |
588 raise RuntimeError('part can only be consumed once') |
611 raise RuntimeError('part can only be consumed once') |