Skip to content

util

Classes:

  • ExprVars

    A helper class for generating variable names used in RPN expressions.

Functions:

ExprVars

ExprVars(
    stop: SupportsIndex | Self | HoldsVideoFormatT | VideoFormatT,
    /,
    *,
    expr_src: bool = False,
)
ExprVars(
    start: SupportsIndex,
    stop: SupportsIndex,
    step: SupportsIndex = 1,
    /,
    *,
    expr_src: bool = False,
)
ExprVars(*args: Any, **kwargs: Any)
ExprVars(
    start_stop: SupportsIndex | Self | HoldsVideoFormatT | VideoFormatT,
    stop: SupportsIndex | MissingT = MISSING,
    step: SupportsIndex = 1,
    /,
    *,
    expr_src: bool = False,
)

Bases: Iterable[str]

A helper class for generating variable names used in RPN expressions.

Initialize an ExprVars instance.

Parameters:

  • start_stop

    (SupportsIndex | Self | HoldsVideoFormatT | VideoFormatT) –

    A start index or an object from which to infer the number of variables (e.g., video format).

  • stop

    (SupportsIndex | MissingT, default: MISSING ) –

    Stop index (exclusive). Required only if start_stop is a numeric start value.

  • step

    (SupportsIndex, default: 1 ) –

    Step size for iteration.

  • expr_src

    (bool, default: False ) –

    Whether to use srcX naming or use alphabetic variables.

Raises:

  • CustomIndexError

    If start is negative or stop is not greater than start.

  • CustomTypeError

    If invalid types are provided.

Methods:

  • __call__

    Allows an ExprVars instance to be called like a function to create a new instance with new parameters.

  • cycle

    An infinite generator of variable names, looping through EXPR_VARS then continuing with srcX style.

  • get_var

    Get a variable name for a specific index.

Attributes:

  • curr (int) –

    Current index in iteration.

  • expr_src (bool) –

    If True, variables are named as src0, src1, etc. Otherwise, "x", "y", "z", "a" and so on.

  • start (int) –

    Starting index for variable generation (inclusive).

  • step (int) –

    Step size for iteration.

  • stop (int) –

    Ending index for variable generation (exclusive).

Source code
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
def __init__(
    self,
    start_stop: SupportsIndex | Self | HoldsVideoFormatT | VideoFormatT,
    stop: SupportsIndex | MissingT = MISSING,
    step: SupportsIndex = 1,
    /,
    *,
    expr_src: bool = False,
) -> None:
    """
    Initialize an ExprVars instance.

    Args:
        start_stop: A start index or an object from which to infer the number of variables (e.g., video format).
        stop: Stop index (exclusive). Required only if `start_stop` is a numeric start value.
        step: Step size for iteration.
        expr_src: Whether to use `srcX` naming or use alphabetic variables.

    Raises:
        CustomIndexError: If `start` is negative or `stop` is not greater than `start`.
        CustomTypeError: If invalid types are provided.
    """
    if isinstance(start_stop, ExprVars):
        self.start = start_stop.start
        self.stop = start_stop.stop
        self.step = start_stop.step
        self.curr = start_stop.curr
        self.expr_src = start_stop.expr_src
        return

    if stop is MISSING:
        self.start = 0
        self.stop = (
            get_video_format(start_stop).num_planes
            if isinstance(start_stop, HoldsVideoFormatT | VideoFormatT)
            else start_stop.__index__()
        )
    else:
        if isinstance(start_stop, HoldsVideoFormatT | VideoFormatT):
            raise CustomTypeError("start cannot be a video format when stop is provided.", self, start_stop)
        self.start = start_stop.__index__()
        self.stop = stop.__index__()

    self.step = step.__index__()

    if self.start < 0:
        raise CustomIndexError('"start" must be greater than or equal to 0.', self, self.start)

    if self.stop <= self.start:
        raise CustomIndexError('"stop" must be greater than "start".', self, (self.start, self.stop))

    self.expr_src = expr_src
    self.curr = self.start

curr instance-attribute

curr: int = start

Current index in iteration.

expr_src instance-attribute

expr_src: bool = expr_src

If True, variables are named as src0, src1, etc. Otherwise, "x", "y", "z", "a" and so on.

start instance-attribute

start: int

Starting index for variable generation (inclusive).

step instance-attribute

step: int = __index__()

Step size for iteration.

stop instance-attribute

stop: int

Ending index for variable generation (exclusive).

__call__

__call__(
    stop: SupportsIndex | Self | HoldsVideoFormatT | VideoFormatT,
    /,
    *,
    expr_src: bool = False,
) -> Self
__call__(
    start: SupportsIndex,
    stop: SupportsIndex,
    step: SupportsIndex = 1,
    /,
    *,
    expr_src: bool = False,
) -> Self
__call__(
    start_stop: SupportsIndex | Self | HoldsVideoFormatT | VideoFormatT,
    stop: SupportsIndex | MissingT = MISSING,
    step: SupportsIndex = 1,
    /,
    *,
    expr_src: bool = False,
) -> Self

Allows an ExprVars instance to be called like a function to create a new instance with new parameters.

Parameters:

  • start_stop

    (SupportsIndex | Self | HoldsVideoFormatT | VideoFormatT) –

    A start index or an object from which to infer the number of variables (e.g., video format).

  • stop

    (SupportsIndex | MissingT, default: MISSING ) –

    Stop index (exclusive). Required only if start_stop is a numeric start value.

  • step

    (SupportsIndex, default: 1 ) –

    Step size for iteration.

  • expr_src

    (bool, default: False ) –

    Whether to use srcX naming or use alphabetic variables.

Returns:

  • Self

    A new instance with the specified parameters.

Source code
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
def __call__(
    self,
    start_stop: SupportsIndex | Self | HoldsVideoFormatT | VideoFormatT,
    stop: SupportsIndex | MissingT = MISSING,
    step: SupportsIndex = 1,
    /,
    *,
    expr_src: bool = False,
) -> Self:
    """
    Allows an ExprVars instance to be called like a function to create a new instance with new parameters.

    Args:
        start_stop: A start index or an object from which to infer the number of variables (e.g., video format).
        stop: Stop index (exclusive). Required only if `start_stop` is a numeric start value.
        step: Step size for iteration.
        expr_src: Whether to use `srcX` naming or use alphabetic variables.

    Returns:
        A new instance with the specified parameters.
    """

    return self.__class__(start_stop, stop, step, expr_src=expr_src)

cycle classmethod

cycle() -> Iterator[str]

An infinite generator of variable names, looping through EXPR_VARS then continuing with srcX style.

Returns:

  • Iterator[str]

    An infinite iterator of variable names.

Source code
226
227
228
229
230
231
232
233
234
235
236
@classproperty
@classmethod
def cycle(cls) -> Iterator[str]:
    """
    An infinite generator of variable names, looping through `EXPR_VARS` then continuing with `srcX` style.

    Returns:
        An infinite iterator of variable names.
    """
    for x in count():
        yield cls.get_var(x)

get_var classmethod

get_var(value: SupportsIndex) -> str

Get a variable name for a specific index.

Parameters:

Returns:

  • str

    The variable name.

Raises:

  • CustomIndexError

    If the index is negative.

Source code
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
@classmethod
def get_var(cls, value: SupportsIndex) -> str:
    """
    Get a variable name for a specific index.

    Args:
        value: Index to convert to variable name.

    Returns:
        The variable name.

    Raises:
        CustomIndexError: If the index is negative.
    """
    value = value.__index__()

    if value < 0:
        raise CustomIndexError('"value" should be bigger than 0!')

    return f"src{value}" if value > 25 else EXPR_VARS[value]

bitdepth_aware_tokenize_expr

bitdepth_aware_tokenize_expr(
    clips: Sequence[VideoNode],
    expr: str,
    chroma: bool,
    func: FuncExceptT | None = None,
) -> str
Source code
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
def bitdepth_aware_tokenize_expr(
    clips: Sequence[vs.VideoNode], expr: str, chroma: bool, func: FuncExceptT | None = None
) -> str:
    from .exprop import ExprToken

    func = func or bitdepth_aware_tokenize_expr

    if not expr or len(expr) < 4:
        return expr

    replaces = list[tuple[str, Callable[[vs.VideoNode, bool, ColorRange], float]]]()

    for token in sorted(ExprToken, key=lambda x: len(x), reverse=True):
        if token.value in expr:
            replaces.append((token.value, token.get_value))

        if token.name in expr:
            replaces.append((f"{token.__class__.__name__}.{token.name}", token.get_value))

    if not replaces:
        return expr

    clips = list(clips)
    ranges = [ColorRange.from_video(c, func=func) for c in clips]

    mapped_clips = list(reversed(list(zip(["", *EXPR_VARS], clips[:1] + clips, ranges[:1] + ranges))))

    for mkey, function in replaces:
        if mkey in expr:
            for key, clip, crange in [
                (f"{mkey}_{k}" if k else f"{mkey}", clip, crange) for k, clip, crange in mapped_clips
            ]:
                expr = re.sub(rf"\b{key}\b", str(function(clip, chroma, crange)), expr)

        if re.search(rf"\b{mkey}\b", expr):
            raise CustomIndexError("Parsing error or not enough clips passed!", func, reason=expr)

    return expr

extra_op_tokenize_expr

extra_op_tokenize_expr(expr: str) -> str
Source code
239
240
241
242
243
244
245
246
247
def extra_op_tokenize_expr(expr: str) -> str:
    # Workaround for the not implemented op
    from .exprop import ExprOp

    for extra_op in ExprOp._extra_op_names_:
        if extra_op.lower() in expr:
            expr = re.sub(rf"\b{extra_op.lower()}\b", getattr(ExprOp, extra_op).convert_extra(), expr)

    return expr

norm_expr_planes

norm_expr_planes(
    clip: VideoNode,
    expr: str | list[str],
    planes: PlanesT = None,
    **kwargs: Iterable[SupportsString] | SupportsString
) -> list[str]
Source code
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
def norm_expr_planes(
    clip: vs.VideoNode,
    expr: str | list[str],
    planes: PlanesT = None,
    **kwargs: Iterable[SupportsString] | SupportsString,
) -> list[str]:
    assert clip.format

    expr_array = normalize_seq(expr, clip.format.num_planes)

    planes = normalize_planes(clip, planes)

    string_args = [(key, normalize_seq(value)) for key, value in kwargs.items()]

    return [
        exp.format(**({"plane_idx": i} | {key: value[i] for key, value in string_args})) if i in planes else ""
        for i, exp in enumerate(expr_array)
    ]