aboutsummaryrefslogtreecommitdiff
path: root/venv/lib/python3.8/site-packages/dash/_patch.py
diff options
context:
space:
mode:
authorsotech117 <michael_foiani@brown.edu>2025-07-31 17:27:24 -0400
committersotech117 <michael_foiani@brown.edu>2025-07-31 17:27:24 -0400
commit5bf22fc7e3c392c8bd44315ca2d06d7dca7d084e (patch)
tree8dacb0f195df1c0788d36dd0064f6bbaa3143ede /venv/lib/python3.8/site-packages/dash/_patch.py
parentb832d364da8c2efe09e3f75828caf73c50d01ce3 (diff)
add code for analysis of data
Diffstat (limited to 'venv/lib/python3.8/site-packages/dash/_patch.py')
-rw-r--r--venv/lib/python3.8/site-packages/dash/_patch.py175
1 files changed, 175 insertions, 0 deletions
diff --git a/venv/lib/python3.8/site-packages/dash/_patch.py b/venv/lib/python3.8/site-packages/dash/_patch.py
new file mode 100644
index 0000000..99a4a91
--- /dev/null
+++ b/venv/lib/python3.8/site-packages/dash/_patch.py
@@ -0,0 +1,175 @@
+from typing import List, Union, Optional, Any
+
+
+def _operation(name, location, **kwargs):
+ return {"operation": name, "location": location, "params": kwargs}
+
+
+_noop = object()
+
+_KeyType = Union[str, int]
+
+
+def validate_slice(obj: Any):
+ if isinstance(obj, slice):
+ raise TypeError("a slice is not a valid index for patch")
+
+
+class Patch:
+ """
+ Patch a callback output value
+
+ Act like a proxy of the output prop value on the frontend.
+
+ Supported prop types: Dictionaries and lists.
+ """
+
+ def __init__(
+ self,
+ location: Optional[List[_KeyType]] = None,
+ parent: Optional["Patch"] = None,
+ ):
+ if location is not None:
+ self._location = location
+ else:
+ # pylint: disable=consider-using-ternary
+ self._location = (parent and parent._location) or []
+ if parent is not None:
+ self._operations = parent._operations
+ else:
+ self._operations = []
+
+ def __getstate__(self):
+ return vars(self)
+
+ def __setstate__(self, state):
+ vars(self).update(state)
+
+ def __getitem__(self, item: _KeyType) -> "Patch":
+ validate_slice(item)
+ return Patch(location=self._location + [item], parent=self)
+
+ def __getattr__(self, item: _KeyType) -> "Patch":
+ if item == "tolist":
+ # to_json fix
+ raise AttributeError
+ if item == "_location":
+ return self._location # type: ignore
+ if item == "_operations":
+ return self._operations # type: ignore
+ return self.__getitem__(item)
+
+ def __setattr__(self, key: _KeyType, value: Any):
+ if key in ("_location", "_operations"):
+ self.__dict__[key] = value
+ else:
+ self.__setitem__(key, value)
+
+ def __delattr__(self, item: _KeyType):
+ self.__delitem__(item)
+
+ def __setitem__(self, key: _KeyType, value: Any):
+ validate_slice(key)
+ if value is _noop:
+ # The += set themselves.
+ return
+ self._operations.append(
+ _operation(
+ "Assign",
+ self._location + [key],
+ value=value,
+ )
+ )
+
+ def __delitem__(self, key: _KeyType):
+ validate_slice(key)
+ self._operations.append(_operation("Delete", self._location + [key]))
+
+ def __iadd__(self, other: Any):
+ if isinstance(other, (list, tuple)):
+ self.extend(other)
+ else:
+ self._operations.append(_operation("Add", self._location, value=other))
+ if not self._location:
+ return self
+ return _noop
+
+ def __isub__(self, other: Any):
+ self._operations.append(_operation("Sub", self._location, value=other))
+ if not self._location:
+ return self
+ return _noop
+
+ def __imul__(self, other: Any) -> "Patch":
+ self._operations.append(_operation("Mul", self._location, value=other))
+ if not self._location:
+ return self
+ return _noop
+
+ def __itruediv__(self, other: Any):
+ self._operations.append(_operation("Div", self._location, value=other))
+ if not self._location:
+ return self
+ return _noop
+
+ def __ior__(self, other: Any):
+ self.update(E=other)
+ if not self._location:
+ return self
+ return _noop
+
+ def __iter__(self):
+ raise TypeError("Patch objects are write-only, you cannot iterate them.")
+
+ def __repr__(self):
+ return f"<write-only dash.Patch object at {self._location}>"
+
+ def append(self, item: Any) -> None:
+ """Add the item to the end of a list"""
+ self._operations.append(_operation("Append", self._location, value=item))
+
+ def prepend(self, item: Any) -> None:
+ """Add the item to the start of a list"""
+ self._operations.append(_operation("Prepend", self._location, value=item))
+
+ def insert(self, index: int, item: Any) -> None:
+ """Add the item at the index of a list"""
+ self._operations.append(
+ _operation("Insert", self._location, value=item, index=index)
+ )
+
+ def clear(self) -> None:
+ """Remove all items in a list"""
+ self._operations.append(_operation("Clear", self._location))
+
+ def reverse(self) -> None:
+ """Reversal of the order of items in a list"""
+ self._operations.append(_operation("Reverse", self._location))
+
+ def extend(self, item: Union[list, tuple]) -> None:
+ """Add all the items to the end of a list"""
+ if not isinstance(item, (list, tuple)):
+ raise TypeError(f"{item} should be a list or tuple")
+ self._operations.append(_operation("Extend", self._location, value=item))
+
+ def remove(self, item: Any) -> None:
+ """filter the item out of a list on the frontend"""
+ self._operations.append(_operation("Remove", self._location, value=item))
+
+ def update(self, E: Any = None, **F) -> None:
+ """Merge a dict or keyword arguments with another dictionary"""
+ value = E or {}
+ value.update(F)
+ self._operations.append(_operation("Merge", self._location, value=value))
+
+ # pylint: disable=no-self-use
+ def sort(self):
+ raise KeyError(
+ "sort is reserved for future use, use brackets to access this key on your object"
+ )
+
+ def to_plotly_json(self) -> Any:
+ return {
+ "__dash_patch_update": "__dash_patch_update",
+ "operations": self._operations,
+ }