about summary refs log tree commit diff
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 here HEAD master
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