Beispiel #1
0
    def navigate(self, name: str, selector: Optional[str]) -> "CommandClient":
        """Resolve the given object in the command graph

        Parameters
        ----------
        name : str
            The name of the command graph object to resolve.
        selector : Optional[str]
            If given, the selector to use to select the next object, and if
            None, then selects the default object.

        Returns
        -------
        CommandClient
            The client with the given command graph object resolved.
        """
        if not isinstance(self._current_node, CommandGraphNode):
            raise SelectError("Invalid navigation", "",
                              self._current_node.selectors)

        if name not in self.children:
            raise SelectError("Not valid child", name,
                              self._current_node.selectors)
        if selector is not None:
            if self._command.has_item(self._current_node, name, selector):
                raise SelectError("Item not available in object", name,
                                  self._current_node.selectors)

        next_node = self._current_node.navigate(name, selector)
        return self.__class__(self._command, current_node=next_node)
Beispiel #2
0
    def navigate(self, name: str, selector: str | None) -> CommandClient:
        """Resolve the given object in the command graph

        Parameters
        ----------
        name: str
            The name of the command graph object to resolve.
        selector: str | None
            If given, the selector to use to select the next object, and if
            None, then selects the default object.

        Returns
        -------
        CommandClient
            The client with the given command graph object resolved.
        """
        if name not in self.children:
            raise SelectError("Not valid child", name,
                              self._current_node.selectors)

        normalized_selector = _normalize_item(
            name, selector) if selector is not None else None
        if normalized_selector is not None:
            if not self._command.has_item(self._current_node, name,
                                          normalized_selector):
                raise SelectError("Item not available in object", name,
                                  self._current_node.selectors)

        next_node = self._current_node.navigate(name, normalized_selector)
        return self.__class__(self._command, current_node=next_node)
Beispiel #3
0
    def __getattr__(self, name: str) -> "InteractiveCommandClient":
        """Get the child element of the currently selected object

        Resolve the element specified by the given name, either the child
        object, or the command on the current object.

        Parameters
        ----------
        name : str
            The name of the element to resolve

        Return
        ------
        InteractiveCommandClient
            The client navigated to the specified name.  Will respresent either
            a command graph node (if the name is a valid child) or a command
            graph call (if the name is a valid command).
        """
        if isinstance(self._current_node, CommandGraphCall):
            raise SelectError("Cannot select children of call", name,
                              self._current_node.selectors)

        # we do not know if the name is a command to be executed, or an object
        # to navigate to
        if name not in self._current_node.children:
            # we are going to resolve a command, check that the command is valid
            if not self._command.has_command(self._current_node, name):
                raise SelectError("Not valid child or command", name,
                                  self._current_node.selectors)
            call_object = self._current_node.call(name)
            return self.__class__(self._command, current_node=call_object)

        next_node = self._current_node.navigate(name, None)
        return self.__class__(self._command, current_node=next_node)
Beispiel #4
0
    def __getattr__(self, name: str) -> InteractiveCommandClient:
        """Get the child element of the currently selected object

        Resolve the element specified by the given name, either the child
        object, or the command on the current object.

        Parameters
        ----------
        name: str
            The name of the element to resolve

        Return
        ------
        InteractiveCommandClient
            The client navigated to the specified name.  Will respresent either
            a command graph node (if the name is a valid child) or a command
            graph call (if the name is a valid command).
        """

        # Python's help() command will try to look up __name__ and __origin__ so we
        # need to handle these explicitly otherwise they'll result in a SelectError
        # which help() does not expect.
        if name in ["__name__", "__origin__"]:
            raise AttributeError

        if isinstance(self._current_node, CommandGraphCall):
            raise SelectError(
                "Cannot select children of call", name, self._current_node.selectors
            )

        # we do not know if the name is a command to be executed, or an object
        # to navigate to
        if name not in self._current_node.children:
            # we are going to resolve a command, check that the command is valid
            if not self._command.has_command(self._current_node, name):
                raise SelectError(
                    "Not valid child or command", name, self._current_node.selectors
                )
            call_object = self._current_node.call(name)
            return self.__class__(self._command, current_node=call_object)

        next_node = self._current_node.navigate(name, None)
        return self.__class__(self._command, current_node=next_node)
Beispiel #5
0
    def __getitem__(self, name: str | int) -> InteractiveCommandClient:
        """Get the selected element of the currently selected object

        From the current command graph object, select the instance with the
        given name.

        Parameters
        ----------
        name: str
            The name, or index if it's of int type, of the item to resolve

        Return
        ------
        InteractiveCommandClient
            The current client, navigated to the specified command graph
            object.
        """
        if isinstance(self._current_node, CommandGraphRoot):
            raise KeyError("Root node has no available items", name,
                           self._current_node.selectors)

        if not isinstance(self._current_node, CommandGraphObject):
            raise SelectError(
                "Unable to make selection on current node",
                str(name),
                self._current_node.selectors,
            )

        if self._current_node.selector is not None:
            raise SelectError("Selection already made", str(name),
                              self._current_node.selectors)

        # check the selection is valid in the server-side qtile manager
        if not self._command.has_item(self._current_node.parent,
                                      self._current_node.object_type, name):
            raise SelectError("Item not available in object", str(name),
                              self._current_node.selectors)

        next_node = self._current_node.parent.navigate(
            self._current_node.object_type, name)
        return self.__class__(self._command, current_node=next_node)
Beispiel #6
0
def _normalize_item(object_type: str | None, item: str) -> str | int:
    if object_type in ["group", "widget", "bar"]:
        return str(item)
    elif object_type in ["layout", "window", "screen"]:
        try:
            return int(item)
        except ValueError:
            # A value error could arise because the next selector has been passed
            raise SelectError(
                f"Unexpected index {item}. Is this an object_type?",
                str(object_type),
                [(str(object_type), str(item))],
            )
    else:
        return item
Beispiel #7
0
    def call(self, name: str) -> "CommandClient":
        """Resolve the call into the command graph

        Parameters
        ----------
        name : str
            The name of the command to resolve in the command graph.

        Returns
        -------
        CommandClient
            The client with the command resolved.
        """
        if not isinstance(self._current_node, CommandGraphNode):
            raise SelectError("Invalid navigation", "",
                              self._current_node.selectors)

        command_call = self._current_node.call("commands")
        commands = self._command.execute(command_call, (), {})
        if name not in commands:
            raise SelectError("Not valid child or command", name,
                              self._current_node.selectors)
        next_node = self._current_node.call(name)
        return self.__class__(self._command, current_node=next_node)
Beispiel #8
0
    def call(self, name: str, *args, **kwargs) -> Any:
        """Resolve and invoke the call into the command graph

        Parameters
        ----------
        name: str
            The name of the command to resolve in the command graph.
        args:
            The arguments to pass into the call invocation.
        kwargs:
            The keyword arguments to pass into the call invocation.

        Returns
        -------
        The output returned from the function call.
        """
        if name not in self.commands:
            raise SelectError("Not valid child or command", name, self._current_node.selectors)

        call = self._current_node.call(name)

        return self._command.execute(call, args, kwargs)
Beispiel #9
0
    def __call__(self, *args, **kwargs) -> Any:
        """When the client has navigated to a command, execute it"""
        if not isinstance(self._current_node, CommandGraphCall):
            raise SelectError("Invalid call", "", self._current_node.selectors)

        return self._command.execute(self._current_node, args, kwargs)
Beispiel #10
0
 def parent(self) -> CommandClient:
     """Get the parent of the current client"""
     if self._current_node.parent is None:
         raise SelectError("", "", self._current_node.selectors)
     return self.__class__(self._command,
                           current_node=self._current_node.parent)
Beispiel #11
0
 def children(self) -> List[str]:
     """Get the children of the current location in the command graph"""
     if isinstance(self._current_node, CommandGraphCall):
         raise SelectError("No children of command graph call", "",
                           self._current_node.selectors)
     return self._current_node.children