From dd22fd09bab29fd0ba815167513c753f180ebb25 Mon Sep 17 00:00:00 2001 From: alexcjohnson Date: Tue, 29 Oct 2019 19:30:34 -0400 Subject: [PATCH 1/5] lint test_fingerprint --- tests/unit/test_fingerprint.py | 71 ++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 28 deletions(-) diff --git a/tests/unit/test_fingerprint.py b/tests/unit/test_fingerprint.py index 913fb09d0f..e8858f709b 100644 --- a/tests/unit/test_fingerprint.py +++ b/tests/unit/test_fingerprint.py @@ -1,51 +1,66 @@ - from dash.fingerprint import build_fingerprint, check_fingerprint version = 1 hash_value = 1 valid_resources = [ - {'path': 'react@16.8.6.min.js', 'fingerprint': 'react@16.v1m1.8.6.min.js'}, - {'path': 'react@16.8.6.min.js', 'fingerprint': 'react@16.v1_1_1m1234567890abcdef.8.6.min.js', 'version': '1.1.1', 'hash': '1234567890abcdef' }, - {'path': 'react@16.8.6.min.js', 'fingerprint': 'react@16.v1_1_1-alpha_1m1234567890abcdef.8.6.min.js', 'version': '1.1.1-alpha.1', 'hash': '1234567890abcdef' }, - {'path': 'dash.plotly.js', 'fingerprint': 'dash.v1m1.plotly.js'}, - {'path': 'dash.plotly.j_s', 'fingerprint': 'dash.v1m1.plotly.j_s'}, - {'path': 'dash.plotly.css', 'fingerprint': 'dash.v1m1.plotly.css'}, - {'path': 'dash.plotly.xxx.yyy.zzz', 'fingerprint': 'dash.v1m1.plotly.xxx.yyy.zzz'}, - {'path': 'dash~plotly.js', 'fingerprint': 'dash~plotly.v1m1.js'} + {"path": "react@16.8.6.min.js", "fingerprint": "react@16.v1m1.8.6.min.js"}, + { + "path": "react@16.8.6.min.js", + "fingerprint": "react@16.v1_1_1m1234567890abcdef.8.6.min.js", + "version": "1.1.1", + "hash": "1234567890abcdef", + }, + { + "path": "react@16.8.6.min.js", + "fingerprint": "react@16.v1_1_1-alpha_1m1234567890abcdef.8.6.min.js", + "version": "1.1.1-alpha.1", + "hash": "1234567890abcdef", + }, + {"path": "dash.plotly.js", "fingerprint": "dash.v1m1.plotly.js"}, + {"path": "dash.plotly.j_s", "fingerprint": "dash.v1m1.plotly.j_s"}, + {"path": "dash.plotly.css", "fingerprint": "dash.v1m1.plotly.css"}, + {"path": "dash.plotly.xxx.yyy.zzz", "fingerprint": "dash.v1m1.plotly.xxx.yyy.zzz"}, + {"path": "dash~plotly.js", "fingerprint": "dash~plotly.v1m1.js"}, ] valid_fingerprints = [ - 'react@16.v1_1_2m1571771240.8.6.min.js', - 'dash.plotly.v1_1_1m1234567890.js', - 'dash.plotly.v1_1_1m1234567890.j_s', - 'dash.plotly.v1_1_1m1234567890.css', - 'dash.plotly.v1_1_1m1234567890.xxx.yyy.zzz', - 'dash.plotly.v1_1_1-alpha1m1234567890.js', - 'dash.plotly.v1_1_1-alpha_3m1234567890.js', - 'dash.plotly.v1_1_1m1234567890123.js', - 'dash.plotly.v1_1_1m4bc3.js', - 'dash~plotly.v1m1.js' + "react@16.v1_1_2m1571771240.8.6.min.js", + "dash.plotly.v1_1_1m1234567890.js", + "dash.plotly.v1_1_1m1234567890.j_s", + "dash.plotly.v1_1_1m1234567890.css", + "dash.plotly.v1_1_1m1234567890.xxx.yyy.zzz", + "dash.plotly.v1_1_1-alpha1m1234567890.js", + "dash.plotly.v1_1_1-alpha_3m1234567890.js", + "dash.plotly.v1_1_1m1234567890123.js", + "dash.plotly.v1_1_1m4bc3.js", + "dash~plotly.v1m1.js", ] invalid_fingerprints = [ - 'dash.plotly.v1_1_1m1234567890..js', - 'dash.plotly.v1_1_1m1234567890.', - 'dash.plotly.v1_1_1m1234567890..', - 'dash.plotly.v1_1_1m1234567890.js.', - 'dash.plotly.v1_1_1m1234567890.j-s' + "dash.plotly.v1_1_1m1234567890..js", + "dash.plotly.v1_1_1m1234567890.", + "dash.plotly.v1_1_1m1234567890..", + "dash.plotly.v1_1_1m1234567890.js.", + "dash.plotly.v1_1_1m1234567890.j-s", ] + def test_fingerprint(): for resource in valid_resources: # The fingerprint matches expectations - fingerprint = build_fingerprint(resource.get('path'), resource.get('version', version), resource.get('hash', hash_value)) - assert fingerprint == resource.get('fingerprint') + fingerprint = build_fingerprint( + resource.get("path"), + resource.get("version", version), + resource.get("hash", hash_value), + ) + assert fingerprint == resource.get("fingerprint") (original_path, has_fingerprint) = check_fingerprint(fingerprint) - # The inverse operation returns that the fingerprint was valid and the original path + # The inverse operation returns that the fingerprint was valid + # and the original path assert has_fingerprint - assert original_path == resource.get('path') + assert original_path == resource.get("path") for resource in valid_fingerprints: (_, has_fingerprint) = check_fingerprint(resource) From f9277fe9af2fb639ab426cb846d201caa017e2d4 Mon Sep 17 00:00:00 2001 From: alexcjohnson Date: Tue, 29 Oct 2019 20:39:35 -0400 Subject: [PATCH 2/5] fix fingerprint for nested folders and pathological cases --- dash/fingerprint.py | 34 +++++++------- tests/unit/test_fingerprint.py | 81 +++++++++++++++++++++++++++------- 2 files changed, 81 insertions(+), 34 deletions(-) diff --git a/dash/fingerprint.py b/dash/fingerprint.py index 01db7af5aa..b9c23d3034 100644 --- a/dash/fingerprint.py +++ b/dash/fingerprint.py @@ -1,31 +1,27 @@ import re -build_regex = re.compile(r'^(?P[\w@~-]+)(?P.*)$') - -check_regex = re.compile( - r'^(?P.*)[.]v[\w-]+m[0-9a-fA-F]+(?P(?:(?:(? 2 and cache_regex.match(name_parts[1]): + original_name = ".".join([name_parts[0]] + name_parts[2:]) + return "/".join(path_parts[:-1] + [original_name]), True + + return path, False diff --git a/tests/unit/test_fingerprint.py b/tests/unit/test_fingerprint.py index e8858f709b..36de80ddcc 100644 --- a/tests/unit/test_fingerprint.py +++ b/tests/unit/test_fingerprint.py @@ -22,27 +22,78 @@ {"path": "dash.plotly.css", "fingerprint": "dash.v1m1.plotly.css"}, {"path": "dash.plotly.xxx.yyy.zzz", "fingerprint": "dash.v1m1.plotly.xxx.yyy.zzz"}, {"path": "dash~plotly.js", "fingerprint": "dash~plotly.v1m1.js"}, + {"path": "nested/folder/file.js", "fingerprint": "nested/folder/file.v1m1.js"}, + { + # kind of pathological, but we have what looks like a version string + # in a different place - still works + "path": "nested.v2m2/folder/file.js", + "fingerprint": "nested.v2m2/folder/file.v1m1.js" + }, + { + # even works if it gets doubled up in the right place + "path": "nested/folder/file.v2m2.js", + "fingerprint": "nested/folder/file.v1m1.v2m2.js" + }, + { + "path": "nested.dotted/folder.structure/file.name.css", + "fingerprint": "nested.dotted/folder.structure/file.v1m1.name.css", + }, + { + "path": "dash..plotly.js", + "fingerprint": "dash.v1_1_1m1234567890..plotly.js", + "version": "1.1.1", + "hash": "1234567890", + }, + { + "path": "dash.", + "fingerprint": "dash.v1_1_1m1234567890.", + "version": "1.1.1", + "hash": "1234567890", + }, + { + "path": "dash..", + "fingerprint": "dash.v1_1_1m1234567890..", + "version": "1.1.1", + "hash": "1234567890", + }, + { + "path": "dash.js.", + "fingerprint": "dash.v1_1_1m1234567890.js.", + "version": "1.1.1", + "hash": "1234567890", + }, + { + "path": "dash.j-s", + "fingerprint": "dash.v1_1_1m1234567890.j-s", + "version": "1.1.1", + "hash": "1234567890", + }, ] valid_fingerprints = [ "react@16.v1_1_2m1571771240.8.6.min.js", - "dash.plotly.v1_1_1m1234567890.js", - "dash.plotly.v1_1_1m1234567890.j_s", - "dash.plotly.v1_1_1m1234567890.css", - "dash.plotly.v1_1_1m1234567890.xxx.yyy.zzz", - "dash.plotly.v1_1_1-alpha1m1234567890.js", - "dash.plotly.v1_1_1-alpha_3m1234567890.js", - "dash.plotly.v1_1_1m1234567890123.js", - "dash.plotly.v1_1_1m4bc3.js", + "dash.v1_1_1m1234567890.plotly.js", + "dash.v1_1_1m1234567890.plotly.j_s", + "dash.v1_1_1m1234567890.plotly.css", + "dash.v1_1_1m1234567890.plotly.xxx.yyy.zzz", + "dash.v1_1_1-alpha1m1234567890.plotly.js", + "dash.v1_1_1-alpha_3m1234567890.plotly.js", + "dash.v1_1_1m1234567890123.plotly.js", + "dash.v1_1_1m4bc3.plotly.js", "dash~plotly.v1m1.js", + "nested/folder/file.v1m1.js", + "nested.dotted/folder.structure/file.v1m1.name.css", + # this one has a pattern that looks like the version string in the wrong place + # AND one in the right place. + "nested.v2m2/folder/file.v1m1.js", + "nested.v2m2.dotted/folder.structure/file.v1m1.name.css", ] invalid_fingerprints = [ - "dash.plotly.v1_1_1m1234567890..js", - "dash.plotly.v1_1_1m1234567890.", - "dash.plotly.v1_1_1m1234567890..", - "dash.plotly.v1_1_1m1234567890.js.", - "dash.plotly.v1_1_1m1234567890.j-s", + "dash.plotly.v1_1_1m1234567890.js", + "folder/dash.plotly.v1_1_1m1234567890.js", + "nested.v1m1/folder/file.js", + "nested.v1m1.dotted/folder.structure/file.name.css", ] @@ -64,8 +115,8 @@ def test_fingerprint(): for resource in valid_fingerprints: (_, has_fingerprint) = check_fingerprint(resource) - assert has_fingerprint + assert has_fingerprint, resource for resource in invalid_fingerprints: (_, has_fingerprint) = check_fingerprint(resource) - assert not has_fingerprint + assert not has_fingerprint, resource From 3c5900f963ada2a49bfe5b67b65973cb223bbab9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Rivet?= Date: Tue, 29 Oct 2019 20:49:32 -0400 Subject: [PATCH 3/5] eval eager_loading when ready (#986) --- CHANGELOG.md | 4 ++++ dash/dash.py | 17 +++++++++++------ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c53116aa7c..52e3a52573 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to `dash` will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## [Unreleased] +### Fixed +- [#986](https://github.com/plotly/dash/pull/986) Fix a bug with evaluation of `_force_eager_loading` when application is loaded with gunicorn + ## [1.5.0] - 2019-10-29 ### Added - [#964](https://github.com/plotly/dash/pull/964) Adds support for preventing updates in clientside functions. diff --git a/dash/dash.py b/dash/dash.py index ddb64bec80..2f2c98e4d4 100644 --- a/dash/dash.py +++ b/dash/dash.py @@ -229,12 +229,6 @@ def __init__( plugins=None, **obsolete ): - # Apply _force_eager_loading overrides from modules - for module_name in ComponentRegistry.registry: - module = sys.modules[module_name] - eager = getattr(module, '_force_eager_loading', False) - eager_loading = eager_loading or eager - for key in obsolete: if key in ["components_cache_max_age", "static_folder"]: raise exceptions.ObsoleteKwargException( @@ -272,6 +266,7 @@ def __init__( assets_external_path=get_combined_config( "assets_external_path", assets_external_path, "" ), + eager_loading=eager_loading, include_assets_files=get_combined_config( "include_assets_files", include_assets_files, True ), @@ -1434,6 +1429,16 @@ def _validate_layout(self): component_ids.add(component_id) def _setup_server(self): + # Apply _force_eager_loading overrides from modules + eager_loading = self.config.eager_loading + for module_name in ComponentRegistry.registry: + module = sys.modules[module_name] + eager = getattr(module, '_force_eager_loading', False) + eager_loading = eager_loading or eager + + # Update eager_loading settings + self.scripts.config.eager_loading = eager_loading + if self.config.include_assets_files: self._walk_assets_directory() From eb854737b506ffd5356bb2f17dca018c77d99fdb Mon Sep 17 00:00:00 2001 From: alexcjohnson Date: Tue, 29 Oct 2019 20:58:06 -0400 Subject: [PATCH 4/5] changelog for cache-subdirs --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 52e3a52573..f567271575 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] ### Fixed +- [#987](https://github.com/plotly/dash/pull/987) Fix cache string handling for component suites with nested folders in their packages. - [#986](https://github.com/plotly/dash/pull/986) Fix a bug with evaluation of `_force_eager_loading` when application is loaded with gunicorn ## [1.5.0] - 2019-10-29 From 8e0c80dd78ae9dea888be7245f824c7362a8ad71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andre=CC=81=20Rivet?= Date: Tue, 29 Oct 2019 21:20:19 -0400 Subject: [PATCH 5/5] bump version to 1.5.1 --- CHANGELOG.md | 2 +- dash/version.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f567271575..45a5adff95 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to `dash` will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). -## [Unreleased] +## [1.5.1] - 2019-10-29 ### Fixed - [#987](https://github.com/plotly/dash/pull/987) Fix cache string handling for component suites with nested folders in their packages. - [#986](https://github.com/plotly/dash/pull/986) Fix a bug with evaluation of `_force_eager_loading` when application is loaded with gunicorn diff --git a/dash/version.py b/dash/version.py index 77f1c8e63c..51ed7c486c 100644 --- a/dash/version.py +++ b/dash/version.py @@ -1 +1 @@ -__version__ = '1.5.0' +__version__ = '1.5.1'