Skip to content

Commit cbbbfcb

Browse files
authored
Merge pull request #3244 from plotly/master-3.0.1
Master 3.0.1
2 parents 304cfb2 + 5803dc4 commit cbbbfcb

File tree

16 files changed

+183
-63
lines changed

16 files changed

+183
-63
lines changed

.github/CODEOWNERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
# These owners will be the default owners for everything in
22
# the repo. Unless a later match takes precedence
3-
* @alexcjohnson @T4rk1n @ndrezn @gvwilson @emilykl
3+
* @T4rk1n @ndrezn @gvwilson @emilykl
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ignore_props = ['ignored_prop']

@plotly/dash-generator-test-component-typescript/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"scripts": {
1111
"build:js": "webpack --mode production",
1212
"setup": "python setup.py sdist",
13-
"build:py_and_r": "dash-generate-components ./src/components dash_generator_test_component_typescript && cp base/** dash_generator_test_component_typescript/ && dash-generate-components ./src/components dash_generator_test_component_typescript --r-prefix 'dgtc_ts'",
13+
"build:py_and_r": "dash-generate-components ./src/components dash_generator_test_component_typescript -t _dash_prop_typing && cp base/** dash_generator_test_component_typescript/",
1414
"build": "run-s build:js build:py_and_r setup",
1515
"test": "jest"
1616
},

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22
All notable changes to `dash` will be documented in this file.
33
This project adheres to [Semantic Versioning](https://semver.org/).
44

5+
## [3.0.1] - 2025-03-24
6+
7+
## Fixed
8+
9+
- [#3239](https://github.com/plotly/dash/pull/3239) Remove stringcase dependency, fix [#3238](https://github.com/plotly/dash/issues/3238)
10+
- [#3232](https://github.com/plotly/dash/pull/3232) Add error handling for when localStorage is disabled
11+
512
## [3.0.0] - 2025-03-17
613

714
## Added
@@ -45,6 +52,7 @@ This project adheres to [Semantic Versioning](https://semver.org/).
4552
- `Dash.run_server` has been removed in favor of `Dash.run`.
4653
- Removed `dcc.LogoutButton` component.
4754
- Renamed all `long` references to `background`.
55+
- Removed `dash_core_components`, `dash_html_components` and `dash_table` stub packages from `dash` install requirements.
4856

4957
## Changed
5058

components/dash-html-components/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,6 @@
5959
"/dash_html_components/*{.js,.map}"
6060
],
6161
"browserslist": [
62-
"last 9 years and not dead"
62+
"last 10 years and not dead"
6363
]
6464
}

dash/_dash_renderer.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import os
22

3-
__version__ = "2.0.4"
3+
__version__ = "2.0.5"
44

55
_available_react_versions = {"18.3.1", "18.2.0", "16.14.0"}
66
_available_reactdom_versions = {"18.3.1", "18.2.0", "16.14.0"}
@@ -64,7 +64,7 @@ def _set_react_version(v_react, v_reactdom=None):
6464
{
6565
"relative_package_path": "dash-renderer/build/dash_renderer.min.js",
6666
"dev_package_path": "dash-renderer/build/dash_renderer.dev.js",
67-
"external_url": "https://unpkg.com/[email protected].4"
67+
"external_url": "https://unpkg.com/[email protected].5"
6868
"/build/dash_renderer.min.js",
6969
"namespace": "dash",
7070
},

dash/_utils.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
import secrets
1212
import string
1313
import inspect
14+
import re
15+
1416
from html import escape
1517
from functools import wraps
1618
from typing import Union
@@ -302,3 +304,14 @@ def get_caller_name():
302304
return s.frame.f_locals.get("__name__", "__main__")
303305

304306
return "__main__"
307+
308+
309+
def pascal_case(name: Union[str, None]):
310+
s = re.sub(r"\s", "_", str(name))
311+
# Replace leading `_`
312+
s = re.sub("^[_]+", "", s)
313+
if not s:
314+
return s
315+
return s[0].upper() + re.sub(
316+
r"[\-_\.]+([a-z])", lambda match: match.group(1).upper(), s[1:]
317+
)

dash/dash-renderer/build/dash_renderer.dev.js

Lines changed: 64 additions & 20 deletions
Large diffs are not rendered by default.

dash/dash-renderer/package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dash/dash-renderer/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "dash-renderer",
3-
"version": "2.0.4",
3+
"version": "2.0.5",
44
"description": "render dash components in react",
55
"main": "build/dash_renderer.min.js",
66
"scripts": {

dash/dash-renderer/src/components/error/menu/VersionInfo.react.js

Lines changed: 69 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,17 @@ async function requestDashVersionInfo(config) {
3232
ddk_version: ddkVersion,
3333
plotly_version: plotlyVersion
3434
} = config;
35-
const cachedVersionInfo = localStorage.getItem('cachedNewDashVersion');
36-
const cachedNewDashVersionLink = localStorage.getItem(
37-
'cachedNewDashVersionLink'
38-
);
39-
const lastFetched = localStorage.getItem('lastFetched');
35+
let cachedVersionInfo, cachedNewDashVersionLink, lastFetched;
36+
try {
37+
cachedVersionInfo = localStorage.getItem('cachedNewDashVersion');
38+
cachedNewDashVersionLink = localStorage.getItem(
39+
'cachedNewDashVersionLink'
40+
);
41+
lastFetched = localStorage.getItem('lastFetched');
42+
} catch (e) {
43+
// If localStorage is not available, return an empty object
44+
return {};
45+
}
4046
if (
4147
lastFetched &&
4248
Date.now() - Number(lastFetched) < DAY_IN_MS &&
@@ -57,12 +63,19 @@ async function requestDashVersionInfo(config) {
5763
.then(response => response.json())
5864
.then(body => {
5965
if (body && body.version && body.link) {
60-
localStorage.setItem(
61-
'cachedNewDashVersion',
62-
JSON.stringify(body.version)
63-
);
64-
localStorage.setItem('cachedNewDashVersionLink', body.link);
65-
localStorage.setItem('lastFetched', Date.now());
66+
try {
67+
localStorage.setItem(
68+
'cachedNewDashVersion',
69+
JSON.stringify(body.version)
70+
);
71+
localStorage.setItem(
72+
'cachedNewDashVersionLink',
73+
body.link
74+
);
75+
localStorage.setItem('lastFetched', Date.now());
76+
} catch (e) {
77+
// Ignore errors if localStorage is not available
78+
}
6679
return body;
6780
} else {
6881
return {};
@@ -75,12 +88,20 @@ async function requestDashVersionInfo(config) {
7588
}
7689

7790
function shouldRequestDashVersion(config) {
78-
const showNotificationsLocalStorage =
79-
localStorage.getItem('showNotifications');
80-
const showNotifications = config.disable_version_check
81-
? false
82-
: showNotificationsLocalStorage !== 'false';
83-
const lastFetched = localStorage.getItem('lastFetched');
91+
// If version check is disabled, return false to avoid
92+
// checking localStorage unnecessarily
93+
if (config.disable_version_check) {
94+
return false;
95+
}
96+
let showNotifications, lastFetched;
97+
try {
98+
showNotifications =
99+
localStorage.getItem('showNotifications') !== 'false';
100+
lastFetched = localStorage.getItem('lastFetched');
101+
} catch (e) {
102+
// If localStorage is not available, return false
103+
return false;
104+
}
84105
return (
85106
showNotifications &&
86107
(!lastFetched || Date.now() - Number(lastFetched) > DAY_IN_MS)
@@ -92,13 +113,21 @@ function shouldShowUpgradeNotification(
92113
newDashVersion,
93114
config
94115
) {
95-
const showNotificationsLocalStorage =
96-
localStorage.getItem('showNotifications');
97-
const showNotifications = config.disable_version_check
98-
? false
99-
: showNotificationsLocalStorage !== 'false';
100-
const lastDismissed = localStorage.getItem('lastDismissed');
101-
const lastDismissedVersion = localStorage.getItem('lastDismissedVersion');
116+
// If version check is disabled, return false to avoid
117+
// checking localStorage unnecessarily
118+
if (config.disable_version_check) {
119+
return false;
120+
}
121+
let showNotifications, lastDismissed, lastDismissedVersion;
122+
try {
123+
showNotifications =
124+
localStorage.getItem('showNotifications') !== 'false';
125+
lastDismissed = localStorage.getItem('lastDismissed');
126+
lastDismissedVersion = localStorage.getItem('lastDismissedVersion');
127+
} catch (e) {
128+
// If localStorage is not available, return false
129+
return false;
130+
}
102131
if (
103132
newDashVersion === undefined ||
104133
compareVersions(currentDashVersion, newDashVersion) >= 0 ||
@@ -113,10 +142,7 @@ function shouldShowUpgradeNotification(
113142
} else if (
114143
lastDismissedVersion &&
115144
!lastDismissed &&
116-
compareVersions(
117-
localStorage.getItem('lastDismissedVersion'),
118-
newDashVersion
119-
) < 0
145+
compareVersions(lastDismissedVersion, newDashVersion) < 0
120146
) {
121147
return true;
122148
} else {
@@ -131,19 +157,31 @@ export const VersionInfo = ({config}) => {
131157

132158
const setDontShowAgain = () => {
133159
// Set local storage to record the last dismissed notification
134-
localStorage.setItem('showNotifications', false);
160+
try {
161+
localStorage.setItem('showNotifications', false);
162+
} catch (e) {
163+
// Ignore errors if localStorage is not available
164+
}
135165
setUpgradeTooltipOpened(false);
136166
};
137167

138168
const setRemindMeLater = () => {
139169
// Set local storage to record the last dismissed notification
140-
localStorage.setItem('lastDismissed', Date.now());
170+
try {
171+
localStorage.setItem('lastDismissed', Date.now());
172+
} catch (e) {
173+
// Ignore errors if localStorage is not available
174+
}
141175
setUpgradeTooltipOpened(false);
142176
};
143177

144178
const setSkipThisVersion = () => {
145179
// Set local storage to record the last dismissed version
146-
localStorage.setItem('lastDismissedVersion', newDashVersion);
180+
try {
181+
localStorage.setItem('lastDismissedVersion', newDashVersion);
182+
} catch (e) {
183+
// Ignore errors if localStorage is not available
184+
}
147185
setUpgradeTooltipOpened(false);
148186
};
149187

dash/development/_py_prop_typing.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import textwrap
55
import importlib
66

7-
import stringcase
7+
from .._utils import pascal_case
88

99

1010
shapes = {}
@@ -54,7 +54,7 @@ def generate_any(*_):
5454

5555
def generate_shape(type_info, component_name: str, prop_name: str):
5656
props = []
57-
name = stringcase.pascalcase(prop_name)
57+
name = pascal_case(prop_name)
5858

5959
for prop_key, prop_type in type_info["value"].items():
6060
typed = get_prop_typing(

dash/py.typed

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
partial

dash/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "3.0.0"
1+
__version__ = "3.0.1"

requirements/install.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,3 @@ requests
77
retrying
88
nest-asyncio
99
setuptools
10-
stringcase>=1.2.0

tests/unit/library/test_utils.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,19 @@ def test_ddut001_attribute_dict():
5858
a.x = 4
5959
assert err.value.args == ("Object is final: No new keys may be added.", "x")
6060
assert "x" not in a
61+
62+
63+
@pytest.mark.parametrize(
64+
"value,expected",
65+
[
66+
("foo_bar", "FooBar"),
67+
("", ""),
68+
("fooBarFoo", "FooBarFoo"),
69+
("foo bar", "FooBar"),
70+
("foo-bar", "FooBar"),
71+
("__private_prop", "PrivateProp"),
72+
("double__middle___triple", "DoubleMiddleTriple"),
73+
],
74+
)
75+
def test_ddut002_pascal_case(value, expected):
76+
assert utils.pascal_case(value) == expected

0 commit comments

Comments
 (0)