10000 Merge pull request #1538 from stonebig/master · winpython/winpython@2b01d20 · GitHub
[go: up one dir, main page]

Skip to content

Commit 2b01d20

Browse files
authored
Merge pull request #1538 from stonebig/master
small simplification
2 parents 58ba1dd + a3ec835 commit 2b01d20

File tree

1 file changed

+59
-67
lines changed

1 file changed

+59
-67
lines changed

winpython/wppm.py

Lines changed: 59 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@
2222
os.environ["HOME"] = os.environ["USERPROFILE"]
2323

2424
class Package:
25-
"standardize a Package from filename or pip list"
26-
def __init__(self, fname, suggested_summary=None):
25+
"""Standardize a Package from filename or pip list."""
26+
def __init__(self, fname: str, suggested_summary: str = None):
2727
self.fname = fname
2828
self.description = piptree.sum_up(suggested_summary) if suggested_summary else ""
2929
self.name, self.version = None, None
@@ -40,33 +40,32 @@ def __str__(self):
4040

4141

4242
class Distribution:
43-
def __init__(self, target=None, verbose=False):
44-
# if no target path given, take the current python interpreter one
45-
self.target = target or os.path.dirname(sys.executable)
43+
"""Handles operations on a WinPython distribution."""
44+
def __init__(self, target: str = None, verbose: bool = False):
45+
self.target = target or os.path.dirname(sys.executable) # Default target more explicit
4646
self.verbose = verbose
4747
self.pip = None
48-
self.to_be_removed = [] # list of directories to be removed later
49-
self.version, self.architecture = utils.get_python_infos(target)
50-
# name of the exe (python.exe or pypy3.exe)
48+
self.to_be_removed = []
49+
self.version, self.architecture = utils.get_python_infos(self.target)
5150
self.short_exe = Path(utils.get_python_executable(self.target)).name
5251

5352
def clean_up(self):
54-
"""Remove directories which couldn't be removed when building"""
53+
"""Remove directories that were marked for removal."""
5554
for path in self.to_be_removed:
5655
try:
5756
shutil.rmtree(path, onexc=utils.onerror)
58-
except WindowsError:
59-
print(f"Directory {path} could not be removed", file=sys.stderr)
57+
except OSError as e:
58+
print(f"Error: Could not remove directory {path}: {e}", file=sys.stderr)
6059

61-
def remove_directory(self, path):
62-
"""Try to remove directory -- on WindowsError, remove it later"""
60+
def remove_directory(self, path: str):
61+
"""Try to remove a directory, add to removal list on failure."""
6362
try:
6463
shutil.rmtree(path)
65-
except WindowsError:
64+
except OSError:
6665
self.to_be_removed.append(path)
6766

68-
def copy_files(self, package, targetdir, srcdir, dstdir, create_bat_files=False):
69-
"""Add copy task"""
67+
def copy_files(self, package: Package, targetdir: str, srcdir: str, dstdir: str, create_bat_files: bool = False):
68+
"""Copy files from srcdir to dstdir within the target distribution."""
7069
srcdir = str(Path(targetdir) / srcdir)
7170
if not Path(srcdir).is_dir():
7271
return
@@ -112,8 +111,8 @@ def create_file(self, package, name, dstdir, contents):
112111
fd.write(contents)
113112
package.files.append(dst)
114113

115-
def get_installed_packages(self, update=False):
116-
"""Return installed packages"""
114+
def get_installed_packages(self, update: bool = False) -> list[Package]:
115+
"""Return installed packages."""
117116

118117
# Include package installed via pip (not via WPPM)
119118
wppm = []
@@ -133,14 +132,14 @@ def get_installed_packages(self, update=False):
133132
]
134133
return sorted(wppm, key=lambda tup: tup.name.lower())
135134

136-
def find_package(self, name):
137-
"""Find installed package"""
135+
def find_package(self, name: str) -> Package | None:
136+
"""Find installed package by name."""
138137
for pack in self.get_installed_packages():
139138
if utils.normalize(pack.name) == utils.normalize(name):
140139
return pack
141140

142-
def patch_all_shebang(self, to_movable=True, max_exe_size=999999, targetdir=""):
143-
"""make all python launchers relatives"""
141+
def patch_all_shebang(self, to_movable: bool = True, max_exe_size: int = 999999, targetdir: str = ""):
142+
"""Make all python launchers relative."""
144143
import glob
145144

146145
for ffname in glob.glob(r"%s\Scripts\*.exe" % self.target):
@@ -150,10 +149,9 @@ def patch_all_shebang(self, to_movable=True, max_exe_size=999999, targetdir=""):
150149
for ffname in glob.glob(r"%s\Scripts\*.py" % self.target):
151150
utils.patch_shebang_line_py(ffname, to_movable=to_movable, targetdir=targetdir)
152151

