Skip to content

Commit 89d3b20

Browse files
committed
gh-155358: [WIP] Deprecate tuple API of structseq objects
1 parent 7c653e2 commit 89d3b20

23 files changed

Lines changed: 241 additions & 129 deletions

Include/internal/pycore_interp_structs.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -823,6 +823,17 @@ typedef _Py_CODEUNIT *(*_PyJitEntryFuncPtr)(struct _PyExecutorObject *exec, _PyI
823823

824824
#define _PyInterpreterGuard_GUARDS_NOT_ALLOWED UINTPTR_MAX
825825

826+
typedef struct {
827+
PyTypeObject *async_gen_hooks_type;
828+
PyTypeObject *flags_type;
829+
#if defined(MS_WINDOWS)
830+
PyTypeObject *windows_version_type;
831+
#endif
832+
#ifdef __EMSCRIPTEN__
833+
PyTypeObject *emscripten_info_type;
834+
#endif
835+
} _PySys_State;
836+
826837
/* PyInterpreterState holds the global state for one of the runtime's
827838
interpreters. Typically the initial (main) interpreter is the only one.
828839
@@ -899,6 +910,7 @@ struct _is {
899910

900911
// Dictionary of the sys module
901912
PyObject *sysdict;
913+
_PySys_State sys_state;
902914

903915
// Dictionary of the builtins module
904916
PyObject *builtins;

Include/internal/pycore_pylifecycle.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ extern PyStatus _PySys_Create(
3232
extern PyStatus _PySys_ReadPreinitWarnOptions(PyWideStringList *options);
3333
extern PyStatus _PySys_ReadPreinitXOptions(PyConfig *config);
3434
extern int _PySys_UpdateConfig(PyThreadState *tstate);
35-
extern void _PySys_FiniTypes(PyInterpreterState *interp);
35+
extern void _PySys_Fini(PyInterpreterState *interp);
3636
extern int _PyBuiltins_AddExceptions(PyObject * bltinmod);
3737
extern PyStatus _Py_HashRandomization_Init(const PyConfig *);
3838

Include/internal/pycore_structseq.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ extern "C" {
1414
// Export for '_curses' shared extension
1515
PyAPI_FUNC(PyTypeObject*) _PyStructSequence_NewType(
1616
PyStructSequence_Desc *desc,
17-
unsigned long tp_flags);
17+
unsigned long tp_flags,
18+
int deprecate_tuple_api);
1819

1920
extern int _PyStructSequence_InitBuiltinWithFlags(
2021
PyInterpreterState *interp,

Lib/http/server.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -857,7 +857,7 @@ def send_head(self):
857857

858858
self.send_response(HTTPStatus.OK)
859859
self.send_header("Content-type", ctype)
860-
self.send_header("Content-Length", str(fs[6]))
860+
self.send_header("Content-Length", str(fs.st_size))
861861
self.send_header("Last-Modified",
862862
self.date_time_string(fs.st_mtime))
863863
self._send_extra_response_headers()

Lib/test/test_grp.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import string
55
import sys
66
import unittest
7+
import warnings
78
from test.support import import_helper
89

910

@@ -14,16 +15,19 @@ class GroupDatabaseTestCase(unittest.TestCase):
1415
def check_value(self, value):
1516
# check that a grp tuple has the entries and
1617
# attributes promised by the docs
17-
self.assertEqual(len(value), 4)
18-
self.assertEqual(value[0], value.gr_name)
1918
self.assertIsInstance(value.gr_name, str)
20-
self.assertEqual(value[1], value.gr_passwd)
2119
self.assertIsInstance(value.gr_passwd, str)
22-
self.assertEqual(value[2], value.gr_gid)
2320
self.assertIsInstance(value.gr_gid, int)
24-
self.assertEqual(value[3], value.gr_mem)
2521
self.assertIsInstance(value.gr_mem, list)
2622

23+
with warnings.catch_warnings(category=DeprecationWarning):
24+
warnings.simplefilter("ignore", category=DeprecationWarning)
25+
self.assertEqual(len(value), 4)
26+
self.assertEqual(value[0], value.gr_name)
27+
self.assertEqual(value[1], value.gr_passwd)
28+
self.assertEqual(value[2], value.gr_gid)
29+
self.assertEqual(value[3], value.gr_mem)
30+
2731
def test_values(self):
2832
entries = grp.getgrall()
2933

Lib/test/test_os/test_os.py

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -665,7 +665,9 @@ def check_stat_attributes(self, fname):
665665
result = os.stat(fname)
666666

667667
# Make sure direct access works
668-
self.assertEqual(result[stat.ST_SIZE], 3)
668+
with warnings.catch_warnings(category=DeprecationWarning):
669+
warnings.simplefilter("ignore", category=DeprecationWarning)
670+
self.assertEqual(result[stat.ST_SIZE], 3)
669671
self.assertEqual(result.st_size, 3)
670672

671673
# Make sure all the attributes are there
@@ -677,8 +679,10 @@ def check_stat_attributes(self, fname):
677679
def trunc(x): return int(x)
678680
else:
679681
def trunc(x): return x
680-
self.assertEqual(trunc(getattr(result, attr)),
681-
result[getattr(stat, name)])
682+
with warnings.catch_warnings(category=DeprecationWarning):
683+
warnings.simplefilter("ignore", category=DeprecationWarning)
684+
self.assertEqual(trunc(getattr(result, attr)),
685+
result[getattr(stat, name)])
682686
self.assertIn(attr, members)
683687

684688
time_attributes = ['st_atime', 'st_mtime', 'st_ctime']
@@ -692,7 +696,9 @@ def trunc(x): return x
692696
self.check_timestamp_agreement(result, time_attributes)
693697

694698
try:
695-
result[200]
699+
with warnings.catch_warnings(category=DeprecationWarning):
700+
warnings.simplefilter("ignore", category=DeprecationWarning)
701+
result[200]
696702
self.fail("No exception raised")
697703
except IndexError:
698704
pass
@@ -1055,9 +1061,11 @@ def support_subsecond(self, filename):
10551061
# Heuristic to check if the filesystem supports timestamp with
10561062
# subsecond resolution: check if float and int timestamps are different
10571063
st = os.stat(filename)
1058-
return ((st.st_atime != st[7])
1059-
or (st.st_mtime != st[8])
1060-
or (st.st_ctime != st[9]))
1064+
with warnings.catch_warnings(category=DeprecationWarning):
1065+
warnings.simplefilter("ignore", category=DeprecationWarning)
1066+
return ((st.st_atime != st[7])
1067+
or (st.st_mtime != st[8])
1068+
or (st.st_ctime != st[9]))
10611069

10621070
def support_atime(self, filename):
10631071
# Heuristic to check if the filesystem stores the access time.

Lib/test/test_os/test_posix.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1816,8 +1816,8 @@ def test_link_dir_fd(self):
18161816
self.skipTest('posix.link(): %s' % e)
18171817
self.addCleanup(posix.unlink, fulllinkname)
18181818
# should have same inodes
1819-
self.assertEqual(posix.stat(fullname)[1],
1820-
posix.stat(fulllinkname)[1])
1819+
self.assertEqual(posix.stat(fullname).st_ino,
1820+
posix.stat(fulllinkname).st_ino)
18211821

18221822
@unittest.skipUnless(os.mkdir in os.supports_dir_fd, "test needs dir_fd support in os.mkdir()")
18231823
def test_mkdir_dir_fd(self):

Lib/test/test_pwd.py

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import string
33
import sys
44
import unittest
5+
import warnings
56
from test.support import import_helper
67

78
pwd = import_helper.import_module('pwd')
@@ -13,22 +14,25 @@ def test_values(self):
1314
entries = pwd.getpwall()
1415

1516
for e in entries:
16-
self.assertEqual(len(e), 7)
17-
self.assertEqual(e[0], e.pw_name)
1817
self.assertIsInstance(e.pw_name, str)
19-
self.assertEqual(e[1], e.pw_passwd)
2018
self.assertIsInstance(e.pw_passwd, str)
21-
self.assertEqual(e[2], e.pw_uid)
2219
self.assertIsInstance(e.pw_uid, int)
23-
self.assertEqual(e[3], e.pw_gid)
2420
self.assertIsInstance(e.pw_gid, int)
25-
self.assertEqual(e[4], e.pw_gecos)
2621
self.assertIn(type(e.pw_gecos), (str, type(None)))
27-
self.assertEqual(e[5], e.pw_dir)
2822
self.assertIsInstance(e.pw_dir, str)
29-
self.assertEqual(e[6], e.pw_shell)
3023
self.assertIsInstance(e.pw_shell, str)
3124

25+
with warnings.catch_warnings(category=DeprecationWarning):
26+
warnings.simplefilter("ignore", category=DeprecationWarning)
27+
self.assertEqual(len(e), 7)
28+
self.assertEqual(e[0], e.pw_name)
29+
self.assertEqual(e[1], e.pw_passwd)
30+
self.assertEqual(e[2], e.pw_uid)
31+
self.assertEqual(e[3], e.pw_gid)
32+
self.assertEqual(e[4], e.pw_gecos)
33+
self.assertEqual(e[5], e.pw_dir)
34+
self.assertEqual(e[6], e.pw_shell)
35+
3236
# The following won't work, because of duplicate entries
3337
# for one uid
3438
# self.assertEqual(pwd.getpwuid(e.pw_uid), e)
@@ -50,7 +54,7 @@ def test_values_extended(self):
5054
# check whether the entry returned by getpwuid()
5155
# for each uid is among those from getpwall() for this uid
5256
for e in entries:
53-
if not e[0] or e[0] == '+':
57+
if not e.pw_name or e.pw_name == '+':
5458
continue # skip NIS entries etc.
5559
self.assertIn(pwd.getpwnam(e.pw_name), entriesbyname[e.pw_name])
5660
self.assertIn(pwd.getpwuid(e.pw_uid), entriesbyuid[e.pw_uid])

Lib/test/test_structseq.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import textwrap
77
import time
88
import unittest
9+
import warnings
910
from test.support import script_helper
1011

1112

@@ -228,7 +229,9 @@ def test_copying_with_unnamed_fields(self):
228229
self.assertEqual(r2.st_mode, r.st_mode)
229230
self.assertEqual(r2.st_atime, r.st_atime)
230231
self.assertEqual(r2.st_atime_ns, r.st_atime_ns)
231-
self.assertIs(r2[0], r[0])
232+
with warnings.catch_warnings(category=DeprecationWarning):
233+
warnings.simplefilter("ignore", category=DeprecationWarning)
234+
self.assertIs(r2[0], r[0])
232235
self.assertIs(r2.st_mode, r.st_mode)
233236
self.assertIs(r2.st_atime, r.st_atime)
234237
self.assertIs(r2.st_atime_ns, r.st_atime_ns)
@@ -239,7 +242,9 @@ def test_copying_with_unnamed_fields(self):
239242
self.assertEqual(r3.st_mode, r.st_mode)
240243
self.assertEqual(r3.st_atime, r.st_atime)
241244
self.assertEqual(r3.st_atime_ns, r.st_atime_ns)
242-
self.assertIsNot(r3[0], r[0])
245+
with warnings.catch_warnings(category=DeprecationWarning):
246+
warnings.simplefilter("ignore", category=DeprecationWarning)
247+
self.assertIsNot(r3[0], r[0])
243248
self.assertIsNot(r3.st_mode, r.st_mode)
244249
self.assertIsNot(r3.st_atime, r.st_atime)
245250
self.assertIsNot(r3.st_atime_ns, r.st_atime_ns)

Lib/test/test_sys.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -874,8 +874,10 @@ def test_sys_flags_indexable_attributes(self):
874874
attr_type = bool if attr in ("dev_mode", "safe_path") else int
875875
self.assertEqual(type(getattr(sys.flags, attr)), attr_type, attr)
876876
attr_value = getattr(sys.flags, attr)
877-
self.assertEqual(sys.flags[attr_idx], attr_value,
878-
msg=f"sys.flags .{attr} vs [{attr_idx}]")
877+
with warnings.catch_warnings(category=DeprecationWarning):
878+
warnings.simplefilter("ignore", category=DeprecationWarning)
879+
self.assertEqual(sys.flags[attr_idx], attr_value,
880+
msg=f"sys.flags .{attr} vs [{attr_idx}]")
879881
self.assertTrue(repr(sys.flags))
880882
self.assertEqual(len(sys.flags), 18, msg="Do not increase, see GH-122575")
881883

@@ -1965,16 +1967,20 @@ def test_asyncgen_hooks(self):
19651967
sys.set_asyncgen_hooks(firstiter=firstiter)
19661968
hooks = sys.get_asyncgen_hooks()
19671969
self.assertIs(hooks.firstiter, firstiter)
1968-
self.assertIs(hooks[0], firstiter)
19691970
self.assertIs(hooks.finalizer, None)
1970-
self.assertIs(hooks[1], None)
1971+
with warnings.catch_warnings(category=DeprecationWarning):
1972+
warnings.simplefilter("ignore", category=DeprecationWarning)
1973+
self.assertIs(hooks[0], firstiter)
1974+
self.assertIs(hooks[1], None)
19711975

19721976
sys.set_asyncgen_hooks(finalizer=finalizer)
19731977
hooks = sys.get_asyncgen_hooks()
19741978
self.assertIs(hooks.firstiter, firstiter)
1975-
self.assertIs(hooks[0], firstiter)
19761979
self.assertIs(hooks.finalizer, finalizer)
1977-
self.assertIs(hooks[1], finalizer)
1980+
with warnings.catch_warnings(category=DeprecationWarning):
1981+
warnings.simplefilter("ignore", category=DeprecationWarning)
1982+
self.assertIs(hooks[0], firstiter)
1983+
self.assertIs(hooks[1], finalizer)
19781984

19791985
sys.set_asyncgen_hooks(*old)
19801986
cur = sys.get_asyncgen_hooks()

0 commit comments

Comments
 (0)