Module unda.unda_client
Expand source code
from collections import deque
from copy import copy, deepcopy
from typing import Dict, Optional
from .constants import DEEPCOPY, LOGGER, RESERVED_NAMES, STACK_HEIGHT
from .functions import extract_changes
class UndaClient:
"""
The `UndaClient` class.
Arguably the most powerful part of Unda. Performs the duties of undo and redo on behalf of another object.
## Usage
Create an UndaClient instance and pass your desired target object, e.g:
```python
target = MyFantasticObject()
my_client = UndaClient(target)
```
## Parameters
### _target:_
The object itself.
### _style:_
The `style` parameter specifies how this Client handles object state data.
There are two different styles:
* `DEEPCOPY` style: With this style, states are regarded as deep-copies of the target object.
* `LOGGER` style: This style regards states as changes to the `__dict__` attribute of the target object.
If left unspecified, Unda will resort to the best method for the current scenario.
To specify a desired style and override Unda's judgement (not recommended), import the name of the style you want,
e.g.:
```python
from unda import LOGGER
```
and pass it as the value of the `style` parameter.
### _auto_first_update:_
If this is set to True, the Client will automatically update the undo dict once it's created, so there would be no
need to call `update()` after creating the Client.
### _undo_stack:_
If any deque is passed, it will be used as the undo stack for the Client. If none is passed (by default), a new
deque will be created for that purpose.
### _redo_stack:_
If any deque is passed, it will be used as the redo stack for the Client. If none is passed (by default), a new
deque will be created for that purpose.
### _stack_height:_
The maximum number of states to store in either stack. Defaults to 30.
"""
def __init__(
self,
target: object,
style: Optional[str] = None,
auto_first_update: bool = True,
undo_stack: Optional[deque] = None,
redo_stack: Optional[deque] = None,
stack_height: Optional[int] = None
):
self.target = target
self.style = style
self.stack_height = stack_height
self.undo_stack = undo_stack
self.redo_stack = redo_stack
self._target_dict: Optional[Dict] = None
self._init_stack_height()
self._init_undo_stack()
self._init_redo_stack()
self._init_style()
if auto_first_update:
self._auto_first_update()
def _init_stack_height(self):
if self.stack_height is None:
self.stack_height = STACK_HEIGHT
def _init_undo_stack(self):
if self.undo_stack is None:
self.undo_stack = deque(maxlen=self.stack_height)
def _init_redo_stack(self):
if self.redo_stack is None:
self.redo_stack = deque(maxlen=self.stack_height)
def _init_style(self):
if self.style is None:
if 'dict' in vars(self.target) and self.target.__sizeof__() > self.target.__dict__.__sizeof__():
self._target_dict = self.__dict__.copy()
self.style = LOGGER
elif 'dict' not in vars(self.target):
self.style = DEEPCOPY
def _auto_first_update(self):
if self.style == DEEPCOPY:
self.undo_stack.append(deepcopy(self.target))
self.clear_redo_stack()
elif self.style == LOGGER:
if len(self.undo_stack) == self.undo_stack.maxlen:
change = self.undo_stack.popleft()
self._target_dict.update(change)
checklist_anomalies = extract_changes(
self.compile_stack(), self.__dict__)
self.undo_stack.append(checklist_anomalies)
self.clear_redo_stack()
del checklist_anomalies
def entrust(self, key, manager) -> None:
"""
Adds the client to the care of an `UndoManager` for easier batch use.
## Parameters
### _key:_
A string used for referencing this Client directly from the `UndaManager`.
### _manager:_
The `UndaManager` object to add this Client to.
"""
manager[key] = self
def clear_undo_stack(self) -> None:
"""
Clears the undo stack for this object.
"""
self.undo_stack.clear()
def clear_redo_stack(self) -> None:
"""
Clears the redo stack for this object.
"""
self.redo_stack.clear()
def clear_stacks(self) -> None:
"""
Clears both the undo and redo stacks for this object.
"""
self.clear_undo_stack()
self.clear_redo_stack()
def compile_stack(self, depth: Optional[int] = None,
start_point: Optional[int] = None,
stack: Optional[deque] = None) -> Dict:
"""
Useful only when using `LOGGER` style.
Creates a version of the target dict that has all state changes in the specified stack applied.
By default, the specified stack is the undo stack.
## Parameters
### _depth:_
The number of changes to apply. Defaults to the total number of changes in the entire stack.
### _start_point:_
The index of the first change to apply. Defaults to 0.
### _stack:_
The stack of relevance.
"""
if stack is None:
del stack
stack: deque = self.undo_stack
if depth is None:
del depth
depth: int = len(stack)
if start_point is None:
del start_point
start_point: int = 0
changes_required = list(stack.copy())[start_point:depth]
result = self._target_dict.copy()
for name in RESERVED_NAMES:
if name in result.keys():
del result[name]
for change in changes_required:
if change is not None:
result.update(change)
return result
def update(self) -> None:
"""
Updates the relevant stack with current state data.
By default, the "relevant stack" is the undo stack.
"""
if self.style == DEEPCOPY:
self.undo_stack.append(deepcopy(self.target))
self.clear_redo_stack()
if self.style == LOGGER:
# If the stack is full, make the oldest change permanent in the target_dict.
if len(self.undo_stack) == self.undo_stack.maxlen:
change = self.undo_stack.popleft()
self._target_dict.update(change)
checklist_anomalies = extract_changes(
self.compile_stack(), self.__dict__)
self.undo_stack.append(checklist_anomalies)
self.clear_redo_stack()
del checklist_anomalies
def undo(self, depth: int = 0, quiet: bool = False, inplace: bool = False) -> Optional[object]:
"""
Saves current state to the redo stack, then returns a version of the target object with the latest state data
in the undo stack applied.
## Parameters
### _depth:_
The number of states to skip with a single undo call. By default, it's 0, and should work for most uses.
### _quiet:_
Specifies if Unda should be quiet if undo is called but there's nothing to revert to. If False, an error will
be returned if that happens.
### _inplace:_
Useful only if the target object has a `__dict__` attribute.
If set to True, the `__dict__` of the target will be replaced by the `__dict__` value of the result of the undo
operation and returns False, thus there would be no need to re-assign the target object's variable to the
result (which is what should be done if this parameter is False).
"""
if not quiet and len(self.undo_stack) == 0:
raise IndexError('There\'s nothing left to undo.')
if self.style == DEEPCOPY:
# Clear all states above the required one.
self.undo_stack = deque(list(self.undo_stack)[0:len(
self.undo_stack) - depth + 1], maxlen=self.stack_height)
# Get the required state
result = self.undo_stack.pop()
# Save the state before the undo call to the redo stack.
self.redo_stack.append(deepcopy(self.target))
if inplace:
self.target.__dict__.update(result.__dict__)
return None
return result
if self.style == LOGGER:
print('Using LOGGER')
current_differences = extract_changes(
self.compile_stack(), self.__dict__)
self.redo_stack.append(current_differences)
result = self.compile_stack()
self.undo_stack = deque(
list(self.undo_stack)[0:len(self.undo_stack) - depth - 1],
maxlen=self.stack_height)
if inplace:
self.target.__dict__.update(result)
return None
_result = result
result = copy(self.target)
result.__dict__.update(_result)
return result
def redo(self, depth: int = 0, quiet: bool = False, inplace: bool = False) -> Optional[object]:
"""
Saves current state to the redo stack, then returns a version of the target object with the latest state data
in the redo stack applied.
## Parameters
### _depth:_
The number of states to skip with a single redo call. By default, it's 0, and should work for most uses.
### _quiet:_
Specifies if Unda should be quiet if redo is called but there's nothing to revert to. If False, an error will
be returned if that happens.
### _inplace:_
Useful only if the target object has a `__dict__` attribute.
If set to True, the `__dict__` of the target will be replaced by the `__dict__` value of the result of the redo
operation and returns False, thus there would be no need to re-assign the target object's variable to the
result (which is what should be done if this parameter is False).
"""
if not quiet and len(self.redo_stack) == 0:
raise IndexError('There\'s nothing left to redo.')
if self.style == DEEPCOPY:
# Clear all states above the required one.
self.redo_stack = deque(list(self.redo_stack)[0:len(
self.redo_stack) - depth + 1], maxlen=self.stack_height)
# Get the required state
result = self.redo_stack.pop()
# Save the state before the redo call to the undo stack.
self.undo_stack.append(deepcopy(self.target))
if inplace:
self.target.__dict__.update(result.__dict__)
return None
return result
if self.style == LOGGER:
current_differences = extract_changes(
self.compile_stack(), self.__dict__)
self.undo_stack.append(current_differences)
result = self.compile_stack()
self.redo_stack = deque(
list(self.redo_stack)[0:len(self.redo_stack) - depth - 1],
maxlen=self.stack_height)
if inplace:
self.target.__dict__.update(result)
return None
_result = result
result = copy(self.target)
result.__dict__.update(_result)
return result
Classes
class UndaClient (target: object, style: Optional[str] = None, auto_first_update: bool = True, undo_stack: Optional[collections.deque] = None, redo_stack: Optional[collections.deque] = None, stack_height: Optional[int] = None)
-
The
UndaClient
class. Arguably the most powerful part of Unda. Performs the duties of undo and redo on behalf of another object.Usage
Create an UndaClient instance and pass your desired target object, e.g:
target = MyFantasticObject() my_client = UndaClient(target)
Parameters
target:
The object itself.
style:
The
style
parameter specifies how this Client handles object state data. There are two different styles: *DEEPCOPY
style: With this style, states are regarded as deep-copies of the target object. *LOGGER
style: This style regards states as changes to the__dict__
attribute of the target object. If left unspecified, Unda will resort to the best method for the current scenario. To specify a desired style and override Unda's judgement (not recommended), import the name of the style you want, e.g.:from unda import LOGGER
and pass it as the value of the
style
parameter.auto_first_update:
If this is set to True, the Client will automatically update the undo dict once it's created, so there would be no need to call
update()
after creating the Client.undo_stack:
If any deque is passed, it will be used as the undo stack for the Client. If none is passed (by default), a new deque will be created for that purpose.
redo_stack:
If any deque is passed, it will be used as the redo stack for the Client. If none is passed (by default), a new deque will be created for that purpose.
stack_height:
The maximum number of states to store in either stack. Defaults to 30.
Expand source code
class UndaClient: """ The `UndaClient` class. Arguably the most powerful part of Unda. Performs the duties of undo and redo on behalf of another object. ## Usage Create an UndaClient instance and pass your desired target object, e.g: ```python target = MyFantasticObject() my_client = UndaClient(target) ``` ## Parameters ### _target:_ The object itself. ### _style:_ The `style` parameter specifies how this Client handles object state data. There are two different styles: * `DEEPCOPY` style: With this style, states are regarded as deep-copies of the target object. * `LOGGER` style: This style regards states as changes to the `__dict__` attribute of the target object. If left unspecified, Unda will resort to the best method for the current scenario. To specify a desired style and override Unda's judgement (not recommended), import the name of the style you want, e.g.: ```python from unda import LOGGER ``` and pass it as the value of the `style` parameter. ### _auto_first_update:_ If this is set to True, the Client will automatically update the undo dict once it's created, so there would be no need to call `update()` after creating the Client. ### _undo_stack:_ If any deque is passed, it will be used as the undo stack for the Client. If none is passed (by default), a new deque will be created for that purpose. ### _redo_stack:_ If any deque is passed, it will be used as the redo stack for the Client. If none is passed (by default), a new deque will be created for that purpose. ### _stack_height:_ The maximum number of states to store in either stack. Defaults to 30. """ def __init__( self, target: object, style: Optional[str] = None, auto_first_update: bool = True, undo_stack: Optional[deque] = None, redo_stack: Optional[deque] = None, stack_height: Optional[int] = None ): self.target = target self.style = style self.stack_height = stack_height self.undo_stack = undo_stack self.redo_stack = redo_stack self._target_dict: Optional[Dict] = None self._init_stack_height() self._init_undo_stack() self._init_redo_stack() self._init_style() if auto_first_update: self._auto_first_update() def _init_stack_height(self): if self.stack_height is None: self.stack_height = STACK_HEIGHT def _init_undo_stack(self): if self.undo_stack is None: self.undo_stack = deque(maxlen=self.stack_height) def _init_redo_stack(self): if self.redo_stack is None: self.redo_stack = deque(maxlen=self.stack_height) def _init_style(self): if self.style is None: if 'dict' in vars(self.target) and self.target.__sizeof__() > self.target.__dict__.__sizeof__(): self._target_dict = self.__dict__.copy() self.style = LOGGER elif 'dict' not in vars(self.target): self.style = DEEPCOPY def _auto_first_update(self): if self.style == DEEPCOPY: self.undo_stack.append(deepcopy(self.target)) self.clear_redo_stack() elif self.style == LOGGER: if len(self.undo_stack) == self.undo_stack.maxlen: change = self.undo_stack.popleft() self._target_dict.update(change) checklist_anomalies = extract_changes( self.compile_stack(), self.__dict__) self.undo_stack.append(checklist_anomalies) self.clear_redo_stack() del checklist_anomalies def entrust(self, key, manager) -> None: """ Adds the client to the care of an `UndoManager` for easier batch use. ## Parameters ### _key:_ A string used for referencing this Client directly from the `UndaManager`. ### _manager:_ The `UndaManager` object to add this Client to. """ manager[key] = self def clear_undo_stack(self) -> None: """ Clears the undo stack for this object. """ self.undo_stack.clear() def clear_redo_stack(self) -> None: """ Clears the redo stack for this object. """ self.redo_stack.clear() def clear_stacks(self) -> None: """ Clears both the undo and redo stacks for this object. """ self.clear_undo_stack() self.clear_redo_stack() def compile_stack(self, depth: Optional[int] = None, start_point: Optional[int] = None, stack: Optional[deque] = None) -> Dict: """ Useful only when using `LOGGER` style. Creates a version of the target dict that has all state changes in the specified stack applied. By default, the specified stack is the undo stack. ## Parameters ### _depth:_ The number of changes to apply. Defaults to the total number of changes in the entire stack. ### _start_point:_ The index of the first change to apply. Defaults to 0. ### _stack:_ The stack of relevance. """ if stack is None: del stack stack: deque = self.undo_stack if depth is None: del depth depth: int = len(stack) if start_point is None: del start_point start_point: int = 0 changes_required = list(stack.copy())[start_point:depth] result = self._target_dict.copy() for name in RESERVED_NAMES: if name in result.keys(): del result[name] for change in changes_required: if change is not None: result.update(change) return result def update(self) -> None: """ Updates the relevant stack with current state data. By default, the "relevant stack" is the undo stack. """ if self.style == DEEPCOPY: self.undo_stack.append(deepcopy(self.target)) self.clear_redo_stack() if self.style == LOGGER: # If the stack is full, make the oldest change permanent in the target_dict. if len(self.undo_stack) == self.undo_stack.maxlen: change = self.undo_stack.popleft() self._target_dict.update(change) checklist_anomalies = extract_changes( self.compile_stack(), self.__dict__) self.undo_stack.append(checklist_anomalies) self.clear_redo_stack() del checklist_anomalies def undo(self, depth: int = 0, quiet: bool = False, inplace: bool = False) -> Optional[object]: """ Saves current state to the redo stack, then returns a version of the target object with the latest state data in the undo stack applied. ## Parameters ### _depth:_ The number of states to skip with a single undo call. By default, it's 0, and should work for most uses. ### _quiet:_ Specifies if Unda should be quiet if undo is called but there's nothing to revert to. If False, an error will be returned if that happens. ### _inplace:_ Useful only if the target object has a `__dict__` attribute. If set to True, the `__dict__` of the target will be replaced by the `__dict__` value of the result of the undo operation and returns False, thus there would be no need to re-assign the target object's variable to the result (which is what should be done if this parameter is False). """ if not quiet and len(self.undo_stack) == 0: raise IndexError('There\'s nothing left to undo.') if self.style == DEEPCOPY: # Clear all states above the required one. self.undo_stack = deque(list(self.undo_stack)[0:len( self.undo_stack) - depth + 1], maxlen=self.stack_height) # Get the required state result = self.undo_stack.pop() # Save the state before the undo call to the redo stack. self.redo_stack.append(deepcopy(self.target)) if inplace: self.target.__dict__.update(result.__dict__) return None return result if self.style == LOGGER: print('Using LOGGER') current_differences = extract_changes( self.compile_stack(), self.__dict__) self.redo_stack.append(current_differences) result = self.compile_stack() self.undo_stack = deque( list(self.undo_stack)[0:len(self.undo_stack) - depth - 1], maxlen=self.stack_height) if inplace: self.target.__dict__.update(result) return None _result = result result = copy(self.target) result.__dict__.update(_result) return result def redo(self, depth: int = 0, quiet: bool = False, inplace: bool = False) -> Optional[object]: """ Saves current state to the redo stack, then returns a version of the target object with the latest state data in the redo stack applied. ## Parameters ### _depth:_ The number of states to skip with a single redo call. By default, it's 0, and should work for most uses. ### _quiet:_ Specifies if Unda should be quiet if redo is called but there's nothing to revert to. If False, an error will be returned if that happens. ### _inplace:_ Useful only if the target object has a `__dict__` attribute. If set to True, the `__dict__` of the target will be replaced by the `__dict__` value of the result of the redo operation and returns False, thus there would be no need to re-assign the target object's variable to the result (which is what should be done if this parameter is False). """ if not quiet and len(self.redo_stack) == 0: raise IndexError('There\'s nothing left to redo.') if self.style == DEEPCOPY: # Clear all states above the required one. self.redo_stack = deque(list(self.redo_stack)[0:len( self.redo_stack) - depth + 1], maxlen=self.stack_height) # Get the required state result = self.redo_stack.pop() # Save the state before the redo call to the undo stack. self.undo_stack.append(deepcopy(self.target)) if inplace: self.target.__dict__.update(result.__dict__) return None return result if self.style == LOGGER: current_differences = extract_changes( self.compile_stack(), self.__dict__) self.undo_stack.append(current_differences) result = self.compile_stack() self.redo_stack = deque( list(self.redo_stack)[0:len(self.redo_stack) - depth - 1], maxlen=self.stack_height) if inplace: self.target.__dict__.update(result) return None _result = result result = copy(self.target) result.__dict__.update(_result) return result
Methods
def clear_redo_stack(self) ‑> None
-
Clears the redo stack for this object.
Expand source code
def clear_redo_stack(self) -> None: """ Clears the redo stack for this object. """ self.redo_stack.clear()
def clear_stacks(self) ‑> None
-
Clears both the undo and redo stacks for this object.
Expand source code
def clear_stacks(self) -> None: """ Clears both the undo and redo stacks for this object. """ self.clear_undo_stack() self.clear_redo_stack()
def clear_undo_stack(self) ‑> None
-
Clears the undo stack for this object.
Expand source code
def clear_undo_stack(self) -> None: """ Clears the undo stack for this object. """ self.undo_stack.clear()
def compile_stack(self, depth: Optional[int] = None, start_point: Optional[int] = None, stack: Optional[collections.deque] = None) ‑> Dict[~KT, ~VT]
-
Useful only when using
LOGGER
style. Creates a version of the target dict that has all state changes in the specified stack applied. By default, the specified stack is the undo stack.Parameters
depth:
The number of changes to apply. Defaults to the total number of changes in the entire stack.
start_point:
The index of the first change to apply. Defaults to 0.
stack:
The stack of relevance.
Expand source code
def compile_stack(self, depth: Optional[int] = None, start_point: Optional[int] = None, stack: Optional[deque] = None) -> Dict: """ Useful only when using `LOGGER` style. Creates a version of the target dict that has all state changes in the specified stack applied. By default, the specified stack is the undo stack. ## Parameters ### _depth:_ The number of changes to apply. Defaults to the total number of changes in the entire stack. ### _start_point:_ The index of the first change to apply. Defaults to 0. ### _stack:_ The stack of relevance. """ if stack is None: del stack stack: deque = self.undo_stack if depth is None: del depth depth: int = len(stack) if start_point is None: del start_point start_point: int = 0 changes_required = list(stack.copy())[start_point:depth] result = self._target_dict.copy() for name in RESERVED_NAMES: if name in result.keys(): del result[name] for change in changes_required: if change is not None: result.update(change) return result
def entrust(self, key, manager) ‑> None
-
Adds the client to the care of an
UndoManager
for easier batch use.Parameters
key:
A string used for referencing this Client directly from the
UndaManager
.manager:
The
UndaManager
object to add this Client to.Expand source code
def entrust(self, key, manager) -> None: """ Adds the client to the care of an `UndoManager` for easier batch use. ## Parameters ### _key:_ A string used for referencing this Client directly from the `UndaManager`. ### _manager:_ The `UndaManager` object to add this Client to. """ manager[key] = self
def redo(self, depth: int = 0, quiet: bool = False, inplace: bool = False) ‑> Optional[object]
-
Saves current state to the redo stack, then returns a version of the target object with the latest state data in the redo stack applied.
Parameters
depth:
The number of states to skip with a single redo call. By default, it's 0, and should work for most uses.
quiet:
Specifies if Unda should be quiet if redo is called but there's nothing to revert to. If False, an error will be returned if that happens.
inplace:
Useful only if the target object has a
__dict__
attribute. If set to True, the__dict__
of the target will be replaced by the__dict__
value of the result of the redo operation and returns False, thus there would be no need to re-assign the target object's variable to the result (which is what should be done if this parameter is False).Expand source code
def redo(self, depth: int = 0, quiet: bool = False, inplace: bool = False) -> Optional[object]: """ Saves current state to the redo stack, then returns a version of the target object with the latest state data in the redo stack applied. ## Parameters ### _depth:_ The number of states to skip with a single redo call. By default, it's 0, and should work for most uses. ### _quiet:_ Specifies if Unda should be quiet if redo is called but there's nothing to revert to. If False, an error will be returned if that happens. ### _inplace:_ Useful only if the target object has a `__dict__` attribute. If set to True, the `__dict__` of the target will be replaced by the `__dict__` value of the result of the redo operation and returns False, thus there would be no need to re-assign the target object's variable to the result (which is what should be done if this parameter is False). """ if not quiet and len(self.redo_stack) == 0: raise IndexError('There\'s nothing left to redo.') if self.style == DEEPCOPY: # Clear all states above the required one. self.redo_stack = deque(list(self.redo_stack)[0:len( self.redo_stack) - depth + 1], maxlen=self.stack_height) # Get the required state result = self.redo_stack.pop() # Save the state before the redo call to the undo stack. self.undo_stack.append(deepcopy(self.target)) if inplace: self.target.__dict__.update(result.__dict__) return None return result if self.style == LOGGER: current_differences = extract_changes( self.compile_stack(), self.__dict__) self.undo_stack.append(current_differences) result = self.compile_stack() self.redo_stack = deque( list(self.redo_stack)[0:len(self.redo_stack) - depth - 1], maxlen=self.stack_height) if inplace: self.target.__dict__.update(result) return None _result = result result = copy(self.target) result.__dict__.update(_result) return result
def undo(self, depth: int = 0, quiet: bool = False, inplace: bool = False) ‑> Optional[object]
-
Saves current state to the redo stack, then returns a version of the target object with the latest state data in the undo stack applied.
Parameters
depth:
The number of states to skip with a single undo call. By default, it's 0, and should work for most uses.
quiet:
Specifies if Unda should be quiet if undo is called but there's nothing to revert to. If False, an error will be returned if that happens.
inplace:
Useful only if the target object has a
__dict__
attribute. If set to True, the__dict__
of the target will be replaced by the__dict__
value of the result of the undo operation and returns False, thus there would be no need to re-assign the target object's variable to the result (which is what should be done if this parameter is False).Expand source code
def undo(self, depth: int = 0, quiet: bool = False, inplace: bool = False) -> Optional[object]: """ Saves current state to the redo stack, then returns a version of the target object with the latest state data in the undo stack applied. ## Parameters ### _depth:_ The number of states to skip with a single undo call. By default, it's 0, and should work for most uses. ### _quiet:_ Specifies if Unda should be quiet if undo is called but there's nothing to revert to. If False, an error will be returned if that happens. ### _inplace:_ Useful only if the target object has a `__dict__` attribute. If set to True, the `__dict__` of the target will be replaced by the `__dict__` value of the result of the undo operation and returns False, thus there would be no need to re-assign the target object's variable to the result (which is what should be done if this parameter is False). """ if not quiet and len(self.undo_stack) == 0: raise IndexError('There\'s nothing left to undo.') if self.style == DEEPCOPY: # Clear all states above the required one. self.undo_stack = deque(list(self.undo_stack)[0:len( self.undo_stack) - depth + 1], maxlen=self.stack_height) # Get the required state result = self.undo_stack.pop() # Save the state before the undo call to the redo stack. self.redo_stack.append(deepcopy(self.target)) if inplace: self.target.__dict__.update(result.__dict__) return None return result if self.style == LOGGER: print('Using LOGGER') current_differences = extract_changes( self.compile_stack(), self.__dict__) self.redo_stack.append(current_differences) result = self.compile_stack() self.undo_stack = deque( list(self.undo_stack)[0:len(self.undo_stack) - depth - 1], maxlen=self.stack_height) if inplace: self.target.__dict__.update(result) return None _result = result result = copy(self.target) result.__dict__.update(_result) return result
def update(self) ‑> None
-
Updates the relevant stack with current state data. By default, the "relevant stack" is the undo stack.
Expand source code
def update(self) -> None: """ Updates the relevant stack with current state data. By default, the "relevant stack" is the undo stack. """ if self.style == DEEPCOPY: self.undo_stack.append(deepcopy(self.target)) self.clear_redo_stack() if self.style == LOGGER: # If the stack is full, make the oldest change permanent in the target_dict. if len(self.undo_stack) == self.undo_stack.maxlen: change = self.undo_stack.popleft() self._target_dict.update(change) checklist_anomalies = extract_changes( self.compile_stack(), self.__dict__) self.undo_stack.append(checklist_anomalies) self.clear_redo_stack() del checklist_anomalies