Skip to content

Proposal: Remove positional-or-keyword parameters from the ReqClient #59

@onyx-and-iris

Description

@onyx-and-iris

Hi, I'd like to propose a major change to the codebase, removal of positional-or-keyword arguments in the ReqClient methods in favour of keyword-only arguments.

Motivation

There are two main motivations for this proposal:

Currently the ReqClient is inflexible to change.

Take this simple example:

    def set_scene_name(self, old_name, new_name):

At the time this method was written it only needed to accept two parameters, the current scene name and the new scene name. So that's fine, however, since then uuid's have been introduced to the protocol and many of the methods now accept either a name or a uuid. Unfortunately, as in this example, we cannot reasonably add scene_uuid because both it and old_name would need to be optional. Making old_name optional would require repositioning it therefore breaking the method.

This leads onto the second motivation.

Bring ReqClient method parameter names inline with the protocol.

Looking through the ReqClient methods it's clear that some of the function parameters were named with usability in mind, for example:

    def set_scene_scene_transition_override(self, scene_name, tr_name, tr_duration):

That's great, however, because the parameter names don't match the protocol field names it means we are unable to test the ReqClient methods against the protocol.json programmatically. Doing so would benefit both maintainers and users of the package because it would speed up the process of adding new methods, ensure parameters are properly marked as optional/required, ensure there are no missing methods and generally make life easier.

Currently this option isn't open to us since renaming the parameters would be a breaking change.

What this might look like

As an example of how this would affect users of the package:

A method like this:

    def set_source_filter_enabled(self, source_name, filter_name, enabled):

would become:

def set_source_filter_enabled(
    self,
    *,
    source_name: Optional[str] = None,
    source_uuid: Optional[str] = None,
    filter_name: str,
    filter_enabled: bool,
):

and instead of calling it like this:

# positional
client.set_source_filter_enabled("Scene", "Chroma Key", True)
# or keyword
client.set_source_filter_enabled(source_name="Scene", filter_name="Chroma Key", enabled=False)

users would need to call it like this:

# keyword-only with argument names that match the protocol field names but snake cased
client.set_source_filter_enabled(
    source_name="Scene",
    filter_name="Chroma Key",
    filter_enabled=True,
)

Consequences

Upsides
  • We can deliver a more consistent and error free library and hopefully keep on top of new additions to the protocol at a faster rate.
  • Consistency between parameter names and protocol fields should reduce some cognitive load when using named parameters.
  • The ReqClient becomes more flexible and we free ourselves from the constraints of keyword-or-positional arguments. This is especially important because we don't control the underlying protocol.
Downsides
  • This would introduce a breaking change and require a major version bump. Consequently, current and past users of the package will need to update their code if they want to keep using obsws-python with future updates.
  • Certain otherwise short function calls will become more verbose, for example:
# before
client.set_current_program_scene("Scene 1")

# after
client.set_current_program_scene(scene_name="Scene 1")

obsws-python is three years in age now and as package authors we've been careful not to introduce reckless breaking changes. This wouldn't be reckless and on the balance of things I think the benefits justify the drawbacks.

Let me know your thoughts.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions