--- a/PipxInterface/Pipx.py Wed Jun 26 18:40:48 2024 +0200 +++ b/PipxInterface/Pipx.py Thu Jun 27 15:42:50 2024 +0200 @@ -10,7 +10,8 @@ import contextlib import json import os -import sys +import pathlib +##import sys import sysconfig from PyQt6.QtCore import QObject, QProcess @@ -111,7 +112,7 @@ return pipx - def runProcess(self, args): + def runPipxProcess(self, args): """ Public method to execute pipx with the given arguments. @@ -124,7 +125,7 @@ ioEncoding = Preferences.getSystem("IOEncoding") process = QProcess() - process.start(sys.executable, ["-m", "pipx"] + args) + process.start(self.__getPipxExecutable(), args) procStarted = process.waitForStarted() if procStarted: finished = process.waitForFinished(30000) @@ -150,6 +151,20 @@ return False, self.tr("pipx could not be started.") + def __metadataDecoderHook(self, jsonDict): + """ + Private method to allow the JSON decoding of Path objects of a spec metadata + file as created by 'pipx list --json'. + + @param jsonDict JSON dictionary to be decoded + @type dict + @return decoded Path object or the dictionary unaltered + @rtype dict or pathlib.Path + """ + if jsonDict.get("__type__") == "Path" and "__Path__" in jsonDict: + return pathlib.Path(jsonDict["__Path__"]) + return jsonDict + ############################################################################ ## Command methods ############################################################################ @@ -163,11 +178,11 @@ """ packages = [] - ok, output = self.runProcess(["list", "--json"]) + ok, output = self.runPipxProcess(["list", "--json"]) if ok: if output: with contextlib.suppress(json.JSONDecodeError): - data = json.loads(output) + data = json.loads(output, object_hook=self.__metadataDecoderHook) for venvName in data["venvs"]: metadata = data["venvs"][venvName]["metadata"] package = { @@ -177,8 +192,7 @@ "python": metadata["python_version"], } for appPath in metadata["main_package"]["app_paths"]: - path = appPath["__Path__"] - package["apps"].append((os.path.basename(path), path)) + package["apps"].append((appPath.name, str(appPath))) packages.append(package) return packages @@ -265,7 +279,7 @@ args.append("--force") if systemSitePackages: args.append("--system-site-packages") - args += specFile + args.append(specFile) dia = PipxExecDialog(self.tr("Install All Packages")) res = dia.startProcess(self.__getPipxExecutable(), args) if res: @@ -281,7 +295,7 @@ of failure @rtype tuple of (bool, str) """ - ok, output = self.runProcess(["list", "--json"]) + ok, output = self.runPipxProcess(["list", "--json"]) if ok: try: with open(specFile, "w") as f: