-
Notifications
You must be signed in to change notification settings - Fork 45
Make class(es) more self-contained, reduce globals #146
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?
Conversation
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.
3f4d8c4 - I'm not sure I understand this one; maybe it's just been too long since I looked at this code, but why is __wrapper being made a class property? If it's assigned in __init__(), then it should probably be an instance property (i.e. self._wrapper).
Normally, yes, I'd agree. But that didn't work, because the callback functions aren't methods — they don't have access to |
|
(Forgot the ping: @grawity ) |
| def __get_volume(): | ||
| vol = float(mpd_wrapper.last_status().get('volume', 0)) | ||
| vol = float(MPRISInterface.__wrapper.last_status().get('volume', 0)) | ||
| if vol > 0: | ||
| return vol / 100.0 | ||
| else: | ||
| return 0.0 | ||
|
|
||
| def __set_volume(value): | ||
| if value >= 0 and value <= 1: | ||
| mpd_wrapper.setvol(int(value * 100)) | ||
| MPRISInterface.__wrapper.setvol(int(value * 100)) | ||
| return |
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.
@grawity This is what I was referring to — the setters and getters aren't defined as methods of MPRISInterface, so they don't have access to self.
| # Player methods | ||
| @dbus.service.method(__player_interface, in_signature='', out_signature='') | ||
| def Next(self): | ||
| mpd_wrapper.next() | ||
| MPRISInterface.__wrapper.next() | ||
| return |
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.
@grawity I could use self.__wrapper for these methods, if you prefer. I decided to just be consistent, but I'm open to changing it if that was the wrong call.
| """ | ||
|
|
||
| def __init__(self, params): | ||
| def __init__(self, params, loop=None): |
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.
Shouldn't loop be a required argument ?
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.
Wow, ancient history, I don't know how I missed these! Sorry about that.
...I think I originally set these up as defaulted arguments because I didn't want to change the class constructors' semantics until I had my additions finalized. But they probably don't need to stay in that state now.
As far as loop goes, though... I mean, I'm not sure it really has to be required.
The only reason loop is passed in is so the relaunch code in _name_owner_changed_callback() can call self._loop.quit(). If self._loop is None (it checks), it just won't call quit() on it.
Which... seems like it would be fine? In situations where a loop isn't supplied (say, in testing).
| __wrapper = None | ||
|
|
||
| def __init__(self, params): | ||
| def __init__(self, params, mpd_wrapper=None): |
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.
mpd_wrapper is required too
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.
mpd_wrapper, OTOH... yeah. I absolutely agree, it needs to be required. I'll fix that and rebase this PR to the current HEAD now.
|
Pushed 6b246e4 to see what it needs to make the wrapper an instance of the class. Feels a bit more idiomatic python to me Overall it's great to be able to run mpDris2 in the repl |
This PR contains a set of what I'm calling "quality of life" changes for the code. Nothing user-visible, this is all an attempt to make the
MPDWrapperclass and its helpers more self-contained, and importable/usable outside of thempDris2source file itself — for testing/debugging purposes. The user should see absolutely no difference in normal operation.Specifically, this PR eliminates all references from inside the class code to symbols that are only defined if the
if __name__== '__main__'block is run. As a result, it's now possible to import the class into an interactive session and call methods on it by hand, without it crashing due to things likempd_wrapperandloopbeing undefined, ornotificationnot being callable because its value isNone.Specific changes (as separate commits):
__main__-only code)notificationin theMPDWrapper.__init__()code asself._notification, since it's never used in the__main__code but all of the class code assumes it's been properly initializedlooponly in the__main__code (I agree that's a good idea), but pass it in to theMPDWrapper()constructor and useself._loopto access it later.MPDWrapperinstance in toMPRISInterface()along with theparams, and store it asMPRISInterface.__wrapper. Then, use that to make calls back to it, instead of trying to usempd_wrapperwhich is undefined if the__main__code wasn't executedWith these changes, it's possible to debug the code interactively via the REPL (after running
ln -s mpDris2 mpDris2.py), all that's required is to set up theMainLoopand create aparamsdictionary, then pass them both toMPDWrapper()thusly:(...and it does.)