gh-118216: Don't consider dotted `__future__` imports (#118267)

This commit is contained in:
Crowthebird 2024-05-02 21:32:20 +08:00 committed by GitHub
parent 67bba9dd0f
commit 7c97dc8c95
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 26 additions and 2 deletions

View File

@ -288,6 +288,10 @@ Other Language Changes
class scopes are not inlined into their parent scope. (Contributed by
Jelle Zijlstra in :gh:`109118` and :gh:`118160`.)
* ``from __future__ import ...`` statements are now just normal
relative imports if dots are present before the module name.
(Contributed by Jeremiah Gabriel Pascual in :gh:`118216`.)
New Modules
===========

View File

@ -203,6 +203,25 @@ class FutureTest(unittest.TestCase):
out = kill_python(p)
self.assertNotIn(b'SyntaxError: invalid syntax', out)
def test_future_dotted_import(self):
with self.assertRaises(ImportError):
exec("from .__future__ import spam")
code = dedent(
"""
from __future__ import print_function
from ...__future__ import ham
"""
)
with self.assertRaises(ImportError):
exec(code)
code = """
from .__future__ import nested_scopes
from __future__ import barry_as_FLUFL
"""
self.assertSyntaxError(code, lineno=2)
class AnnotationsFutureTestCase(unittest.TestCase):
template = dedent(
"""

View File

@ -0,0 +1 @@
Don't consider :mod:`__future__` imports with dots before the module name.

View File

@ -3849,7 +3849,7 @@ compiler_from_import(struct compiler *c, stmt_ty s)
}
if (location_is_after(LOC(s), c->c_future.ff_location) &&
s->v.ImportFrom.module &&
s->v.ImportFrom.module && s->v.ImportFrom.level == 0 &&
_PyUnicode_EqualToASCIIString(s->v.ImportFrom.module, "__future__"))
{
Py_DECREF(names);

View File

@ -77,7 +77,7 @@ future_parse(_PyFutureFeatures *ff, mod_ty mod, PyObject *filename)
* are another future statement and a doc string.
*/
if (s->kind == ImportFrom_kind) {
if (s->kind == ImportFrom_kind && s->v.ImportFrom.level == 0) {
identifier modname = s->v.ImportFrom.module;
if (modname &&
_PyUnicode_EqualToASCIIString(modname, "__future__")) {