geigerzaehler / beets-alternatives

Beets plugin to manage external files
MIT License
91 stars 21 forks source link

Use pathlib in tests and add symlink test #84

Closed geigerzaehler closed 3 months ago

geigerzaehler commented 3 months ago

Could you comment a bit on your motivation to refactor this now?

Of course. I’ve been bugged by finding the cause for #74 and my suspicion is that it comes from beets’s path handling. In addition to that, I feel that beets’s path handling is hard to understand, difficult to use and a lot less readable than pathlib.

My impression is that this might introduce extra friction at the interface between beets and the plugin, given that beets still (tries to) consistently represents everything as bytes internally.

I understand your concern. But in my experience the main friction comes from how beets handles paths and how hard that is to understand and predict. For example, you said that beets “tries to“ use bytes for paths but that is not actually the case on Windows where syspath returns a str. On all other platforms it just passes through the argument, so it is up to the user to ensure the correct type.

This is also why improved type hints don’t solve the underlying problem. (The would help improve understanding in a lot of other areas, though.)

I didn't review this PR in full; and I don't think I have the time to do so: That would require going back to the beets code quite a lot and checking my expectations about it.

That’s ok, thanks for your effort anyway. Since this only touches test code (for now) I think it’s ok to play a bit loose with things like the type passed to Mediafile since it just works™.

wisp3rwind commented 3 months ago

Could you comment a bit on your motivation to refactor this now?

Of course. I’ve been bugged by finding the cause for #74 and my suspicion is that it comes from beets’s path handling. In addition to that, I feel that beets’s path handling is hard to understand, difficult to use and a lot less readable than pathlib.

It definitely is, and I don't think there's any documentation on how it's supposed to work. However, I'm not sure whether pathlib would really resolve all issues on its own, or whether it would just shift input validation/normalization to different places in the code.

My impression is that this might introduce extra friction at the interface between beets and the plugin, given that beets still (tries to) consistently represents everything as bytes internally.

I understand your concern. But in my experience the main friction comes from how beets handles paths and how hard that is to understand and predict. For example, you said that beets “tries to“ use bytes for paths but that is not actually the case on Windows where syspath returns a str. On all other platforms it just passes through the argument, so it is up to the user to ensure the correct type.

It should be the case on Windows as well: From my understanding, the intended usage is

Thus, overall, except for input and at API boundaries, any path handled by beets should always be represented as bytes. I'm pretty sure that there are still some bugs lurking in beets, definitely in some of the vendored plugins and possibly even in the core.

This is also why improved type hints don’t solve the underlying problem. (The would help improve understanding in a lot of other areas, though.)

One idea that I mentioned at some point is using newtypes for InternalPath, SysPath (which would have a platform-dependent inner type) and thereby help verification by the type checker. But that on its own would already by a rather big project in beets.

I didn't review this PR in full; and I don't think I have the time to do so: That would require going back to the beets code quite a lot and checking my expectations about it.

That’s ok, thanks for your effort anyway. Since this only touches test code (for now) I think it’s ok to play a bit loose with things like the type passed to Mediafile since it just works™.

I'm still not fully convinced, since this means that the testing code might end up using different types/code paths than the real usage in beets.

That said and given that I'm not going to review this in more depth, please ignore my comments and go with your judgement if you're convinced that this should be done!

geigerzaehler commented 3 months ago

Thanks for the reply. I appreciate your input on this.

I’ve reflected on the change again but I think the main argument is still very strong: There’s a standard, pythonic way to deal with paths robustly and not care about the OS. That way is different from beets’s but I trust the former more and I believe it is the way forward. I’m willing to deal with the friction that comes from using both.

With that in mind, I’ll go ahead and merge this change. I’ll have another PR ready soon that also switches to pathlib in the actual plugin implementation.