You can extend fileseq.FileSequence or fileseq.FilePathSequence by subclassing fileseq.BaseFileSequence. This allows you to support non-standard notation for frame ranges, padding, or path types by overriding specific internal hooks.
To create a fully round-trippable custom sequence (where str(seq) returns the original custom syntax), you typically need to override three methods:
_preprocess_sequence: Translate custom syntax into a format the fileseq grammar understands._resolve_padding: Translate the parsed grammar padding back into your custom token for internal storage.getPaddingNum: Ensure setPadding and other methods recognize your custom padding token.
Additionally, you can use _postprocess_sequence to restore custom syntax (like range delimiters) that isn't related to the padding token itself.
import re
import fileseq
class VRayFileSequence(fileseq.FileSequence):
"""Translate VRay `<frameNN>` padding tokens natively."""
_VRAY_PAD_RE = re.compile(r'<frame(\d+)>')
_used_custom_padding = False
def _preprocess_sequence(self, sequence: str) -> str:
"""Translate `<frameNN>` → `%0Nd` so the grammar accepts it."""
def replace(m):
width = int(m.group(1))
self._used_custom_padding = True
return '%0{}d'.format(width) if width > 0 else '%d'
return self._VRAY_PAD_RE.sub(replace, sequence)
def _resolve_padding(self, parsed_pad: str, zfill: int, pad_style) -> str:
"""Translate the parsed printf form back to the canonical VRay token."""
if zfill > 0 and self._used_custom_padding:
return '<frame{:02d}>'.format(zfill)
return parsed_pad
@classmethod
def getPaddingNum(cls, chars: str, **kwargs) -> int:
"""Recognise `<frameNN>` tokens in addition to the built-in formats."""
m = cls._VRAY_PAD_RE.match(chars)
if m:
return int(m.group(1))
return super().getPaddingNum(chars, **kwargs)
# Usage
seq = VRayFileSequence('/render/beauty.1-100<frame04>.exr')
print(seq.padding()) # '<frame04>'
print(str(seq)) # '/render/beauty.1-100<frame04>.exr'
print(seq.frame(42)) # '/render/beauty.0042.exr'