Skip to content

Commit eaf6c8c

Browse files
Add test.support.os_helper @ 3.13.5
1 parent f402dee commit eaf6c8c

File tree

2 files changed

+202
-169
lines changed

2 files changed

+202
-169
lines changed

Lib/test/support/os_helper.py

Lines changed: 58 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import collections.abc
22
import contextlib
33
import errno
4+
import logging
45
import os
56
import re
67
import stat
@@ -10,7 +11,6 @@
1011
import unittest
1112
import warnings
1213

13-
# From CPython 3.13.5
1414
from test import support
1515

1616

@@ -23,8 +23,8 @@
2323

2424
# TESTFN_UNICODE is a non-ascii filename
2525
TESTFN_UNICODE = TESTFN_ASCII + "-\xe0\xf2\u0258\u0141\u011f"
26-
if sys.platform == 'darwin':
27-
# In Mac OS X's VFS API file names are, by definition, canonically
26+
if support.is_apple:
27+
# On Apple's VFS API file names are, by definition, canonically
2828
# decomposed Unicode, encoded using UTF-8. See QA1173:
2929
# http://developer.apple.com/mac/library/qa/qa2001/qa1173.html
3030
import unicodedata
@@ -49,8 +49,8 @@
4949
'encoding (%s). Unicode filename tests may not be effective'
5050
% (TESTFN_UNENCODABLE, sys.getfilesystemencoding()))
5151
TESTFN_UNENCODABLE = None
52-
# macOS and Emscripten deny unencodable filenames (invalid utf-8)
53-
elif sys.platform not in {'darwin', 'emscripten', 'wasi'}:
52+
# Apple and Emscripten deny unencodable filenames (invalid utf-8)
53+
elif not support.is_apple and sys.platform not in {"emscripten", "wasi"}:
5454
try:
5555
# ascii and utf-8 cannot encode the byte 0xff
5656
b'\xff'.decode(sys.getfilesystemencoding())
@@ -199,10 +199,8 @@ def skip_unless_symlink(test):
199199
return test if ok else unittest.skip(msg)(test)
200200

201201

202-
# From CPython 3.13.5
203202
_can_hardlink = None
204203

205-
# From CPython 3.13.5
206204
def can_hardlink():
207205
global _can_hardlink
208206
if _can_hardlink is None:
@@ -212,7 +210,6 @@ def can_hardlink():
212210
return _can_hardlink
213211

214212

215-
# From CPython 3.13.5
216213
def skip_unless_hardlink(test):
217214
ok = can_hardlink()
218215
msg = "requires hardlink support"
@@ -268,15 +265,15 @@ def can_chmod():
268265
global _can_chmod
269266
if _can_chmod is not None:
270267
return _can_chmod
271-
if not hasattr(os, "chown"):
268+
if not hasattr(os, "chmod"):
272269
_can_chmod = False
273270
return _can_chmod
274271
try:
275272
with open(TESTFN, "wb") as f:
276273
try:
277-
os.chmod(TESTFN, 0o777)
274+
os.chmod(TESTFN, 0o555)
278275
mode1 = os.stat(TESTFN).st_mode
279-
os.chmod(TESTFN, 0o666)
276+
os.chmod(TESTFN, 0o777)
280277
mode2 = os.stat(TESTFN).st_mode
281278
except OSError as e:
282279
can = False
@@ -323,6 +320,10 @@ def can_dac_override():
323320
else:
324321
_can_dac_override = True
325322
finally:
323+
try:
324+
os.chmod(TESTFN, 0o700)
325+
except OSError:
326+
pass
326327
unlink(TESTFN)
327328

328329
return _can_dac_override
@@ -378,8 +379,12 @@ def _waitfor(func, pathname, waitall=False):
378379
# Increase the timeout and try again
379380
time.sleep(timeout)
380381
timeout *= 2
381-
warnings.warn('tests may fail, delete still pending for ' + pathname,
382-
RuntimeWarning, stacklevel=4)
382+
logging.getLogger(__name__).warning(
383+
'tests may fail, delete still pending for %s',
384+
pathname,
385+
stack_info=True,
386+
stacklevel=4,
387+
)
383388

384389
def _unlink(filename):
385390
_waitfor(os.unlink, filename)
@@ -494,9 +499,14 @@ def temp_dir(path=None, quiet=False):
494499
except OSError as exc:
495500
if not quiet:
496501
raise
497-
warnings.warn(f'tests may fail, unable to create '
498-
f'temporary directory {path!r}: {exc}',
499-
RuntimeWarning, stacklevel=3)
502+
logging.getLogger(__name__).warning(
503+
"tests may fail, unable to create temporary directory %r: %s",
504+
path,
505+
exc,
506+
exc_info=exc,
507+
stack_info=True,
508+
stacklevel=3,
509+
)
500510
if dir_created:
501511
pid = os.getpid()
502512
try:
@@ -527,9 +537,15 @@ def change_cwd(path, quiet=False):
527537
except OSError as exc:
528538
if not quiet:
529539
raise
530-
warnings.warn(f'tests may fail, unable to change the current working '
531-
f'directory to {path!r}: {exc}',
532-
RuntimeWarning, stacklevel=3)
540+
logging.getLogger(__name__).warning(
541+
'tests may fail, unable to change the current working directory '
542+
'to %r: %s',
543+
path,
544+
exc,
545+
exc_info=exc,
546+
stack_info=True,
547+
stacklevel=3,
548+
)
533549
try:
534550
yield os.getcwd()
535551
finally:
@@ -612,11 +628,18 @@ def __fspath__(self):
612628
def fd_count():
613629
"""Count the number of open file descriptors.
614630
"""
615-
if sys.platform.startswith(('linux', 'freebsd', 'emscripten')):
631+
if sys.platform.startswith(('linux', 'android', 'freebsd', 'emscripten')):
632+
fd_path = "/proc/self/fd"
633+
elif support.is_apple:
634+
fd_path = "/dev/fd"
635+
else:
636+
fd_path = None
637+
638+
if fd_path is not None:
616639
try:
617-
names = os.listdir("/proc/self/fd")
640+
names = os.listdir(fd_path)
618641
# Subtract one because listdir() internally opens a file
619-
# descriptor to list the content of the /proc/self/fd/ directory.
642+
# descriptor to list the content of the directory.
620643
return len(names) - 1
621644
except FileNotFoundError:
622645
pass
@@ -686,9 +709,10 @@ def temp_umask(umask):
686709

687710

688711
class EnvironmentVarGuard(collections.abc.MutableMapping):
712+
"""Class to help protect the environment variable properly.
689713
690-
"""Class to help protect the environment variable properly. Can be used as
691-
a context manager."""
714+
Can be used as a context manager.
715+
"""
692716

693717
def __init__(self):
694718
self._environ = os.environ
@@ -722,7 +746,6 @@ def __len__(self):
722746
def set(self, envvar, value):
723747
self[envvar] = value
724748

725-
# From CPython 3.13.5
726749
def unset(self, envvar, /, *envvars):
727750
"""Unset one or more environment variables."""
728751
for ev in (envvar, *envvars):
@@ -746,13 +769,16 @@ def __exit__(self, *ignore_exc):
746769

747770

748771
try:
749-
import ctypes
750-
kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
751-
752-
ERROR_FILE_NOT_FOUND = 2
753-
DDD_REMOVE_DEFINITION = 2
754-
DDD_EXACT_MATCH_ON_REMOVE = 4
755-
DDD_NO_BROADCAST_SYSTEM = 8
772+
if support.MS_WINDOWS:
773+
import ctypes
774+
kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
775+
776+
ERROR_FILE_NOT_FOUND = 2
777+
DDD_REMOVE_DEFINITION = 2
778+
DDD_EXACT_MATCH_ON_REMOVE = 4
779+
DDD_NO_BROADCAST_SYSTEM = 8
780+
else:
781+
raise AttributeError
756782
except (ImportError, AttributeError):
757783
def subst_drive(path):
758784
raise unittest.SkipTest('ctypes or kernel32 is not available')

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy