Also tighten `filetype` attribute type - empty value was previously
handled to accommodate a couple of tests, but they aren't failing
anymore, it seems.
TIL that `with_suffix` does not simply append the suffix to the filename
- it instead replaces the old/current suffix. Or whatever seems to
look like a suffix, in our case, unfortunately...
This PR addresses Dependabot vulnerability alerts and secret scanner
reports by updating dependencies and redacting some of the sensitive
configuration field.
* **Dependency Updates:** Updated various dependencies, including those
flagged by Dependabot, as reflected in `poetry.lock`. This resolves
known vulnerabilities.
* **Secret Redaction:** Addressed secret scanner findings by redacting
sensitive configuration values (e.g., `tokenfile`, `apikey`, `password`,
`username`, `userid`) in `beatport`, `discogs`, `embyupdate`,
`fetchart`, `lastimport`, `spotify`, and `subsonicupdate` plugins.
* **Python Version:** Standardized on Python 3.9 across GitHub Actions
workflows.
* **Code Style:** Minor adjustments for `ruff` compatibility, including
string concatenations and f-string quote consistency.
These have probably not been run by anyone in ages, better to move the
code to our test suite where it is regularly exercised. In fact, the
latter covers most of the cases already. The only missing tests seem to
be those were exceptions are raised in the first or last stage. Thus,
this adds such tests.
These have probably not been run by anyone in ages, better to move the
code to our test suite where it is regularly exercised. In fact, the
latter covers most of the cases already. The only missing tests seem to
be those were exceptions are raised in the first or last stage. Thus,
this adds such tests.
**Refactor: Simplify Path Generation and Legalization**
This PR refactors the way destination paths for library items are
generated and made filesystem-safe. The goal is to simplify the process,
make it more robust, and centralize most of the path manipulation logic.
**Key Changes:**
* **`Item.destination` Simplified:**
* The method now has a clearer interface, primarily controlled by the
`relative_to_libdir` flag (replacing the old `fragment` flag).
* It consistently returns the path as `bytes`, ready for filesystem
operations.
* Path legalization logic (sanitization, truncation, replacements) is
now delegated to `util.legalize_path`.
* **`util.legalize_path` Enhanced:**
* Takes responsibility for the full legalization process, including
truncation based on filesystem limits.
* Uses new helper functions (`util.truncate_path`, `util.truncate_str`)
for robust truncation of path components while preserving extensions and
handling multi-byte characters correctly.
* Includes logic to handle potential conflicts where
sanitization/replacements might interfere with truncation, falling back
to default rules if necessary.
* **Centralized Max Length:**
* A new cached function `util.get_max_filename_length` determines the
maximum filename length, checking the config first and then querying the
filesystem.
This refactoring leads to cleaner code by separating concerns:
`Item.destination` focuses on generating the *intended* path based on
metadata and formats, while `util.legalize_path` and its helpers handle
the complexities of making that path valid for the target filesystem.
Background
The `_legalize_stage` function was causing issues with Mypy due to
inconsistent type usage between the `path` and `extension` parameters.
This inconsistency stemmed from the `fragment` parameter influencing the
types of these variables.
Key issues
1. `path` was defined as `str`, while `extension` was `bytes`.
2. Depending on `fragment`, `extension` could be either `str` or `bytes`.
3. `path` was sometimes converted to `bytes` within `_legalize_stage`.
Item.destination` method
- The `fragment` parameter determined the output format:
- `False`: Returned absolute path as bytes (default)
- `True`: Returned path relative to library directory as str
Thus
- Rename `fragment` parameter to `relative_to_libdir` for clarity
- Ensure `Item.destination` returns `bytes` in all cases
- Code expecting strings now converts the output to `str`
- Use only `str` type in `_legalize_stage` and `_legalize_path`
functions
- These functions are no longer dependent on `relative_to_libdir`
# Remove Python 2 compatibility code for string encoding/decoding
This PR simplifies the codebase by removing Python 2 compatibility code
related to string encoding and decoding operations. Key changes:
- Remove custom `_convert_args`, `arg_encoding()`, `_fsencoding()` and
`convert_command_args()` functions
- Replace with standard library's `os.fsencode()` and `os.fsdecode()`
for file system path handling
- Simplify bytestring/string conversions throughout the codebase
- Update test code to use modern string handling
These changes reduce code complexity and maintenance burden since Python
2 support is no longer needed.
which added some mypy config to pyproject.toml, leading to mypy ignoring
setup.cfg
(this shows up in CI output for #5701, but is not very visible
since we currently ignore mypy errors)
Related: https://github.com/beetbox/beets/pull/5728
## Description
This might be a quick one, depending on how you feel about it... It
allows you to pickle DB model objects. I don't think this is used
directly in Beets, but it might be useful in general. For instance, we
encountered an issue where we wanted to quickly pickle an Item or Album.
This sometimes worked and other times failed, which seemed quite
inconsistent.
Some DB model methods and properties have the side effect of attaching
an SQLite connection to self (._db), which prevents serialization. The
fix is quite straightforward, so I thought we might want to integrate
this into beets directly.
## To Do
- [x] Changelog
- [x] Tests
some work following up my review of https://github.com/beetbox/beets/pull/5718
- add typings
- refactor the logic in the core `ft_in_title` function, motivated by the
fact that I found this more difficult to read than necessary during the
review