Skip to content

Commit

Permalink
Update dependencies and do not install reflink on Windows for tests (#…
Browse files Browse the repository at this point in the history
…5407)

See my comment under #5406 for context

> The build on win32 is failing to install reflink because it's [only
supported until Python
3.7](https://gitlab.com/rubdos/pyreflink/-/blob/master/setup.py?ref_type=heads).
>
> I will address this in a separate PR and rebase this one accordingly
once the fix is merged.
>
> Note: this issue popped up now because I added a new requests-mock
dependency which invalidated cached dependencies.
  • Loading branch information
snejus authored Sep 8, 2024
2 parents 98f4a88 + 851699a commit 54b2435
Show file tree
Hide file tree
Showing 9 changed files with 804 additions and 743 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
run: |
sudo apt update
sudo apt install ffmpeg gobject-introspection libgirepository1.0-dev
poetry install --extras replaygain
poetry install --extras=replaygain --extras=reflink
- name: Install Python dependencies
run: poetry install --only=main,test --extras=autobpm
Expand Down
8 changes: 0 additions & 8 deletions beets/test/_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

import os
import sys
import tempfile
import unittest
from contextlib import contextmanager

Expand Down Expand Up @@ -66,13 +65,6 @@
HAVE_SYMLINK = sys.platform != "win32"
HAVE_HARDLINK = sys.platform != "win32"

try:
import reflink

HAVE_REFLINK = reflink.supported_at(tempfile.gettempdir())
except ImportError:
HAVE_REFLINK = False


def item(lib=None):
global _item_ident
Expand Down
16 changes: 15 additions & 1 deletion beets/test/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
from functools import cached_property
from io import StringIO
from pathlib import Path
from tempfile import mkdtemp, mkstemp
from tempfile import gettempdir, mkdtemp, mkstemp
from typing import Any, ClassVar
from unittest.mock import patch

Expand Down Expand Up @@ -147,6 +147,20 @@ def has_program(cmd, args=["--version"]):
return True


def check_reflink_support(path: str) -> bool:
try:
import reflink
except ImportError:
return False

return reflink.supported_at(path)


NEEDS_REFLINK = unittest.skipUnless(
check_reflink_support(gettempdir()), "no reflink support for libdir"
)


class TestHelper(_common.Assertions):
"""Helper mixin for high-level cli and plugin tests.
Expand Down
40 changes: 22 additions & 18 deletions beets/util/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
# included in all copies or substantial portions of the Software.

"""Miscellaneous utility functions."""

from __future__ import annotations

import errno
Expand All @@ -29,6 +30,7 @@
from collections import Counter
from contextlib import suppress
from enum import Enum
from importlib import import_module
from logging import Logger
from multiprocessing.pool import ThreadPool
from pathlib import Path
Expand Down Expand Up @@ -615,31 +617,33 @@ def reflink(
Raise an `OSError` if `dest` already exists, unless `replace` is
True. If `path` == `dest`, then do nothing.
If reflinking fails and `fallback` is enabled, try copying the file
instead. Otherwise, raise an error without trying a plain copy.
May raise an `ImportError` if the `reflink` module is not available.
If `fallback` is enabled, ignore errors and copy the file instead.
Otherwise, errors are re-raised as FilesystemError with an explanation.
"""
import reflink as pyreflink

if samefile(path, dest):
return

if os.path.exists(syspath(dest)) and not replace:
raise FilesystemError("file exists", "rename", (path, dest))
raise FilesystemError("target exists", "rename", (path, dest))

if fallback:
with suppress(Exception):
return import_module("reflink").reflink(path, dest)
return copy(path, dest, replace)

try:
pyreflink.reflink(path, dest)
except (NotImplementedError, pyreflink.ReflinkImpossibleError):
if fallback:
copy(path, dest, replace)
else:
raise FilesystemError(
"OS/filesystem does not support reflinks.",
"link",
(path, dest),
traceback.format_exc(),
)
import_module("reflink").reflink(path, dest)
except (ImportError, OSError):
raise
except Exception as exc:
msg = {
"EXDEV": "Cannot reflink across devices",
"EOPNOTSUPP": "Device does not support reflinks",
}.get(str(exc), "OS does not support reflinks")

raise FilesystemError(
msg, "reflink", (path, dest), traceback.format_exc()
) from exc


def unique_path(path: bytes) -> bytes:
Expand Down
4 changes: 2 additions & 2 deletions docs/reference/config.rst
Original file line number Diff line number Diff line change
Expand Up @@ -600,13 +600,13 @@ Defaults to ``no``.

This kind of clone is only available on certain filesystems: for example,
btrfs and APFS. For more details on filesystem support, see the `pyreflink`_
documentation. Note that you need to install ``pyreflink``, either through
documentation. Note that you need to install ``pyreflink``, either through
``python -m pip install beets[reflink]`` or ``python -m pip install reflink``.

The option is ignored if ``move`` is enabled (i.e., beets can move or
copy files but it doesn't make sense to do both).

.. _file clones: https://blogs.oracle.com/otn/save-disk-space-on-linux-by-cloning-files-on-btrfs-and-ocfs2
.. _file clones: https://en.wikipedia.org/wiki/Copy-on-write
.. _pyreflink: https://reflink.readthedocs.io/en/latest/

resume
Expand Down
Loading

0 comments on commit 54b2435

Please sign in to comment.