-
-
Notifications
You must be signed in to change notification settings - Fork 419
PICARD-3041: Fix QUrl
drag-n-drop issue; added path canonicalisation
#2704
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
PICARD-3041: Fix QUrl
drag-n-drop issue; added path canonicalisation
#2704
Conversation
…rewrites the drive)
@@ -475,16 +483,38 @@ def scrollTo(self, index, scrolltype=QtWidgets.QAbstractItemView.ScrollHint.Ensu | |||
def drop_urls(urls, target, move_to_multi_tracks=True): | |||
files = [] | |||
new_paths = [] | |||
tagger = QtCore.QCoreApplication.instance() | |||
# We need to cast to Tagger here to avoid type checking errors below. | |||
tagger = cast("Tagger", QtCore.QCoreApplication.instance()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unrelated to this PR, but there are more places where we should do that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Revert or no? It was annoying me to get error intellisense highlights without it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI: I recommend ty
, when the project comes out of pre-release: https://github.com/astral-sh/ty It's from the same authors as ruff
and uv
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wouldn't do this. As Python is not statically typed there is no need for such casts during runtime.
But getting the main application instance is a typical case. Maybe we should provide our own helper method for this. This could have the appropriate type hint set for the return value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have the time right now to review the code in detail. But I have my concerns about the general approach for fixing a very specific issue reported on macOS.
The approach of verifying every path component in different Unicode normalizations against the file system by iterating over the parent directory appears to me to be a rather big performance issue. Specifically when doing so over a virtual filesystem backed by an SSH connection (which is the case for PICARD-3041). And it is not even clear to me, whether this change indeed fixes the reported issue.
In general our file handling is already rather complex, due to considering multiple special cases across operating systems. We already do path normalization at various parts, e.g. with the normpath
function that also handles Windows long paths.
This change seems to me to add yet another layer to this complexity, while I think the issue behind PICARD-3041 might be related to some path handling we already do. My main suspects would be the encode_filename
/ decode_filename
helpers that are not consistently used everywhere and also might lead to those normalization issues.
If we actually end up in situations where we need to try different Unicode normalizations, maybe we should only do this in the error case?
I'm not generally against this change, and if you all convince me that this is all needed to fix path issues on macOS then we maybe need to go this approach. But right now it does seem to add a lot of complexity.
It's not just OP's macFUSE/sshfs issue; what this will fix though is for programmes that supply schema-less URL's. QT people already made it clear they're not going to fix it. Like you, their concern was complexity and who's really responsible? I mean yeah, it would be wonderful if all apps provide full URI for files. >>> from PyQt6.QtCore import QUrl
>>> url = QUrl("/User/music/file.mp3")
>>> url.toLocalFile()
''
>>> url.path()
'/User/music/file.mp3'
>>> url.scheme()
''
>>>
I was going to take on those next. Introducing a According to the LLM I'm using, there's actually a lot more to do in terms of handling non-unicode systems better. Next tasks to standardize non‑Unicode/locale handling
|
How exactly is the fact that we get a path and not a file URI the cause of the issue in the ticket? The functionality should generally stay the same, with or without the My main concern with this PR is really the macOS code that tries to resolve a misencoded filename against the filesystem. This feels to me as it is working around the symptoms rather to address the root cause, which is that we end up with a misencoded file path for some reason. At a minimum we should:
|
I have the same concern regarding this patch. |
I don't follow. In a schema-less URL,
The work for which should be its own epic, to make picard play well with non-unicode FS and locales. I'm wondering if the juice is even worth the squeeze. There's a handful user complaints on JIRA that is yet to be resolved (mutagen errors, posix bytes-encoded paths, etc.), well, including this one... |
Generally yes of course (e.g. if passed form command line). Inside the specific code path of dropping in We should of course fix this handling, and accept schema less "URL" in this drop action. My concerns are more about the path canonicalization code, specifically on macOS, and the PR claiming to solve PICARD-3041 (which it might or might not do). |
@phw Let me take some time to digest this. Maybe
The reason ![]() |
Summary
See: https://bugreports.qt.io/browse/QTBUG-19827
And see: https://bugreports.qt.io/browse/QTBUG-22382
toLocalFile
returning blank is intended behaviour.Problem
QUrl.toLocalFile()
return empty and dropping files no-op.Solution
picard/ui/itemviews/basetreeview.py
: Indrop_urls
, useurl.toLocalFile() or url.path()
and canonicalize the result.picard/util/__init__.py
: Addcanonicalize_path
:\\?\\
prefix) when needed.picard/ui/mainwindow/__init__.py
: Canonicalize paths from “Add Files” and “Add Folder” before use.test/test_path_handling.py
: DnD coverage (scheme-less and file://, move vs add, null trimming, HTTP handling).test/test_canonicalize_path.py
: Canonicalization (NULs, normalization, relative/absolute, Windows long-path behavior).test/test_resolve_path_components_macos.py
(macOS-only): NFC/NFD resolution per component.Action
Additional actions required:
Notes:
open_local_path
).