Skip to content

Commit 2852e17

Browse files
committed
Merge remote-tracking branch 'origin/dev' into cam/1263/fix-infinite-resize-loop
2 parents fae843c + b57e0f5 commit 2852e17

39 files changed

+716
-218
lines changed

.github/workflows/testing.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,7 @@ jobs:
135135

136136
- name: Run typing tests
137137
run: |
138-
cd tests
139-
pytest compliance/test_typing.py
138+
pytest tests/compliance/test_typing.py
140139
141140
background-callbacks:
142141
name: Run Background & Async Callback Tests (Python ${{ matrix.python-version }})

CHANGELOG.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,18 @@ This project adheres to [Semantic Versioning](https://semver.org/).
88
- [#3395](https://github.com/plotly/dash/pull/3396) Add position argument to hooks.devtool
99
- [#3403](https://github.com/plotly/dash/pull/3403) Add app_context to get_app, allowing to get the current app in routes.
1010
- [#3407](https://github.com/plotly/dash/pull/3407) Add `hidden` to callback arguments, hiding the callback from appearing in the devtool callback graph.
11+
- [#3397](https://github.com/plotly/dash/pull/3397) Add optional callbacks, suppressing callback warning for missing component ids for a single callback.
1112
- [#3424](https://github.com/plotly/dash/pull/3424) Adds support for `Patch` on clientside callbacks class `dash_clientside.Patch`, as well as supporting side updates, eg: (Running, SetProps).
1213
- [#3347](https://github.com/plotly/dash/pull/3347) Added 'api_endpoint' to `callback` to expose api endpoints at the provided path for use to be executed directly without dash.
14+
- [#3445](https://github.com/plotly/dash/pull/3445) Added API to reverse direction of slider component.
15+
- [#3460](https://github.com/plotly/dash/pull/3460) Add `/health` endpoint for server monitoring and health checks.
16+
- [#3465](https://github.com/plotly/dash/pull/3465) Plotly cloud integrations, add devtool API, placeholder plotly cloud CLI & publish button, `dash[cloud]` extra dependencies.
1317

1418
## Fixed
1519
- [#3395](https://github.com/plotly/dash/pull/3395) Fix Components added through set_props() cannot trigger related callback functions. Fix [#3316](https://github.com/plotly/dash/issues/3316)
16-
- [#3397](https://github.com/plotly/dash/pull/3397) Add optional callbacks, suppressing callback warning for missing component ids for a single callback.
1720
- [#3415](https://github.com/plotly/dash/pull/3415) Fix the error triggered when only a single no_update is returned for client-side callback functions with multiple Outputs. Fix [#3366](https://github.com/plotly/dash/issues/3366)
1821
- [#3416](https://github.com/plotly/dash/issues/3416) Fix DeprecationWarning in dash/_jupyter.py by migrating from deprecated ipykernel.comm.Comm to comm module
22+
- [#3488](https://github.com/plotly/dash/pull/3488) Fix pkgutil.find_loader removal in Python 3.14
1923

2024
## [3.2.0] - 2025-07-31
2125

components/dash-core-components/src/components/Slider.react.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,11 @@ Slider.propTypes = {
156156
*/
157157
verticalHeight: PropTypes.number,
158158

159+
/**
160+
* If the value is true, it means the component is rendered reverse.
161+
*/
162+
reverse: PropTypes.bool,
163+
159164
/**
160165
* Additional CSS class for the root DOM node
161166
*/
@@ -208,6 +213,7 @@ Slider.defaultProps = {
208213
persisted_props: ['value'],
209214
persistence_type: 'local',
210215
verticalHeight: 400,
216+
reverse: false,
211217
};
212218

213219
export const propTypes = Slider.propTypes;

components/dash-core-components/src/fragments/Slider.react.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ const sliderProps = [
2727
'included',
2828
'tooltip',
2929
'vertical',
30+
'reverse',
3031
'id',
3132
];
3233

dash/_callback.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import hashlib
33
from functools import wraps
44

5-
from typing import Callable, Optional, Any, List, Tuple, Union
5+
from typing import Callable, Optional, Any, List, Tuple, Union, Dict
66

77

88
import asyncio
@@ -59,10 +59,10 @@ def _invoke_callback(func, *args, **kwargs): # used to mark the frame for the d
5959
return func(*args, **kwargs) # %% callback invoked %%
6060

6161

62-
GLOBAL_CALLBACK_LIST = []
63-
GLOBAL_CALLBACK_MAP = {}
64-
GLOBAL_INLINE_SCRIPTS = []
65-
GLOBAL_API_PATHS = {}
62+
GLOBAL_CALLBACK_LIST: List[Any] = []
63+
GLOBAL_CALLBACK_MAP: Dict[str, Any] = {}
64+
GLOBAL_INLINE_SCRIPTS: List[Any] = []
65+
GLOBAL_API_PATHS: Dict[str, Any] = {}
6666

6767

6868
# pylint: disable=too-many-locals,too-many-arguments
@@ -177,7 +177,7 @@ def callback(
177177
callbacks in the Dash devtools.
178178
"""
179179

180-
background_spec = None
180+
background_spec: Any = None
181181

182182
config_prevent_initial_callbacks = _kwargs.pop(
183183
"config_prevent_initial_callbacks", False
@@ -186,7 +186,7 @@ def callback(
186186
callback_list = _kwargs.pop("callback_list", GLOBAL_CALLBACK_LIST)
187187

188188
if background:
189-
background_spec: Any = {
189+
background_spec = {
190190
"interval": interval,
191191
}
192192

@@ -687,7 +687,7 @@ def add_context(*args, **kwargs):
687687
args, kwargs, inputs_state_indices, has_output, insert_output
688688
)
689689

690-
response: dict = {"multi": True}
690+
response: dict = {"multi": True} # type: ignore
691691

692692
jsonResponse = None
693693
try:
@@ -759,7 +759,7 @@ async def async_add_context(*args, **kwargs):
759759
args, kwargs, inputs_state_indices, has_output, insert_output
760760
)
761761

762-
response: dict = {"multi": True}
762+
response = {"multi": True}
763763

764764
try:
765765
if background is not None:

dash/_callback_context.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@
1010
from ._utils import AttributeDict, stringify_id
1111

1212

13-
context_value = contextvars.ContextVar("callback_context")
13+
context_value: contextvars.ContextVar[
14+
typing.Dict[str, typing.Any]
15+
] = contextvars.ContextVar("callback_context")
1416
context_value.set({})
1517

1618

dash/_dash_renderer.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import os
2+
from typing import Any, List, Dict
23

34
__version__ = "2.2.0"
45

56
_available_react_versions = {"18.3.1", "18.2.0", "16.14.0"}
67
_available_reactdom_versions = {"18.3.1", "18.2.0", "16.14.0"}
7-
_js_dist_dependencies = [] # to be set by _set_react_version
8+
_js_dist_dependencies: List[Dict[str, Any]] = [] # to be set by _set_react_version
89

910

1011
def _set_react_version(v_react, v_reactdom=None):

dash/_get_app.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22

33
from contextvars import ContextVar, copy_context
44
from textwrap import dedent
5+
from typing import Any, Optional
56

6-
APP = None
7+
APP: Optional[Any] = None
78

8-
app_context = ContextVar("dash_app_context")
9+
app_context: ContextVar[Any] = ContextVar("dash_app_context")
910

1011

1112
def with_app_context(func):
@@ -39,6 +40,13 @@ def wrap(*args, **kwargs):
3940

4041

4142
def get_app():
43+
"""
44+
Return the current Dash app instance.
45+
46+
Useful in multi-page apps when Python files within the `pages/` folder
47+
need to reference the `app` object but importing it directly would cause
48+
a circular import error.
49+
"""
4250
try:
4351
ctx_app = app_context.get()
4452
if ctx_app is not None:

dash/_hooks.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@
2727

2828
# pylint: disable=too-few-public-methods
2929
class _Hook(_tx.Generic[HookDataType]):
30-
def __init__(self, func, priority=0, final=False, data: HookDataType = None):
30+
def __init__(
31+
self, func, priority=0, final=False, data: _t.Optional[HookDataType] = None
32+
):
3133
self.func = func
3234
self.final = final
3335
self.data = data
@@ -39,7 +41,7 @@ def __call__(self, *args, **kwargs):
3941

4042
class _Hooks:
4143
def __init__(self) -> None:
42-
self._ns = {
44+
self._ns: _t.Dict[str, _t.List[_t.Any]] = {
4345
"setup": [],
4446
"layout": [],
4547
"routes": [],
@@ -49,14 +51,14 @@ def __init__(self) -> None:
4951
"custom_data": [],
5052
"dev_tools": [],
5153
}
52-
self._js_dist = []
53-
self._css_dist = []
54+
self._js_dist: _t.List[_t.Any] = []
55+
self._css_dist: _t.List[_t.Any] = []
5456
self._clientside_callbacks: _t.List[
5557
_t.Tuple[ClientsideFuncType, _t.Any, _t.Any]
5658
] = []
5759

5860
# final hooks are a single hook added to the end of regular hooks.
59-
self._finals = {}
61+
self._finals: _t.Dict[str, _t.Any] = {}
6062

6163
def add_hook(
6264
self,

0 commit comments

Comments
 (0)