Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitc206e53

Browse files
gh-65961: RaiseDeprecationWarning when__package__ differs from__spec__.parent (#97879)
Also remove `importlib.util.set_package()` which was already slated for removal.Co-authored-by: Eric Snow <ericsnowcurrently@gmail.com>
1 parent2016bc5 commitc206e53

File tree

9 files changed

+45
-102
lines changed

9 files changed

+45
-102
lines changed

‎Doc/library/importlib.rst

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1378,15 +1378,6 @@ an :term:`importer`.
13781378
..deprecated::3.4
13791379
The import machinery takes care of this automatically.
13801380

1381-
..decorator::set_package
1382-
1383-
A:term:`decorator` for:meth:`importlib.abc.Loader.load_module` to set the
1384-
:attr:`__package__` attribute on the returned module. If:attr:`__package__`
1385-
is set and has a value other than ``None`` it will not be changed.
1386-
1387-
..deprecated::3.4
1388-
The import machinery takes care of this automatically.
1389-
13901381
..function::spec_from_loader(name, loader, *, origin=None, is_package=None)
13911382

13921383
A factory function for creating a:class:`~importlib.machinery.ModuleSpec`

‎Doc/reference/import.rst

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,6 @@ of what happens during the loading portion of import::
358358
sys.modules[spec.name] = module
359359
elif not hasattr(spec.loader, 'exec_module'):
360360
module = spec.loader.load_module(spec.name)
361-
# Set __loader__ and __package__ if missing.
362361
else:
363362
sys.modules[spec.name] = module
364363
try:
@@ -539,6 +538,10 @@ The import machinery fills in these attributes on each module object
539538
during loading, based on the module's spec, before the loader executes
540539
the module.
541540

541+
It is **strongly** recommended that you rely on:attr:`__spec__` and
542+
its attributes instead of any of the other individual attributes
543+
listed below.
544+
542545
..attribute::__name__
543546

544547
The ``__name__`` attribute must be set to the fully qualified name of
@@ -552,24 +555,36 @@ the module.
552555
for introspection, but can be used for additional loader-specific
553556
functionality, for example getting data associated with a loader.
554557

558+
It is **strongly** recommended that you rely on:attr:`__spec__`
559+
instead instead of this attribute.
560+
555561
..attribute::__package__
556562

557-
The module's ``__package__`` attributemust be set. Its value must
563+
The module's ``__package__`` attributemay be set. Its value must
558564
be a string, but it can be the same value as its ``__name__``. When
559565
the module is a package, its ``__package__`` value should be set to
560566
its ``__name__``. When the module is not a package, ``__package__``
561567
should be set to the empty string for top-level modules, or for
562568
submodules, to the parent package's name. See:pep:`366` for further
563569
details.
564570

565-
This attribute is used instead of ``__name__`` to calculate explicit
566-
relative imports for main modules, as defined in:pep:`366`. It is
567-
expected to have the same value as ``__spec__.parent``.
571+
It is **strongly** recommended that you rely on:attr:`__spec__`
572+
instead instead of this attribute.
568573

569574
..versionchanged::3.6
570575
The value of ``__package__`` is expected to be the same as
571576
``__spec__.parent``.
572577

578+
..versionchanged::3.10
579+
:exc:`ImportWarning` is raised if import falls back to
580+
``__package__`` instead of
581+
:attr:`~importlib.machinery.ModuleSpec.parent`.
582+
583+
..versionchanged::3.12
584+
Raise:exc:`DeprecationWarning` instead of:exc:`ImportWarning`
585+
when falling back to ``__package__``.
586+
587+
573588
..attribute::__spec__
574589

575590
The ``__spec__`` attribute must be set to the module spec that was
@@ -578,7 +593,7 @@ the module.
578593
interpreter startup <programs>`. The one exception is ``__main__``,
579594
where ``__spec__`` is:ref:`set to None in some cases<main_spec>`.
580595

581-
When ``__package__`` is notdefined, ``__spec__.parent`` is used as
596+
When ``__spec__.parent`` is notset, ``__package__`` is used as
582597
a fallback.
583598

584599
..versionadded::3.4
@@ -623,6 +638,9 @@ the module.
623638
if a loader can load from a cached module but otherwise does not load
624639
from a file, that atypical scenario may be appropriate.
625640

641+
It is **strongly** recommended that you rely on:attr:`__spec__`
642+
instead instead of ``__cached__``.
643+
626644
.. _package-path-rules:
627645

628646
module.__path__

‎Doc/whatsnew/3.12.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,11 @@ Deprecated
215215
may be removed in a future version of Python. Use the single-arg versions
216216
of these functions instead. (Contributed by Ofey Chan in:gh:`89874`.)
217217

218+
*:exc:`DeprecationWarning` is now raised when ``__package__`` on a
219+
module differs from ``__spec__.parent`` (previously it was
220+
:exc:`ImportWarning`).
221+
(Contributed by Brett Cannon in:gh:`65961`.)
222+
218223

219224
Pending Removal in Python 3.13
220225
------------------------------
@@ -275,6 +280,9 @@ Pending Removal in Python 3.14
275280
* Creating:c:data:`immutable types <Py_TPFLAGS_IMMUTABLETYPE>` with mutable
276281
bases using the C API.
277282

283+
* ``__package__`` will cease to be set or taken into consideration by
284+
the import system (:gh:`97879`).
285+
278286

279287
Pending Removal in Future Versions
280288
----------------------------------
@@ -432,6 +440,10 @@ Removed
432440
* References to, and support for ``module_repr()`` has been eradicated.
433441

434442

443+
* ``importlib.util.set_package`` has been removed.
444+
(Contributed by Brett Cannon in:gh:`65961`.)
445+
446+
435447
Porting to Python 3.12
436448
======================
437449

‎Lib/importlib/_bootstrap.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1228,7 +1228,7 @@ def _calc___package__(globals):
12281228
ifspecisnotNoneandpackage!=spec.parent:
12291229
_warnings.warn("__package__ != __spec__.parent "
12301230
f"({package!r} !={spec.parent!r})",
1231-
ImportWarning,stacklevel=3)
1231+
DeprecationWarning,stacklevel=3)
12321232
returnpackage
12331233
elifspecisnotNone:
12341234
returnspec.parent

‎Lib/importlib/util.py

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -141,26 +141,6 @@ def _module_to_load(name):
141141
module.__initializing__=False
142142

143143

144-
defset_package(fxn):
145-
"""Set __package__ on the returned module.
146-
147-
This function is deprecated.
148-
149-
"""
150-
@functools.wraps(fxn)
151-
defset_package_wrapper(*args,**kwargs):
152-
warnings.warn('The import system now takes care of this automatically; '
153-
'this decorator is slated for removal in Python 3.12',
154-
DeprecationWarning,stacklevel=2)
155-
module=fxn(*args,**kwargs)
156-
ifgetattr(module,'__package__',None)isNone:
157-
module.__package__=module.__name__
158-
ifnothasattr(module,'__path__'):
159-
module.__package__=module.__package__.rpartition('.')[0]
160-
returnmodule
161-
returnset_package_wrapper
162-
163-
164144
defset_loader(fxn):
165145
"""Set __loader__ on the returned module.
166146

‎Lib/test/test_importlib/import_/test___package__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@ def test_spec_fallback(self):
7474
self.assertEqual(module.__name__,'pkg')
7575

7676
deftest_warn_when_package_and_spec_disagree(self):
77-
# Raisean ImportWarning if __package__ != __spec__.parent.
78-
withself.assertWarns(ImportWarning):
77+
# Raisea DeprecationWarning if __package__ != __spec__.parent.
78+
withself.assertWarns(DeprecationWarning):
7979
self.import_module({'__package__':'pkg.fake',
8080
'__spec__':FakeSpec('pkg.fakefake')})
8181

‎Lib/test/test_importlib/test_util.py

Lines changed: 0 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -252,69 +252,6 @@ def load_module(self, module):
252252
)=util.test_both(ModuleForLoaderTests,util=importlib_util)
253253

254254

255-
classSetPackageTests:
256-
257-
"""Tests for importlib.util.set_package."""
258-
259-
defverify(self,module,expect):
260-
"""Verify the module has the expected value for __package__ after
261-
passing through set_package."""
262-
fxn=lambda:module
263-
wrapped=self.util.set_package(fxn)
264-
withwarnings.catch_warnings():
265-
warnings.simplefilter('ignore',DeprecationWarning)
266-
wrapped()
267-
self.assertTrue(hasattr(module,'__package__'))
268-
self.assertEqual(expect,module.__package__)
269-
270-
deftest_top_level(self):
271-
# __package__ should be set to the empty string if a top-level module.
272-
# Implicitly tests when package is set to None.
273-
module=types.ModuleType('module')
274-
module.__package__=None
275-
self.verify(module,'')
276-
277-
deftest_package(self):
278-
# Test setting __package__ for a package.
279-
module=types.ModuleType('pkg')
280-
module.__path__= ['<path>']
281-
module.__package__=None
282-
self.verify(module,'pkg')
283-
284-
deftest_submodule(self):
285-
# Test __package__ for a module in a package.
286-
module=types.ModuleType('pkg.mod')
287-
module.__package__=None
288-
self.verify(module,'pkg')
289-
290-
deftest_setting_if_missing(self):
291-
# __package__ should be set if it is missing.
292-
module=types.ModuleType('mod')
293-
ifhasattr(module,'__package__'):
294-
delattr(module,'__package__')
295-
self.verify(module,'')
296-
297-
deftest_leaving_alone(self):
298-
# If __package__ is set and not None then leave it alone.
299-
forvaluein (True,False):
300-
module=types.ModuleType('mod')
301-
module.__package__=value
302-
self.verify(module,value)
303-
304-
deftest_decorator_attrs(self):
305-
deffxn(module):pass
306-
withwarnings.catch_warnings():
307-
warnings.simplefilter('ignore',DeprecationWarning)
308-
wrapped=self.util.set_package(fxn)
309-
self.assertEqual(wrapped.__name__,fxn.__name__)
310-
self.assertEqual(wrapped.__qualname__,fxn.__qualname__)
311-
312-
313-
(Frozen_SetPackageTests,
314-
Source_SetPackageTests
315-
)=util.test_both(SetPackageTests,util=importlib_util)
316-
317-
318255
classSetLoaderTests:
319256

320257
"""Tests importlib.util.set_loader()."""
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
When ``__package__`` is different than ``__spec__.parent``, raise a
2+
``DeprecationWarning`` instead of ``ImportWarning``.
3+
4+
Also remove ``importlib.util.set_package()`` which was scheduled for
5+
removal.

‎Python/import.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1573,7 +1573,7 @@ resolve_name(PyThreadState *tstate, PyObject *name, PyObject *globals, int level
15731573
gotoerror;
15741574
}
15751575
elseif (equal==0) {
1576-
if (PyErr_WarnEx(PyExc_ImportWarning,
1576+
if (PyErr_WarnEx(PyExc_DeprecationWarning,
15771577
"__package__ != __spec__.parent",1)<0) {
15781578
gotoerror;
15791579
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp