Skip to content

Commit

Permalink
widget: drop UNSPECIFIED arg to set_font()
Browse files Browse the repository at this point in the history
It's a little weird to have what is essentially our own version of None as
a default argument for one function. Let's drop it, and just use none the
real None.

Hopefully nobody uses this, since it's the default arg, but I wrote a
migration anyway, mostly to understand how the new migrations work.

The motivation here is that I want to use set_font() as an example of the
type hoisting, since it has interesting types (int, str, ColorType which is
itself a union, etc.).

Signed-off-by: Tycho Andersen <[email protected]>
  • Loading branch information
tych0 committed Mar 22, 2024
1 parent 73024e1 commit 34a95f3
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 18 deletions.
91 changes: 91 additions & 0 deletions libqtile/scripts/migrations/rename_unspecified.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# Copyright (c) 2023, elParaguayo. All rights reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
import libcst as cst

from libqtile.scripts.migrations._base import (
Check,
RenamerTransformer,
_QtileMigrator,
add_migration,
)


class RenameUnspecifiedTransformer(RenamerTransformer):
from_to = ("UNSPECIFIED", "None")

def strip_unspecified_imports(self, original_node, updated_node) -> cst.Import:
new_names = list(filter(lambda n: n.name.value != "UNSPECIFIED", original_node.names))
if len(new_names) == len(original_node.names):
return original_node
if len(new_names) == 0:
return cst.RemoveFromParent()
return updated_node.with_changes(names=new_names)

def leave_Import(self, original_node: cst.Import, updated_node: cst.Import): # noqa: N802
return self.strip_unspecified_imports(original_node, updated_node)

def leave_ImportFrom( # noqa: N802
self, original_node: cst.ImportFrom, updated_node: cst.ImportFrom
):
return self.strip_unspecified_imports(original_node, updated_node)


class RenameUnspecified(_QtileMigrator):
ID = "RenameUnspecified"

SUMMARY = "Changes ``UNSPECIFIED`` argument to ``None``."

HELP = """
The UNSPECIFIED object was removed in favor of using python's None.
"""

AFTER_VERSION = "0.24.0"

TESTS = [
Check(
"""
from libqtile.widget.base import UNSPECIFIED, ORIENTATION_BOTH
from libqtile.widget import TextBox
from libqtile.layout import Tile
tb = TextBox(text="hello")
# just to use ORIENTATION_BOTH and force us to delete only the
# right thing
tb.orientations = ORIENTATION_BOTH
tb.set_font(font=UNSPECIFIED)
""",
"""
from libqtile.widget.base import ORIENTATION_BOTH
from libqtile.widget import TextBox
from libqtile.layout import Tile
tb = TextBox(text="hello")
# just to use ORIENTATION_BOTH and force us to delete only the
# right thing
tb.orientations = ORIENTATION_BOTH
tb.set_font(font=None)
""",
)
]

visitor = RenameUnspecifiedTransformer


add_migration(RenameUnspecified)
18 changes: 9 additions & 9 deletions libqtile/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,7 @@
from pathlib import Path
from random import randint
from shutil import which
from typing import TYPE_CHECKING

if TYPE_CHECKING:
from typing import Any, Callable, Coroutine, TypeVar, Union

ColorType = Union[str, tuple[int, int, int], tuple[int, int, int, float]]
ColorsType = Union[ColorType, list[ColorType]]

T = TypeVar("T")
from typing import TYPE_CHECKING, Union

try:
from dbus_next import AuthError, Message, Variant
Expand All @@ -52,6 +44,14 @@

from libqtile.log_utils import logger

ColorType = Union[str, tuple[int, int, int], tuple[int, int, int, float]]
if TYPE_CHECKING:
from typing import Any, Callable, Coroutine, TypeVar

ColorsType = Union[ColorType, list[ColorType]]

T = TypeVar("T")

dbus_bus_connections = set()

# Create a list to collect references to tasks so they're not garbage collected
Expand Down
20 changes: 11 additions & 9 deletions libqtile/widget/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,14 @@
import copy
import math
import subprocess
from typing import TYPE_CHECKING
from typing import TYPE_CHECKING, Union

from libqtile import bar, configurable, confreader
from libqtile.command import interface
from libqtile.command.base import CommandError, CommandObject, expose_command
from libqtile.lazy import LazyCall
from libqtile.log_utils import logger
from libqtile.utils import create_task
from libqtile.utils import ColorType, create_task

if TYPE_CHECKING:
from typing import Any
Expand Down Expand Up @@ -446,9 +446,6 @@ def remove_mirror(self, widget: _Widget):
del self._old_draw


UNSPECIFIED = bar.Obj("UNSPECIFIED")


class _TextBox(_Widget):
"""
Base class for widgets that are just boxes containing text.
Expand Down Expand Up @@ -717,16 +714,21 @@ def hide_scroll(self):
self.update("")

@expose_command()
def set_font(self, font=UNSPECIFIED, fontsize=UNSPECIFIED, fontshadow=UNSPECIFIED):
def set_font(
self,
font: Union[str, None] = None,
fontsize: Union[int, None] = None,
fontshadow: Union[ColorType, None] = None,
):
"""
Change the font used by this widget. If font is None, the current
font is used.
"""
if font is not UNSPECIFIED:
if font is not None:
self.font = font
if fontsize is not UNSPECIFIED:
if fontsize is not None:
self.fontsize = fontsize
if fontshadow is not UNSPECIFIED:
if fontshadow is not None:
self.fontshadow = fontshadow
self.bar.draw()

Expand Down

0 comments on commit 34a95f3

Please sign in to comment.