Skip to content

Commit 1dc57e8

Browse files
authored
Update some libs to 3.14.6 (RustPython#8102)
1 parent eccbc5e commit 1dc57e8

17 files changed

Lines changed: 604 additions & 354 deletions

File tree

Lib/test/test_fcntl.py

Lines changed: 73 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,24 @@
11
"""Test program for the fcntl C module.
22
"""
3+
import errno
4+
import multiprocessing
35
import platform
46
import os
57
import struct
68
import sys
79
import unittest
8-
from multiprocessing import Process
9-
from test.support import verbose, cpython_only
10+
from test.support import (
11+
cpython_only, get_pagesize, is_apple, requires_subprocess, verbose, is_emscripten
12+
)
1013
from test.support.import_helper import import_module
11-
from test.support.os_helper import TESTFN, unlink
14+
from test.support.os_helper import TESTFN, unlink, make_bad_fd
1215

1316

1417
# Skip test if no fcntl module.
1518
fcntl = import_module('fcntl')
1619

1720

1821

19-
def get_lockdata():
20-
try:
21-
os.O_LARGEFILE
22-
except AttributeError:
23-
start_len = "ll"
24-
else:
25-
start_len = "qq"
26-
27-
if (sys.platform.startswith(('netbsd', 'freebsd', 'openbsd'))
28-
or sys.platform == 'darwin'):
29-
if struct.calcsize('l') == 8:
30-
off_t = 'l'
31-
pid_t = 'i'
32-
else:
33-
off_t = 'lxxxx'
34-
pid_t = 'l'
35-
lockdata = struct.pack(off_t + off_t + pid_t + 'hh', 0, 0, 0,
36-
fcntl.F_WRLCK, 0)
37-
elif sys.platform.startswith('gnukfreebsd'):
38-
lockdata = struct.pack('qqihhi', 0, 0, 0, fcntl.F_WRLCK, 0, 0)
39-
elif sys.platform in ['hp-uxB', 'unixware7']:
40-
lockdata = struct.pack('hhlllii', fcntl.F_WRLCK, 0, 0, 0, 0, 0, 0)
41-
else:
42-
lockdata = struct.pack('hh'+start_len+'hh', fcntl.F_WRLCK, 0, 0, 0, 0, 0)
43-
if lockdata:
44-
if verbose:
45-
print('struct.pack: ', repr(lockdata))
46-
return lockdata
47-
48-
lockdata = get_lockdata()
49-
5022
class BadFile:
5123
def __init__(self, fn):
5224
self.fn = fn
@@ -78,12 +50,45 @@ def tearDown(self):
7850
self.f.close()
7951
unlink(TESTFN)
8052

53+
@staticmethod
54+
def get_lockdata():
55+
try:
56+
os.O_LARGEFILE
57+
except AttributeError:
58+
start_len = "ll"
59+
else:
60+
start_len = "qq"
61+
62+
if (
63+
sys.platform.startswith(('netbsd', 'freebsd', 'openbsd'))
64+
or is_apple
65+
):
66+
if struct.calcsize('l') == 8:
67+
off_t = 'l'
68+
pid_t = 'i'
69+
else:
70+
off_t = 'lxxxx'
71+
pid_t = 'l'
72+
lockdata = struct.pack(off_t + off_t + pid_t + 'hh', 0, 0, 0,
73+
fcntl.F_WRLCK, 0)
74+
elif sys.platform.startswith('gnukfreebsd'):
75+
lockdata = struct.pack('qqihhi', 0, 0, 0, fcntl.F_WRLCK, 0, 0)
76+
elif sys.platform in ['hp-uxB', 'unixware7']:
77+
lockdata = struct.pack('hhlllii', fcntl.F_WRLCK, 0, 0, 0, 0, 0, 0)
78+
else:
79+
lockdata = struct.pack('hh'+start_len+'hh', fcntl.F_WRLCK, 0, 0, 0, 0, 0)
80+
if lockdata:
81+
if verbose:
82+
print('struct.pack: ', repr(lockdata))
83+
return lockdata
84+
8185
def test_fcntl_fileno(self):
8286
# the example from the library docs
8387
self.f = open(TESTFN, 'wb')
8488
rv = fcntl.fcntl(self.f.fileno(), fcntl.F_SETFL, os.O_NONBLOCK)
8589
if verbose:
8690
print('Status from fcntl with O_NONBLOCK: ', rv)
91+
lockdata = self.get_lockdata()
8792
rv = fcntl.fcntl(self.f.fileno(), fcntl.F_SETLKW, lockdata)
8893
if verbose:
8994
print('String from fcntl with F_SETLKW: ', repr(rv))
@@ -95,6 +100,7 @@ def test_fcntl_file_descriptor(self):
95100
rv = fcntl.fcntl(self.f, fcntl.F_SETFL, os.O_NONBLOCK)
96101
if verbose:
97102
print('Status from fcntl with O_NONBLOCK: ', rv)
103+
lockdata = self.get_lockdata()
98104
rv = fcntl.fcntl(self.f, fcntl.F_SETLKW, lockdata)
99105
if verbose:
100106
print('String from fcntl with F_SETLKW: ', repr(rv))
@@ -112,7 +118,9 @@ def test_fcntl_bad_file(self):
112118

113119
@cpython_only
114120
def test_fcntl_bad_file_overflow(self):
115-
from _testcapi import INT_MAX, INT_MIN
121+
_testcapi = import_module("_testcapi")
122+
INT_MAX = _testcapi.INT_MAX
123+
INT_MIN = _testcapi.INT_MIN
116124
# Issue 15989
117125
with self.assertRaises(OverflowError):
118126
fcntl.fcntl(INT_MAX + 1, fcntl.F_SETFL, os.O_NONBLOCK)
@@ -124,19 +132,25 @@ def test_fcntl_bad_file_overflow(self):
124132
fcntl.fcntl(BadFile(INT_MIN - 1), fcntl.F_SETFL, os.O_NONBLOCK)
125133

126134
@unittest.skipIf(
127-
platform.machine().startswith('arm') and platform.system() == 'Linux',
128-
"ARM Linux returns EINVAL for F_NOTIFY DN_MULTISHOT")
135+
(platform.machine().startswith("arm") and platform.system() == "Linux")
136+
or platform.system() == "Android",
137+
"this platform returns EINVAL for F_NOTIFY DN_MULTISHOT")
129138
def test_fcntl_64_bit(self):
130-
# Issue #1309352: fcntl shouldn't fail when the third arg fits in a
139+
# Issue GH-42434: fcntl shouldn't fail when the third arg fits in a
131140
# C 'long' but not in a C 'int'.
132141
try:
133142
cmd = fcntl.F_NOTIFY
134-
# This flag is larger than 2**31 in 64-bit builds
143+
# DN_MULTISHOT is >= 2**31 in 64-bit builds
135144
flags = fcntl.DN_MULTISHOT
136145
except AttributeError:
137146
self.skipTest("F_NOTIFY or DN_MULTISHOT unavailable")
138147
fd = os.open(os.path.dirname(os.path.abspath(TESTFN)), os.O_RDONLY)
139148
try:
149+
try:
150+
fcntl.fcntl(fd, cmd, fcntl.DN_DELETE)
151+
except OSError as exc:
152+
if exc.errno == errno.EINVAL:
153+
self.skipTest("F_NOTIFY not available by this environment")
140154
fcntl.fcntl(fd, cmd, flags)
141155
finally:
142156
os.close(fd)
@@ -155,35 +169,35 @@ def test_flock(self):
155169
self.assertRaises(ValueError, fcntl.flock, -1, fcntl.LOCK_SH)
156170
self.assertRaises(TypeError, fcntl.flock, 'spam', fcntl.LOCK_SH)
157171

158-
# TODO RustPython
159-
@unittest.skipUnless(sys.platform == 'linux', 'test requires Linux')
160172
@unittest.skipIf(platform.system() == "AIX", "AIX returns PermissionError")
173+
@requires_subprocess()
161174
def test_lockf_exclusive(self):
162175
self.f = open(TESTFN, 'wb+')
163176
cmd = fcntl.LOCK_EX | fcntl.LOCK_NB
164177
fcntl.lockf(self.f, cmd)
165-
p = Process(target=try_lockf_on_other_process_fail, args=(TESTFN, cmd))
178+
mp = multiprocessing.get_context('spawn')
179+
p = mp.Process(target=try_lockf_on_other_process_fail, args=(TESTFN, cmd))
166180
p.start()
167181
p.join()
168182
fcntl.lockf(self.f, fcntl.LOCK_UN)
169183
self.assertEqual(p.exitcode, 0)
170184

171-
# TODO RustPython
172-
@unittest.skipUnless(sys.platform == 'linux', 'test requires Linux')
173185
@unittest.skipIf(platform.system() == "AIX", "AIX returns PermissionError")
186+
@requires_subprocess()
174187
def test_lockf_share(self):
175188
self.f = open(TESTFN, 'wb+')
176189
cmd = fcntl.LOCK_SH | fcntl.LOCK_NB
177190
fcntl.lockf(self.f, cmd)
178-
p = Process(target=try_lockf_on_other_process, args=(TESTFN, cmd))
191+
mp = multiprocessing.get_context('spawn')
192+
p = mp.Process(target=try_lockf_on_other_process, args=(TESTFN, cmd))
179193
p.start()
180194
p.join()
181195
fcntl.lockf(self.f, fcntl.LOCK_UN)
182196
self.assertEqual(p.exitcode, 0)
183197

184198
@cpython_only
185199
def test_flock_overflow(self):
186-
import _testcapi
200+
_testcapi = import_module("_testcapi")
187201
self.assertRaises(OverflowError, fcntl.flock, _testcapi.INT_MAX+1,
188202
fcntl.LOCK_SH)
189203

@@ -197,14 +211,16 @@ def test_fcntl_f_getpath(self):
197211
@unittest.skipUnless(
198212
hasattr(fcntl, "F_SETPIPE_SZ") and hasattr(fcntl, "F_GETPIPE_SZ"),
199213
"F_SETPIPE_SZ and F_GETPIPE_SZ are not available on all platforms.")
214+
@unittest.skipIf(is_emscripten, "Emscripten pipefs doesn't support these")
200215
def test_fcntl_f_pipesize(self):
201216
test_pipe_r, test_pipe_w = os.pipe()
202217
try:
203218
# Get the default pipesize with F_GETPIPE_SZ
204219
pipesize_default = fcntl.fcntl(test_pipe_w, fcntl.F_GETPIPE_SZ)
205220
pipesize = pipesize_default // 2 # A new value to detect change.
206-
if pipesize < 512: # the POSIX minimum
207-
raise unittest.SkitTest(
221+
pagesize_default = get_pagesize()
222+
if pipesize < pagesize_default: # the POSIX minimum
223+
raise unittest.SkipTest(
208224
'default pipesize too small to perform test.')
209225
fcntl.fcntl(test_pipe_w, fcntl.F_SETPIPE_SZ, pipesize)
210226
self.assertEqual(fcntl.fcntl(test_pipe_w, fcntl.F_GETPIPE_SZ),
@@ -213,6 +229,15 @@ def test_fcntl_f_pipesize(self):
213229
os.close(test_pipe_r)
214230
os.close(test_pipe_w)
215231

232+
@unittest.skipUnless(hasattr(fcntl, 'F_DUPFD'), 'need fcntl.F_DUPFD')
233+
def test_bad_fd(self):
234+
# gh-134744: Test error handling
235+
fd = make_bad_fd()
236+
with self.assertRaises(OSError):
237+
fcntl.fcntl(fd, fcntl.F_DUPFD, 0)
238+
with self.assertRaises(OSError):
239+
fcntl.fcntl(fd, fcntl.F_DUPFD, b'\0' * 1024)
240+
216241

217242
if __name__ == '__main__':
218243
unittest.main()

0 commit comments

Comments
 (0)