code: def _parse_frange_part(frange):
          
          match = FRANGE_RE.match(frange)
          if not match:
              msg = 'Could not parse "{0}": did not match {1}'
              raise ParseException(msg.format(frange, FRANGE_RE.pattern))
          start, end, modifier, chunk = match.groups()
          start = int(start)
          end = int(end) if end is not None else start
  
          if end > start and chunk is not None and int(chunk) < 0:
              msg = 'Could not parse "{0}: chunk can not be negative'
              raise ParseException(msg.format(frange))
  
          chunk = abs(int(chunk)) if chunk is not None else 1
          # a zero chunk is just plain illogical
          if chunk == 0:
              msg = 'Could not parse "{0}": chunk cannot be 0'
              raise ParseException(msg.format(frange))
          return start, end, modifier, chunk
docs: Internal method: parse a discrete frame range part.
  
          Args:
              frange (str): single part of a frame range as a string
                  (ie "1-100x5")
  
          Returns:
              tuple: (start, end, modifier, chunk)
  
          Raises:
              :class:`.ParseException`: if the frame range can
                  not be parsed