153-
def install(self, package, install_options=None):
154-
"""Install package in distribution"""
155-
# wheel addition
156-
if package.fname.endswith((".whl", ".tar.gz", ".zip")):
152+
def install(self, package: Package, install_options: list[str] = None): # Type hint install_options
153+
"""Install package in distribution."""
154+
if package.fname.endswith((".whl", ".tar.gz", ".zip")): # Check extension with tuple
157155
self.install_bdist_direct(package, install_options=install_options)
158156
self.handle_specific_packages(package)
159157
# minimal post-install actions
@@ -206,9 +204,7 @@ def patch_standard_packages(self, package_name="", to_movable=True):
206204
# sheb_mov2 = tried way, but doesn't work for pip (at least)
207205
sheb_fix = " executable = get_executable()"
208206
sheb_mov1 = " executable = os.path.join(os.path.basename(get_executable()))"
209-
sheb_mov2 = (
210-
" executable = os.path.join('..',os.path.basename(get_executable()))"
211-
)
207+
sheb_mov2 = " executable = os.path.join('..',os.path.basename(get_executable()))"
212208

213209
# Adpating to PyPy
214210
the_place = site_package_place + r"pip\_vendor\distlib\scripts.py"
@@ -240,30 +236,25 @@ def patch_standard_packages(self, package_name="", to_movable=True):
240236
else:
241237
self.create_pybat(package_name.lower())
242238

