diff --git a/libqtile/scripts/migrate.py b/libqtile/scripts/migrate.py index 85f8312d08..e1b4541459 100644 --- a/libqtile/scripts/migrate.py +++ b/libqtile/scripts/migrate.py @@ -33,13 +33,9 @@ if TYPE_CHECKING: from collections.abc import Iterator -BACKUP_SUFFIX = ".migrate.bak" - - -try: import libcst -except ImportError: - pass + +BACKUP_SUFFIX = ".migrate.bak" class AbortMigration(Exception): @@ -50,6 +46,21 @@ class SkipFile(Exception): pass +def needs_libcst(func): + def _wrapper(*args, **kwargs): + if "libcst" not in sys.modules: + try: + global libcst + libcst = __import__("libcst", globals(), locals()) + except ImportError: + print("libcst is needed for 'qtile migrate' commands.") + print("Please install it and try again.") + sys.exit(1) + func(*args, **kwargs) + + return _wrapper + + def version_tuple(value: str) -> tuple[int, ...]: try: val = tuple(int(x) for x in value.split(".")) @@ -72,16 +83,12 @@ class QtileMigrate: without needing to pass them around all the time. """ + @needs_libcst def __call__(self, args: argparse.Namespace) -> None: """ This is called by ArgParse when we run `qtile migrate`. The parsed options are passed as an argument. """ - if "libcst" not in sys.modules: - print("libcst can't be found. Unable to migrate config file.") - print("Please install it and try again.") - sys.exit(1) - self.args = args self.filter_migrations()