From 2569e2b3c124fa2f2457d55ed7acbc7d3195a0da Mon Sep 17 00:00:00 2001 From: Ichunjo Date: Wed, 15 Jan 2025 04:06:04 +0100 Subject: [PATCH 1/3] norm_expr: supports TupleExprList --- vsexprtools/funcs.py | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/vsexprtools/funcs.py b/vsexprtools/funcs.py index de609de..8b5fb4b 100644 --- a/vsexprtools/funcs.py +++ b/vsexprtools/funcs.py @@ -2,7 +2,7 @@ from functools import partial from math import ceil -from typing import Any, Iterable, Literal, Sequence +from typing import Any, Iterable, Literal, Sequence, cast from vstools import ( CustomRuntimeError, CustomValueError, FuncExceptT, HoldsVideoFormatT, PlanesT, ProcessVariableResClip, StrArr, @@ -10,7 +10,7 @@ get_video_format, to_arr, vs ) -from .exprop import ExprOp, ExprOpBase +from .exprop import ExprOp, ExprOpBase, ExprList, TupleExprList from .util import ExprVars, bitdepth_aware_tokenize_expr, complexpr_available, norm_expr_planes __all__ = [ @@ -97,19 +97,37 @@ def combine( def norm_expr( - clips: VideoNodeIterable, expr: str | StrArr | tuple[str | StrArr, ...], planes: PlanesT = None, - format: HoldsVideoFormatT | VideoFormatT | None = None, opt: bool | None = None, - boundary: bool = True, force_akarin: Literal[False] | FuncExceptT = False, - func: FuncExceptT | None = None, split_planes: bool = False, **kwargs: Any + clips: VideoNodeIterable, + expr: str | StrArr | ExprList | tuple[str | StrArr | ExprList, ...] | TupleExprList, + planes: PlanesT = None, format: HoldsVideoFormatT | VideoFormatT | None = None, + opt: bool | None = None, boundary: bool = True, + force_akarin: Literal[False] | FuncExceptT = False, func: FuncExceptT | None = None, + split_planes: bool = False, + **kwargs: Any ) -> vs.VideoNode: clips = flatten_vnodes(clips, split_planes=split_planes) if isinstance(expr, str): nexpr = tuple([[expr]]) - elif not isinstance(expr, tuple): - nexpr = tuple([to_arr(expr)]) # type: ignore + elif isinstance(expr, tuple): + if isinstance(expr, TupleExprList): + if len(expr) < 1: + raise CustomRuntimeError( + "When passing a TupleExprList you need at least one expr in it!", func, expr + ) + + nclips: list[vs.VideoNode] | vs.VideoNode = clips + + for e in expr: + nclips = norm_expr( + nclips, e, planes, format, opt, boundary, force_akarin, func, split_planes, **kwargs + ) + + return cast(vs.VideoNode, nclips) + else: + nexpr = tuple([to_arr(x) for x in expr]) # type: ignore[arg-type] else: - nexpr = tuple([to_arr(x) for x in expr]) # type: ignore + nexpr = tuple([to_arr(expr)]) # type: ignore[arg-type] normalized_exprs = [StrList(plane_expr).to_str() for plane_expr in nexpr] From 559d44bfde91ff6c31fccf7a97afb48144a4ff20 Mon Sep 17 00:00:00 2001 From: Ichunjo Date: Wed, 15 Jan 2025 04:06:17 +0100 Subject: [PATCH 2/3] norm_expr: add docstring --- vsexprtools/funcs.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/vsexprtools/funcs.py b/vsexprtools/funcs.py index 8b5fb4b..d27acde 100644 --- a/vsexprtools/funcs.py +++ b/vsexprtools/funcs.py @@ -105,6 +105,25 @@ def norm_expr( split_planes: bool = False, **kwargs: Any ) -> vs.VideoNode: + """ + Evaluates an expression per pixel. + + :param clips: Input clip(s). + :param expr: Expression to be evaluated. + A single str will be processed for all planes. + A list will be concatenated to form a single expr for all planes. + A tuple of these types will allow to specify a different expr for each planes. + A TupleExprList will enable multiple passes of norm_expr based on the ExprLists. + included in it + :param planes: Planes to process, defaults to all. + :param format: Output format, defaults to the first clip format. + :param opt: Forces integer evaluation as much as possible. + :param boundary: Specifies the default boundary condition for relative pixel accesses: + - 0 means clamped + - 1 means mirrored + :param split_planes: Splits the VideoNodes into their individual planes. + :return: Evaluated clip. + """ clips = flatten_vnodes(clips, split_planes=split_planes) if isinstance(expr, str): From f0f0a71ff40bcb0fffea9099d29a8d0611a49697 Mon Sep 17 00:00:00 2001 From: Ichunjo Date: Wed, 15 Jan 2025 05:29:49 +0100 Subject: [PATCH 3/3] fix ESLism --- vsexprtools/funcs.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/vsexprtools/funcs.py b/vsexprtools/funcs.py index d27acde..9ec0257 100644 --- a/vsexprtools/funcs.py +++ b/vsexprtools/funcs.py @@ -112,10 +112,9 @@ def norm_expr( :param expr: Expression to be evaluated. A single str will be processed for all planes. A list will be concatenated to form a single expr for all planes. - A tuple of these types will allow to specify a different expr for each planes. - A TupleExprList will enable multiple passes of norm_expr based on the ExprLists. - included in it - :param planes: Planes to process, defaults to all. + A tuple of these types will allow specification of different expr for each planes. + A TupleExprList will make a norm_expr call for each expression within this tuple. + :param planes: Plane to process, defaults to all. :param format: Output format, defaults to the first clip format. :param opt: Forces integer evaluation as much as possible. :param boundary: Specifies the default boundary condition for relative pixel accesses: