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 use zero-values
instead.

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 fix the types on things in
set_font(), aka we shouldn't allow fontsize: str, but we have to because of
UNSPECIFIED.

Signed-off-by: Tycho Andersen <tycho@tycho.pizza>
  • Loading branch information
tych0 committed Apr 28, 2024
1 parent 3e7284b commit ba0d945
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 9 deletions.
112 changes: 112 additions & 0 deletions libqtile/scripts/migrations/rename_unspecified.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# 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.
from itertools import filterfalse

import libcst as cst
import libcst.matchers as m

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


class RenameUnspecifiedTransformer(MigrationTransformer):
@m.leave(m.Call(func=m.Attribute(attr=m.Name("set_font"))))
def update_unspecified_arg(self, original_node, updated_node) -> cst.Call:
args = original_node.args

def is_interesting_arg(arg):
return m.matches(arg.value, m.Name("UNSPECIFIED"))

args = list(filterfalse(is_interesting_arg, original_node.args))

if len(args) == len(original_node.args):
return original_node

return updated_node.with_changes(args=args)

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
self.lint(original_node, "'UNSPECIFIED' can be dropped")
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 = "Drops `UNSPECIFIED` argument"

HELP = """
The UNSPECIFIED object was removed in favor of using the zero values (or
None) to leave behavior unspecified. That is:
font=UNSPECIFIED -> font=None
fontsize=UNSPECIFIED -> fontsize=0
fontshadow=UNSPECIFIED -> fontshadow=""
"""

AFTER_VERSION = "0.25.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, fontsize=12)
""",
"""
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(fontsize=12)
""",
)
]

visitor = RenameUnspecifiedTransformer


add_migration(RenameUnspecified)
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: int = 0,
fontshadow: ColorType = "",
):
"""
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 != 0:
self.fontsize = fontsize
if fontshadow is not UNSPECIFIED:
if fontshadow != "":
self.fontshadow = fontshadow
self.bar.draw()

Expand Down

0 comments on commit ba0d945

Please sign in to comment.