Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit a3ec835

Browse filesBrowse files
committed
small simplification
1 parent 649907e commit a3ec835
Copy full SHA for a3ec835

File tree

Expand file treeCollapse file tree

1 file changed

+59
-67
lines changed
Filter options
Expand file treeCollapse file tree

1 file changed

+59
-67
lines changed

‎winpython/wppm.py

Copy file name to clipboardExpand all lines: winpython/wppm.py
+59-67Lines 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)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.