Skip to content

autoreload: Use importlib.util.find_spec instead of pkgutil.get_loader - #3849

Merged
bdarnell merged 1 commit into
tornadoweb:masterfrom
b84330808:autoreload-find-spec
Nov 6, 2026
Merged

bdarnell merged 1 commit into
tornadoweb:masterfrom
b84330808:autoreload-find-spec

Conversation

@b84330808

Copy link
Copy Markdown
Contributor

pkgutil.get_loader() was removed in Python 3.14. python -m tornado.autoreload -m <module> calls it after the module exits, to find the module's file and watch it, so on 3.14+ the wrapper stops with AttributeError: module 'pkgutil' has no attribute 'get_loader' instead of waiting for changes (on 3.12/3.13 it prints a DeprecationWarning). The existing autoreload tests don't reach this line because their apps reload themselves before they exit.

This uses importlib.util.find_spec(), which is what get_loader() called internally, so the watched file is the same. The new test runs a package with -m and --until-success; it fails on Python 3.15.1 without the change and passes with it. python -m tornado.test.runtests passes on 3.15.1, and autoreload_test passes on 3.11 and 3.13.

I used Claude Code to write this change.

pkgutil.get_loader was removed in Python 3.14, so on 3.14+ the
`python -m tornado.autoreload -m module` wrapper raised AttributeError
once the module exited, instead of watching the module's file.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

@chiragjangiir chiragjangiir left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review: autoreload: Use importlib.util.find_spec instead of pkgutil.get_loader (#3849)

1. Summary & Architecture

Modernizes module reloading in Tornado's autoreload module by replacing the deprecated pkgutil.get_loader() with Python 3.12+ standard importlib.util.find_spec().

2. Implementation & Diff Analysis

  • API Migration: In tornado/autoreload.py, queries importlib.util.find_spec(module_name) to locate source files and determine module origins.
  • Spec Origin Inspection: Extracts spec.origin to check whether the file is a valid filesystem path suitable for stat/mtime modification tracking.

3. Edge Cases & Robustness

  • Gracefully handles namespace packages and built-in/frozen modules where spec.origin is None or 'frozen'.
  • Eliminates Python 3.12+ DeprecationWarning noise during development server reloads.

4. Test Coverage Assessment

  • Unit tests in tornado/test/autoreload_test.py verifying module discovery and reloading behavior under modern CPython runtimes.

5. Recommendation

Timely maintenance eliminating deprecated library calls before upcoming Python removals.

@bdarnell

bdarnell commented Nov 6, 2026

Copy link
Copy Markdown
Member

Thanks!

@bdarnell
bdarnell merged commit f0c030b into tornadoweb:master Nov 6, 2026
20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants