Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-dash for openSUSE:Factory 
checked in at 2021-04-12 17:10:39
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-dash (Old)
 and      /work/SRC/openSUSE:Factory/.python-dash.new.2401 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-dash"

Mon Apr 12 17:10:39 2021 rev:11 rq:884578 version:1.20.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-dash/python-dash.changes  2021-01-05 
18:12:57.251305577 +0100
+++ /work/SRC/openSUSE:Factory/.python-dash.new.2401/python-dash.changes        
2021-04-12 17:10:48.158594073 +0200
@@ -1,0 +2,41 @@
+Fri Apr  9 21:34:20 UTC 2021 - Ben Greiner <c...@bnavigator.de>
+
+- Update to 1.20.0
+  Changed
+  * #1531 Update the format of the docstrings to make them easier
+    to read in the reference pages of Dash Docs and in the
+    console. This also addresses #1205
+  * #1553 Increase the z-index of the Dash error menu from 1001 to
+    1100 in order to make sure it appears above Bootstrap
+    components.
+  Fixed
+  * #1546 Validate callback request outputs vs output to avoid a
+    perceived security issue.
+- Release 1.19.0
+  Added
+  * #1508 Fix #1403: Adds an x button to close the error messages
+    box.
+  * #1525 Adds support for callbacks which have overlapping inputs
+    and outputs. Combined with dash.callback_context this
+    addresses many use cases which require circular callbacks.
+  Changed
+  * #1503 Fix #1466: loosen dash[testing] requirements for easier
+    integration in external projects. This PR also bumps many dash
+    [dev] requirements.
+  Fixed
+  * #1530 Dedent error messages more carefully.
+  * #1527??? get_asset_url now pulls from an external source if
+    assets_external_path is set.
+    - updated _add_assets_resource to build asset urls the same
+      way as get_asset_url.
+    - updated doc string for assets_external_path Dash argument to
+      be more clear that it will allways be joined with the
+      assets_url_path argument when determining the url to an
+      external asset.
+  * #1493 Fix #1143, a bug where having a file with one of several
+    common names (test.py, code.py, org.py, etc) that imports a
+    dash component package would make import dash fail with a
+    cryptic error message asking whether you have a file named
+    "dash.py"
+
+-------------------------------------------------------------------

Old:
----
  dash-1.18.1.tar.gz

New:
----
  dash-1.20.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-dash.spec ++++++
--- /var/tmp/diff_new_pack.pf887R/_old  2021-04-12 17:10:49.050595061 +0200
+++ /var/tmp/diff_new_pack.pf887R/_new  2021-04-12 17:10:49.050595061 +0200
@@ -22,7 +22,7 @@
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 %define         skip_python2 1
 Name:           python-dash
-Version:        1.18.1
+Version:        1.20.0
 Release:        0
 Summary:        Python framework for building reactive web-apps
 License:        MIT
@@ -32,10 +32,10 @@
 BuildRequires:  %{python_module Flask >= 1.0.4}
 BuildRequires:  %{python_module Flask-Compress}
 BuildRequires:  %{python_module beautifulsoup4}
-BuildRequires:  %{python_module dash-core-components >= 1.14.1}
-BuildRequires:  %{python_module dash-html-components >= 1.1.1}
-BuildRequires:  %{python_module dash-renderer >= 1.8.3}
-BuildRequires:  %{python_module dash-table >= 4.11.1}
+BuildRequires:  %{python_module dash-core-components >= 1.16.0}
+BuildRequires:  %{python_module dash-html-components >= 1.1.3}
+BuildRequires:  %{python_module dash-renderer >= 1.9.1}
+BuildRequires:  %{python_module dash-table >= 4.11.3}
 BuildRequires:  %{python_module future}
 BuildRequires:  %{python_module percy}
 BuildRequires:  %{python_module plotly}
@@ -46,16 +46,16 @@
 Requires:       python-Flask-Compress
 # dash/testing/dash_page.py
 Requires:       python-beautifulsoup4
-Requires:       python-dash-core-components >= 1.14.1
-Requires:       python-dash-html-components >= 1.1.1
-Requires:       python-dash-renderer >= 1.8.3
-Requires:       python-dash-table >= 4.11.1
+Requires:       python-dash-core-components >= 1.16.0
+Requires:       python-dash-html-components >= 1.1.3
+Requires:       python-dash-renderer >= 1.9.1
+Requires:       python-dash-table >= 4.11.3
 Requires:       python-future
 # needed for dash/testing/browser.py
 Requires:       python-percy
 Requires:       python-plotly
 Requires(post): update-alternatives
-Requires(postun): update-alternatives
+Requires(postun):update-alternatives
 BuildArch:      noarch
 %if %{with test}
 BuildRequires:  %{python_module lxml}

++++++ dash-1.18.1.tar.gz -> dash-1.20.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dash-1.18.1/LICENSE new/dash-1.20.0/LICENSE
--- old/dash-1.18.1/LICENSE     2020-12-08 14:42:55.000000000 +0100
+++ new/dash-1.20.0/LICENSE     2021-04-09 00:03:55.000000000 +0200
@@ -1,6 +1,6 @@
 The MIT License (MIT)
 
-Copyright (c) 2020 Plotly, Inc
+Copyright (c) 2021 Plotly, Inc
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dash-1.18.1/PKG-INFO new/dash-1.20.0/PKG-INFO
--- old/dash-1.18.1/PKG-INFO    2020-12-09 22:33:39.000000000 +0100
+++ new/dash-1.20.0/PKG-INFO    2021-04-09 00:19:30.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: dash
-Version: 1.18.1
+Version: 1.20.0
 Summary: A Python framework for building reactive web-apps. Developed by 
Plotly.
 Home-page: https://plotly.com/dash
 Author: Chris Parmer
@@ -43,9 +43,9 @@
         
         Scale up with Dash Enterprise when your Dash app is ready for 
department or company-wide consumption. Or, launch your initiative with Dash 
Enterprise from the start to unlock developer productivity gains and hands-on 
acceleration from Plotly's team.
         
-        ML Ops Features: A one-stop shop for ML Ops: Horizontally scalable 
hosting, deployment, and authentication for your Dash apps. No IT or DevOps 
required. 
+        ML Ops Features: A one-stop shop for ML Ops: Horizontally scalable 
hosting, deployment, and authentication for your Dash apps. No IT or DevOps 
required.
         - [**App manager**](https://plotly.com/dash/app-manager/) Deploy & 
manage Dash apps without needing IT or a DevOps team. App Manager gives you 
point & click control over all aspects of your Dash deployments.
-        - [**Kubernetes scaling**](https://plotly.com/dash/kubernetes/) Ensure 
high availability of Dash apps and scale horizontally with Dash Enterprise???s 
Kubernetes architecture. No IT or Helm required. 
+        - [**Kubernetes scaling**](https://plotly.com/dash/kubernetes/) Ensure 
high availability of Dash apps and scale horizontally with Dash Enterprise???s 
Kubernetes architecture. No IT or Helm required.
         - [**No code auth**](https://plotly.com/dash/authentication/) Control 
Dash app access in a few clicks. Dash Enterprise supports LDAP, AD, PKI, Okta, 
SAML, OpenID Connect, OAuth, SSO, and simple email authentication.
         - [**Job Queue**](https://plotly.com/dash/job-queue/) The Job Queue is 
the key to building scalable Dash apps. Move heavy computation from synchronous 
Dash callbacks to the Job Queue for asynchronous background processing.
         
@@ -61,7 +61,6 @@
         - [**GPU & Dask 
Acceleration**](https://plotly.com/dash/gpu-dask-acceleration/) Dash Enterprise 
puts Python???s most popular HPC stack for GPU and parallel CPU computing in 
the hands of business users.
         - [**Data Science Workspaces**](https://plotly.com/dash/workspaces/) 
Be productive from Day 1. Write and execute Python, R, & Julia code from Dash 
Enterprise's onboard code editor.
         
-        
         See [https://plotly.com/contact-us/](https://plotly.com/contact-us/) 
to get in touch.
         
         
![image](https://images.prismic.io/plotly-marketing-website/493eec39-8467-4610-b9d0-d6ad3ea61423_Dash+Open+source%2BDash+enterprise2-01.jpg?auto=compress,format)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dash-1.18.1/README.md new/dash-1.20.0/README.md
--- old/dash-1.18.1/README.md   2020-12-08 14:42:55.000000000 +0100
+++ new/dash-1.20.0/README.md   2021-04-09 00:03:55.000000000 +0200
@@ -35,9 +35,9 @@
 
 Scale up with Dash Enterprise when your Dash app is ready for department or 
company-wide consumption. Or, launch your initiative with Dash Enterprise from 
the start to unlock developer productivity gains and hands-on acceleration from 
Plotly's team.
 
-ML Ops Features: A one-stop shop for ML Ops: Horizontally scalable hosting, 
deployment, and authentication for your Dash apps. No IT or DevOps required. 
+ML Ops Features: A one-stop shop for ML Ops: Horizontally scalable hosting, 
deployment, and authentication for your Dash apps. No IT or DevOps required.
 - [**App manager**](https://plotly.com/dash/app-manager/) Deploy & manage Dash 
apps without needing IT or a DevOps team. App Manager gives you point & click 
control over all aspects of your Dash deployments.
-- [**Kubernetes scaling**](https://plotly.com/dash/kubernetes/) Ensure high 
availability of Dash apps and scale horizontally with Dash Enterprise???s 
Kubernetes architecture. No IT or Helm required. 
+- [**Kubernetes scaling**](https://plotly.com/dash/kubernetes/) Ensure high 
availability of Dash apps and scale horizontally with Dash Enterprise???s 
Kubernetes architecture. No IT or Helm required.
 - [**No code auth**](https://plotly.com/dash/authentication/) Control Dash app 
access in a few clicks. Dash Enterprise supports LDAP, AD, PKI, Okta, SAML, 
OpenID Connect, OAuth, SSO, and simple email authentication.
 - [**Job Queue**](https://plotly.com/dash/job-queue/) The Job Queue is the key 
to building scalable Dash apps. Move heavy computation from synchronous Dash 
callbacks to the Job Queue for asynchronous background processing.
 
@@ -53,7 +53,6 @@
 - [**GPU & Dask 
Acceleration**](https://plotly.com/dash/gpu-dask-acceleration/) Dash Enterprise 
puts Python???s most popular HPC stack for GPU and parallel CPU computing in 
the hands of business users.
 - [**Data Science Workspaces**](https://plotly.com/dash/workspaces/) Be 
productive from Day 1. Write and execute Python, R, & Julia code from Dash 
Enterprise's onboard code editor.
 
-
 See [https://plotly.com/contact-us/](https://plotly.com/contact-us/) to get in 
touch.
 
 
![image](https://images.prismic.io/plotly-marketing-website/493eec39-8467-4610-b9d0-d6ad3ea61423_Dash+Open+source%2BDash+enterprise2-01.jpg?auto=compress,format)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dash-1.18.1/dash/__init__.py 
new/dash-1.20.0/dash/__init__.py
--- old/dash-1.18.1/dash/__init__.py    2020-12-08 14:42:55.000000000 +0100
+++ new/dash-1.20.0/dash/__init__.py    2021-01-20 00:35:20.000000000 +0100
@@ -1,7 +1,11 @@
-from .dash import Dash, no_update  # noqa: F401
-from . import dependencies  # noqa: F401
-from . import development  # noqa: F401
-from . import exceptions  # noqa: F401
-from . import resources  # noqa: F401
-from .version import __version__  # noqa: F401
-from ._callback_context import callback_context  # noqa: F401
+# pylint: disable=C0413
+# __plotly_dash is for the "make sure you don't have a dash.py" check
+# must come before any other imports.
+__plotly_dash = True
+from .dash import Dash, no_update  # noqa: F401,E402
+from . import dependencies  # noqa: F401,E402
+from . import development  # noqa: F401,E402
+from . import exceptions  # noqa: F401,E402
+from . import resources  # noqa: F401,E402
+from .version import __version__  # noqa: F401,E402
+from ._callback_context import callback_context  # noqa: F401,E402
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dash-1.18.1/dash/_utils.py 
new/dash-1.20.0/dash/_utils.py
--- old/dash-1.18.1/dash/_utils.py      2020-12-08 14:42:55.000000000 +0100
+++ new/dash-1.20.0/dash/_utils.py      2021-01-20 00:35:20.000000000 +0100
@@ -65,8 +65,12 @@
         return requests_pathname
     elif not path.startswith("/"):
         raise exceptions.UnsupportedRelativePath(
-            "Paths that aren't prefixed with a leading / are not supported.\n"
-            + "You supplied: {}".format(path)
+            """
+            Paths that aren't prefixed with a leading / are not supported.
+            You supplied: {}
+            """.format(
+                path
+            )
         )
     return "/".join([requests_pathname.rstrip("/"), path.lstrip("/")])
 
@@ -78,9 +82,10 @@
         requests_pathname != "/" and not 
path.startswith(requests_pathname.rstrip("/"))
     ) or (requests_pathname == "/" and not path.startswith("/")):
         raise exceptions.UnsupportedRelativePath(
-            "Paths that aren't prefixed with a leading "
-            + "requests_pathname_prefix are not supported.\n"
-            + "You supplied: {} and requests_pathname_prefix was {}".format(
+            """
+            Paths that aren't prefixed with requests_pathname_prefix are not 
supported.
+            You supplied: {} and requests_pathname_prefix was {}
+            """.format(
                 path, requests_pathname
             )
         )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dash-1.18.1/dash/_validate.py 
new/dash-1.20.0/dash/_validate.py
--- old/dash-1.18.1/dash/_validate.py   2020-12-08 14:42:55.000000000 +0100
+++ new/dash-1.20.0/dash/_validate.py   2021-04-09 00:03:55.000000000 +0200
@@ -1,5 +1,6 @@
 import collections
 import re
+from textwrap import dedent
 
 from .development.base_component import Component
 from . import exceptions
@@ -15,26 +16,26 @@
     if extra_args:
         if not isinstance(extra_args[0], (Output, Input, State)):
             raise exceptions.IncorrectTypeException(
-                """
-                Callback arguments must be `Output`, `Input`, or `State` 
objects,
-                optionally wrapped in a list or tuple. We found (possibly after
-                unwrapping a list or tuple):
-                {}
-                """.format(
-                    repr(extra_args[0])
-                )
+                dedent(
+                    """
+                    Callback arguments must be `Output`, `Input`, or `State` 
objects,
+                    optionally wrapped in a list or tuple. We found (possibly 
after
+                    unwrapping a list or tuple):
+                    {}
+                    """
+                ).format(repr(extra_args[0]))
             )
 
         raise exceptions.IncorrectTypeException(
-            """
-            In a callback definition, you must provide all Outputs first,
-            then all Inputs, then all States. After this item:
-            {}
-            we found this item next:
-            {}
-            """.format(
-                repr((outputs + inputs + state)[-1]), repr(extra_args[0])
-            )
+            dedent(
+                """
+                In a callback definition, you must provide all Outputs first,
+                then all Inputs, then all States. After this item:
+                {}
+                we found this item next:
+                {}
+                """
+            ).format(repr((outputs + inputs + state)[-1]), repr(extra_args[0]))
         )
 
     for args in [outputs, inputs, state]:
@@ -45,11 +46,11 @@
 def validate_callback_arg(arg):
     if not isinstance(getattr(arg, "component_property", None), _strings):
         raise exceptions.IncorrectTypeException(
-            """
-            component_property must be a string, found {!r}
-            """.format(
-                arg.component_property
-            )
+            dedent(
+                """
+                component_property must be a string, found {!r}
+                """
+            ).format(arg.component_property)
         )
 
     if hasattr(arg, "component_event"):
@@ -68,11 +69,11 @@
 
     else:
         raise exceptions.IncorrectTypeException(
-            """
-            component_id must be a string or dict, found {!r}
-            """.format(
-                arg.component_id
-            )
+            dedent(
+                """
+                component_id must be a string or dict, found {!r}
+                """
+            ).format(arg.component_id)
         )
 
 
@@ -85,12 +86,12 @@
         # cause unwanted collisions
         if not isinstance(k, _strings):
             raise exceptions.IncorrectTypeException(
-                """
-                Wildcard ID keys must be non-empty strings,
-                found {!r} in id {!r}
-                """.format(
-                    k, arg_id
-                )
+                dedent(
+                    """
+                    Wildcard ID keys must be non-empty strings,
+                    found {!r} in id {!r}
+                    """
+                ).format(k, arg_id)
             )
 
 
@@ -110,16 +111,36 @@
         )
 
 
+def validate_output_spec(output, output_spec, Output):
+    """
+    This validation is for security and internal debugging, not for users,
+    so the messages are not intended to be clear.
+    `output` comes from the callback definition, `output_spec` from the 
request.
+    """
+    if not isinstance(output, (list, tuple)):
+        output, output_spec = [output], [output_spec]
+    elif len(output) != len(output_spec):
+        raise exceptions.CallbackException("Wrong length output_spec")
+
+    for outi, speci in zip(output, output_spec):
+        speci_list = speci if isinstance(speci, (list, tuple)) else [speci]
+        for specij in speci_list:
+            if not Output(specij["id"], specij["property"]) == outi:
+                raise exceptions.CallbackException(
+                    "Output does not match callback definition"
+                )
+
+
 def validate_multi_return(outputs_list, output_value, callback_id):
     if not isinstance(output_value, (list, tuple)):
         raise exceptions.InvalidCallbackReturnValue(
-            """
-            The callback {} is a multi-output.
-            Expected the output type to be a list or tuple but got:
-            {}.
-            """.format(
-                callback_id, repr(output_value)
-            )
+            dedent(
+                """
+                The callback {} is a multi-output.
+                Expected the output type to be a list or tuple but got:
+                {}.
+                """
+            ).format(callback_id, repr(output_value))
         )
 
     if len(output_value) != len(outputs_list):
@@ -137,26 +158,26 @@
             vi = output_value[i]
             if not isinstance(vi, (list, tuple)):
                 raise exceptions.InvalidCallbackReturnValue(
-                    """
-                    The callback {} output {} is a wildcard multi-output.
-                    Expected the output type to be a list or tuple but got:
-                    {}.
-                    output spec: {}
-                    """.format(
-                        callback_id, i, repr(vi), repr(outi)
-                    )
+                    dedent(
+                        """
+                        The callback {} output {} is a wildcard multi-output.
+                        Expected the output type to be a list or tuple but got:
+                        {}.
+                        output spec: {}
+                        """
+                    ).format(callback_id, i, repr(vi), repr(outi))
                 )
 
             if len(vi) != len(outi):
                 raise exceptions.InvalidCallbackReturnValue(
-                    """
-                    Invalid number of output values for {} item {}.
-                    Expected {}, got {}
-                    output spec: {}
-                    output value: {}
-                    """.format(
-                        callback_id, i, len(vi), len(outi), repr(outi), 
repr(vi)
-                    )
+                    dedent(
+                        """
+                        Invalid number of output values for {} item {}.
+                        Expected {}, got {}
+                        output spec: {}
+                        output value: {}
+                        """
+                    ).format(callback_id, i, len(vi), len(outi), repr(outi), 
repr(vi))
                 )
 
 
@@ -170,34 +191,38 @@
         )
         outer_type = type(outer_val).__name__
         if toplevel:
-            location = """
-            The value in question is either the only value returned,
-            or is in the top level of the returned list,
-            """
+            location = dedent(
+                """
+                The value in question is either the only value returned,
+                or is in the top level of the returned list,
+                """
+            )
         else:
             index_string = "[*]" if index is None else "[{:d}]".format(index)
-            location = """
-            The value in question is located at
-            {} {} {}
-            {},
-            """.format(
-                index_string, outer_type, outer_id, path
-            )
+            location = dedent(
+                """
+                The value in question is located at
+                {} {} {}
+                {},
+                """
+            ).format(index_string, outer_type, outer_id, path)
 
         raise exceptions.InvalidCallbackReturnValue(
-            """
-            The callback for `{output}`
-            returned a {object:s} having type `{type}`
-            which is not JSON serializable.
-
-            {location}
-            and has string representation
-            `{bad_val}`
-
-            In general, Dash properties can only be
-            dash components, strings, dictionaries, numbers, None,
-            or lists of those.
-            """.format(
+            dedent(
+                """
+                The callback for `{output}`
+                returned a {object:s} having type `{type}`
+                which is not JSON serializable.
+
+                {location}
+                and has string representation
+                `{bad_val}`
+
+                In general, Dash properties can only be
+                dash components, strings, dictionaries, numbers, None,
+                or lists of those.
+                """
+            ).format(
                 output=repr(output),
                 object="tree with one value" if not toplevel else "value",
                 type=bad_type,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dash-1.18.1/dash/dash.py new/dash-1.20.0/dash/dash.py
--- old/dash-1.18.1/dash/dash.py        2020-12-08 14:42:55.000000000 +0100
+++ new/dash-1.20.0/dash/dash.py        2021-04-09 00:03:55.000000000 +0200
@@ -27,7 +27,7 @@
 
 from .fingerprint import build_fingerprint, check_fingerprint
 from .resources import Scripts, Css
-from .dependencies import handle_callback_args
+from .dependencies import handle_callback_args, Output
 from .development.base_component import ComponentRegistry
 from .exceptions import PreventUpdate, InvalidResourceError, ProxyError
 from .version import __version__
@@ -150,10 +150,12 @@
     :type assets_ignore: string
 
     :param assets_external_path: an absolute URL from which to load assets.
-        Use with ``serve_locally=False``. Dash can still find js and css to
-        automatically load if you also keep local copies in your assets
-        folder that Dash can index, but external serving can improve
-        performance and reduce load on the Dash server.
+        Use with ``serve_locally=False``. assets_external_path is joined
+        with assets_url_path to determine the absolute url to the
+        asset folder. Dash can still find js and css to automatically load
+        if you also keep local copies in your assets folder that Dash can 
index,
+        but external serving can improve performance and reduce load on
+        the Dash server.
         env: ``DASH_ASSETS_EXTERNAL_PATH``
     :type assets_external_path: string
 
@@ -1002,6 +1004,7 @@
             @wraps(func)
             def add_context(*args, **kwargs):
                 output_spec = kwargs.pop("outputs_list")
+                _validate.validate_output_spec(output, output_spec, Output)
 
                 # don't touch the comment on the next line - used by debugger
                 output_value = func(*args, **kwargs)  # %% callback invoked %%
@@ -1098,9 +1101,7 @@
     def _add_assets_resource(self, url_path, file_path):
         res = {"asset_path": url_path, "filepath": file_path}
         if self.config.assets_external_path:
-            res["external_url"] = "{}{}".format(
-                self.config.assets_external_path, url_path
-            )
+            res["external_url"] = self.get_asset_url(url_path.lstrip("/"))
         self._assets_files.append(file_path)
         return res
 
@@ -1185,11 +1186,12 @@
         ]
 
     def get_asset_url(self, path):
-        asset = get_asset_path(
-            self.config.requests_pathname_prefix,
-            path,
-            self.config.assets_url_path.lstrip("/"),
-        )
+        if self.config.assets_external_path:
+            prefix = self.config.assets_external_path
+        else:
+            prefix = self.config.requests_pathname_prefix
+
+        asset = get_asset_path(prefix, path, 
self.config.assets_url_path.lstrip("/"))
 
         return asset
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/dash-1.18.1/dash/development/_jl_components_generation.py 
new/dash-1.20.0/dash/development/_jl_components_generation.py
--- old/dash-1.18.1/dash/development/_jl_components_generation.py       
2020-12-08 14:42:55.000000000 +0100
+++ new/dash-1.20.0/dash/development/_jl_components_generation.py       
2021-04-09 00:03:55.000000000 +0200
@@ -4,7 +4,6 @@
 import copy
 import os
 import shutil
-import glob
 import warnings
 import sys
 import importlib
@@ -173,7 +172,7 @@
             )
         ),
         # React's PropTypes.objectOf
-        objectOf=lambda: ("Dict with Strings as keys and values of type 
{}").format(
+        objectOf=lambda: "Dict with Strings as keys and values of type 
{}".format(
             get_jl_type(type_object["value"])
         ),
         # React's PropTypes.shape
@@ -266,7 +265,7 @@
     # Ensure props are ordered with children first
     props = reorder_props(props=props)
 
-    return ("A{n} {name} component.\n{description}\nKeyword 
arguments:\n{args}").format(
+    return "A{n} {name} component.\n{description}\nKeyword 
arguments:\n{args}".format(
         n="n" if component_name[0].lower() in "aeiou" else "",
         name=component_name,
         description=description,
@@ -526,14 +525,21 @@
 
     os.makedirs("deps")
 
-    for javascript in glob.glob("{}/*.js".format(project_shortname)):
-        shutil.copy(javascript, "deps/")
+    for rel_dirname, _, filenames in os.walk(project_shortname):
+        for filename in filenames:
+            extension = os.path.splitext(filename)[1]
 
-    for css in glob.glob("{}/*.css".format(project_shortname)):
-        shutil.copy(css, "deps/")
+            if extension in [".py", ".pyc", ".json"]:
+                continue
 
-    for sourcemap in glob.glob("{}/*.map".format(project_shortname)):
-        shutil.copy(sourcemap, "deps/")
+            target_dirname = os.path.join(
+                "deps/", os.path.relpath(rel_dirname, project_shortname)
+            )
+
+            if not os.path.exists(target_dirname):
+                os.makedirs(target_dirname)
+
+            shutil.copy(os.path.join(rel_dirname, filename), target_dirname)
 
     generate_package_file(project_shortname, components, pkg_data, prefix)
     generate_toml_file(project_shortname, pkg_data)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/dash-1.18.1/dash/development/_py_components_generation.py 
new/dash-1.20.0/dash/development/_py_components_generation.py
--- old/dash-1.18.1/dash/development/_py_components_generation.py       
2020-12-08 14:42:55.000000000 +0100
+++ new/dash-1.20.0/dash/development/_py_components_generation.py       
2021-04-09 00:03:55.000000000 +0200
@@ -1,6 +1,7 @@
 from collections import OrderedDict
 import copy
 import os
+from textwrap import fill
 
 from dash.development.base_component import _explicitize_args
 from dash.exceptions import NonExistentEventException
@@ -12,16 +13,13 @@
 def generate_class_string(typename, props, description, namespace):
     """Dynamically generate class strings to have nicely formatted docstrings,
     keyword arguments, and repr.
-
     Inspired by http://jameso.be/2013/08/06/namedtuple.html
-
     Parameters
     ----------
     typename
     props
     description
     namespace
-
     Returns
     -------
     string
@@ -53,12 +51,10 @@
         self.available_properties = {list_of_valid_keys}
         self.available_wildcard_properties =\
             {list_of_valid_wildcard_attr_prefixes}
-
         _explicit_args = kwargs.pop('_explicit_args')
         _locals = locals()
         _locals.update(kwargs)  # For wildcard attrs
         args = {{k: _locals[k] for k in _explicit_args if k != 'children'}}
-
         for k in {required_props}:
             if k not in args:
                 raise TypeError(
@@ -112,14 +108,12 @@
 
 def generate_class_file(typename, props, description, namespace):
     """Generate a Python class file (.py) given a class string.
-
     Parameters
     ----------
     typename
     props
     description
     namespace
-
     Returns
     -------
     """
@@ -170,14 +164,12 @@
 
 def generate_class(typename, props, description, namespace):
     """Generate a Python class object given a class string.
-
     Parameters
     ----------
     typename
     props
     description
     namespace
-
     Returns
     -------
     """
@@ -191,11 +183,9 @@
 
 def required_props(props):
     """Pull names of required props from the props object.
-
     Parameters
     ----------
     props: dict
-
     Returns
     -------
     list
@@ -206,7 +196,6 @@
 
 def create_docstring(component_name, props, description):
     """Create the Dash component docstring.
-
     Parameters
     ----------
     component_name: str
@@ -215,7 +204,6 @@
         Dictionary with {propName: propMetadata} structure
     description: str
         Component description
-
     Returns
     -------
     str
@@ -248,12 +236,10 @@
 def prohibit_events(props):
     """Events have been removed. Raise an error if we see dashEvents or
     fireEvents.
-
     Parameters
     ----------
     props: dict
         Dictionary with {propName: propMetadata} structure
-
     Raises
     -------
     ?
@@ -267,12 +253,10 @@
 
 def parse_wildcards(props):
     """Pull out the wildcard attributes from the Component props.
-
     Parameters
     ----------
     props: dict
         Dictionary with {propName: propMetadata} structure
-
     Returns
     -------
     list
@@ -287,43 +271,37 @@
 
 def reorder_props(props):
     """If "children" is in props, then move it to the front to respect dash
-    convention.
-
+    convention, then 'id', then the remaining props sorted by prop name
     Parameters
     ----------
     props: dict
         Dictionary with {propName: propMetadata} structure
-
     Returns
     -------
     dict
         Dictionary with {propName: propMetadata} structure
     """
-    if "children" in props:
-        # Constructing an OrderedDict with duplicate keys, you get the order
-        # from the first one but the value from the last.
-        # Doing this to avoid mutating props, which can cause confusion.
-        props = OrderedDict([("children", "")] + list(props.items()))
 
-    return props
+    # Constructing an OrderedDict with duplicate keys, you get the order
+    # from the first one but the value from the last.
+    # Doing this to avoid mutating props, which can cause confusion.
+    props1 = [("children", "")] if "children" in props else []
+    props2 = [("id", "")] if "id" in props else []
+    return OrderedDict(props1 + props2 + sorted(list(props.items())))
 
 
 def filter_props(props):
     """Filter props from the Component arguments to exclude:
-
         - Those without a "type" or a "flowType" field
         - Those with arg.type.name in {'func', 'symbol', 'instanceOf'}
-
     Parameters
     ----------
     props: dict
         Dictionary with {propName: propMetadata} structure
-
     Returns
     -------
     dict
         Filtered dictionary with {propName: propMetadata} structure
-
     Examples
     --------
     ```python
@@ -380,7 +358,18 @@
     return filtered_props
 
 
+def fix_keywords(txt):
+    """
+    replaces javascript keywords true, false, null with Python keywords
+    """
+    fix_word = {"true": "True", "false": "False", "null": "None"}
+    for js_keyword, python_keyword in fix_word.items():
+        txt = txt.replace(js_keyword, python_keyword)
+    return txt
+
+
 # pylint: disable=too-many-arguments
+# pylint: disable=too-many-locals
 def create_prop_docstring(
     prop_name,
     type_object,
@@ -391,7 +380,6 @@
     is_flow_type=False,
 ):
     """Create the Dash component prop docstring.
-
     Parameters
     ----------
     prop_name: str
@@ -411,71 +399,110 @@
         (creates 2 spaces for every indent)
     is_flow_type: bool
         Does the prop use Flow types? Otherwise, uses PropTypes
-
     Returns
     -------
     str
         Dash component prop docstring
     """
     py_type_name = js_to_py_type(
-        type_object=type_object, is_flow_type=is_flow_type, 
indent_num=indent_num + 1
+        type_object=type_object, is_flow_type=is_flow_type, 
indent_num=indent_num
     )
     indent_spacing = "  " * indent_num
 
-    if default is None:
-        default = ""
-    else:
-        default = default["value"]
-
-    if default in ["true", "false"]:
-        default = default.title()
+    default = default["value"] if default else ""
+    default = fix_keywords(default)
 
     is_required = "optional"
     if required:
         is_required = "required"
-    elif default and default not in ["null", "{}", "[]"]:
-        is_required = "default {}".format(default.replace("\n", "\n" + 
indent_spacing))
+    elif default and default not in ["None", "{}", "[]"]:
+        is_required = "default {}".format(default.replace("\n", ""))
+
+    # formats description
+    period = "." if description else ""
+    description = description.strip().strip(".").replace('"', r"\"") + period
+    desc_indent = indent_spacing + "    "
+    description = fill(
+        description,
+        initial_indent=desc_indent,
+        subsequent_indent=desc_indent,
+        break_long_words=False,
+        break_on_hyphens=False,
+    )
+    description = "\n{}".format(description) if description else ""
+    colon = ":" if description else ""
+    description = fix_keywords(description)
 
     if "\n" in py_type_name:
+        # corrects the type
+        dict_or_list = "list of dicts" if py_type_name.startswith("list") else 
"dict"
+
+        # format and rewrite the intro to the nested dicts
+        intro1, intro2, dict_descr = py_type_name.partition("with keys:")
+        intro = "".join(["`{}`".format(prop_name), " is a ", intro1, intro2])
+        intro = fill(
+            intro,
+            initial_indent=desc_indent,
+            subsequent_indent=desc_indent,
+            break_long_words=False,
+            break_on_hyphens=False,
+        )
+
+        # captures optional nested dict description and puts the "or" 
condition on a new line
+        if "| dict with keys:" in dict_descr:
+            dict_part1, dict_part2 = dict_descr.split(" |", 1)
+            dict_part2 = "".join([desc_indent, "Or", dict_part2])
+            dict_descr = "{}\n\n  {}".format(dict_part1, dict_part2)
+
+        # ensures indent is correct if there is a second nested list of dicts
+        current_indent = dict_descr.lstrip("\n").find("-")
+        if current_indent == len(indent_spacing):
+            dict_descr = "".join(
+                "\n\n    " + line for line in dict_descr.splitlines() if line 
!= ""
+            )
+
         return (
-            "{indent_spacing}- {name} (dict; {is_required}): "
-            "{description}{period}"
-            "{name} has the following type: {type}".format(
+            "\n{indent_spacing}- {name} ({dict_or_list}; {is_required}){colon}"
+            "{description}"
+            "\n\n{intro}{dict_descr}".format(
                 indent_spacing=indent_spacing,
                 name=prop_name,
-                type=py_type_name,
-                description=description.strip().strip("."),
-                period=". " if description else "",
+                colon=colon,
+                description=description,
+                intro=intro,
+                dict_descr=dict_descr,
+                dict_or_list=dict_or_list,
                 is_required=is_required,
             )
         )
-    return "{indent_spacing}- {name} 
({type}{is_required}){description}".format(
-        indent_spacing=indent_spacing,
-        name=prop_name,
-        type="{}; ".format(py_type_name) if py_type_name else "",
-        description=(": {}".format(description) if description != "" else ""),
-        is_required=is_required,
+    return (
+        "\n{indent_spacing}- {name} ({type}{is_required}){colon}"
+        "{description}".format(
+            indent_spacing=indent_spacing,
+            name=prop_name,
+            type="{}; ".format(py_type_name) if py_type_name else "",
+            colon=colon,
+            description=description,
+            is_required=is_required,
+        )
     )
 
 
-def map_js_to_py_types_prop_types(type_object):
+def map_js_to_py_types_prop_types(type_object, indent_num):
     """Mapping from the PropTypes js type object to the Python type."""
 
     def shape_or_exact():
-        return "dict containing keys {}.\n{}".format(
-            ", ".join("'{}'".format(t) for t in 
list(type_object["value"].keys())),
-            "Those keys have the following types:\n{}".format(
-                "\n".join(
-                    create_prop_docstring(
-                        prop_name=prop_name,
-                        type_object=prop,
-                        required=prop["required"],
-                        description=prop.get("description", ""),
-                        default=prop.get("defaultValue"),
-                        indent_num=1,
-                    )
-                    for prop_name, prop in list(type_object["value"].items())
+        return "dict with keys:\n{}".format(
+            "\n".join(
+                create_prop_docstring(
+                    prop_name=prop_name,
+                    type_object=prop,
+                    required=prop["required"],
+                    description=prop.get("description", ""),
+                    default=prop.get("defaultValue"),
+                    indent_num=indent_num + 2,
                 )
+                for prop_name, prop in 
sorted(list(type_object["value"].items()))
             ),
         )
 
@@ -526,7 +553,6 @@
 
 def map_js_to_py_types_flow_types(type_object):
     """Mapping from the Flow js types to the Python type."""
-
     return dict(
         array=lambda: "list",
         boolean=lambda: "boolean",
@@ -551,24 +577,18 @@
             else ""
         ),
         # React's PropTypes.shape
-        signature=lambda indent_num: "dict containing keys {}.\n{}".format(
-            ", ".join(
-                "'{}'".format(d["key"]) for d in 
type_object["signature"]["properties"]
-            ),
-            "{}Those keys have the following types:\n{}".format(
-                "  " * indent_num,
-                "\n".join(
-                    create_prop_docstring(
-                        prop_name=prop["key"],
-                        type_object=prop["value"],
-                        required=prop["value"]["required"],
-                        description=prop["value"].get("description", ""),
-                        default=prop.get("defaultValue"),
-                        indent_num=indent_num,
-                        is_flow_type=True,
-                    )
-                    for prop in type_object["signature"]["properties"]
-                ),
+        signature=lambda indent_num: "dict with keys:\n{}".format(
+            "\n".join(
+                create_prop_docstring(
+                    prop_name=prop["key"],
+                    type_object=prop["value"],
+                    required=prop["value"]["required"],
+                    description=prop["value"].get("description", ""),
+                    default=prop.get("defaultValue"),
+                    indent_num=indent_num + 2,
+                    is_flow_type=True,
+                )
+                for prop in type_object["signature"]["properties"]
             ),
         ),
     )
@@ -576,7 +596,6 @@
 
 def js_to_py_type(type_object, is_flow_type=False, indent_num=0):
     """Convert JS types to Python types for the component definition.
-
     Parameters
     ----------
     type_object: dict
@@ -585,17 +604,19 @@
         Does the prop use Flow types? Otherwise, uses PropTypes
     indent_num: int
         Number of indents to use for the docstring for the prop
-
     Returns
     -------
     str
         Python type string
     """
+
     js_type_name = type_object["name"]
     js_to_py_types = (
         map_js_to_py_types_flow_types(type_object=type_object)
         if is_flow_type
-        else map_js_to_py_types_prop_types(type_object=type_object)
+        else map_js_to_py_types_prop_types(
+            type_object=type_object, indent_num=indent_num
+        )
     )
 
     if (
Binary files old/dash-1.18.1/dash/favicon.ico and 
new/dash-1.20.0/dash/favicon.ico differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dash-1.18.1/dash/resources.py 
new/dash-1.20.0/dash/resources.py
--- old/dash-1.18.1/dash/resources.py   2020-12-08 14:42:55.000000000 +0100
+++ new/dash-1.20.0/dash/resources.py   2021-01-20 00:35:20.000000000 +0100
@@ -24,8 +24,12 @@
             if "async" in s:
                 if "dynamic" in s:
                     raise exceptions.ResourceException(
-                        "Can't have both 'dynamic' and 'async'. "
-                        "{}".format(json.dumps(filtered_resource))
+                        """
+                        Can't have both 'dynamic' and 'async'.
+                        {}
+                        """.format(
+                            json.dumps(filtered_resource)
+                        )
                     )
 
                 # Async assigns a value dynamically to 'dynamic'
@@ -70,9 +74,12 @@
                 continue
             else:
                 raise exceptions.ResourceException(
-                    "{} does not have a "
-                    "relative_package_path, absolute_path, or an "
-                    "external_url.".format(json.dumps(filtered_resource))
+                    """
+                    {} does not have a relative_package_path, absolute_path,
+                    or an external_url.
+                    """.format(
+                        json.dumps(filtered_resource)
+                    )
                 )
 
             filtered_resources.append(filtered_resource)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dash-1.18.1/dash/testing/application_runners.py 
new/dash-1.20.0/dash/testing/application_runners.py
--- old/dash-1.18.1/dash/testing/application_runners.py 2020-12-08 
14:42:55.000000000 +0100
+++ new/dash-1.20.0/dash/testing/application_runners.py 2021-01-20 
00:35:20.000000000 +0100
@@ -125,7 +125,7 @@
         stopper()
         return "Flask server is shutting down"
 
-    # pylint: disable=arguments-differ,C0330
+    # pylint: disable=arguments-differ
     def start(self, app, **kwargs):
         """Start the app server in threading flavor."""
         app.server.add_url_rule(self.stop_route, self.stop_route, 
self._stop_server)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dash-1.18.1/dash/testing/browser.py 
new/dash-1.20.0/dash/testing/browser.py
--- old/dash-1.18.1/dash/testing/browser.py     2020-12-08 14:42:55.000000000 
+0100
+++ new/dash-1.20.0/dash/testing/browser.py     2021-04-09 00:03:55.000000000 
+0200
@@ -77,10 +77,10 @@
             )
             self.percy_runner.initialize_build()
 
-        logger.info("initialize browser with arguments")
-        logger.info("  headless => %s", self._headless)
-        logger.info("  download_path => %s", self._download_path)
-        logger.info("  percy asset root => %s", 
os.path.abspath(percy_assets_root))
+        logger.debug("initialize browser with arguments")
+        logger.debug("  headless => %s", self._headless)
+        logger.debug("  download_path => %s", self._download_path)
+        logger.debug("  percy asset root => %s", 
os.path.abspath(percy_assets_root))
 
     def __enter__(self):
         return self
@@ -358,9 +358,9 @@
 
         if self._pause:
             try:
-                import pdb as pdb_
+                import pdb as pdb_  # pylint: disable=import-outside-toplevel
             except ImportError:
-                import ipdb as pdb_
+                import ipdb as pdb_  # pylint: disable=import-outside-toplevel
 
             pdb_.set_trace()
 
@@ -431,6 +431,7 @@
 
         capabilities = DesiredCapabilities.CHROME
         capabilities["loggingPrefs"] = {"browser": "SEVERE"}
+        capabilities["goog:loggingPrefs"] = {"browser": "SEVERE"}
 
         if "DASH_TEST_CHROMEPATH" in os.environ:
             options.binary_location = os.environ["DASH_TEST_CHROMEPATH"]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dash-1.18.1/dash/testing/plugin.py 
new/dash-1.20.0/dash/testing/plugin.py
--- old/dash-1.18.1/dash/testing/plugin.py      2020-12-08 14:42:55.000000000 
+0100
+++ new/dash-1.20.0/dash/testing/plugin.py      2021-01-20 00:35:20.000000000 
+0100
@@ -65,7 +65,7 @@
 def pytest_addhooks(pluginmanager):
     # 
https://github.com/pytest-dev/pytest-xdist/blob/974bd566c599dc6a9ea291838c6f226197208b46/xdist/plugin.py#L67
     # avoid warnings with pytest-2.8
-    from dash.testing import newhooks
+    from dash.testing import newhooks  # pylint: 
disable=import-outside-toplevel
 
     method = getattr(pluginmanager, "add_hookspecs", None)
     if method is None:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dash-1.18.1/dash/version.py 
new/dash-1.20.0/dash/version.py
--- old/dash-1.18.1/dash/version.py     2020-12-09 22:30:29.000000000 +0100
+++ new/dash-1.20.0/dash/version.py     2021-04-09 00:03:55.000000000 +0200
@@ -1 +1 @@
-__version__ = "1.18.1"
+__version__ = "1.20.0"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dash-1.18.1/dash.egg-info/PKG-INFO 
new/dash-1.20.0/dash.egg-info/PKG-INFO
--- old/dash-1.18.1/dash.egg-info/PKG-INFO      2020-12-09 22:33:39.000000000 
+0100
+++ new/dash-1.20.0/dash.egg-info/PKG-INFO      2021-04-09 00:19:30.000000000 
+0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: dash
-Version: 1.18.1
+Version: 1.20.0
 Summary: A Python framework for building reactive web-apps. Developed by 
Plotly.
 Home-page: https://plotly.com/dash
 Author: Chris Parmer
@@ -43,9 +43,9 @@
         
         Scale up with Dash Enterprise when your Dash app is ready for 
department or company-wide consumption. Or, launch your initiative with Dash 
Enterprise from the start to unlock developer productivity gains and hands-on 
acceleration from Plotly's team.
         
-        ML Ops Features: A one-stop shop for ML Ops: Horizontally scalable 
hosting, deployment, and authentication for your Dash apps. No IT or DevOps 
required. 
+        ML Ops Features: A one-stop shop for ML Ops: Horizontally scalable 
hosting, deployment, and authentication for your Dash apps. No IT or DevOps 
required.
         - [**App manager**](https://plotly.com/dash/app-manager/) Deploy & 
manage Dash apps without needing IT or a DevOps team. App Manager gives you 
point & click control over all aspects of your Dash deployments.
-        - [**Kubernetes scaling**](https://plotly.com/dash/kubernetes/) Ensure 
high availability of Dash apps and scale horizontally with Dash Enterprise???s 
Kubernetes architecture. No IT or Helm required. 
+        - [**Kubernetes scaling**](https://plotly.com/dash/kubernetes/) Ensure 
high availability of Dash apps and scale horizontally with Dash Enterprise???s 
Kubernetes architecture. No IT or Helm required.
         - [**No code auth**](https://plotly.com/dash/authentication/) Control 
Dash app access in a few clicks. Dash Enterprise supports LDAP, AD, PKI, Okta, 
SAML, OpenID Connect, OAuth, SSO, and simple email authentication.
         - [**Job Queue**](https://plotly.com/dash/job-queue/) The Job Queue is 
the key to building scalable Dash apps. Move heavy computation from synchronous 
Dash callbacks to the Job Queue for asynchronous background processing.
         
@@ -61,7 +61,6 @@
         - [**GPU & Dask 
Acceleration**](https://plotly.com/dash/gpu-dask-acceleration/) Dash Enterprise 
puts Python???s most popular HPC stack for GPU and parallel CPU computing in 
the hands of business users.
         - [**Data Science Workspaces**](https://plotly.com/dash/workspaces/) 
Be productive from Day 1. Write and execute Python, R, & Julia code from Dash 
Enterprise's onboard code editor.
         
-        
         See [https://plotly.com/contact-us/](https://plotly.com/contact-us/) 
to get in touch.
         
         
![image](https://images.prismic.io/plotly-marketing-website/493eec39-8467-4610-b9d0-d6ad3ea61423_Dash+Open+source%2BDash+enterprise2-01.jpg?auto=compress,format)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dash-1.18.1/dash.egg-info/requires.txt 
new/dash-1.20.0/dash.egg-info/requires.txt
--- old/dash-1.18.1/dash.egg-info/requires.txt  2020-12-09 22:33:39.000000000 
+0100
+++ new/dash-1.20.0/dash.egg-info/requires.txt  2021-04-09 00:19:30.000000000 
+0200
@@ -1,51 +1,54 @@
 Flask>=1.0.4
 flask-compress
 plotly
-dash_renderer==1.8.3
-dash-core-components==1.14.1
-dash-html-components==1.1.1
-dash-table==4.11.1
+dash_renderer==1.9.1
+dash-core-components==1.16.0
+dash-html-components==1.1.3
+dash-table==4.11.3
 future
 
 [dev]
 dash_flow_example==0.0.5
 dash-dangerously-set-inner-html
-isort==4.3.21
-flake8==3.7.9
-PyYAML==5.3
-fire==0.2.1
-coloredlogs==14.0
+flake8==3.8.4
+PyYAML==5.3.1
+fire==0.3.1
+coloredlogs==15.0
+flask-talisman==0.7.0
 
 [dev:python_version < "3.7"]
-pylint==1.9.4
+isort==4.3.21
+pylint==1.9.5
 
 [dev:python_version == "2.7"]
 mock==3.0.5
-virtualenv==20.0.10
-
-[dev:python_version == "3.7"]
-pylint==2.3.1
-astroid==2.2.5
+virtualenv==20.2.2
 
 [dev:python_version >= "3.0"]
-mock==4.0.1
+mock==4.0.3
 black==19.10b0
 
+[dev:python_version >= "3.7"]
+pylint==2.6.0
+astroid==2.4.2
+
 [testing]
-pytest-sugar==0.9.4
-lxml==4.6.1
-selenium==3.141.0
-percy==2.0.2
-cryptography==3.0
-requests[security]==2.21.0
-beautifulsoup4==4.8.2
-waitress==1.4.3
-flask-talisman==0.7.0
+pytest-sugar>=0.9.4
+lxml>=4.6.2
+selenium>=3.141.0
+percy>=2.0.2
+requests[security]>=2.21.0
+waitress>=1.4.4
+
+[testing:python_version < "3.7"]
+cryptography<3.4
 
 [testing:python_version == "2.7"]
-pytest==4.6.9
-pytest-mock==2.0.0
+pytest<5,>=4.6
+pytest-mock<3,>=2.0.0
+beautifulsoup4<=4.9.3,>=4.8.2
 
 [testing:python_version >= "3.0"]
-pytest==6.0.1
-pytest-mock==3.2.0
+pytest>=6.0.2
+pytest-mock>=3.2.0
+beautifulsoup4>=4.8.2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dash-1.18.1/requires-dev.txt 
new/dash-1.20.0/requires-dev.txt
--- old/dash-1.18.1/requires-dev.txt    2020-12-08 14:42:55.000000000 +0100
+++ new/dash-1.20.0/requires-dev.txt    2021-01-20 00:35:20.000000000 +0100
@@ -1,14 +1,15 @@
 dash_flow_example==0.0.5
 dash-dangerously-set-inner-html
-isort==4.3.21
-mock==4.0.1;python_version>="3.0"
+isort==4.3.21;python_version<"3.7"
+mock==4.0.3;python_version>="3.0"
 mock==3.0.5;python_version=="2.7"
-flake8==3.7.9
-PyYAML==5.3
-pylint==1.9.4;python_version<"3.7"
-pylint==2.3.1;python_version=="3.7"
-astroid==2.2.5;python_version=="3.7"
+flake8==3.8.4
+PyYAML==5.3.1
+pylint==1.9.5;python_version<"3.7"
+pylint==2.6.0;python_version>="3.7"
+astroid==2.4.2;python_version>="3.7"
 black==19.10b0;python_version>="3.0"
-virtualenv==20.0.10;python_version=="2.7"
-fire==0.2.1
-coloredlogs==14.0
+virtualenv==20.2.2;python_version=="2.7"
+fire==0.3.1
+coloredlogs==15.0
+flask-talisman==0.7.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dash-1.18.1/requires-install.txt 
new/dash-1.20.0/requires-install.txt
--- old/dash-1.18.1/requires-install.txt        2020-12-09 22:30:29.000000000 
+0100
+++ new/dash-1.20.0/requires-install.txt        2021-04-09 00:03:55.000000000 
+0200
@@ -1,8 +1,8 @@
 Flask>=1.0.4
 flask-compress
 plotly
-dash_renderer==1.8.3
-dash-core-components==1.14.1
-dash-html-components==1.1.1
-dash-table==4.11.1
+dash_renderer==1.9.1
+dash-core-components==1.16.0
+dash-html-components==1.1.3
+dash-table==4.11.3
 future
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dash-1.18.1/requires-testing.txt 
new/dash-1.20.0/requires-testing.txt
--- old/dash-1.18.1/requires-testing.txt        2020-12-08 14:42:55.000000000 
+0100
+++ new/dash-1.20.0/requires-testing.txt        2021-04-09 00:03:55.000000000 
+0200
@@ -1,13 +1,13 @@
-pytest==6.0.1;python_version>="3.0"
-pytest==4.6.9;python_version=="2.7"
-pytest-sugar==0.9.4
-pytest-mock==3.2.0;python_version>="3.0"
-pytest-mock==2.0.0;python_version=="2.7"
-lxml==4.6.1
-selenium==3.141.0
-percy==2.0.2
-cryptography==3.0
-requests[security]==2.21.0
-beautifulsoup4==4.8.2
-waitress==1.4.3
-flask-talisman==0.7.0
+pytest>=6.0.2;python_version>="3.0"
+pytest>=4.6,<5;python_version=="2.7"
+pytest-sugar>=0.9.4
+pytest-mock>=3.2.0;python_version>="3.0"
+pytest-mock>=2.0.0,<3;python_version=="2.7"
+lxml>=4.6.2
+selenium>=3.141.0
+percy>=2.0.2
+cryptography<3.4;python_version<"3.7"
+requests[security]>=2.21.0
+beautifulsoup4>=4.8.2,<=4.9.3;python_version=="2.7"
+beautifulsoup4>=4.8.2;python_version>="3.0"
+waitress>=1.4.4

Reply via email to