| 56 | |
| 57 | |
| 58 | class Stack: |
| 59 | __slots__ = ("bottom", "frame") |
| 60 | |
| 61 | def __init__(self): |
| 62 | self.bottom = Frame() |
| 63 | self.frame = self.bottom |
| 64 | |
| 65 | def __contains__(self, key: str) -> bool: |
| 66 | if type(key) != str: |
| 67 | raise TypeError("Key index must be a string") |
| 68 | |
| 69 | try: |
| 70 | _ = self[key] |
| 71 | return True |
| 72 | except KeyError: |
| 73 | return False |
| 74 | |
| 75 | def __getitem__(self, key: str): |
| 76 | if type(key) != str: |
| 77 | raise TypeError("Key index must be a string") |
| 78 | |
| 79 | return self.frame[key] |
| 80 | |
| 81 | def __setitem__(self, key: str, value: Any): |
| 82 | if type(key) != str: |
| 83 | raise TypeError("Key index must be a string") |
| 84 | |
| 85 | self.frame[key] = value |
| 86 | |
| 87 | def push(self): |
| 88 | new_frame = Frame() |
| 89 | new_frame.previous = self.frame |
| 90 | self.frame = new_frame |
| 91 | |
| 92 | def pop(self): |
| 93 | top = self.frame |
| 94 | if top.previous is None: |
| 95 | raise ValueError("Can't pop top frame") |
| 96 | |
| 97 | self.frame = top.previous |
| 98 | del top |
| 99 | |
| 100 | def copy(self): |
| 101 | frames = [] |
| 102 | frame = self.frame |
| 103 | while frame: |
| 104 | new_frame = frame.copy() |
| 105 | if frames: |
| 106 | new_frame.previous = frames[-1] |
| 107 | frames.append(new_frame) |
| 108 | frame = frame.previous |
| 109 | |
| 110 | new_stack = self.__class__() |
| 111 | new_stack.frame = frames[-1] |
| 112 | new_stack.bottom = frames[0] |
| 113 | return new_stack |
| 114 | |
| 115 |
no outgoing calls