Skip to content

Commit 102e72b

Browse files
committed
Add typing to hooks & patch
1 parent 395852e commit 102e72b

File tree

2 files changed

+38
-27
lines changed

2 files changed

+38
-27
lines changed

dash/_hooks.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,8 @@ def add_hook(
6161
hook: str,
6262
func: _t.Callable,
6363
priority: _t.Optional[int] = None,
64-
final=False,
65-
data=None,
64+
final: bool = False,
65+
data: _t.Optional[HookDataType] = None,
6666
):
6767
if final:
6868
existing = self._finals.get(hook)
@@ -117,7 +117,7 @@ def route(
117117
name: _t.Optional[str] = None,
118118
methods: _t.Sequence[str] = ("GET",),
119119
priority: _t.Optional[int] = None,
120-
final=False,
120+
final: bool = False,
121121
):
122122
"""
123123
Add a route to the Dash server.
@@ -136,7 +136,7 @@ def wrap(func: _t.Callable[[], _f.Response]):
136136

137137
return wrap
138138

139-
def error(self, priority: _t.Optional[int] = None, final=False):
139+
def error(self, priority: _t.Optional[int] = None, final: bool = False):
140140
"""Automatically add an error handler to the dash app."""
141141

142142
def _error(func: _t.Callable[[Exception], _t.Any]):
@@ -145,7 +145,9 @@ def _error(func: _t.Callable[[Exception], _t.Any]):
145145

146146
return _error
147147

148-
def callback(self, *args, priority: _t.Optional[int] = None, final=False, **kwargs):
148+
def callback(
149+
self, *args, priority: _t.Optional[int] = None, final: bool = False, **kwargs
150+
):
149151
"""
150152
Add a callback to all the apps with the hook installed.
151153
"""

dash/_patch.py

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
1+
from typing import List, Union, Optional, Any
2+
3+
14
def _operation(name, location, **kwargs):
25
return {"operation": name, "location": location, "params": dict(**kwargs)}
36

47

58
_noop = object()
69

10+
_KeyType = Union[str, int]
11+
712

8-
def validate_slice(obj):
13+
def validate_slice(obj: Any):
914
if isinstance(obj, slice):
1015
raise TypeError("a slice is not a valid index for patch")
1116

@@ -19,7 +24,11 @@ class Patch:
1924
Supported prop types: Dictionaries and lists.
2025
"""
2126

22-
def __init__(self, location=None, parent=None):
27+
def __init__(
28+
self,
29+
location: Optional[List[_KeyType]] = None,
30+
parent: Optional["Patch"] = None,
31+
):
2332
if location is not None:
2433
self._location = location
2534
else:
@@ -36,11 +45,11 @@ def __getstate__(self):
3645
def __setstate__(self, state):
3746
vars(self).update(state)
3847

39-
def __getitem__(self, item) -> "Patch":
48+
def __getitem__(self, item: _KeyType) -> "Patch":
4049
validate_slice(item)
4150
return Patch(location=self._location + [item], parent=self)
4251

43-
def __getattr__(self, item) -> "Patch":
52+
def __getattr__(self, item: _KeyType) -> "Patch":
4453
if item == "tolist":
4554
# to_json fix
4655
raise AttributeError
@@ -50,16 +59,16 @@ def __getattr__(self, item) -> "Patch":
5059
return self._operations # type: ignore
5160
return self.__getitem__(item)
5261

53-
def __setattr__(self, key, value):
62+
def __setattr__(self, key: _KeyType, value: Any):
5463
if key in ("_location", "_operations"):
5564
self.__dict__[key] = value
5665
else:
5766
self.__setitem__(key, value)
5867

59-
def __delattr__(self, item):
68+
def __delattr__(self, item: _KeyType):
6069
self.__delitem__(item)
6170

62-
def __setitem__(self, key, value):
71+
def __setitem__(self, key: _KeyType, value: Any):
6372
validate_slice(key)
6473
if value is _noop:
6574
# The += set themselves.
@@ -72,11 +81,11 @@ def __setitem__(self, key, value):
7281
)
7382
)
7483

75-
def __delitem__(self, key):
84+
def __delitem__(self, key: _KeyType):
7685
validate_slice(key)
7786
self._operations.append(_operation("Delete", self._location + [key]))
7887

79-
def __iadd__(self, other):
88+
def __iadd__(self, other: Any):
8089
if isinstance(other, (list, tuple)):
8190
self.extend(other)
8291
else:
@@ -85,25 +94,25 @@ def __iadd__(self, other):
8594
return self
8695
return _noop
8796

88-
def __isub__(self, other):
97+
def __isub__(self, other: Any):
8998
self._operations.append(_operation("Sub", self._location, value=other))
9099
if not self._location:
91100
return self
92101
return _noop
93102

94-
def __imul__(self, other):
103+
def __imul__(self, other: Any) -> "Patch":
95104
self._operations.append(_operation("Mul", self._location, value=other))
96105
if not self._location:
97106
return self
98107
return _noop
99108

100-
def __itruediv__(self, other):
109+
def __itruediv__(self, other: Any):
101110
self._operations.append(_operation("Div", self._location, value=other))
102111
if not self._location:
103112
return self
104113
return _noop
105114

106-
def __ior__(self, other):
115+
def __ior__(self, other: Any):
107116
self.update(E=other)
108117
if not self._location:
109118
return self
@@ -115,39 +124,39 @@ def __iter__(self):
115124
def __repr__(self):
116125
return f"<write-only dash.Patch object at {self._location}>"
117126

118-
def append(self, item):
127+
def append(self, item: Any) -> None:
119128
"""Add the item to the end of a list"""
120129
self._operations.append(_operation("Append", self._location, value=item))
121130

122-
def prepend(self, item):
131+
def prepend(self, item: Any) -> None:
123132
"""Add the item to the start of a list"""
124133
self._operations.append(_operation("Prepend", self._location, value=item))
125134

126-
def insert(self, index, item):
135+
def insert(self, index: int, item: Any) -> None:
127136
"""Add the item at the index of a list"""
128137
self._operations.append(
129138
_operation("Insert", self._location, value=item, index=index)
130139
)
131140

132-
def clear(self):
141+
def clear(self) -> None:
133142
"""Remove all items in a list"""
134143
self._operations.append(_operation("Clear", self._location))
135144

136-
def reverse(self):
145+
def reverse(self) -> None:
137146
"""Reversal of the order of items in a list"""
138147
self._operations.append(_operation("Reverse", self._location))
139148

140-
def extend(self, item):
149+
def extend(self, item: Union[list, tuple]) -> None:
141150
"""Add all the items to the end of a list"""
142151
if not isinstance(item, (list, tuple)):
143152
raise TypeError(f"{item} should be a list or tuple")
144153
self._operations.append(_operation("Extend", self._location, value=item))
145154

146-
def remove(self, item):
155+
def remove(self, item: Any) -> None:
147156
"""filter the item out of a list on the frontend"""
148157
self._operations.append(_operation("Remove", self._location, value=item))
149158

150-
def update(self, E=None, **F):
159+
def update(self, E: Any = None, **F) -> None:
151160
"""Merge a dict or keyword arguments with another dictionary"""
152161
value = E or {}
153162
value.update(F)
@@ -159,7 +168,7 @@ def sort(self):
159168
"sort is reserved for future use, use brackets to access this key on your object"
160169
)
161170

162-
def to_plotly_json(self):
171+
def to_plotly_json(self) -> Any:
163172
return {
164173
"__dash_patch_update": "__dash_patch_update",
165174
"operations": self._operations,

0 commit comments

Comments
 (0)