# Path: ebu_tt_live/bindings/pyxb_utils.py
# def get_xml_parsing_context():
#     """
#     The parsing context is a simple python dictionary that helps tie together semantic rules at parsing time.
# 
#     For example: making sure that limitedClockTimingtype and fullClockTimingType are instantiated appropriately taking
#     into account the timeBase attribute on the tt element. In that case when the timeBase element is encountered by the
#     parser is is added to the parsing context object to help PyXB make the right type in the timingType union.
# 
#     :return: dict that is te parsing context for the currently running parser
#     :return: None if not in parsing mode
#     """
#     log.debug('Accessing xml_parsing_context: {}'.format(__xml_parsing_context))
#     if __xml_parsing_context.parsing is False:
#         # We are not in parsing mode
#         return None
#     return __xml_parsing_context.context
# 
# Path: ebu_tt_live/errors.py
# class LogicError(Exception):
#     pass
# 
# class SemanticValidationError(Exception):
#     pass
# 
# class OutsideSegmentError(StopBranchIteration):
#     """
#     This exception is meant to be raised by the copying functionality to make the iterator know that a particular
#     subtree is not meant to be parsed.
#     """
# 
# Path: ebu_tt_live/strings.py
# ERR_SEMANTIC_VALIDATION_TIMING_TYPE = gettext('{attr_type}({attr_value}) is not a valid type for {attr_name} in timeBase={time_base}')


from datetime import timedelta
from ebu_tt_live.bindings import get_xml_parsing_context
from ebu_tt_live.errors import LogicError, SemanticValidationError, OutsideSegmentError
from ebu_tt_live.strings import ERR_SEMANTIC_VALIDATION_TIMING_TYPE
        else:
            # Fallback case if there is no duration specified the same as the other containers
            super(BodyTimingValidationMixin, self)._pre_calculate_end()
            # WARNING this assigns it so we are done
            return
        # If one of our special ifs worked let's assign the value here.
        self._pre_assign_end(proposed_end)

    def _pre_calculate_begin(self):
        self._pre_assign_begin(self._begin_timedelta)

    def _post_pop_end(self):
        end_timedelta = None

        if self._end_timedelta is not None or self._dur_timedelta is not None:
            # We pushed on the stack it is time to pop it
            end_timedelta = self._semantic_dataset['timing_end_stack'].pop()

        return end_timedelta

    def _semantic_timebase_validation(self, dataset, element_content):

        super(BodyTimingValidationMixin, self)._semantic_timebase_validation(dataset, element_content)
        time_base = dataset['tt_element'].timeBase

        if self.dur is not None:
            if hasattr(self.dur, 'compatible_timebases'):
                # Check typing of dur attribute against the timebase
                timebases = self.dur.compatible_timebases()
                if time_base not in timebases['dur']:

# Path: ebu_tt_live/bindings/pyxb_utils.py
# def get_xml_parsing_context():
#     """
#     The parsing context is a simple python dictionary that helps tie together semantic rules at parsing time.
# 
#     For example: making sure that limitedClockTimingtype and fullClockTimingType are instantiated appropriately taking
#     into account the timeBase attribute on the tt element. In that case when the timeBase element is encountered by the
#     parser is is added to the parsing context object to help PyXB make the right type in the timingType union.
# 
#     :return: dict that is te parsing context for the currently running parser
#     :return: None if not in parsing mode
#     """
#     log.debug('Accessing xml_parsing_context: {}'.format(__xml_parsing_context))
#     if __xml_parsing_context.parsing is False:
#         # We are not in parsing mode
#         return None
#     return __xml_parsing_context.context
# 
# Path: ebu_tt_live/errors.py
# class LogicError(Exception):
#     pass
# 
# class SemanticValidationError(Exception):
#     pass
# 
# class OutsideSegmentError(StopBranchIteration):
#     """
#     This exception is meant to be raised by the copying functionality to make the iterator know that a particular
#     subtree is not meant to be parsed.
#     """
# 
# Path: ebu_tt_live/strings.py
# ERR_SEMANTIC_VALIDATION_TIMING_TYPE = gettext('{attr_type}({attr_value}) is not a valid type for {attr_name} in timeBase={time_base}')


# Path: ebu_tt_live/bindings/validation/timing.py
from datetime import timedelta
from ebu_tt_live.bindings import get_xml_parsing_context
from ebu_tt_live.errors import LogicError, SemanticValidationError, OutsideSegmentError
from ebu_tt_live.strings import ERR_SEMANTIC_VALIDATION_TIMING_TYPE

        else:
            # Fallback case if there is no duration specified the same as the other containers
            super(BodyTimingValidationMixin, self)._pre_calculate_end()
            # WARNING this assigns it so we are done
            return
        # If one of our special ifs worked let's assign the value here.
        self._pre_assign_end(proposed_end)

    def _pre_calculate_begin(self):
        self._pre_assign_begin(self._begin_timedelta)

    def _post_pop_end(self):
        end_timedelta = None

        if self._end_timedelta is not None or self._dur_timedelta is not None:
            # We pushed on the stack it is time to pop it
            end_timedelta = self._semantic_dataset['timing_end_stack'].pop()

        return end_timedelta

    def _semantic_timebase_validation(self, dataset, element_content):

        super(BodyTimingValidationMixin, self)._semantic_timebase_validation(dataset, element_content)
        time_base = dataset['tt_element'].timeBase

        if self.dur is not None:
            if hasattr(self.dur, 'compatible_timebases'):
                # Check typing of dur attribute against the timebase
                timebases = self.dur.compatible_timebases()
                if time_base not in timebases['dur']:

                    raise SemanticValidationError(