243-
def create_pybat(
244-
self,
245-
names="",
246-
contents=r"""@echo off
239+
240+
def create_pybat(self, names="", contents=r"""@echo off
247241
..\python "%~dpn0" %*""",
248242
):
249243
"""Create launcher batch script when missing"""
250244

251-
scriptpy = str(Path(self.target) / "Scripts") # std Scripts of python
252-
253-
# PyPy has no initial Scipts directory
254-
if not Path(scriptpy).is_dir():
255-
os.mkdir(scriptpy)
245+
scriptpy = Path(self.target) / "Scripts" # std Scripts of python
246+
os.makedirs(scriptpy, exist_ok=True)
256247
if not list(names) == names:
257248
my_list = [f for f in os.listdir(scriptpy) if "." not in f and f.startswith(names)]
258249
else:
259250
my_list = names
260251
for name in my_list:
261-
if Path(scriptpy).is_dir() and (Path(scriptpy) / name).is_file():
252+
if scriptpy.is_dir() and (scriptpy / name).is_file():
262253
if (
263-
not (Path(scriptpy) / (name + ".exe")).is_file()
264-
and not (Path(scriptpy) / (name + ".bat")).is_file()
254+
not (scriptpy / (name + ".exe")).is_file()
255+
and not (scriptpy / (name + ".bat")).is_file()
265256
):
266-
with open(Path(scriptpy) / (name + ".bat"), "w") as fd:
257+
with open(scriptpy / (name + ".bat"), "w") as fd:
267258
fd.write(contents)
268259
fd.close()
269260

@@ -272,9 +263,7 @@ def handle_specific_packages(self, package):
272263
if package.name.lower() in ("pyqt4", "pyqt5", "pyside2"):
273264
# Qt configuration file (where to find Qt)
274265
name = "qt.conf"
275-
contents = """[Paths]
276-
Prefix = .
277-
Binaries = ."""
266+
contents = """[Paths]\nPrefix = .\nBinaries = ."""
278267
self.create_file(package, name, str(Path("Lib") / "site-packages" / package.name), contents)
279268
self.create_file(package, name, ".", contents.replace(".", f"./Lib/site-packages/{package.name}"))
280269
# pyuic script
@@ -296,13 +285,14 @@ def handle_specific_packages(self, package):
296285
for dirname in ("Loader", "port_v2", "port_v3"):
297286
self.create_file(package, "__init__.py", str(Path(uic_path) / dirname), "")
298287

299-
def _print(self, package, action):
300-
"""Print package-related action text (e.g. 'Installing')"""
288+
289+
def _print(self, package: Package, action: str):
290+
"""Print package-related action text."""
301291
text = f"{action} {package.name} {package.version}"
302292
if self.verbose:
303293
utils.print_box(text)
304294
else:
305-
print(" " + text + "...", end=" ")
295+
print(f" {text}...", end=" ")
306296

307297
def _print_done(self):
308298
"""Print OK at the end of a process"""
@@ -318,6 +308,7 @@ def uninstall(self, package):
318308
subprocess.call([this_exec, "-m", "pip", "uninstall", package.name, "-y"], cwd=self.target)
319309
self._print_done()
320310

311+
321312
def install_bdist_direct(self, package, install_options=None):
322313
"""Install a package directly !"""
323314
self._print(package,f"Installing {package.fname.split('.')[-1]}")
@@ -335,18 +326,22 @@ def install_bdist_direct(self, package, install_options=None):
335326
package = Package(fname)
336327
self._print_done()
337328

338-
def install_script(self, script, install_options=None):
329+
330+
def install_script(self, script: str, install_options: list[str] = None): # Type hint install_options
331+
"""Install a script using pip."""
339332
try:
340333
fname = utils.do_script(
341334
script,
342335
python_exe=utils.get_python_executable(self.target), # PyPy3 !
343336
verbose=self.verbose,
344337
install_options=install_options,
345338
)
346-
except RuntimeError:
339+
except RuntimeError as e: # Catch specific RuntimeError
347340
if not self.verbose:
348341
print("Failed!")
349-
raise
342+
raise # Re-raise if not verbose
343+
else:
344+
print(f"Script installation failed: {e}") # Print error if verbose
350345

351346

352347
def main(test=False):
@@ -415,7 +410,7 @@ def main(test=False):
415410
const=True,
416411
default=False,
417412
help=f"list packages matching the given [optionnal] package expression: wppm -ls, wppm -ls pand",
418-
)
413+
)
419414
parser.add_argument(
420415
"-p",
421416
dest="pipdown",
@@ -473,9 +468,8 @@ def main(test=False):
473468
)
474469
args = parser.parse_args()
475470
targetpython = None
476-
if args.target and not args.target==sys.prefix:
477-
targetpython = args.target if args.target[-4:] == '.exe' else str(Path(args.target) / 'python.exe')
478-
# print(targetpython.resolve() to check)
471+
if args.target and args.target != sys.prefix:
472+
targetpython = args.target if args.target.lower().endswith('.exe') else str(Path(args.target) / 'python.exe')
479473
if args.install and args.uninstall:
480474
raise RuntimeError("Incompatible arguments: --install and --uninstall")
481475
if args.registerWinPython and args.unregisterWinPython:
@@ -492,51 +486,49 @@ def main(test=False):
492486
sys.exit()
493487
elif args.list:
494488
pip = piptree.PipData(targetpython)
495-
todo = [l for l in pip.pip_list(full=True) if bool(re.search(args.fname, l[0])) ]
496-
titles = [['Package', 'Version', 'Summary'],['_' * max(x, 6) for x in utils.columns_width(todo)]]
489+
todo = [l for l in pip.pip_list(full=True) if bool(re.search(args.fname, l[0]))]
490+
titles = [['Package', 'Version', 'Summary'], ['_' * max(x, 6) for x in utils.columns_width(todo)]]
497491
listed = utils.formatted_list(titles + todo, max_width=70)
498492
for p in listed:
499493
print(*p)
500494
sys.exit()
501495
elif args.all:
502496
pip = piptree.PipData(targetpython)
503-
todo = [l for l in pip.pip_list(full=True) if bool(re.search(args.fname, l[0])) ]
497+
todo = [l for l in pip.pip_list(full=True) if bool(re.search(args.fname, l[0]))]
504498
for l in todo:
505499
# print(pip.distro[l[0]])
506500
title = f"** Package: {l[0]} **"
507-
print("\n"+"*"*len(title), f"\n{title}", "\n"+"*"*len(title) )
501+
print("\n" + "*" * len(title), f"\n{title}", "\n" + "*" * len(title))
508502
for key, value in pip.raw[l[0]].items():
509503
rawtext = json.dumps(value, indent=2, ensure_ascii=False)
510504
lines = [l for l in rawtext.split(r"\n") if len(l.strip()) > 2]
511-
if key.lower() != 'description' or args.verbose==True:
505+
if key.lower() != 'description' or args.verbose:
512506
print(f"{key}: ", "\n".join(lines).replace('"', ""))
513-
sys.exit()
507+
sys.exit()
514508
if args.registerWinPython:
515509
print(registerWinPythonHelp)
516510
if utils.is_python_distribution(args.target):
517511
dist = Distribution(args.target)
518512
else:
519-
raise WindowsError(f"Invalid Python distribution {args.target}")
513+
raise OSError(f"Invalid Python distribution {args.target}")
520514
print(f"registering {args.target}")
521515
print("continue ? Y/N")
522516
theAnswer = input()
523517
if theAnswer == "Y":
524518
from winpython import associate
525-
526519
associate.register(dist.target, verbose=args.verbose)
527520
sys.exit()
528521
if args.unregisterWinPython:
529522
print(unregisterWinPythonHelp)
530523
if utils.is_python_distribution(args.target):
531524
dist = Distribution(args.target)
532525
else:
533-
raise WindowsError(f"Invalid Python distribution {args.target}")
526+
raise OSError(f"Invalid Python distribution {args.target}")
534527
print(f"unregistering {args.target}")
535528
print("continue ? Y/N")
536529
theAnswer = input()
537530
if theAnswer == "Y":
538531
from winpython import associate
539-
540532
associate.unregister(dist.target, verbose=args.verbose)
541533
sys.exit()
542534
elif not args.install and not args.uninstall:
@@ -546,7 +538,7 @@ def main(test=False):
546538
parser.print_help()
547539
sys.exit()
548540
else:
549-
raise IOError(f"File not found: {args.fname}")
541+
raise FileNotFoundError(f"File not found: {args.fname}")
550542
if utils.is_python_distribution(args.target):
551543
dist = Distribution(args.target, verbose=True)
552544
try:
@@ -560,7 +552,7 @@ def main(test=False):
560552
except NotImplementedError:
561553
raise RuntimeError("Package is not (yet) supported by WPPM")
562554
else:
563-
raise WindowsError(f"Invalid Python distribution {args.target}")
555+
raise OSError(f"Invalid Python distribution {args.target}")
564556

565557

566558
if __name__ == "__main__":

0 commit comments

Comments
 (0)
0