Skip to content

Commit 965d706

Browse files
committed
Replace bytestring_path with builtin os.fsencode
Same `os.fsdecode`, this has only been available since Python 3.2 which was after this code was written.
1 parent c26c736 commit 965d706

35 files changed

+163
-194
lines changed

beets/art.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222

2323
import mediafile
2424

25-
from beets.util import bytestring_path, displayable_path, syspath
25+
from beets.util import displayable_path, syspath
2626
from beets.util.artresizer import ArtResizer
2727

2828

@@ -183,7 +183,7 @@ def check_art_similarity(
183183

184184
def extract(log, outpath, item):
185185
art = get_art(log, item)
186-
outpath = bytestring_path(outpath)
186+
outpath = os.fsencode(outpath)
187187
if not art:
188188
log.info("No album art present in {0}, skipping.", item)
189189
return
@@ -193,7 +193,7 @@ def extract(log, outpath, item):
193193
if not ext:
194194
log.warning("Unknown image type in {0}.", displayable_path(item.path))
195195
return
196-
outpath += bytestring_path("." + ext)
196+
outpath += os.fsencode("." + ext)
197197

198198
log.info(
199199
"Extracting album art from: {0} to: {1}",

beets/importer.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1800,7 +1800,7 @@ def albums_in_dir(path):
18001800
start_collapsing = True
18011801
subdir_pat = None
18021802
for subdir in dirs:
1803-
subdir = util.bytestring_path(subdir)
1803+
subdir = os.fsencode(subdir)
18041804
# The first directory dictates the pattern for
18051805
# the remaining directories.
18061806
if not subdir_pat:

beets/library.py

+9-16
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,7 @@
2828
import beets
2929
from beets import dbcore, logging, plugins, util
3030
from beets.dbcore import Results, types
31-
from beets.util import (
32-
MoveOperation,
33-
bytestring_path,
34-
lazy_property,
35-
normpath,
36-
samefile,
37-
syspath,
38-
)
31+
from beets.util import MoveOperation, lazy_property, normpath, samefile, syspath
3932
from beets.util.functemplate import Template, template
4033

4134
# To use the SQLite "blob" type, it doesn't suffice to provide a byte
@@ -214,12 +207,12 @@ def format(self, value):
214207
return util.displayable_path(value)
215208

216209
def parse(self, string):
217-
return normpath(bytestring_path(string))
210+
return normpath(os.fsencode(string))
218211

219212
def normalize(self, value):
220213
if isinstance(value, str):
221214
# Paths stored internally as encoded bytes.
222-
return bytestring_path(value)
215+
return os.fsencode(value)
223216

224217
elif isinstance(value, BLOB_TYPE):
225218
# We unwrap buffers to bytes.
@@ -681,7 +674,7 @@ def __setitem__(self, key, value):
681674
# Encode unicode paths and read buffers.
682675
if key == "path":
683676
if isinstance(value, str):
684-
value = bytestring_path(value)
677+
value = os.fsencode(value)
685678
elif isinstance(value, BLOB_TYPE):
686679
value = bytes(value)
687680
elif key == "album_id":
@@ -1402,7 +1395,7 @@ def art_destination(self, image, item_dir=None):
14021395
items, so the album must contain at least one item or
14031396
item_dir must be provided.
14041397
"""
1405-
image = bytestring_path(image)
1398+
image = os.fsencode(image)
14061399
item_dir = item_dir or self.item_dir()
14071400

14081401
filename_tmpl = template(beets.config["art_filename"].as_str())
@@ -1414,12 +1407,12 @@ def art_destination(self, image, item_dir=None):
14141407
subpath = util.sanitize_path(
14151408
subpath, replacements=self._db.replacements
14161409
)
1417-
subpath = bytestring_path(subpath)
1410+
subpath = os.fsencode(subpath)
14181411

14191412
_, ext = os.path.splitext(image)
14201413
dest = os.path.join(item_dir, subpath + ext)
14211414

1422-
return bytestring_path(dest)
1415+
return os.fsencode(dest)
14231416

14241417
def set_art(self, path, copy=True):
14251418
"""Set the album's cover art to the image at the given path.
@@ -1429,7 +1422,7 @@ def set_art(self, path, copy=True):
14291422
14301423
Send an 'art_set' event with `self` as the sole argument.
14311424
"""
1432-
path = bytestring_path(path)
1425+
path = os.fsencode(path)
14331426
oldart = self.artpath
14341427
artdest = self.art_destination(path)
14351428

@@ -1568,7 +1561,7 @@ def __init__(
15681561
timeout = beets.config["timeout"].as_number()
15691562
super().__init__(path, timeout=timeout)
15701563

1571-
self.directory = bytestring_path(normpath(directory))
1564+
self.directory = os.fsencode(normpath(directory))
15721565
self.path_formats = path_formats
15731566
self.replacements = replacements
15741567

beets/test/_common.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
from beets import util # noqa: E402
3131
from beets import importer, logging # noqa: E402
3232
from beets.ui import commands # noqa: E402
33-
from beets.util import bytestring_path, syspath # noqa: E402
33+
from beets.util import syspath # noqa: E402
3434

3535
beetsplug.__path__ = [
3636
os.path.abspath(
@@ -44,7 +44,7 @@
4444
]
4545

4646
# Test resources path.
47-
RSRC = util.bytestring_path(
47+
RSRC = os.fsencode(
4848
os.path.abspath(
4949
os.path.join(
5050
os.path.dirname(__file__),
@@ -207,7 +207,7 @@ def setUp(self):
207207

208208
# Direct paths to a temporary directory. Tests can also use this
209209
# temporary directory.
210-
self.temp_dir = util.bytestring_path(tempfile.mkdtemp())
210+
self.temp_dir = os.fsencode(tempfile.mkdtemp())
211211

212212
beets.config["statefile"] = os.fsdecode(
213213
os.path.join(self.temp_dir, b"state.pickle")
@@ -399,7 +399,7 @@ def create_temp_dir(self):
399399
"""Create a temporary directory and assign it into `self.temp_dir`.
400400
Call `remove_temp_dir` later to delete it.
401401
"""
402-
self.temp_dir = bytestring_path(tempfile.mkdtemp())
402+
self.temp_dir = os.fsencode(tempfile.mkdtemp())
403403

404404
def remove_temp_dir(self):
405405
"""Delete the temporary directory created by `create_temp_dir`."""

beets/test/helper.py

+12-12
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
from beets.library import Album, Item, Library
5050
from beets.test import _common
5151
from beets.ui.commands import TerminalImportSession
52-
from beets.util import MoveOperation, bytestring_path, syspath
52+
from beets.util import MoveOperation, syspath
5353

5454

5555
class LogCapture(logging.Handler):
@@ -182,7 +182,7 @@ def setup_beets(self, disk=False):
182182
self.config["directory"] = os.fsdecode(self.libdir)
183183

184184
if disk:
185-
dbpath = util.bytestring_path(self.config["library"].as_filename())
185+
dbpath = os.fsencode(self.config["library"].as_filename())
186186
else:
187187
dbpath = ":memory:"
188188
self.lib = Library(dbpath, self.libdir)
@@ -241,7 +241,7 @@ def create_importer(self, item_count=1, album_count=1):
241241

242242
album_no = 0
243243
while album_count:
244-
album = util.bytestring_path(f"album {album_no}")
244+
album = os.fsencode(f"album {album_no}")
245245
album_dir = os.path.join(import_dir, album)
246246
if os.path.exists(syspath(album_dir)):
247247
album_no += 1
@@ -254,7 +254,7 @@ def create_importer(self, item_count=1, album_count=1):
254254
while album_item_count:
255255
title = f"track {track_no}"
256256
src = os.path.join(_common.RSRC, b"full.mp3")
257-
title_file = util.bytestring_path(f"{title}.mp3")
257+
title_file = os.fsencode(f"{title}.mp3")
258258
dest = os.path.join(album_dir, title_file)
259259
if os.path.exists(syspath(dest)):
260260
track_no += 1
@@ -341,7 +341,7 @@ def add_item_fixture(self, **values):
341341
item = self.create_item(**values)
342342
extension = item["format"].lower()
343343
item["path"] = os.path.join(
344-
_common.RSRC, util.bytestring_path("min." + extension)
344+
_common.RSRC, os.fsencode("min." + extension)
345345
)
346346
item.add(self.lib)
347347
item.move(operation=MoveOperation.COPY)
@@ -356,7 +356,7 @@ def add_item_fixtures(self, ext="mp3", count=1):
356356
"""Add a number of items with files to the database."""
357357
# TODO base this on `add_item()`
358358
items = []
359-
path = os.path.join(_common.RSRC, util.bytestring_path("full." + ext))
359+
path = os.path.join(_common.RSRC, os.fsencode("full." + ext))
360360
for i in range(count):
361361
item = Item.from_path(path)
362362
item.album = f"\u00e4lbum {i}" # Check unicode paths
@@ -380,7 +380,7 @@ def add_album_fixture(
380380
items = []
381381
path = os.path.join(
382382
_common.RSRC,
383-
util.bytestring_path(f"{fname}.{ext}"),
383+
os.fsencode(f"{fname}.{ext}"),
384384
)
385385
for discnumber in range(1, disc_count + 1):
386386
for i in range(track_count):
@@ -407,17 +407,17 @@ def create_mediafile_fixture(self, ext="mp3", images=[]):
407407
specified extension a cover art image is added to the media
408408
file.
409409
"""
410-
src = os.path.join(_common.RSRC, util.bytestring_path("full." + ext))
410+
src = os.path.join(_common.RSRC, os.fsencode("full." + ext))
411411
handle, path = mkstemp()
412-
path = bytestring_path(path)
412+
path = os.fsencode(path)
413413
os.close(handle)
414414
shutil.copyfile(syspath(src), syspath(path))
415415

416416
if images:
417417
mediafile = MediaFile(path)
418418
imgs = []
419419
for img_ext in images:
420-
file = util.bytestring_path(f"image-2x3.{img_ext}")
420+
file = os.fsencode(f"image-2x3.{img_ext}")
421421
img_path = os.path.join(_common.RSRC, file)
422422
with open(img_path, "rb") as f:
423423
imgs.append(Image(f.read()))
@@ -467,7 +467,7 @@ def create_temp_dir(self):
467467
`self.temp_dir`. Call `remove_temp_dir` later to delete it.
468468
"""
469469
temp_dir = mkdtemp()
470-
self.temp_dir = util.bytestring_path(temp_dir)
470+
self.temp_dir = os.fsencode(temp_dir)
471471

472472
def remove_temp_dir(self):
473473
"""Delete the temporary directory created by `create_temp_dir`."""
@@ -544,7 +544,7 @@ def _create_import_dir(self, count=3):
544544
for i in range(count):
545545
# Copy files
546546
medium_path = os.path.join(
547-
album_path, bytestring_path("track_%d.mp3" % (i + 1))
547+
album_path, os.fsencode("track_%d.mp3" % (i + 1))
548548
)
549549
shutil.copy(syspath(resource_path), syspath(medium_path))
550550
medium = MediaFile(medium_path)

beets/ui/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1753,7 +1753,7 @@ def _ensure_db_directory_exists(path):
17531753

17541754
def _open_library(config):
17551755
"""Create a new library instance from the configuration."""
1756-
dbpath = util.bytestring_path(config["library"].as_filename())
1756+
dbpath = os.fsencode(config["library"].as_filename())
17571757
_ensure_db_directory_exists(dbpath)
17581758
try:
17591759
lib = library.Library(

beets/util/__init__.py

+10-32
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ def normpath(path: bytes) -> bytes:
160160
"""
161161
path = syspath(path, prefix=False)
162162
path = os.path.normpath(os.path.abspath(os.path.expanduser(path)))
163-
return bytestring_path(path)
163+
return os.fsencode(path)
164164

165165

166166
def ancestry(path: bytes) -> List[str]:
@@ -199,8 +199,8 @@ def sorted_walk(
199199
warning messages are logged there when a directory cannot be listed.
200200
"""
201201
# Make sure the paths aren't Unicode strings.
202-
path = bytestring_path(path)
203-
ignore = [bytestring_path(i) for i in ignore]
202+
path = os.fsencode(path)
203+
ignore = [os.fsencode(i) for i in ignore]
204204

205205
# Get all the directories and files at this level.
206206
try:
@@ -216,7 +216,7 @@ def sorted_walk(
216216
dirs = []
217217
files = []
218218
for base in contents:
219-
base = bytestring_path(base)
219+
base = os.fsencode(base)
220220

221221
# Skip ignored filenames.
222222
skip = False
@@ -322,8 +322,8 @@ def prune_dirs(
322322
if not os.path.exists(directory):
323323
# Directory gone already.
324324
continue
325-
clutter: List[bytes] = [bytestring_path(c) for c in clutter]
326-
match_paths = [bytestring_path(d) for d in os.listdir(directory)]
325+
clutter: List[bytes] = [os.fsencode(c) for c in clutter]
326+
match_paths = [os.fsencode(d) for d in os.listdir(directory)]
327327
try:
328328
if fnmatch_all(match_paths, clutter):
329329
# Directory contains only clutter (or nothing).
@@ -380,29 +380,7 @@ def _fsencoding() -> str:
380380
return encoding
381381

382382

383-
def bytestring_path(path: Bytes_or_String) -> bytes:
384-
"""Given a path, which is either a bytes or a unicode, returns a str
385-
path (ensuring that we never deal with Unicode pathnames). Path should be
386-
bytes but has safeguards for strings to be converted.
387-
"""
388-
# Pass through bytestrings.
389-
if isinstance(path, bytes):
390-
return path
391-
392-
# On Windows, remove the magic prefix added by `syspath`. This makes
393-
# ``bytestring_path(syspath(X)) == X``, i.e., we can safely
394-
# round-trip through `syspath`.
395-
if os.path.__name__ == "ntpath" and path.startswith(WINDOWS_MAGIC_PREFIX):
396-
path = path[len(WINDOWS_MAGIC_PREFIX) :]
397-
398-
# Try to encode with default encodings, but fall back to utf-8.
399-
try:
400-
return path.encode(_fsencoding())
401-
except (UnicodeError, LookupError):
402-
return path.encode("utf-8")
403-
404-
405-
PATH_SEP: bytes = bytestring_path(os.sep)
383+
PATH_SEP: bytes = os.fsencode(os.sep)
406384

407385

408386
def displayable_path(
@@ -522,8 +500,8 @@ def move(path: bytes, dest: bytes, replace: bool = False):
522500
os.replace(syspath(path), syspath(dest))
523501
except OSError:
524502
# Copy the file to a temporary destination.
525-
basename = os.path.basename(bytestring_path(dest))
526-
dirname = os.path.dirname(bytestring_path(dest))
503+
basename = os.path.basename(os.fsencode(dest))
504+
dirname = os.path.dirname(os.fsencode(dest))
527505
tmp = tempfile.NamedTemporaryFile(
528506
suffix=syspath(b".beets", prefix=False),
529507
prefix=syspath(b"." + basename, prefix=False),
@@ -738,7 +716,7 @@ def _legalize_stage(
738716

739717
# Encode for the filesystem.
740718
if not fragment:
741-
path = bytestring_path(path) # type: ignore
719+
path = os.fsencode(path) # type: ignore
742720

743721
# Preserve extension.
744722
path += extension.lower()

beets/util/artresizer.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
from urllib.parse import urlencode
2727

2828
from beets import logging, util
29-
from beets.util import bytestring_path, displayable_path, syspath
29+
from beets.util import displayable_path, syspath
3030

3131
PROXY_URL = "https://images.weserv.nl/"
3232

@@ -54,7 +54,7 @@ def temp_file_for(path):
5454
"""
5555
ext = os.path.splitext(path)[1]
5656
with NamedTemporaryFile(suffix=os.fsdecode(ext), delete=False) as f:
57-
return bytestring_path(f.name)
57+
return os.fsencode(f.name)
5858

5959

6060
class LocalBackendNotAvailableError(Exception):

0 commit comments

Comments
 (0)