Opened 3 hours ago
#36956 new Cleanup/optimization
import_string logic for AttributeError is too broad, can be improved under Python 3.10+
| Reported by: | Glenn Matthews | Owned by: | |
|---|---|---|---|
| Component: | Utilities | Version: | 6.0 |
| Severity: | Normal | Keywords: | import_string |
| Cc: | Triage Stage: | Unreviewed | |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
The logic in import_string that maps AttributeError to ImportError is overly-broad and can be misleading, as any AttributeError raised while importing the requested module will cause Django to report (perhaps misleadingly) that the specific attribute being requested is not defined:
try:
return cached_import(module_path, class_name)
except AttributeError as err:
raise ImportError(
'Module "%s" does not define a "%s" attribute/class'
% (module_path, class_name)
) from err
In Python 3.10 and later, AttributeError has been enhanced (https://docs.python.org/3/library/exceptions.html#AttributeError) to include explicit name and obj parameters, making it easy to tell exactly which specific attribute the error is attributed to.
My proposal is that the above logic should be enhanced to something like the following:
try:
return cached_import(module_path, class_name)
except AttributeError as err:
if err.name and err.name != class_name:
raise
raise ImportError(
'Module "%s" does not define a "%s" attribute/class'
% (module_path, class_name)
) from err
If accepted, I'll be happy to open a PR as described.