aboutsummaryrefslogtreecommitdiff
path: root/.venv/lib/python3.12/site-packages/pydash/chaining/chaining.py
diff options
context:
space:
mode:
authorS. Solomon Darnell2025-03-28 21:52:21 -0500
committerS. Solomon Darnell2025-03-28 21:52:21 -0500
commit4a52a71956a8d46fcb7294ac71734504bb09bcc2 (patch)
treeee3dc5af3b6313e921cd920906356f5d4febc4ed /.venv/lib/python3.12/site-packages/pydash/chaining/chaining.py
parentcc961e04ba734dd72309fb548a2f97d67d578813 (diff)
downloadgn-ai-master.tar.gz
two version of R2R are hereHEADmaster
Diffstat (limited to '.venv/lib/python3.12/site-packages/pydash/chaining/chaining.py')
-rw-r--r--.venv/lib/python3.12/site-packages/pydash/chaining/chaining.py264
1 files changed, 264 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/pydash/chaining/chaining.py b/.venv/lib/python3.12/site-packages/pydash/chaining/chaining.py
new file mode 100644
index 00000000..09a364c5
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/pydash/chaining/chaining.py
@@ -0,0 +1,264 @@
+"""
+Method chaining interface.
+
+.. versionadded:: 1.0.0
+"""
+
+import typing as t
+
+import pydash as pyd
+from pydash.exceptions import InvalidMethod
+
+from ..helpers import UNSET, Unset
+from .all_funcs import AllFuncs
+
+
+__all__ = (
+ "chain",
+ "tap",
+)
+
+ValueT_co = t.TypeVar("ValueT_co", covariant=True)
+T = t.TypeVar("T")
+T2 = t.TypeVar("T2")
+
+
+class Chain(AllFuncs, t.Generic[ValueT_co]):
+ """Enables chaining of :attr:`module` functions."""
+
+ #: Object that contains attribute references to available methods.
+ module = pyd
+ invalid_method_exception = InvalidMethod
+
+ def __init__(self, value: t.Union[ValueT_co, Unset] = UNSET) -> None:
+ self._value = value
+
+ def _wrap(self, func) -> "ChainWrapper[t.Union[ValueT_co, Unset]]":
+ """Implement `AllFuncs` interface."""
+ return ChainWrapper(self._value, func)
+
+ def value(self) -> ValueT_co:
+ """
+ Return current value of the chain operations.
+
+ Returns:
+ Current value of chain operations.
+ """
+ return self(self._value)
+
+ def to_string(self) -> str:
+ """
+ Return current value as string.
+
+ Returns:
+ Current value of chain operations casted to ``str``.
+ """
+ return self.module.to_string(self.value())
+
+ def commit(self) -> "Chain[ValueT_co]":
+ """
+ Executes the chained sequence and returns the wrapped result.
+
+ Returns:
+ New instance of :class:`Chain` with resolved value from
+ previous :class:`Class`.
+ """
+ return Chain(self.value())
+
+ def plant(self, value: t.Any) -> "Chain[ValueT_co]":
+ """
+ Return a clone of the chained sequence planting `value` as the wrapped value.
+
+ Args:
+ value: Value to plant as the initial chain value.
+ """
+ # pylint: disable=no-member,maybe-no-member
+ wrapper = self._value
+ wrappers = []
+
+ if hasattr(wrapper, "_value"):
+ wrappers = [wrapper]
+
+ while isinstance(wrapper._value, ChainWrapper):
+ wrapper = wrapper._value # type: ignore
+ wrappers.insert(0, wrapper)
+
+ clone: Chain[t.Any] = Chain(value)
+
+ for wrap in wrappers:
+ clone = ChainWrapper(clone._value, wrap.method)( # type: ignore
+ *wrap.args, # type: ignore
+ **wrap.kwargs, # type: ignore
+ )
+
+ return clone
+
+ def __call__(self, value) -> ValueT_co:
+ """
+ Return result of passing `value` through chained methods.
+
+ Args:
+ value: Initial value to pass through chained methods.
+
+ Returns:
+ Result of method chain evaluation of `value`.
+ """
+ if isinstance(self._value, ChainWrapper):
+ # pylint: disable=maybe-no-member
+ value = self._value.unwrap(value)
+ return value
+
+
+class ChainWrapper(t.Generic[ValueT_co]):
+ """Wrap :class:`Chain` method call within a :class:`ChainWrapper` context."""
+
+ def __init__(self, value: ValueT_co, method) -> None:
+ self._value = value
+ self.method = method
+ self.args = ()
+ self.kwargs: t.Dict[t.Any, t.Any] = {}
+
+ def _generate(self):
+ """Generate a copy of this instance."""
+ # pylint: disable=attribute-defined-outside-init
+ new = self.__class__.__new__(self.__class__)
+ new.__dict__ = self.__dict__.copy()
+ return new
+
+ def unwrap(self, value=UNSET):
+ """
+ Execute :meth:`method` with :attr:`_value`, :attr:`args`, and :attr:`kwargs`.
+
+ If :attr:`_value` is an instance of :class:`ChainWrapper`, then unwrap it before calling
+ :attr:`method`.
+ """
+ # Generate a copy of ourself so that we don't modify the chain wrapper
+ # _value directly. This way if we are late passing a value, we don't
+ # "freeze" the chain wrapper value when a value is first passed.
+ # Otherwise, we'd locked the chain wrapper value permanently and not be
+ # able to reuse it.
+ wrapper = self._generate()
+
+ if isinstance(wrapper._value, ChainWrapper):
+ # pylint: disable=no-member,maybe-no-member
+ wrapper._value = wrapper._value.unwrap(value)
+ elif not isinstance(value, ChainWrapper) and value is not UNSET:
+ # Override wrapper's initial value.
+ wrapper._value = value
+
+ if wrapper._value is not UNSET:
+ value = wrapper._value
+
+ return wrapper.method(value, *wrapper.args, **wrapper.kwargs)
+
+ def __call__(self, *args, **kwargs):
+ """
+ Invoke the :attr:`method` with :attr:`value` as the first argument and return a new
+ :class:`Chain` object with the return value.
+
+ Returns:
+ New instance of :class:`Chain` with the results of :attr:`method` passed in as
+ value.
+ """
+ self.args = args
+ self.kwargs = kwargs
+ return Chain(self)
+
+
+class _Dash(object):
+ """Class that provides attribute access to valid :mod:`pydash` methods and callable access to
+ :mod:`pydash` method chaining."""
+
+ def __getattr__(self, attr):
+ """Proxy to :meth:`Chain.get_method`."""
+ return Chain.get_method(attr)
+
+ def __call__(self, value: t.Union[ValueT_co, Unset] = UNSET) -> Chain[ValueT_co]:
+ """Return a new instance of :class:`Chain` with `value` as the seed."""
+ return Chain(value)
+
+
+def chain(value: t.Union[T, Unset] = UNSET) -> Chain[T]:
+ """
+ Creates a :class:`Chain` object which wraps the given value to enable intuitive method chaining.
+ Chaining is lazy and won't compute a final value until :meth:`Chain.value` is called.
+
+ Args:
+ value: Value to initialize chain operations with.
+
+ Returns:
+ Instance of :class:`Chain` initialized with `value`.
+
+ Example:
+
+ >>> chain([1, 2, 3, 4]).map(lambda x: x * 2).sum().value()
+ 20
+ >>> chain().map(lambda x: x * 2).sum()([1, 2, 3, 4])
+ 20
+
+ >>> summer = chain([1, 2, 3, 4]).sum()
+ >>> new_summer = summer.plant([1, 2])
+ >>> new_summer.value()
+ 3
+ >>> summer.value()
+ 10
+
+ >>> def echo(item):
+ ... print(item)
+ >>> summer = chain([1, 2, 3, 4]).for_each(echo).sum()
+ >>> committed = summer.commit()
+ 1
+ 2
+ 3
+ 4
+ >>> committed.value()
+ 10
+ >>> summer.value()
+ 1
+ 2
+ 3
+ 4
+ 10
+
+ .. versionadded:: 1.0.0
+
+ .. versionchanged:: 2.0.0
+ Made chaining lazy.
+
+ .. versionchanged:: 3.0.0
+
+ - Added support for late passing of `value`.
+ - Added :meth:`Chain.plant` for replacing initial chain value.
+ - Added :meth:`Chain.commit` for returning a new :class:`Chain` instance initialized with
+ the results from calling :meth:`Chain.value`.
+ """
+ return Chain(value)
+
+
+def tap(value: T, interceptor: t.Callable[[T], t.Any]) -> T:
+ """
+ Invokes `interceptor` with the `value` as the first argument and then returns `value`. The
+ purpose of this method is to "tap into" a method chain in order to perform operations on
+ intermediate results within the chain.
+
+ Args:
+ value: Current value of chain operation.
+ interceptor: Function called on `value`.
+
+ Returns:
+ `value` after `interceptor` call.
+
+ Example:
+
+ >>> data = []
+ >>> def log(value):
+ ... data.append(value)
+ >>> chain([1, 2, 3, 4]).map(lambda x: x * 2).tap(log).value()
+ [2, 4, 6, 8]
+ >>> data
+ [[2, 4, 6, 8]]
+
+ .. versionadded:: 1.0.0
+ """
+ interceptor(value)
+ return value