Replace py3_path and cpu_count implementations with builtins (#5227)

Replace py3_path by standard os.fsdecode and use native os.cpu_count.

These functions had been written before builtins achieving the same have
been made available (in Python 3.2 and 3.4). 

Now that they are available though, this PR updates the codebase to use
builtin implementations rather than the custom ones.
This commit is contained in:
Šarūnas Nejus 2024-06-16 11:50:27 +01:00 committed by GitHub
commit 0e87389994
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 79 additions and 129 deletions

View file

@ -51,7 +51,7 @@ from typing import (
from unidecode import unidecode
import beets
from beets.util import functemplate, py3_path
from beets.util import functemplate
from ..util.functemplate import Template
from . import types
@ -1059,9 +1059,9 @@ class Database:
"""
# Make a new connection. The `sqlite3` module can't use
# bytestring paths here on Python 3, so we need to
# provide a `str` using `py3_path`.
# provide a `str` using `os.fsdecode`.
conn = sqlite3.connect(
py3_path(self.path),
os.fsdecode(self.path),
timeout=self.timeout,
# We have our own same-thread checks in _connection(), but need to
# call conn.close() in _close()

View file

@ -1136,7 +1136,7 @@ class ArchiveImportTask(SentinelImportTask):
return False
for path_test, _ in cls.handlers():
if path_test(util.py3_path(path)):
if path_test(os.fsdecode(path)):
return True
return False
@ -1186,11 +1186,11 @@ class ArchiveImportTask(SentinelImportTask):
`toppath` to that directory.
"""
for path_test, handler_class in self.handlers():
if path_test(util.py3_path(self.toppath)):
if path_test(os.fsdecode(self.toppath)):
break
extract_to = mkdtemp()
archive = handler_class(util.py3_path(self.toppath), mode="r")
archive = handler_class(os.fsdecode(self.toppath), mode="r")
try:
archive.extractall(extract_to)

View file

@ -209,19 +209,19 @@ class TestCase(unittest.TestCase, Assertions):
# temporary directory.
self.temp_dir = util.bytestring_path(tempfile.mkdtemp())
beets.config["statefile"] = util.py3_path(
beets.config["statefile"] = os.fsdecode(
os.path.join(self.temp_dir, b"state.pickle")
)
beets.config["library"] = util.py3_path(
beets.config["library"] = os.fsdecode(
os.path.join(self.temp_dir, b"library.db")
)
beets.config["directory"] = util.py3_path(
beets.config["directory"] = os.fsdecode(
os.path.join(self.temp_dir, b"libdir")
)
# Set $HOME, which is used by Confuse to create directories.
self._old_home = os.environ.get("HOME")
os.environ["HOME"] = util.py3_path(self.temp_dir)
os.environ["HOME"] = os.fsdecode(self.temp_dir)
# Initialize, but don't install, a DummyIO.
self.io = DummyIO()

View file

@ -166,7 +166,7 @@ class TestHelper:
Make sure you call ``teardown_beets()`` afterwards.
"""
self.create_temp_dir()
os.environ["BEETSDIR"] = util.py3_path(self.temp_dir)
os.environ["BEETSDIR"] = os.fsdecode(self.temp_dir)
self.config = beets.config
self.config.clear()
@ -179,7 +179,7 @@ class TestHelper:
self.libdir = os.path.join(self.temp_dir, b"libdir")
os.mkdir(syspath(self.libdir))
self.config["directory"] = util.py3_path(self.libdir)
self.config["directory"] = os.fsdecode(self.libdir)
if disk:
dbpath = util.bytestring_path(self.config["library"].as_filename())

View file

@ -1633,7 +1633,7 @@ def _load_plugins(options, config):
log.debug("plugin paths: {0}", util.displayable_path(paths))
# On Python 3, the search paths need to be unicode.
paths = [util.py3_path(p) for p in paths]
paths = [os.fsdecode(p) for p in paths]
# Extend the `beetsplug` package to include the plugin paths.
import beetsplug

View file

@ -803,21 +803,6 @@ def legalize_path(
return second_stage_path, retruncated
def py3_path(path: Union[bytes, str]) -> str:
"""Convert a bytestring path to Unicode.
This helps deal with APIs on Python 3 that *only* accept Unicode
(i.e., `str` objects). I philosophically disagree with this
decision, because paths are sadly bytes on Unix, but that's the way
it is. So this function helps us "smuggle" the true bytes data
through APIs that took Python 3's Unicode mandate too seriously.
"""
if isinstance(path, str):
return path
assert isinstance(path, bytes)
return os.fsdecode(path)
def str2bool(value: str) -> bool:
"""Returns a boolean reflecting a human-entered string."""
return value.lower() in ("yes", "1", "true", "t", "y")
@ -848,41 +833,6 @@ def plurality(objs: Sequence[T]) -> T:
return c.most_common(1)[0]
def cpu_count() -> int:
"""Return the number of hardware thread contexts (cores or SMT
threads) in the system.
"""
# Adapted from the soundconverter project:
# https://github.com/kassoulet/soundconverter
if sys.platform == "win32":
try:
num = int(os.environ["NUMBER_OF_PROCESSORS"])
except (ValueError, KeyError):
num = 0
elif sys.platform == "darwin":
try:
num = int(
command_output(
[
"/usr/sbin/sysctl",
"-n",
"hw.ncpu",
]
).stdout
)
except (ValueError, OSError, subprocess.CalledProcessError):
num = 0
else:
try:
num = os.sysconf("SC_NPROCESSORS_ONLN")
except (ValueError, OSError, AttributeError):
num = 0
if num >= 1:
return num
else:
return 1
def convert_command_args(args: List[bytes]) -> List[str]:
"""Convert command arguments, which may either be `bytes` or `str`
objects, to uniformly surrogate-escaped strings."""

View file

@ -26,7 +26,7 @@ from tempfile import NamedTemporaryFile
from urllib.parse import urlencode
from beets import logging, util
from beets.util import bytestring_path, displayable_path, py3_path, syspath
from beets.util import bytestring_path, displayable_path, syspath
PROXY_URL = "https://images.weserv.nl/"
@ -53,7 +53,7 @@ def temp_file_for(path):
specified path.
"""
ext = os.path.splitext(path)[1]
with NamedTemporaryFile(suffix=py3_path(ext), delete=False) as f:
with NamedTemporaryFile(suffix=os.fsdecode(ext), delete=False) as f:
return bytestring_path(f.name)
@ -386,7 +386,7 @@ class PILBackend(LocalBackend):
# progressive=False only affects JPEGs and is the default,
# but we include it here for explicitness.
im.save(py3_path(path_out), quality=quality, progressive=False)
im.save(os.fsdecode(path_out), quality=quality, progressive=False)
if max_filesize > 0:
# If maximum filesize is set, we attempt to lower the quality
@ -410,7 +410,7 @@ class PILBackend(LocalBackend):
lower_qual = 10
# Use optimize flag to improve filesize decrease
im.save(
py3_path(path_out),
os.fsdecode(path_out),
quality=lower_qual,
optimize=True,
progressive=False,
@ -447,7 +447,7 @@ class PILBackend(LocalBackend):
try:
im = Image.open(syspath(path_in))
im.save(py3_path(path_out), progressive=False)
im.save(os.fsdecode(path_out), progressive=False)
return path_out
except OSError:
# FIXME: Should probably issue a warning?
@ -473,7 +473,7 @@ class PILBackend(LocalBackend):
try:
with Image.open(syspath(source)) as im:
im.save(py3_path(target), progressive=not deinterlaced)
im.save(os.fsdecode(target), progressive=not deinterlaced)
return target
except (
ValueError,
@ -506,7 +506,7 @@ class PILBackend(LocalBackend):
meta = PngImagePlugin.PngInfo()
for k, v in metadata.items():
meta.add_text(k, v, 0)
im.save(py3_path(file), "PNG", pnginfo=meta)
im.save(os.fsdecode(file), "PNG", pnginfo=meta)
class Shareable(type):

View file

@ -15,11 +15,10 @@
"""An AURA server using Flask."""
import os.path
import os
import re
from dataclasses import dataclass
from mimetypes import guess_type
from os.path import getsize, isfile
from typing import ClassVar, Mapping, Type
from flask import (
@ -46,7 +45,6 @@ from beets.dbcore.query import (
from beets.library import Album, Item, LibModel, Library
from beets.plugins import BeetsPlugin
from beets.ui import Subcommand, _open_library
from beets.util import py3_path
# Constants
@ -482,7 +480,7 @@ class AlbumDocument(AURADocument):
}
# Add images relationship if album has associated images
if album.artpath:
path = py3_path(album.artpath)
path = os.fsdecode(album.artpath)
filename = path.split("/")[-1]
image_id = f"album-{album.id}-{filename}"
relationships["images"] = {
@ -660,7 +658,7 @@ class ImageDocument(AURADocument):
# Cut the filename off of artpath
# This is in preparation for supporting images in the same
# directory that are not tracked by beets.
artpath = py3_path(album.artpath)
artpath = os.fsdecode(album.artpath)
dir_path = "/".join(artpath.split("/")[:-1])
else:
# Images for other resource types are not supported
@ -668,7 +666,7 @@ class ImageDocument(AURADocument):
img_path = os.path.join(dir_path, img_filename)
# Check the image actually exists
if isfile(img_path):
if os.path.isfile(img_path):
return img_path
else:
return None
@ -690,7 +688,7 @@ class ImageDocument(AURADocument):
attributes = {
"role": "cover",
"mimetype": guess_type(image_path)[0],
"size": getsize(image_path),
"size": os.path.getsize(image_path),
}
try:
from PIL import Image
@ -781,8 +779,8 @@ def audio_file(track_id):
),
)
path = py3_path(track.path)
if not isfile(path):
path = os.fsdecode(track.path)
if not os.path.isfile(path):
return AURADocument.error(
"404 Not Found",
"No audio file for the requested track.",

View file

@ -114,7 +114,7 @@ class ConvertPlugin(BeetsPlugin):
"pretend": False,
"link": False,
"hardlink": False,
"threads": util.cpu_count(),
"threads": os.cpu_count(),
"format": "mp3",
"id3v23": "inherit",
"formats": {
@ -636,8 +636,8 @@ class ConvertPlugin(BeetsPlugin):
# Create a temporary file for the conversion.
tmpdir = self.config["tmpdir"].get()
if tmpdir:
tmpdir = util.py3_path(util.bytestring_path(tmpdir))
fd, dest = tempfile.mkstemp(util.py3_path(b"." + ext), dir=tmpdir)
tmpdir = os.fsdecode(util.bytestring_path(tmpdir))
fd, dest = tempfile.mkstemp(os.fsdecode(b"." + ext), dir=tmpdir)
os.close(fd)
dest = util.bytestring_path(dest)
_temp_files.append(dest) # Delete the transcode later.

View file

@ -26,7 +26,7 @@ import requests
from mediafile import image_mime_type
from beets import config, importer, plugins, ui, util
from beets.util import bytestring_path, py3_path, sorted_walk, syspath
from beets.util import bytestring_path, sorted_walk, syspath
from beets.util.artresizer import ArtResizer
try:
@ -381,7 +381,7 @@ class RemoteArtSource(ArtSource):
ext,
)
suffix = py3_path(ext)
suffix = os.fsdecode(ext)
with NamedTemporaryFile(suffix=suffix, delete=False) as fh:
# write the first already loaded part of the image
fh.write(header)

View file

@ -49,13 +49,7 @@ from beets import ui
from beets.importer import ImportSession, ImportTask
from beets.library import Album, Item, Library
from beets.plugins import BeetsPlugin
from beets.util import (
command_output,
cpu_count,
displayable_path,
py3_path,
syspath,
)
from beets.util import command_output, displayable_path, syspath
# Utilities.
@ -942,7 +936,7 @@ class GStreamerBackend(Backend):
self._file = self._files.pop(0)
self._pipe.set_state(self.Gst.State.NULL)
self._src.set_property("location", py3_path(syspath(self._file)))
self._src.set_property("location", os.fsdecode(syspath(self._file)))
self._pipe.set_state(self.Gst.State.PLAYING)
return True
@ -972,7 +966,7 @@ class GStreamerBackend(Backend):
# Set a new file on the filesrc element, can only be done in the
# READY state
self._src.set_state(self.Gst.State.READY)
self._src.set_property("location", py3_path(syspath(self._file)))
self._src.set_property("location", os.fsdecode(syspath(self._file)))
self._decbin.link(self._conv)
self._pipe.set_state(self.Gst.State.READY)
@ -1050,7 +1044,9 @@ class AudioToolsBackend(Backend):
file format is not supported
"""
try:
audiofile = self._mod_audiotools.open(py3_path(syspath(item.path)))
audiofile = self._mod_audiotools.open(
os.fsdecode(syspath(item.path))
)
except OSError:
raise ReplayGainError(f"File {item.path} was not found")
except self._mod_audiotools.UnsupportedFile:
@ -1226,7 +1222,7 @@ class ReplayGainPlugin(BeetsPlugin):
"overwrite": False,
"auto": True,
"backend": "command",
"threads": cpu_count(),
"threads": os.cpu_count(),
"parallel_on_import": False,
"per_disc": False,
"peak": "true",

View file

@ -222,7 +222,7 @@ class PathlibURI(URIGetter):
name = "Python Pathlib"
def uri(self, path):
return PurePosixPath(util.py3_path(path)).as_uri()
return PurePosixPath(os.fsdecode(path)).as_uri()
def copy_c_string(c_string):

View file

@ -312,7 +312,7 @@ def item_file(item_id):
if os.name == "nt":
item_path = util.syspath(item.path)
else:
item_path = util.py3_path(item.path)
item_path = os.fsdecode(item.path)
base_filename = os.path.basename(item_path)
# FIXME: Arguably, this should just use `displayable_path`: The latter

View file

@ -33,7 +33,7 @@ import confuse
import yaml
from beets.test.helper import TestHelper
from beets.util import bluelet, py3_path
from beets.util import bluelet
from beetsplug import bpd
gstplayer = importlib.util.module_from_spec(
@ -313,7 +313,7 @@ class BPDTestHelper(unittest.TestCase, TestHelper):
"""
# Create a config file:
config = {
"pluginpath": [py3_path(self.temp_dir)],
"pluginpath": [os.fsdecode(self.temp_dir)],
"plugins": "bpd",
# use port 0 to let the OS choose a free port
"bpd": {"host": host, "port": 0, "control_port": 0},
@ -321,7 +321,10 @@ class BPDTestHelper(unittest.TestCase, TestHelper):
if password:
config["bpd"]["password"] = password
config_file = tempfile.NamedTemporaryFile(
mode="wb", dir=py3_path(self.temp_dir), suffix=".yaml", delete=False
mode="wb",
dir=os.fsdecode(self.temp_dir),
suffix=".yaml",
delete=False,
)
config_file.write(
yaml.dump(config, Dumper=confuse.Dumper, encoding="utf-8")
@ -337,9 +340,9 @@ class BPDTestHelper(unittest.TestCase, TestHelper):
"--library",
self.config["library"].as_filename(),
"--directory",
py3_path(self.libdir),
os.fsdecode(self.libdir),
"--config",
py3_path(config_file.name),
os.fsdecode(config_file.name),
"bpd",
],
assigned_port,
@ -399,7 +402,11 @@ class BPDTestHelper(unittest.TestCase, TestHelper):
"""Add the given item to the BPD playlist or queue."""
paths = [
"/".join(
[item.artist, item.album, py3_path(os.path.basename(item.path))]
[
item.artist,
item.album,
os.fsdecode(os.path.basename(item.path)),
]
)
for item in items
]

View file

@ -14,7 +14,7 @@
import unittest
from os import path, remove
from os import fsdecode, path, remove
from shutil import rmtree
from tempfile import mkdtemp
from unittest.mock import MagicMock, Mock, PropertyMock
@ -26,7 +26,7 @@ from beets.library import Album, Item, parse_query_string
from beets.test import _common
from beets.test.helper import TestHelper
from beets.ui import UserError
from beets.util import CHAR_REPLACE, bytestring_path, py3_path, syspath
from beets.util import CHAR_REPLACE, bytestring_path, syspath
from beetsplug.smartplaylist import SmartPlaylistPlugin
@ -173,7 +173,7 @@ class SmartPlaylistTest(_common.TestCase):
dir = bytestring_path(mkdtemp())
config["smartplaylist"]["relative_to"] = False
config["smartplaylist"]["playlist_dir"] = py3_path(dir)
config["smartplaylist"]["playlist_dir"] = fsdecode(dir)
try:
spl.update_playlists(lib)
except Exception:
@ -218,7 +218,7 @@ class SmartPlaylistTest(_common.TestCase):
config["smartplaylist"]["output"] = "extm3u"
config["smartplaylist"]["prefix"] = "http://beets:8337/files"
config["smartplaylist"]["relative_to"] = False
config["smartplaylist"]["playlist_dir"] = py3_path(dir)
config["smartplaylist"]["playlist_dir"] = fsdecode(dir)
try:
spl.update_playlists(lib)
except Exception:
@ -269,7 +269,7 @@ class SmartPlaylistTest(_common.TestCase):
dir = bytestring_path(mkdtemp())
config["smartplaylist"]["output"] = "extm3u"
config["smartplaylist"]["relative_to"] = False
config["smartplaylist"]["playlist_dir"] = py3_path(dir)
config["smartplaylist"]["playlist_dir"] = fsdecode(dir)
config["smartplaylist"]["fields"] = ["id", "genre"]
try:
spl.update_playlists(lib)
@ -316,7 +316,7 @@ class SmartPlaylistTest(_common.TestCase):
dir = bytestring_path(mkdtemp())
tpl = "http://beets:8337/item/$id/file"
config["smartplaylist"]["uri_format"] = tpl
config["smartplaylist"]["playlist_dir"] = py3_path(dir)
config["smartplaylist"]["playlist_dir"] = fsdecode(dir)
# The following options should be ignored when uri_format is set
config["smartplaylist"]["relative_to"] = "/data"
config["smartplaylist"]["prefix"] = "/prefix"
@ -350,7 +350,7 @@ class SmartPlaylistCLITest(_common.TestCase, TestHelper):
{"name": "all.m3u", "query": ""},
]
)
config["smartplaylist"]["playlist_dir"].set(py3_path(self.temp_dir))
config["smartplaylist"]["playlist_dir"].set(fsdecode(self.temp_dir))
self.load_plugins("smartplaylist")
def tearDown(self):

View file

@ -41,7 +41,7 @@ from beets.test.helper import (
capture_log,
has_program,
)
from beets.util import bytestring_path, displayable_path, py3_path, syspath
from beets.util import bytestring_path, displayable_path, syspath
class ScrubbedImportTest(_common.TestCase, ImportHelper):
@ -261,10 +261,10 @@ class NonAutotaggedImportTest(_common.TestCase, ImportHelper):
def create_archive(session):
(handle, path) = mkstemp(dir=py3_path(session.temp_dir))
(handle, path) = mkstemp(dir=os.fsdecode(session.temp_dir))
path = bytestring_path(path)
os.close(handle)
archive = ZipFile(py3_path(path), mode="w")
archive = ZipFile(os.fsdecode(path), mode="w")
archive.write(syspath(os.path.join(_common.RSRC, b"full.mp3")), "full.mp3")
archive.close()
path = bytestring_path(path)
@ -319,7 +319,7 @@ class ImportTarTest(ImportZipTest):
(handle, path) = mkstemp(dir=syspath(self.temp_dir))
path = bytestring_path(path)
os.close(handle)
archive = TarFile(py3_path(path), mode="w")
archive = TarFile(os.fsdecode(path), mode="w")
archive.add(
syspath(os.path.join(_common.RSRC, b"full.mp3")), "full.mp3"
)

View file

@ -22,7 +22,6 @@ from datetime import datetime
from beets.library import Item
from beets.test import _common
from beets.test.helper import TestHelper
from beets.util import py3_path
def _parsetime(s):
@ -46,11 +45,11 @@ class MetaSyncTest(_common.TestCase, TestHelper):
self.config["metasync"]["source"] = "itunes"
if _is_windows():
self.config["metasync"]["itunes"]["library"] = py3_path(
self.config["metasync"]["itunes"]["library"] = os.fsdecode(
self.itunes_library_windows
)
else:
self.config["metasync"]["itunes"]["library"] = py3_path(
self.config["metasync"]["itunes"]["library"] = os.fsdecode(
self.itunes_library_unix
)

View file

@ -852,11 +852,11 @@ class ConfigTest(unittest.TestCase, TestHelper, _common.Assertions):
# directory there. Some tests will set `BEETSDIR` themselves.
del os.environ["BEETSDIR"]
self._old_home = os.environ.get("HOME")
os.environ["HOME"] = util.py3_path(self.temp_dir)
os.environ["HOME"] = os.fsdecode(self.temp_dir)
# Also set APPDATA, the Windows equivalent of setting $HOME.
self._old_appdata = os.environ.get("APPDATA")
os.environ["APPDATA"] = util.py3_path(
os.environ["APPDATA"] = os.fsdecode(
os.path.join(self.temp_dir, b"AppData", b"Roaming")
)
@ -992,7 +992,7 @@ class ConfigTest(unittest.TestCase, TestHelper, _common.Assertions):
self.assertEqual(config["anoption"].get(), "cli overwrite")
def test_cli_config_file_overwrites_beetsdir_defaults(self):
os.environ["BEETSDIR"] = util.py3_path(self.beetsdir)
os.environ["BEETSDIR"] = os.fsdecode(self.beetsdir)
env_config_path = os.path.join(self.beetsdir, b"config.yaml")
with open(env_config_path, "w") as file:
file.write("anoption: value")
@ -1054,7 +1054,7 @@ class ConfigTest(unittest.TestCase, TestHelper, _common.Assertions):
)
def test_cli_config_paths_resolve_relative_to_beetsdir(self):
os.environ["BEETSDIR"] = util.py3_path(self.beetsdir)
os.environ["BEETSDIR"] = os.fsdecode(self.beetsdir)
cli_config_path = os.path.join(self.temp_dir, b"config.yaml")
with open(cli_config_path, "w") as file:
@ -1089,7 +1089,7 @@ class ConfigTest(unittest.TestCase, TestHelper, _common.Assertions):
self.assertTrue(plugins.find_plugins()[0].is_test_plugin)
def test_beetsdir_config(self):
os.environ["BEETSDIR"] = util.py3_path(self.beetsdir)
os.environ["BEETSDIR"] = os.fsdecode(self.beetsdir)
env_config_path = os.path.join(self.beetsdir, b"config.yaml")
with open(env_config_path, "w") as file:
@ -1101,11 +1101,11 @@ class ConfigTest(unittest.TestCase, TestHelper, _common.Assertions):
def test_beetsdir_points_to_file_error(self):
beetsdir = os.path.join(self.temp_dir, b"beetsfile")
open(beetsdir, "a").close()
os.environ["BEETSDIR"] = util.py3_path(beetsdir)
os.environ["BEETSDIR"] = os.fsdecode(beetsdir)
self.assertRaises(ConfigError, self.run_command, "test")
def test_beetsdir_config_does_not_load_default_user_config(self):
os.environ["BEETSDIR"] = util.py3_path(self.beetsdir)
os.environ["BEETSDIR"] = os.fsdecode(self.beetsdir)
with open(self.user_config_path, "w") as file:
file.write("anoption: value")
@ -1114,7 +1114,7 @@ class ConfigTest(unittest.TestCase, TestHelper, _common.Assertions):
self.assertFalse(config["anoption"].exists())
def test_default_config_paths_resolve_relative_to_beetsdir(self):
os.environ["BEETSDIR"] = util.py3_path(self.beetsdir)
os.environ["BEETSDIR"] = os.fsdecode(self.beetsdir)
config.read()
self.assert_equal_path(
@ -1127,7 +1127,7 @@ class ConfigTest(unittest.TestCase, TestHelper, _common.Assertions):
)
def test_beetsdir_config_paths_resolve_relative_to_beetsdir(self):
os.environ["BEETSDIR"] = util.py3_path(self.beetsdir)
os.environ["BEETSDIR"] = os.fsdecode(self.beetsdir)
env_config_path = os.path.join(self.beetsdir, b"config.yaml")
with open(env_config_path, "w") as file:

View file

@ -131,7 +131,7 @@ class InitTest(_common.LibTestCase):
class ParentalDirCreation(_common.TestCase):
def test_create_yes(self):
non_exist_path = _common.util.py3_path(
non_exist_path = _common.os.fsdecode(
os.path.join(self.temp_dir, b"nonexist", str(random()).encode())
)
# Deepcopy instead of recovering because exceptions might
@ -143,10 +143,10 @@ class ParentalDirCreation(_common.TestCase):
lib._close()
def test_create_no(self):
non_exist_path_parent = _common.util.py3_path(
non_exist_path_parent = _common.os.fsdecode(
os.path.join(self.temp_dir, b"nonexist")
)
non_exist_path = _common.util.py3_path(
non_exist_path = _common.os.fsdecode(
os.path.join(non_exist_path_parent.encode(), str(random()).encode())
)
test_config = deepcopy(config)