Fix pkgutil.find_loader deprecation warning
Users might encounter:
'pkgutil.find_loader' is deprecated and slated for removal in Python 3.14; use importlib.util.find_spec() instead.
in Dash. To ensure forwards compatibility we should update to the new recommended method.
Python 3.14 is expected to arrive in October 2025
I can use this patch fix AttributeError: module 'pkgutil' has no attribute 'find_loader' in dash 3.0.4(python v3.14.0b2:12d3f88)
--- .venv/Lib/site-packages/dash/dash.py.orig 2024-01-01 00:00:00.000000000 +0000
+++ .venv/Lib/site-packages/dash/dash.py 2024-01-01 00:00:01.000000000 +0000
@@ -1888,18 +1888,20 @@
if dev_tools.hot_reload:
_reload = self._hot_reload
_reload.hash = generate_hash()
- # find_loader should return None on __main__ but doesn't
+ # find_spec should return None on __main__ but doesn't
# on some Python versions https://bugs.python.org/issue14710
packages = [
- pkgutil.find_loader(x)
+ importlib.util.find_spec(x)
for x in list(ComponentRegistry.registry)
if x != "__main__"
]
# # additional condition to account for AssertionRewritingHook object
# # loader when running pytest
+ dash_test_path = None # Initialize to prevent UnboundLocalError
if "_pytest" in sys.modules:
from _pytest.assertion.rewrite import ( # pylint: disable=import-outside-toplevel
AssertionRewritingHook, # type: ignore[reportPrivateImportUsage]
)
@@ -1911,8 +1913,10 @@
packages[index] = dash_spec
component_packages_dist = [
- dash_test_path # type: ignore[reportPossiblyUnboundVariable]
- if isinstance(package, ModuleSpec)
+ dash_test_path
+ if isinstance(package, ModuleSpec) and dash_test_path is not None
+ else os.path.dirname(package.origin) # type: ignore[reportAttributeAccessIssue]
+ if hasattr(package, "origin") and package.origin
else os.path.dirname(package.path) # type: ignore[reportAttributeAccessIssue]
if hasattr(package, "path")
else os.path.dirname(
@@ -1924,11 +1928,15 @@
]
for i, package in enumerate(packages):
- if hasattr(package, "path") and "dash/dash" in os.path.dirname(
- package.path # type: ignore[reportAttributeAccessIssue]
- ):
+ package_path = None
+ if hasattr(package, "origin") and package.origin:
+ package_path = package.origin
+ elif hasattr(package, "path"):
+ package_path = package.path # type: ignore[reportAttributeAccessIssue]
+
+ if package_path and "dash/dash" in os.path.dirname(package_path):
component_packages_dist[i : i + 1] = [
- os.path.join(os.path.dirname(package.path), x) # type: ignore[reportAttributeAccessIssue]
+ os.path.join(os.path.dirname(package_path), x)
for x in ["dcc", "html", "dash_table"]
]
A friendly bump, to put additional attention to this. Python 3.14 is almost out. Originally reported in #3136 at the end of Jan.
@vex87 , I don't understand everything in the patch, but it looks like you solved the problem already pretty thoroughly. Could you be able to put together a PR?
Personally I see this DeprecationWarning float by 20~50 times a day (every hot-reload), so it is a bit of a distraction. Thanks.
Another bump. We give 3.3.0rc0 a try. The issue is still not resolved.
Package operations: 0 installs, 1 update, 0 removals
- Updating dash (3.2.0 -> 3.3.0rc0)
Writing lock file
(venv) PS C:\Users\gxvh\Python\dwsc-site> flask run
2025-09-26 09:08:10 - INFO - Settings class: dwsc.config.LocalDevelopmentConfig
C:\Users\xxxx\Python\site\venv\Lib\site-packages\dash\dash.py:2055: DeprecationWarning:
'pkgutil.find_loader' is deprecated and slated for removal in Python 3.14; use importlib.util.find_spec() instead
Callback Map: Len=228, Inputs=358, States=149, Outputs=413
@ghaarsma not planned for 3.3.0 yet but this is absolutely on our radar 🫡
What's the change of this making it into 3.3.0? Its all that's keeping me from updating my project to python 3.14 :(
Officially deprecated, had to downgrade project
File ".venv/lib/python3.14/site-packages/dash/dash.py", line 1990, in enable_dev_tools
pkgutil.find_loader(x)
^^^^^^^^^^^^^^^^^^^
AttributeError: module 'pkgutil' has no attribute 'find_loader'