-
Notifications
You must be signed in to change notification settings - Fork 3
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
support replacing in list-type fields #8
base: master
Are you sure you want to change the base?
Conversation
Please let me know if you'd like documentation changes and/or additional test cases or fields in the tests. Thanks! |
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.
Thanks for the work, looks good to me! I just have a question and a suggestion for you to look at.
This has the potential to (further) increase the processing time when importing based on the number of replacement rules
I'm not too worried about that, I think the README addresses the possible performance penalty when running too many replacements.
Please let me know if you'd like documentation changes and/or additional test cases or fields in the tests. Thanks!
I think you're all set!
beetsplug/importreplace.py
Outdated
def _replace_field(self, text: str, replacements: [(Pattern, str)]) -> str: | ||
|
||
return reduce(self._replace, replacements, text) | ||
def _replace_field(self, text: str|list, replacements: [(Pattern, str)]) -> str|list: |
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.
Is this syntax compatible with <3.10? Currently the setup.py
for this plugin indicates it supports beets >=1.4.7, and I think that version supports Python 3.6. So I'd like to keep it compatible with older versions as well.
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.
It is not; the X|Y
shorthand for Union[X, Y]
was added in 3.10 with PEP 604
beetsplug/importreplace.py
Outdated
return reduce(self._replace, replacements, text) | ||
def _replace_field(self, text: str|list, replacements: [(Pattern, str)]) -> str|list: | ||
if isinstance(text, list): | ||
return list(map(lambda item: reduce(self._replace, replacements, item), text)) |
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 think lambda item: self._replace_field(item, replacements)
would be nicer, since it'd keep the same logic as the str
case.
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 think this may be a nice application for @singledispatchmethod
, something like
@singledispatchmethod
@classmethod
def _replace(cls, value: Any, replacement: Replacement) -> Any:
raise NotImplementedError
@_replace.register(str)
@classmethod
def _replace_str(cls, value: str, replacement: Replacement) -> str:
return replacement[0].sub(repl=replacement[1], string=value)
@_replace.register(list)
@classmethod
def _replace_list(cls, value: list[str], replacement: Replacement) -> list[str]:
return [cls._replace(item, replacement) for item in 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.
It looks like @singledispatchmethod
was introduced in 3.4.
@edgars-supe, would you have an opinion on the minimum version of Python we would want to support?
I appreciate all of these comments and suggestions, I am learning a lot :)
Thanks for the feedback and suggestions! Backward compatibility wasn't something I had considered (hooray sunny day case!), but will definitely be looking into it. I anticipate it taking a little bit of time to test the different permutations to satisfy my curiosity: This means that Python 3.6 was the current version at time of beets 1.4.7 release and 2.7, 3.4, and 3.5 had not met their end-of-life and were supported. I'm now extremely curious and (un)?lucky for me there are pre-built container images available for trying it out. At a minimum, definitely with 3.6/1.4.7 and 3.7/2.0.0 (latest beets minimum Python version). |
A slight complication- the list-like fields was only added in beets v2.0.0: beetbox/beets@f72261e Also- apparently re.Pattern was only added in Python 3.7, which I'll see if I can get the code to handle. |
Some updates:
If we can set the minimum supported Python version to 3.4 (or even 3.9), we could use the As always, any pointers (references? 😁) or ideas are most welcome. |
Apologies for my late reply. And thanks for the extensive research, much appreciated! I'll preface all of this by saying I'm not a Python dev, I don't use Python in my day-to-day, so I don't really have an opinion (or knowledge) on most of these things, but I'll do my best to look into things and make some decisions. So, as for the Python version, I think it doesn't make sense to support <=3.6, since it is EOL. And since the plugin uses As for beets - I'll set the minimum version to 1.5.0, as it was released 3 years ago, officially supports Python 3.7 and will cover the two issues you mentioned. |
Changes have been pushed to |
Note that all Python versions up to and including 3.8 are now EOL. Though, as @edgars-supe mentioned
I think it's a good idea to start with picking the oldest |
Also @edgars-supe happy to see that your pick of |
c71adfc
to
068eb1e
Compare
This PR addresses #7 by adding support for replacing in the list-type fields returned by the Musicbrainz database.
If the field being modified is a list, the replacements are applied to each item in the list. This has the potential to (further) increase the processing time when importing based on the number of replacement rules, although pre-compiling and reusing the patterns should help.