def invertedFrameRange(self, zfill=0): """ Return the inverse of the :class:`FrameSet` 's frame range, padded if desired. The inverse is every frame within the full extent of the range. Examples: >>> FrameSet('1-100x2').invertedFrameRange() '2-98x2' >>> FrameSet('1-100x2').invertedFrameRange(5) '00002-00098x2' If the inverted frame size exceeds `fileseq.constants.MAX_FRAME_SIZE`, a ``MaxSizeException`` will be raised. Args: zfill (int): the width to use to zero-pad the frame range string Returns: str: Raises: :class:`fileseq.exceptions.MaxSizeException`: """ result = [] frames = sorted(self.items) for idx, frame in enumerate(frames[:-1]): next_frame = frames[idx + 1] if next_frame - frame != 1: r = xrange(frame + 1, next_frame) # Check if the next update to the result set # will exceed out max frame size. # Prevent memory overflows. self._maxSizeCheck(len(r) + len(result)) result += r if not result: return '' return FrameSet.framesToFrameRange(result, zfill=zfill, sort=False, compress=False)
def invertedFrameRange(self, zfill=0): """ Return the inverse of the :class:`FrameSet` 's frame range, padded if desired. The inverse is every frame within the full extent of the range. :Example: >>> FrameSet('1-100x2').invertedFrameRange() '2-98x2' >>> FrameSet('1-100x2').invertedFrameRange(5) '00002-00098x2' If the inverted frame size exceeds `fileseq.constants.MAX_FRAME_SIZE`, a ``MaxSizeException`` will be raised. :type zfill: int :param zfill: the width to use to zero-pad the frame range string :rtype: str :raises: :class:`fileseq.exceptions.MaxSizeException` """ result = [] frames = sorted(self.items) for idx, frame in enumerate(frames[:-1]): next_frame = frames[idx + 1] if next_frame - frame != 1: r = xrange(frame + 1, next_frame) # Check if the next update to the result set # will exceed out max frame size. # Prevent memory overflows. self._maxSizeCheck(len(r) + len(result)) result += r if not result: return '' return FrameSet.framesToFrameRange( result, zfill=zfill, sort=False, compress=False)
def __init__(self, frange): # if the user provides anything but a string, short-circuit the build if not isinstance(frange, basestring): # if it's apparently a FrameSet already, short-circuit the build if set(dir(frange)).issuperset(self.__slots__): for attr in self.__slots__: setattr(self, attr, getattr(frange, attr)) return # if it's inherently disordered, sort and build elif isinstance(frange, Set): self._maxSizeCheck(frange) self._items = frozenset(map(int, frange)) self._order = tuple(sorted(self._items)) self._frange = FrameSet.framesToFrameRange(self._order, sort=False, compress=False) return # if it's ordered, find unique and build elif isinstance(frange, Sequence): self._maxSizeCheck(frange) items = set() order = unique(items, map(int, frange)) self._order = tuple(order) self._items = frozenset(items) self._frange = FrameSet.framesToFrameRange(self._order, sort=False, compress=False) return # in all other cases, cast to a string else: try: frange = str(frange) except Exception as err: msg = 'Could not parse "{0}": cast to string raised: {1}' raise ParseException(msg.format(frange, err)) # we're willing to trim padding characters from consideration # this translation is orders of magnitude faster than prior method self._frange = str(frange).translate(None, ''.join(PAD_MAP.keys())) # because we're acting like a set, we need to support the empty set if not self._frange: self._items = frozenset() self._order = tuple() return # build the mutable stores, then cast to immutable for storage items = set() order = [] maxSize = constants.MAX_FRAME_SIZE for part in self._frange.split(","): # this is to deal with leading / trailing commas if not part: continue # parse the partial range start, end, modifier, chunk = FrameSet._parse_frange_part(part) # handle batched frames (1-100x5) if modifier == 'x': frames = xfrange(start, end, chunk, maxSize=maxSize) frames = [f for f in frames if f not in items] self._maxSizeCheck(len(frames) + len(items)) order.extend(frames) items.update(frames) # handle staggered frames (1-100:5) elif modifier == ':': for stagger in xrange(chunk, 0, -1): frames = xfrange(start, end, stagger, maxSize=maxSize) frames = [f for f in frames if f not in items] self._maxSizeCheck(len(frames) + len(items)) order.extend(frames) items.update(frames) # handle filled frames (1-100y5) elif modifier == 'y': not_good = frozenset( xfrange(start, end, chunk, maxSize=maxSize)) frames = xfrange(start, end, 1, maxSize=maxSize) frames = (f for f in frames if f not in not_good) frames = [f for f in frames if f not in items] self._maxSizeCheck(len(frames) + len(items)) order.extend(frames) items.update(frames) # handle full ranges and single frames else: frames = xfrange(start, end, 1 if start < end else -1, maxSize=maxSize) frames = [f for f in frames if f not in items] self._maxSizeCheck(len(frames) + len(items)) order.extend(frames) items.update(frames) # lock the results into immutable internals # this allows for hashing and fast equality checking self._items = frozenset(items) self._order = tuple(order)
def testXrange(self): # Test that a platform-specific xrange does not produce OverflowError xrng = utils.xrange(1, sys.maxsize) self.assertTrue(len(xrng) != 0)
def __init__(self, frange): # if the user provides anything but a string, short-circuit the build if not isinstance(frange, basestring): # if it's apparently a FrameSet already, short-circuit the build if set(dir(frange)).issuperset(self.__slots__): for attr in self.__slots__: setattr(self, attr, getattr(frange, attr)) return # if it's inherently disordered, sort and build elif isinstance(frange, Set): self._maxSizeCheck(frange) self._items = frozenset(map(int, frange)) self._order = tuple(sorted(self._items)) self._frange = FrameSet.framesToFrameRange( self._order, sort=False, compress=False) return # if it's ordered, find unique and build elif isinstance(frange, Sequence): self._maxSizeCheck(frange) items = set() order = unique(items, map(int, frange)) self._order = tuple(order) self._items = frozenset(items) self._frange = FrameSet.framesToFrameRange( self._order, sort=False, compress=False) return # in all other cases, cast to a string else: try: frange = str(frange) except Exception as err: msg = 'Could not parse "{0}": cast to string raised: {1}' raise ParseException(msg.format(frange, err)) # we're willing to trim padding characters from consideration # this translation is orders of magnitude faster than prior method self._frange = str(frange).translate(None, ''.join(PAD_MAP.keys())) # because we're acting like a set, we need to support the empty set if not self._frange: self._items = frozenset() self._order = tuple() return # build the mutable stores, then cast to immutable for storage items = set() order = [] maxSize = constants.MAX_FRAME_SIZE for part in self._frange.split(","): # this is to deal with leading / trailing commas if not part: continue # parse the partial range start, end, modifier, chunk = FrameSet._parse_frange_part(part) # handle batched frames (1-100x5) if modifier == 'x': frames = xfrange(start, end, chunk, maxSize=maxSize) frames = [f for f in frames if f not in items] self._maxSizeCheck(len(frames) + len(items)) order.extend(frames) items.update(frames) # handle staggered frames (1-100:5) elif modifier == ':': for stagger in xrange(chunk, 0, -1): frames = xfrange(start, end, stagger, maxSize=maxSize) frames = [f for f in frames if f not in items] self._maxSizeCheck(len(frames) + len(items)) order.extend(frames) items.update(frames) # handle filled frames (1-100y5) elif modifier == 'y': not_good = frozenset(xfrange(start, end, chunk, maxSize=maxSize)) frames = xfrange(start, end, 1, maxSize=maxSize) frames = (f for f in frames if f not in not_good) frames = [f for f in frames if f not in items] self._maxSizeCheck(len(frames) + len(items)) order.extend(frames) items.update(frames) # handle full ranges and single frames else: frames = xfrange(start, end, 1 if start < end else -1, maxSize=maxSize) frames = [f for f in frames if f not in items] self._maxSizeCheck(len(frames) + len(items)) order.extend(frames) items.update(frames) # lock the results into immutable internals # this allows for hashing and fast equality checking self._items = frozenset(items) self._order = tuple(order)