Skip to content

handpicked suggestions from Mistral AI #1544

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 28 additions & 40 deletions make.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,13 @@ def build_installer_7zip(script_template_path: Path, output_script_path: Path, r
("PORTABLE_DIR=", f"PORTABLE_DIR={PORTABLE_DIRECTORY}& rem "),
("SEVENZIP_EXE=", f"SEVENZIP_EXE={find_7zip_executable()}& rem "),
] + [(f"{a}=", f"{a}={b}& rem ") for a, b in replacements]

utils.replace_in_file(script_template_path, data_to_replace, output_script_path)

try:
# Execute the generated 7-Zip script, with stdout=sys.stderr to see 7zip compressing
command = f'"{output_script_path}"'
print(f"Executing 7-Zip script: {command}")
subprocess.run(command, shell=True, check=True, stderr=sys.stderr, stdout=sys.stderr)
print(f'Executing 7-Zip script: "{output_script_path}"')
subprocess.run(f'"{output_script_path}"', shell=True, check=True, stderr=sys.stderr, stdout=sys.stderr)
except subprocess.CalledProcessError as e:
print(f"Error executing 7-Zip script: {e}", file=sys.stderr)

Expand All @@ -76,11 +75,9 @@ def copy_items(source_directories: list[Path], target_directory: Path, verbose:

def parse_list_argument(argument_value: str | list[str], separator=" ") -> list[str]:
"""Parse a separated list argument into a list of strings."""
if argument_value is None:
if not argument_value:
return []
if isinstance(argument_value, str):
return argument_value.split(separator)
return list(argument_value)
return argument_value.split(separator) if isinstance(argument_value, str) else list(argument_value)

class WinPythonDistributionBuilder:
"""Builds a WinPython distribution."""
Expand Down Expand Up @@ -163,20 +160,17 @@ def _get_installed_tools_markdown(self) -> str:

def get_tool_path(relative_path):
path = self.winpython_directory / relative_path if self.winpython_directory else None
return path if path and (path.is_file() or path.is_dir()) else None
return path if path and path.exists() else None

if nodejs_path := get_tool_path(self.NODEJS_RELATIVE_PATH):
node_version = utils.get_nodejs_version(nodejs_path)
npm_version = utils.get_npmjs_version(nodejs_path)
installed_tools += [("Nodejs", node_version), ("npmjs", npm_version)]
installed_tools.append(("Nodejs", utils.get_nodejs_version(nodejs_path)))
installed_tools.append(("npmjs", utils.get_npmjs_version(nodejs_path)))

if pandoc_executable := get_tool_path("t/pandoc.exe"):
pandoc_version = utils.get_pandoc_version(str(pandoc_executable.parent))
installed_tools.append(("Pandoc", pandoc_version))
if pandoc_exe := get_tool_path("t/pandoc.exe"):
installed_tools.append(("Pandoc", utils.get_pandoc_version(str(pandoc_exe.parent))))

if vscode_executable := get_tool_path("t/VSCode/Code.exe"):
vscode_version = utils.getFileProperties(str(vscode_executable))["FileVersion"]
installed_tools.append(("VSCode", vscode_version))
if vscode_exe := get_tool_path("t/VSCode/Code.exe"):
installed_tools.append(("VSCode", utils.getFileProperties(str(vscode_exe))["FileVersion"]))

tool_lines = []
for name, version in installed_tools:
Expand All @@ -187,7 +181,7 @@ def get_tool_path(relative_path):

def _get_installed_packages_markdown(self) -> str:
"""Generates Markdown for installed packages section in package index."""
if self.distribution is None:
if not self.distribution:
return "" # Distribution not initialized yet.
self.installed_packages = self.distribution.get_installed_packages(update=True)
package_lines = [
Expand All @@ -204,25 +198,20 @@ def winpython_version_name(self) -> str:
@property
def python_full_version(self) -> str:
"""Retrieves the Python full version string from the distribution."""
if self.distribution is None:
return "0.0.0" # Placeholder before initialization
return utils.get_python_long_version(self.distribution.target)
return utils.get_python_long_version(self.distribution.target) if self.distribution else "0.0.0"

@property
def python_executable_directory(self) -> str:
"""Returns the directory containing the Python executable."""
python_path_directory = self.winpython_directory / self.python_directory_name if self.winpython_directory else None
if python_path_directory and python_path_directory.is_dir():
return str(python_path_directory)
python_path_executable = self.winpython_directory / self.python_name if self.winpython_directory else None
return str(python_path_executable) if python_path_executable else ""
if self.winpython_directory:
python_path_directory = self.winpython_directory / self.python_directory_name
return str(python_path_directory) if python_path_directory.is_dir() else str(self.winpython_directory / self.python_name)
return ""

@property
def architecture_bits(self) -> int:
"""Returns the architecture (32 or 64 bits) of the distribution."""
if self.distribution:
return self.distribution.architecture
return 64
return self.distribution.architecture if self.distribution else 64

def create_installer_7zip(self, installer_type: str = ".exe"):
"""Creates a WinPython installer using 7-Zip: ".exe", ".7z", ".zip")"""
Expand All @@ -241,7 +230,6 @@ def create_installer_7zip(self, installer_type: str = ".exe"):
("RELEASELEVEL", self.release_level),
("INSTALLER_OPTION", installer_type),
]

build_installer_7zip(PORTABLE_DIRECTORY / template_name, self.target_directory / output_name, replacements)

def _print_action(self, text: str):
Expand Down Expand Up @@ -351,9 +339,9 @@ def build(self, rebuild: bool = True, requirements_files_list=None, winpy_dirnam

def rebuild_winpython_package(source_directory: Path, target_directory: Path, architecture: int = 64, verbose: bool = False):
"""Rebuilds the winpython package from source using flit."""
for filename in os.listdir(target_directory):
if filename.startswith("winpython-") and filename.endswith((".exe", ".whl", ".gz")):
os.remove(Path(target_directory) / filename)
for file in target_directory.glob("winpython-*"):
if file.suffix in (".exe", ".whl", ".gz"):
file.unlink()
utils.buildflit_wininst(source_directory, copy_to=target_directory, verbose=verbose)

def make_all(build_number: int, release_level: str, pyver: str, architecture: int, basedir: Path,
Expand Down Expand Up @@ -391,14 +379,14 @@ def make_all(build_number: int, release_level: str, pyver: str, architecture: in
find_links_dirs_list = parse_list_argument(find_links, ",")
requirements_files_list = [Path(f) for f in parse_list_argument(requirements, ",") if f]
find_links_options = [f"--find-links={link}" for link in find_links_dirs_list + [source_dirs]]
build_directory = str(Path(basedir) / ("bu" + flavor))
build_directory = Path(basedir) / ("bu" + flavor)

if rebuild:
utils.print_box(f"Making WinPython {architecture}bits at {Path(basedir) / ('bu' + flavor)}")
os.makedirs(Path(build_directory), exist_ok=True)
os.makedirs(build_directory, exist_ok=True)
# use source_dirs as the directory to re-build Winpython wheel
winpython_source_dir = Path(__file__).resolve().parent
rebuild_winpython_package(winpython_source_dir, source_dirs, architecture, verbose)
rebuild_winpython_package(winpython_source_dir, Path(source_dirs), architecture, verbose)

builder = WinPythonDistributionBuilder(
build_number, release_level, build_directory, wheels_directory=source_dirs,
Expand All @@ -420,11 +408,11 @@ def make_all(build_number: int, release_level: str, pyver: str, architecture: in

builder.build(rebuild=rebuild, requirements_files_list=requirements_files_list, winpy_dirname=winpython_dirname)

if ".zip" in str(create_installer).lower():
if ".zip" in create_installer.lower():
builder.create_installer_7zip(".zip")
if ".7z" in str(create_installer).lower():
if ".7z" in create_installer.lower():
builder.create_installer_7zip(".7z")
if "7zip" in str(create_installer).lower():
if "7zip" in create_installer.lower():
builder.create_installer_7zip(".exe")

if __name__ == "__main__":
Expand Down
36 changes: 15 additions & 21 deletions winpython/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,6 @@ def patch_shebang_line(fname, pad=b" ", to_movable=True, targetdir=""):
"""Remove absolute path to python.exe in shebang lines in binary files, or re-add it."""
target_dir = targetdir if to_movable else os.path.abspath(os.path.join(os.path.dirname(fname), r"..")) + "\\"
executable = sys.executable

shebang_line = re.compile(rb"""(#!.*pythonw?\.exe)"?""") # Python3+
if "pypy3" in sys.executable:
shebang_line = re.compile(rb"""(#!.*pypy3w?\.exe)"?""") # Pypy3+
Expand All @@ -239,12 +238,9 @@ def patch_shebang_line(fname, pad=b" ", to_movable=True, targetdir=""):
def patch_shebang_line_py(fname, to_movable=True, targetdir=""):
"""Changes shebang line in '.py' file to relative or absolue path"""
import fileinput
if to_movable:
exec_path = r'#!.\python.exe'
if 'pypy3' in sys.executable: # PyPy !
exec_path = r'#!.\pypy3.exe'
else:
exec_path = '#!' + sys.executable
exec_path = r'#!.\python.exe' if to_movable else '#!' + sys.executable
if 'pypy3' in sys.executable:
exec_path = r'#!.\pypy3.exe' if to_movable else exec_path
for line in fileinput.input(fname, inplace=True):
if re.match(r'^#\!.*python\.exe$', line) or re.match(r'^#\!.*pypy3\.exe$', line):
print(exec_path)
Expand All @@ -253,18 +249,16 @@ def patch_shebang_line_py(fname, to_movable=True, targetdir=""):

def guess_encoding(csv_file):
"""guess the encoding of the given file"""
# UTF_8_BOM = "\xEF\xBB\xBF"
with open(csv_file, "rb") as f:
data = f.read(5)
if data.startswith(b"\xEF\xBB\xBF"): # UTF-8 with a "BOM" (normally no BOM in utf-8)
return ["utf-8-sig"]
else: # in Windows, guessing utf-8 doesn't work, so we have to try
try:
with open(csv_file, encoding="utf-8") as f:
preview = f.read(222222)
return ["utf-8"]
except:
return [locale.getdefaultlocale()[1], "utf-8"]
try:
with open(csv_file, encoding="utf-8") as f:
preview = f.read(222222)
return ["utf-8"]
except:
return [locale.getdefaultlocale()[1], "utf-8"]

def replace_in_file(filepath: Path, replacements: list[tuple[str, str]], filedest: Path = None, verbose=False):
"""
Expand All @@ -290,9 +284,9 @@ def replace_in_file(filepath: Path, replacements: list[tuple[str, str]], filedes
def patch_sourcefile(fname, in_text, out_text, silent_mode=False):
"""Replace a string in a source file."""
if not silent_mode:
print(f"patching {fname} from {in_text} to {out_text}")
if Path(fname).is_file() and not in_text == out_text:
replace_in_file(Path(fname), [(in_text , out_text)])
print(f"patching {fname} from {in_text} to {out_text}")
if Path(fname).is_file() and in_text != out_text:
replace_in_file(Path(fname), [(in_text, out_text)])

def _create_temp_dir():
"""Create a temporary directory and remove it at exit"""
Expand Down Expand Up @@ -324,7 +318,7 @@ def get_source_package_infos(fname):
def buildflit_wininst(root, python_exe=None, copy_to=None, verbose=False):
"""Build Wheel from Python package located in *root* with flit."""
python_exe = python_exe or sys.executable
cmd = [python_exe, '-m' ,'flit', 'build']
cmd = [python_exe, '-m', 'flit', 'build']
if verbose:
subprocess.call(cmd, cwd=root)
else:
Expand Down Expand Up @@ -362,7 +356,7 @@ def direct_pip_install(fname, python_exe=None, verbose=False, install_options=No
python_exe = python_exe or sys.executable
myroot = str(Path(python_exe).parent)

cmd = [python_exe, "-m", "pip", "install"] + (install_options or []) +[fname]
cmd = [python_exe, "-m", "pip", "install"] + (install_options or []) + [fname]
if not verbose:
process = subprocess.Popen(cmd, cwd=myroot, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = process.communicate()
Expand Down Expand Up @@ -416,7 +410,7 @@ def get_package_metadata(database, name):
db = cp.ConfigParser()
filepath = Path(database) if Path(database).is_absolute() else Path(DATA_PATH) / database
db.read_file(open(str(filepath), encoding=guess_encoding(filepath)[0]))

my_metadata = {
"description": "",
"url": f"https://pypi.org/project/{name}",
Expand Down
35 changes: 14 additions & 21 deletions winpython/wppm.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,12 +144,12 @@ def patch_standard_packages(self, package_name="", to_movable=True):
import filecmp

# 'pywin32' minimal post-install (pywin32_postinstall.py do too much)
if package_name.lower() == "pywin32" or package_name == "":
if package_name.lower() in ("", "pywin32"):
origin = Path(self.target) / "site-packages" / "pywin32_system32"
destin = Path(self.target)
if origin.is_dir():
for name in os.listdir(origin):
here, there = (origin / name), (destin / name)
here, there = origin / name, destin / name
if not there.exists() or not filecmp.cmp(here, there):
shutil.copyfile(here, there)
# 'pip' to do movable launchers (around line 100) !!!!
Expand All @@ -162,7 +162,7 @@ def patch_standard_packages(self, package_name="", to_movable=True):
sheb_mov1 = " executable = os.path.join(os.path.basename(get_executable()))"
sheb_mov2 = " executable = os.path.join('..',os.path.basename(get_executable()))"

the_place = Path(self.target ) / "lib" / "site-packages" / "pip" / "_vendor" / "distlib" / "scripts.py"
the_place = Path(self.target) / "lib" / "site-packages" / "pip" / "_vendor" / "distlib" / "scripts.py"
print(the_place)
if to_movable:
utils.patch_sourcefile(the_place, sheb_fix, sheb_mov1)
Expand All @@ -173,7 +173,7 @@ def patch_standard_packages(self, package_name="", to_movable=True):

# create movable launchers for previous package installations
self.patch_all_shebang(to_movable=to_movable)
if package_name.lower() == "spyder" or package_name == "":
if package_name.lower() in ("", "spyder"):
# spyder don't goes on internet without I ask
utils.patch_sourcefile(
Path(self.target) / "lib" / "site-packages" / "spyder" / "config" /"main.py",
Expand Down Expand Up @@ -202,14 +202,13 @@ def handle_specific_packages(self, package):
"%WINPYDIR%\python.exe" "%WINPYDIR%\Lib\site-packages\package.name\uic\pyuic.py" %1 %2 %3 %4 %5 %6 %7 %8 %9"""
# PyPy adaption: python.exe or pypy3.exe
my_exec = Path(utils.get_python_executable(self.target)).name
tmp_string = tmp_string.replace("python.exe", my_exec)
self.create_file(package, f"pyuic{package.name[-1]}.bat", "Scripts", tmp_string.replace("package.name", package.name))
tmp_string = tmp_string.replace("python.exe", my_exec).replace("package.name", package.name)
self.create_file(package, f"pyuic{package.name[-1]}.bat", "Scripts", tmp_string)
# Adding missing __init__.py files (fixes Issue 8)
uic_path = str(Path("Lib") / "site-packages" / package.name / "uic")
for dirname in ("Loader", "port_v2", "port_v3"):
self.create_file(package, "__init__.py", str(Path(uic_path) / dirname), "")


def _print(self, package: Package, action: str):
"""Print package-related action text."""
text = f"{action} {package.name} {package.version}"
Expand All @@ -232,7 +231,6 @@ def uninstall(self, package):
subprocess.call([this_exec, "-m", "pip", "uninstall", package.name, "-y"], cwd=self.target)
self._print_done()


def install_bdist_direct(self, package, install_options=None):
"""Install a package directly !"""
self._print(package,f"Installing {package.fname.split('.')[-1]}")
Expand All @@ -250,22 +248,17 @@ def install_bdist_direct(self, package, install_options=None):
package = Package(fname)
self._print_done()


def main(test=False):
if test:
sbdir = str(Path(__file__).parents[0].parent.parent.parent / "sandbox")
tmpdir = str(Path(sbdir) / "tobedeleted")

fname = str(Path(sbdir) / "VTK-5.10.0-Qt-4.7.4.win32-py2.7.exe")
print(Package(fname))
sbdir = Path(__file__).parents[0].parent.parent.parent / "sandbox"
tmpdir = sbdir / "tobedeleted"
fname = sbdir / "VTK-5.10.0-Qt-4.7.4.win32-py2.7.exe")
print(Package(str(fname)))
sys.exit()
target = str(
Path(utils.BASE_DIR) / "build" / "winpython-2.7.3" / "python-2.7.3"
)
fname = str(Path(utils.BASE_DIR) / "packages.src" / "docutils-0.9.1.tar.gz")

dist = Distribution(target, verbose=True)
pack = Package(fname)
target = Path(utils.BASE_DIR) / "build" / "winpython-2.7.3" / "python-2.7.3"
fname = Path(utils.BASE_DIR) / "packages.src" / "docutils-0.9.1.tar.gz"
dist = Distribution(str(target), verbose=True)
pack = Package(str(fname))
print(pack.description)
# dist.install(pack)
# dist.uninstall(pack)
Expand Down