@@ -4112,13 +4112,32 @@ def can_use_pidfd():
41124112 return True
41134113
41144114
4115+ def can_use_kevent ():
4116+ if not subprocess ._CAN_USE_KQUEUE :
4117+ return False
4118+ kq = select .kqueue ()
4119+ try :
4120+ kev = select .kevent (
4121+ os .getpid (),
4122+ filter = select .KQ_FILTER_PROC ,
4123+ flags = select .KQ_EV_ADD | select .KQ_EV_ONESHOT ,
4124+ fflags = select .KQ_NOTE_EXIT ,
4125+ )
4126+ events = kq .control ([kev ], 1 , 0 )
4127+ return True
4128+ except OSError :
4129+ return False
4130+ finally :
4131+ kq .close ()
4132+
4133+
41154134
41164135class FastWaitTestCase (BaseTestCase ):
41174136 """Tests for efficient (pidfd_open() + poll() / kqueue()) process
41184137 waiting in subprocess.Popen.wait().
41194138 """
41204139 CAN_USE_PIDFD_OPEN = can_use_pidfd ()
4121- CAN_USE_KQUEUE = subprocess . _CAN_USE_KQUEUE
4140+ CAN_USE_KQUEUE = can_use_kevent ()
41224141
41234142 def assert_fast_waitpid_error (self , patch_point ):
41244143 # Emulate a case where pidfd_open() (Linux) or kqueue()
@@ -4132,15 +4151,15 @@ def assert_fast_waitpid_error(self, patch_point):
41324151 self .assertEqual (p .wait (timeout = support .SHORT_TIMEOUT ), 0 )
41334152 assert m .called
41344153
4135- @unittest .skipIf (not CAN_USE_PIDFD_OPEN , reason = "pidfd_open not supported " )
4154+ @unittest .skipIf (not CAN_USE_PIDFD_OPEN , reason = "needs pidfd_open() " )
41364155 def test_wait_pidfd_open_error (self ):
41374156 self .assert_fast_waitpid_error ("os.pidfd_open" )
41384157
4139- @unittest .skipIf (not CAN_USE_KQUEUE , reason = "macOS / BSD only " )
4158+ @unittest .skipIf (not CAN_USE_KQUEUE , reason = "needs kqueue() for proc " )
41404159 def test_wait_kqueue_error (self ):
41414160 self .assert_fast_waitpid_error ("select.kqueue" )
41424161
4143- @unittest .skipIf (not CAN_USE_KQUEUE , reason = "macOS / BSD only " )
4162+ @unittest .skipIf (not CAN_USE_KQUEUE , reason = "needs kqueue() for proc " )
41444163 def test_kqueue_control_error (self ):
41454164 # Emulate a case where kqueue.control() fails. Busy-poll wait
41464165 # should be used as fallback.
@@ -4179,11 +4198,11 @@ def wrapper(*args, **kwargs):
41794198 assert m .called
41804199 self .assertEqual (status , 0 )
41814200
4182- @unittest .skipIf (not CAN_USE_PIDFD_OPEN , reason = "pidfd_open not supported " )
4201+ @unittest .skipIf (not CAN_USE_PIDFD_OPEN , reason = "needs pidfd_open() " )
41834202 def test_pidfd_open_race (self ):
41844203 self .assert_wait_race_condition ("os.pidfd_open" , os .pidfd_open )
41854204
4186- @unittest .skipIf (not CAN_USE_KQUEUE , reason = "macOS / BSD only " )
4205+ @unittest .skipIf (not CAN_USE_KQUEUE , reason = "needs kqueue() for proc " )
41874206 def test_kqueue_race (self ):
41884207 self .assert_wait_race_condition ("select.kqueue" , select .kqueue )
41894208
@@ -4209,11 +4228,11 @@ def waitpid_wrapper(pid, flags):
42094228 assert m1 .called
42104229 assert m2 .called
42114230
4212- @unittest .skipIf (not CAN_USE_PIDFD_OPEN , reason = "pidfd_open not supported " )
4231+ @unittest .skipIf (not CAN_USE_PIDFD_OPEN , reason = "needs pidfd_open() " )
42134232 def test_pidfd_open_notification_without_immediate_reap (self ):
42144233 self .assert_notification_without_immediate_reap ("_wait_pidfd" )
42154234
4216- @unittest .skipIf (not CAN_USE_KQUEUE , reason = "macOS / BSD only " )
4235+ @unittest .skipIf (not CAN_USE_KQUEUE , reason = "needs kqueue() for proc " )
42174236 def test_kqueue_notification_without_immediate_reap (self ):
42184237 self .assert_notification_without_immediate_reap ("_wait_kqueue" )
42194238
0 commit comments