diff --git a/Qt5_requirements64.txt b/Qt5_requirements64.txt
deleted file mode 100644
index a72667c1..00000000
--- a/Qt5_requirements64.txt
+++ /dev/null
@@ -1,373 +0,0 @@
-# the essential
-wheel
-pywin32
-
-# compilers
-cython
-pycparser
-cffi
-numba
-maturin
-
-# done in pre-step in mkl
-numpy
-scipy
-numexpr
-##mkl_service
-
-# pytorch eco-system
-Torch
-torchvision
-torchaudio
-botorch
-fastai
-dask_ml
-
-#LLM huggingface
-openai
-transformers[torch]
-accelerate
-
-
-# complementary tools
-mypy
-black
-pep8
-twine
-pytest
-coverage
-hypothesis
-pybind11
-flit
-poetry
-virtualenv
-pympler
-
-sqlite_bro
-baresql
-idlex
-
-# scientific
-matplotlib
-sympy
-
-scikit_learn
-scikit_image
-
-SQLAlchemy
-alembic
-
-#statistic
-statsmodels
-pmdarima
-pymc
-
-# to become skrub
-dirty_cat
-
-pandas
-# pandas-datareader
-xarray
-
-#pdf
-pdfrw
-reportlab
-
-#git
-gitdb
-gitpython
-
-# Jupyter
-jupyter
-# jupyterlab, ipython
-papermill
-ipython_sql
-ipympl
-ipyleaflet
-ipycanvas
-#not popular jupyterlab_rise
-
-jedi
-
-# gui
-seaborn
-altair
-plotnine
-plotly
-bokeh
-datashader
-holoviews
-mpld3
-networkx
-bqplot
-imageio
-imageio_ffmpeg
-hvplot
-wordcloud
-panel
-
-
-# gui geographic
-geopandas
-geopy
-pydeck
-# geoviews has no success
-gdal
-
-#solvers
-pycosat
-ecos
-qpsolvers
-cvxpy
-pulp
-
-# Qt5
-
-# QT
-spyder
-pyzo
-pyqtgraph
-qtconsole
-guiqwt
-PythonQwt
-guidata
-formlayout
-folium
-
-# web
-Flask
-Django
-python_dotenv
-uvicorn
-beautifulsoup4
-regex
-lxml
-html5lib
-requests
-datasette
-yarl
-xmltodict
-pystache
-pysocks
-pyjwt
-mako
-
-# parallelize (and replace celery)
-joblib
-dask[complete]
-dask_image
-cloudpickle
-fastparquet
-
-# write & read QRcode
-python-barcode
-qrcode
-opencv-python
-
-# ports
-pyodbc
-pyserial
-# pywinusb to replace per puysb+libusb-package ?
-pywinusb
-
-#rust packages
-duckdb
-polars
-
-# excel
-xlsxwriter
-openpyxl
-
-# connect to other langages
-julia
-pythonnet
-clrmagic
-
-ptpython
-
-# async
-trio
-trio-asyncio
-
-# large lange models
-llm
-llm_gpt4all
-llm_llama_cpp
-llm_markov
-huggingface_hub
-
-imbalanced-learn
-
-
-fastapi
-
-
-# needs recent wheel for altai5
-#great_expectations
-
-datasette_graphql
-sqlite_utils
-db.py
-aiosqlite
-
-
-# compression
-zstandard
-
-#2023-08-22 fuzz replacements
-rapidfuzz
-
-# dashboards
-streamlit
-dash
-
-#popular 2023-08-23
-greenlet
-Markdown
-docopt
-PyOpenGL
-Sphinx
-sphinx_rtd_theme
-rx
-bottleneck
-pystache
-pypandoc
-scikit-optimize
-fuzzywuzzy
-loky
-astropy
-snuggs
-rasterio
-flask-session
-python-multipart
-filterpy
-requests_ntlm
-
-swifter
-emcee
-zarr
-pyflux
-snakeviz
-nbdime
-simplegeneric
-ipydatagrid
-
-simpy
-supersmoother
-mpl_scatter_density
-ppci
-nltk
-simplejson
-sounddevice
-pygame
-moviepy
-altair-transform
-altair_data_server
-pygad
-xgboost
-xlwings
-cvxopt
-mpmath
-#azure
-azure-identity
-azure-cosmos
-azure-core
-sspyrs
-
-# sql - data
-adodbapi
-
-
-sqlparse
-
-mysql_connector_python
-pg8000
-
-pymongo
-redis
-
-#hdf files
-h5py
-tables
-netCDF4
-# not_popular python-hdf4
-
-cytoolz
-
-blosc
-
-brewer2mpl
-
-PyAudio
-
-lmfit
-
-# less popular cartographic
-mercantile
-pyepsg
-
-#preparing parquet
-python_snappy
-brotli
-
-feather_format
-
-jupyter_sphinx
-
-streamz
-
-vega_datasets
-
-
-gmpy2
-
-mlxtend
-
-quantecon
-
-quart
-
-hypercorn
-
-umap-learn
-flask-sqlalchemy
-
-nlopt
-
-httpie
-flask-Mail
-
-lz4
-
-jupyter_bokeh
-
-pydeck
-
-wasmer
-wasmer_compiler_cranelift
-wasmer_compiler_singlepass
-
-nbval
-
-## onnxruntime
-
-pynndescent
-
-quadprog
-
-orjson
-
-jupyter_packaging
-
-deap
-
-tbats
-
-missingno
-
-# for flask
-waitress
-
-
-
-
diff --git a/README.rst b/README.rst
index 1294e96b..a5f445e9 100644
--- a/README.rst
+++ b/README.rst
@@ -3,7 +3,7 @@ WinPython tools
Copyright @ 2012-2013 Pierre Raybaut
-Copyright @ 2014-2024+ The Winpython development team https://github.com/winpython/
+Copyright @ 2014-2025+ The Winpython development team https://github.com/winpython/
Licensed under the terms of the MIT License
(see winpython/__init__.py for details)
@@ -29,7 +29,7 @@ WinPython build toolchain
Dependencies
------------
-* Python3 >= 3.8
+* Python3 >= 3.9
Requirements
diff --git a/changelogs/WinPythondot-64bit-3.12.10.0.md b/changelogs/WinPythondot-64bit-3.12.10.0.md
new file mode 100644
index 00000000..31153ea2
--- /dev/null
+++ b/changelogs/WinPythondot-64bit-3.12.10.0.md
@@ -0,0 +1,29 @@
+## WinPython 3.12.10.0dot
+
+The following packages are included in WinPython-64bit v3.12.10.0dot .
+
+
+
+### Tools
+
+Name | Version | Description
+-----|---------|------------
+
+
+### Python packages
+
+Name | Version | Description
+-----|---------|------------
+[Python](http://www.python.org/) | 3.12.10 | Python programming language with standard library
+[build](https://pypi.org/project/build) | 1.2.2.post1 | A simple, correct Python build frontend
+[colorama](https://pypi.org/project/colorama) | 0.4.6 | Cross-platform colored terminal text.
+[packaging](https://pypi.org/project/packaging) | 24.2 | Core utilities for Python packages
+[pip](https://pypi.org/project/pip) | 25.0.1 | The PyPA recommended tool for installing Python packages.
+[pyproject-hooks](https://pypi.org/project/pyproject-hooks) | 1.1.0 | Wrappers to call pyproject.toml-based build backend hooks.
+[setuptools](https://pypi.org/project/setuptools) | 75.8.2 | Easily download, build, install, upgrade, and uninstall Python packages
+[sqlite-bro](https://pypi.org/project/sqlite-bro) | 0.13.1 | a graphic SQLite Client in 1 Python file
+[sv-ttk](https://pypi.org/project/sv-ttk) | 2.6.0 | A gorgeous theme for Tkinter, based on Windows 11's UI
+[wheel](https://pypi.org/project/wheel) | 0.45.1 | A built-package format for Python
+[winpython](https://pypi.org/project/winpython) | 15.3.20250425 | WinPython distribution tools, including WPPM
+
+
diff --git a/changelogs/WinPythondot-64bit-3.12.10.0_History.md b/changelogs/WinPythondot-64bit-3.12.10.0_History.md
new file mode 100644
index 00000000..aef40183
--- /dev/null
+++ b/changelogs/WinPythondot-64bit-3.12.10.0_History.md
@@ -0,0 +1,22 @@
+## History of changes for WinPython-64bit 3.12.10.0dot
+
+The following changes were made to WinPython-64bit distribution since version 3.12.9.0dot.
+
+
+
+### Python packages
+
+New packages:
+
+ * [sv-ttk](https://pypi.org/project/sv-ttk) 2.6.0 (A gorgeous theme for Tkinter, based on Windows 11's UI)
+
+Upgraded packages:
+
+ * [pip](https://pypi.org/project/pip) 24.3.1 → 25.0.1 (The PyPA recommended tool for installing Python packages.)
+ * [Python](http://www.python.org/) 3.12.9 → 3.12.10 (Python programming language with standard library)
+ * [setuptools](https://pypi.org/project/setuptools) 75.6.0 → 75.8.2 (Easily download, build, install, upgrade, and uninstall Python packages)
+ * [winpython](https://pypi.org/project/winpython) 13.1.20250215 → 15.3.20250425 (WinPython distribution tools, including WPPM)
+
+
+
+* * *
diff --git a/changelogs/WinPythondot-64bit-3.12.8.1.md b/changelogs/WinPythondot-64bit-3.12.8.1.md
new file mode 100644
index 00000000..4c75f289
--- /dev/null
+++ b/changelogs/WinPythondot-64bit-3.12.8.1.md
@@ -0,0 +1,28 @@
+## WinPython 3.12.8.1dot
+
+The following packages are included in WinPython-64bit v3.12.8.1dot b3.
+
+
+
+### Tools
+
+Name | Version | Description
+-----|---------|------------
+
+
+### Python packages
+
+Name | Version | Description
+-----|---------|------------
+[Python](http://www.python.org/) | 3.12.8 | Python programming language with standard library
+[build](https://pypi.org/project/build) | 1.2.2.post1 | A simple, correct Python build frontend
+[colorama](https://pypi.org/project/colorama) | 0.4.6 | Cross-platform colored terminal text.
+[packaging](https://pypi.org/project/packaging) | 24.2 | Core utilities for Python packages
+[pip](https://pypi.org/project/pip) | 24.3.1 | The PyPA recommended tool for installing Python packages.
+[pyproject_hooks](https://pypi.org/project/pyproject_hooks) | 1.1.0 | Wrappers to call pyproject.toml-based build backend hooks.
+[setuptools](https://pypi.org/project/setuptools) | 75.6.0 | Easily download, build, install, upgrade, and uninstall Python packages
+[sqlite_bro](https://pypi.org/project/sqlite_bro) | 0.13.1 | a graphic SQLite Client in 1 Python file
+[wheel](https://pypi.org/project/wheel) | 0.44.0 | A built-package format for Python
+[winpython](https://pypi.org/project/winpython) | 11.5.20250126 | WinPython distribution tools, including WPPM
+
+
diff --git a/changelogs/WinPythondot-64bit-3.12.8.1_History.md b/changelogs/WinPythondot-64bit-3.12.8.1_History.md
new file mode 100644
index 00000000..4276ca3f
--- /dev/null
+++ b/changelogs/WinPythondot-64bit-3.12.8.1_History.md
@@ -0,0 +1,14 @@
+## History of changes for WinPython-64bit 3.12.8.1dot
+
+The following changes were made to WinPython-64bit distribution since version 3.12.8.0dot.
+
+
+### Python packages
+
+Upgraded packages:
+
+ * [winpython](https://pypi.org/project/winpython) 11.2.20241228 → 11.5.20250126 (WinPython distribution tools, including WPPM)
+
+
+
+* * *
diff --git a/changelogs/WinPythondot-64bit-3.12.9.0.md b/changelogs/WinPythondot-64bit-3.12.9.0.md
new file mode 100644
index 00000000..7d8615bd
--- /dev/null
+++ b/changelogs/WinPythondot-64bit-3.12.9.0.md
@@ -0,0 +1,28 @@
+## WinPython 3.12.9.0dot
+
+The following packages are included in WinPython-64bit v3.12.9.0dot .
+
+
+
+### Tools
+
+Name | Version | Description
+-----|---------|------------
+
+
+### Python packages
+
+Name | Version | Description
+-----|---------|------------
+[Python](http://www.python.org/) | 3.12.9 | Python programming language with standard library
+[build](https://pypi.org/project/build) | 1.2.2.post1 | A simple, correct Python build frontend
+[colorama](https://pypi.org/project/colorama) | 0.4.6 | Cross-platform colored terminal text.
+[packaging](https://pypi.org/project/packaging) | 24.2 | Core utilities for Python packages
+[pip](https://pypi.org/project/pip) | 24.3.1 | The PyPA recommended tool for installing Python packages.
+[pyproject_hooks](https://pypi.org/project/pyproject_hooks) | 1.1.0 | Wrappers to call pyproject.toml-based build backend hooks.
+[setuptools](https://pypi.org/project/setuptools) | 75.6.0 | Easily download, build, install, upgrade, and uninstall Python packages
+[sqlite_bro](https://pypi.org/project/sqlite_bro) | 0.13.1 | a graphic SQLite Client in 1 Python file
+[wheel](https://pypi.org/project/wheel) | 0.45.1 | A built-package format for Python
+[winpython](https://pypi.org/project/winpython) | 13.1.20250215 | WinPython distribution tools, including WPPM
+
+
diff --git a/changelogs/WinPythondot-64bit-3.12.9.0_History.md b/changelogs/WinPythondot-64bit-3.12.9.0_History.md
new file mode 100644
index 00000000..4685d221
--- /dev/null
+++ b/changelogs/WinPythondot-64bit-3.12.9.0_History.md
@@ -0,0 +1,16 @@
+## History of changes for WinPython-64bit 3.12.9.0dot
+
+The following changes were made to WinPython-64bit distribution since version 3.12.8.0dot.
+
+
+### Python packages
+
+Upgraded packages:
+
+ * [Python](http://www.python.org/) 3.12.8 → 3.12.9 (Python programming language with standard library)
+ * [wheel](https://pypi.org/project/wheel) 0.44.0 → 0.45.1 (A built-package format for Python)
+ * [winpython](https://pypi.org/project/winpython) 11.2.20241228 → 13.1.20250215 (WinPython distribution tools, including WPPM)
+
+
+
+* * *
diff --git a/changelogs/WinPythondot-64bit-3.13.1.1.md b/changelogs/WinPythondot-64bit-3.13.1.1.md
new file mode 100644
index 00000000..b711c0ef
--- /dev/null
+++ b/changelogs/WinPythondot-64bit-3.13.1.1.md
@@ -0,0 +1,28 @@
+## WinPython 3.13.1.1dot
+
+The following packages are included in WinPython-64bit v3.13.1.1dot b3.
+
+
+
+### Tools
+
+Name | Version | Description
+-----|---------|------------
+
+
+### Python packages
+
+Name | Version | Description
+-----|---------|------------
+[Python](http://www.python.org/) | 3.13.1 | Python programming language with standard library
+[build](https://pypi.org/project/build) | 1.2.2.post1 | A simple, correct Python build frontend
+[colorama](https://pypi.org/project/colorama) | 0.4.6 | Cross-platform colored terminal text.
+[packaging](https://pypi.org/project/packaging) | 24.2 | Core utilities for Python packages
+[pip](https://pypi.org/project/pip) | 24.3.1 | The PyPA recommended tool for installing Python packages.
+[pyproject_hooks](https://pypi.org/project/pyproject_hooks) | 1.1.0 | Wrappers to call pyproject.toml-based build backend hooks.
+[setuptools](https://pypi.org/project/setuptools) | 75.6.0 | Easily download, build, install, upgrade, and uninstall Python packages
+[sqlite_bro](https://pypi.org/project/sqlite_bro) | 0.13.1 | a graphic SQLite Client in 1 Python file
+[wheel](https://pypi.org/project/wheel) | 0.44.0 | A built-package format for Python
+[winpython](https://pypi.org/project/winpython) | 11.5.20250126 | WinPython distribution tools, including WPPM
+
+
diff --git a/changelogs/WinPythondot-64bit-3.13.1.1_History.md b/changelogs/WinPythondot-64bit-3.13.1.1_History.md
new file mode 100644
index 00000000..32a5992a
--- /dev/null
+++ b/changelogs/WinPythondot-64bit-3.13.1.1_History.md
@@ -0,0 +1,14 @@
+## History of changes for WinPython-64bit 3.13.1.1dot
+
+The following changes were made to WinPython-64bit distribution since version 3.13.1.0dot.
+
+
+### Python packages
+
+Upgraded packages:
+
+ * [winpython](https://pypi.org/project/winpython) 11.2.20241228 → 11.5.20250126 (WinPython distribution tools, including WPPM)
+
+
+
+* * *
diff --git a/changelogs/WinPythondot-64bit-3.13.2.0.md b/changelogs/WinPythondot-64bit-3.13.2.0.md
new file mode 100644
index 00000000..ccbfa9a8
--- /dev/null
+++ b/changelogs/WinPythondot-64bit-3.13.2.0.md
@@ -0,0 +1,28 @@
+## WinPython 3.13.2.0dot
+
+The following packages are included in WinPython-64bit v3.13.2.0dot .
+
+
+
+### Tools
+
+Name | Version | Description
+-----|---------|------------
+
+
+### Python packages
+
+Name | Version | Description
+-----|---------|------------
+[Python](http://www.python.org/) | 3.13.2 | Python programming language with standard library
+[build](https://pypi.org/project/build) | 1.2.2.post1 | A simple, correct Python build frontend
+[colorama](https://pypi.org/project/colorama) | 0.4.6 | Cross-platform colored terminal text.
+[packaging](https://pypi.org/project/packaging) | 24.2 | Core utilities for Python packages
+[pip](https://pypi.org/project/pip) | 24.3.1 | The PyPA recommended tool for installing Python packages.
+[pyproject_hooks](https://pypi.org/project/pyproject_hooks) | 1.1.0 | Wrappers to call pyproject.toml-based build backend hooks.
+[setuptools](https://pypi.org/project/setuptools) | 75.6.0 | Easily download, build, install, upgrade, and uninstall Python packages
+[sqlite_bro](https://pypi.org/project/sqlite_bro) | 0.13.1 | a graphic SQLite Client in 1 Python file
+[wheel](https://pypi.org/project/wheel) | 0.45.1 | A built-package format for Python
+[winpython](https://pypi.org/project/winpython) | 13.1.20250222 | WinPython distribution tools, including WPPM
+
+
diff --git a/changelogs/WinPythondot-64bit-3.13.2.0_History.md b/changelogs/WinPythondot-64bit-3.13.2.0_History.md
new file mode 100644
index 00000000..b4bbb942
--- /dev/null
+++ b/changelogs/WinPythondot-64bit-3.13.2.0_History.md
@@ -0,0 +1,16 @@
+## History of changes for WinPython-64bit 3.13.2.0dot
+
+The following changes were made to WinPython-64bit distribution since version 3.13.1.1dot.
+
+
+### Python packages
+
+Upgraded packages:
+
+ * [Python](http://www.python.org/) 3.13.1 → 3.13.2 (Python programming language with standard library)
+ * [wheel](https://pypi.org/project/wheel) 0.44.0 → 0.45.1 (A built-package format for Python)
+ * [winpython](https://pypi.org/project/winpython) 11.5.20250126 → 13.1.20250222 (WinPython distribution tools, including WPPM)
+
+
+
+* * *
diff --git a/changelogs/WinPythondot-64bit-3.13.3.0.md b/changelogs/WinPythondot-64bit-3.13.3.0.md
new file mode 100644
index 00000000..210bbc6d
--- /dev/null
+++ b/changelogs/WinPythondot-64bit-3.13.3.0.md
@@ -0,0 +1,29 @@
+## WinPython 3.13.3.0dot
+
+The following packages are included in WinPython-64bit v3.13.3.0dot .
+
+
+
+### Tools
+
+Name | Version | Description
+-----|---------|------------
+
+
+### Python packages
+
+Name | Version | Description
+-----|---------|------------
+[Python](http://www.python.org/) | 3.13.3 | Python programming language with standard library
+[build](https://pypi.org/project/build) | 1.2.2.post1 | A simple, correct Python build frontend
+[colorama](https://pypi.org/project/colorama) | 0.4.6 | Cross-platform colored terminal text.
+[packaging](https://pypi.org/project/packaging) | 24.2 | Core utilities for Python packages
+[pip](https://pypi.org/project/pip) | 25.0.1 | The PyPA recommended tool for installing Python packages.
+[pyproject-hooks](https://pypi.org/project/pyproject-hooks) | 1.1.0 | Wrappers to call pyproject.toml-based build backend hooks.
+[setuptools](https://pypi.org/project/setuptools) | 75.8.2 | Easily download, build, install, upgrade, and uninstall Python packages
+[sqlite-bro](https://pypi.org/project/sqlite-bro) | 0.13.1 | a graphic SQLite Client in 1 Python file
+[sv-ttk](https://pypi.org/project/sv-ttk) | 2.6.0 | A gorgeous theme for Tkinter, based on Windows 11's UI
+[wheel](https://pypi.org/project/wheel) | 0.45.1 | A built-package format for Python
+[winpython](https://pypi.org/project/winpython) | 15.3.20250425 | WinPython distribution tools, including WPPM
+
+
diff --git a/changelogs/WinPythondot-64bit-3.13.3.0_History.md b/changelogs/WinPythondot-64bit-3.13.3.0_History.md
new file mode 100644
index 00000000..105c04ff
--- /dev/null
+++ b/changelogs/WinPythondot-64bit-3.13.3.0_History.md
@@ -0,0 +1,22 @@
+## History of changes for WinPython-64bit 3.13.3.0dot
+
+The following changes were made to WinPython-64bit distribution since version 3.13.2.0dot.
+
+
+
+### Python packages
+
+New packages:
+
+ * [sv-ttk](https://pypi.org/project/sv-ttk) 2.6.0 (A gorgeous theme for Tkinter, based on Windows 11's UI)
+
+Upgraded packages:
+
+ * [pip](https://pypi.org/project/pip) 24.3.1 → 25.0.1 (The PyPA recommended tool for installing Python packages.)
+ * [Python](http://www.python.org/) 3.13.2 → 3.13.3 (Python programming language with standard library)
+ * [setuptools](https://pypi.org/project/setuptools) 75.6.0 → 75.8.2 (Easily download, build, install, upgrade, and uninstall Python packages)
+ * [winpython](https://pypi.org/project/winpython) 13.1.20250222 → 15.3.20250425 (WinPython distribution tools, including WPPM)
+
+
+
+* * *
diff --git a/changelogs/WinPythondot-64bit-3.14.0.0.md b/changelogs/WinPythondot-64bit-3.14.0.0.md
new file mode 100644
index 00000000..a97b3e37
--- /dev/null
+++ b/changelogs/WinPythondot-64bit-3.14.0.0.md
@@ -0,0 +1,28 @@
+## WinPython 3.14.0.0dot
+
+The following packages are included in WinPython-64bit v3.14.0.0dot a5b.
+
+
+
+### Tools
+
+Name | Version | Description
+-----|---------|------------
+
+
+### Python packages
+
+Name | Version | Description
+-----|---------|------------
+[Python](http://www.python.org/) | 3.14.0 | Python programming language with standard library
+[build](https://pypi.org/project/build) | 1.2.2.post1 | A simple, correct Python build frontend
+[colorama](https://pypi.org/project/colorama) | 0.4.6 | Cross-platform colored terminal text.
+[packaging](https://pypi.org/project/packaging) | 24.2 | Core utilities for Python packages
+[pip](https://pypi.org/project/pip) | 25.0.1 | The PyPA recommended tool for installing Python packages.
+[pyproject_hooks](https://pypi.org/project/pyproject_hooks) | 1.1.0 | Wrappers to call pyproject.toml-based build backend hooks.
+[setuptools](https://pypi.org/project/setuptools) | 75.6.0 | Easily download, build, install, upgrade, and uninstall Python packages
+[sqlite_bro](https://pypi.org/project/sqlite_bro) | 0.13.1 | a graphic SQLite Client in 1 Python file
+[wheel](https://pypi.org/project/wheel) | 0.45.1 | A built-package format for Python
+[winpython](https://pypi.org/project/winpython) | 13.1.20250222 | WinPython distribution tools, including WPPM
+
+
diff --git a/changelogs/WinPythondot-64bit-3.14.0.0_History.md b/changelogs/WinPythondot-64bit-3.14.0.0_History.md
new file mode 100644
index 00000000..5b7848f1
--- /dev/null
+++ b/changelogs/WinPythondot-64bit-3.14.0.0_History.md
@@ -0,0 +1,8 @@
+## History of changes for WinPython-64bit 3.14.0.0dot
+
+The following changes were made to WinPython-64bit distribution since version 3.14.0.0dot.
+
+
+
+
+* * *
diff --git a/changelogs/WinPythonslim-64bit-3.12.10.0.md b/changelogs/WinPythonslim-64bit-3.12.10.0.md
new file mode 100644
index 00000000..a8084d3f
--- /dev/null
+++ b/changelogs/WinPythonslim-64bit-3.12.10.0.md
@@ -0,0 +1,515 @@
+## WinPython 3.12.10.0slim
+
+The following packages are included in WinPython-64bit v3.12.10.0slim .
+
+
+
+### Tools
+
+Name | Version | Description
+-----|---------|------------
+[Pandoc](https://pandoc.org) | 3.1.9 | an universal document converter
+
+### Python packages
+
+Name | Version | Description
+-----|---------|------------
+[Python](http://www.python.org/) | 3.12.10 | Python programming language with standard library
+[absl-py](https://pypi.org/project/absl-py) | 2.0.0 | Abseil Python Common Libraries, see https://github.com/abseil/abseil-py.
+[adbc-driver-manager](https://pypi.org/project/adbc-driver-manager) | 1.3.0 | A generic entrypoint for ADBC drivers.
+[aiofiles](https://pypi.org/project/aiofiles) | 23.2.1 | File support for asyncio.
+[aiohappyeyeballs](https://pypi.org/project/aiohappyeyeballs) | 2.4.4 | Happy Eyeballs for asyncio
+[aiohttp](https://pypi.org/project/aiohttp) | 3.11.11 | Async http client/server framework (asyncio)
+[aiosignal](https://pypi.org/project/aiosignal) | 1.3.1 | aiosignal: a list of registered asynchronous callbacks
+[aiosqlite](https://pypi.org/project/aiosqlite) | 0.20.0 | asyncio bridge to the standard sqlite3 module
+[alabaster](https://pypi.org/project/alabaster) | 0.7.16 | A light, configurable Sphinx theme
+[alembic](https://pypi.org/project/alembic) | 1.15.1 | A database migration tool for SQLAlchemy.
+[altair](https://pypi.org/project/altair) | 5.5.0 | Vega-Altair: A declarative statistical visualization library for Python.
+[aniso8601](https://pypi.org/project/aniso8601) | 9.0.1 | A library for parsing ISO 8601 strings.
+[annotated-types](https://pypi.org/project/annotated-types) | 0.6.0 | Reusable constraint types to use with typing.Annotated
+[ansicolors](https://pypi.org/project/ansicolors) | 1.1.8 | ANSI colors for Python
+[anthropic](https://pypi.org/project/anthropic) | 0.49.0 | The official Python library for the anthropic API
+[anyio](https://pypi.org/project/anyio) | 4.8.0 | High level compatibility layer for multiple asynchronous event loop implementations
+[anywidget](https://pypi.org/project/anywidget) | 0.9.12 | custom jupyter widgets made easy
+[appdirs](https://pypi.org/project/appdirs) | 1.4.4 | A small Python module for determining appropriate platform-specific dirs, e.g. a "user data dir".
+[argon2-cffi](https://pypi.org/project/argon2-cffi) | 23.1.0 | Argon2 for Python
+[argon2-cffi-bindings](https://pypi.org/project/argon2-cffi-bindings) | 21.2.0 | Low-level CFFI bindings for Argon2
+[array-api-compat](https://pypi.org/project/array-api-compat) | 1.11.1 | A wrapper around NumPy and other array libraries to make them compatible with the Array API standard
+[arrow](https://pypi.org/project/arrow) | 1.3.0 | Better dates & times for Python
+[asgi-csrf](https://pypi.org/project/asgi-csrf) | 0.9 | ASGI middleware for protecting against CSRF attacks
+[asgiref](https://pypi.org/project/asgiref) | 3.8.1 | ASGI specs, helper code, and adapters
+[asn1crypto](https://pypi.org/project/asn1crypto) | 1.5.1 | Fast ASN.1 parser and serializer with definitions for private keys, public keys, certificates, CRL, OCSP, CMS, PKCS#3, PKCS#7, PKCS#8, PKCS#12,
+[asteval](https://pypi.org/project/asteval) | 0.9.31 | Safe, minimalistic evaluator of python expression using ast module
+[astroid](https://pypi.org/project/astroid) | 3.1.0 | An abstract syntax tree for Python with inference support.
+[astropy](https://pypi.org/project/astropy) | 6.1.6 | Astronomy and astrophysics core library
+[astropy-iers-data](https://pypi.org/project/astropy-iers-data) | 0.2024.12.23.0.33.24 | IERS Earth Rotation and Leap Second tables for the astropy core package
+[asttokens](https://pypi.org/project/asttokens) | 2.4.1 | Annotate AST trees with source code positions
+[async-lru](https://pypi.org/project/async-lru) | 2.0.4 | Simple LRU cache for asyncio
+[asyncssh](https://pypi.org/project/asyncssh) | 2.20.0 | AsyncSSH: Asynchronous SSHv2 client and server library
+[atomicwrites](https://pypi.org/project/atomicwrites) | 1.4.0 | Atomic file writes.
+[attrs](https://pypi.org/project/attrs) | 23.2.0 | Classes Without Boilerplate
+[autopep8](https://pypi.org/project/autopep8) | 2.0.4 | A tool that automatically formats Python code to conform to the PEP 8 style guide
+[azure-core](https://pypi.org/project/azure-core) | 1.32.0 | Microsoft Azure Core Library for Python
+[azure-cosmos](https://pypi.org/project/azure-cosmos) | 4.9.0 | Microsoft Azure Cosmos Client Library for Python
+[azure-identity](https://pypi.org/project/azure-identity) | 1.21.0 | Microsoft Azure Identity Library for Python
+[babel](https://pypi.org/project/babel) | 2.16.0 | Internationalization utilities
+[baresql](https://pypi.org/project/baresql) | 1.0.0 | playing SQL directly on Python datas
+[beautifulsoup4](https://pypi.org/project/beautifulsoup4) | 4.12.2 | Screen-scraping library
+[binaryornot](https://pypi.org/project/binaryornot) | 0.4.4 | Ultra-lightweight pure Python package to check if a file is binary or text.
+[black](https://pypi.org/project/black) | 25.1.0 | The uncompromising code formatter.
+[bleach](https://pypi.org/project/bleach) | 6.1.0 | An easy safelist-based HTML-sanitizing tool.
+[blinker](https://pypi.org/project/blinker) | 1.9.0 | Fast, simple object-to-object and broadcast signaling
+[bokeh](https://pypi.org/project/bokeh) | 3.7.2 | Interactive plots and applications in the browser from Python
+[branca](https://pypi.org/project/branca) | 0.8.0 | Generate complex HTML+JS pages with Python
+[brotli](https://pypi.org/project/brotli) | 1.1.0 | Python bindings for the Brotli compression library
+[build](https://pypi.org/project/build) | 1.2.2.post1 | A simple, correct Python build frontend
+[cachetools](https://pypi.org/project/cachetools) | 5.5.2 | Extensible memoizing collections and decorators
+[certifi](https://pypi.org/project/certifi) | 2025.1.31 | Python package for providing Mozilla's CA Bundle.
+[cffi](https://pypi.org/project/cffi) | 1.17.1 | Foreign Function Interface for Python calling C code.
+[chardet](https://pypi.org/project/chardet) | 5.2.0 | Universal encoding detector for Python 3
+[charset-normalizer](https://pypi.org/project/charset-normalizer) | 3.4.0 | The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet.
+[clarabel](https://pypi.org/project/clarabel) | 0.10.0 | Clarabel Conic Interior Point Solver for Rust / Python
+[click](https://pypi.org/project/click) | 8.1.8 | Composable command line interface toolkit
+[click-default-group](https://pypi.org/project/click-default-group) | 1.2.4 | click_default_group
+[cloudpickle](https://pypi.org/project/cloudpickle) | 3.1.1 | Pickler class to extend the standard pickle.Pickler functionality
+[cohere](https://pypi.org/project/cohere) | 5.13.12 |
+[colorama](https://pypi.org/project/colorama) | 0.4.6 | Cross-platform colored terminal text.
+[colorcet](https://pypi.org/project/colorcet) | 3.1.0 | Collection of perceptually uniform colormaps
+[colorlog](https://pypi.org/project/colorlog) | 6.8.2 | Add colours to the output of Python's logging module.
+[comm](https://pypi.org/project/comm) | 0.2.2 | Jupyter Python Comm implementation, for usage in ipykernel, xeus-python etc.
+[contourpy](https://pypi.org/project/contourpy) | 1.3.1 | Python library for calculating contours of 2D quadrilateral grids
+[cookiecutter](https://pypi.org/project/cookiecutter) | 2.6.0 | A command-line utility that creates projects from project templates, e.g.
+[cryptography](https://pypi.org/project/cryptography) | 44.0.0 | cryptography is a package which provides cryptographic recipes and primitives to Python developers.
+[cvxopt](https://pypi.org/project/cvxopt) | 1.3.2 | Convex optimization package
+[cvxpy](https://pypi.org/project/cvxpy) | 1.6.4 | A domain-specific language for modeling convex optimization problems in Python.
+[cycler](https://pypi.org/project/cycler) | 0.12.1 | Composable style cycles
+[cython](https://pypi.org/project/cython) | 3.0.12 | The Cython compiler for writing C extensions in the Python language.
+[cytoolz](https://pypi.org/project/cytoolz) | 1.0.1 | Cython implementation of Toolz: High performance functional utilities
+[dask](https://pypi.org/project/dask) | 2025.3.0 | Parallel PyData with Task Scheduling
+[datasette](https://pypi.org/project/datasette) | 0.65.1 | An open source multi-tool for exploring and publishing data
+[datasette-graphql](https://pypi.org/project/datasette-graphql) | 2.2 | Datasette plugin providing an automatic GraphQL API for your SQLite databases
+[datashader](https://pypi.org/project/datashader) | 0.17.0 | Data visualization toolchain based on aggregating into a grid
+[deap](https://pypi.org/project/deap) | 1.4.2 | Distributed Evolutionary Algorithms in Python
+[debugpy](https://pypi.org/project/debugpy) | 1.8.0 | An implementation of the Debug Adapter Protocol for Python
+[decorator](https://pypi.org/project/decorator) | 5.1.1 | Decorators for Humans
+[defusedxml](https://pypi.org/project/defusedxml) | 0.7.1 | XML bomb protection for Python stdlib modules
+[deprecated](https://pypi.org/project/deprecated) | 1.2.14 | Python @deprecated decorator to deprecate old python classes, functions or methods.
+[diff-match-patch](https://pypi.org/project/diff-match-patch) | 20241021 | Repackaging of Google's Diff Match and Patch libraries.
+[dill](https://pypi.org/project/dill) | 0.3.9 | serialize all of Python
+[distributed](https://pypi.org/project/distributed) | 2025.3.0 | Distributed scheduler for Dask
+[distro](https://pypi.org/project/distro) | 1.8.0 | Distro - an OS platform information API
+[django](https://pypi.org/project/django) | 5.0.7 | A high-level Python web framework that encourages rapid development and clean, pragmatic design.
+[dnspython](https://pypi.org/project/dnspython) | 2.6.1 | DNS toolkit
+[docstring-to-markdown](https://pypi.org/project/docstring-to-markdown) | 0.15 | On the fly conversion of Python docstrings to markdown
+[docutils](https://pypi.org/project/docutils) | 0.21.2 | Docutils -- Python Documentation Utilities
+[duckdb](https://pypi.org/project/duckdb) | 1.2.2 | DuckDB in-process database
+[entrypoints](https://pypi.org/project/entrypoints) | 0.4 | Discover and load entry points from installed packages.
+[et-xmlfile](https://pypi.org/project/et-xmlfile) | 1.1.0 | An implementation of lxml.xmlfile for the standard library
+[eval-type-backport](https://pypi.org/project/eval-type-backport) | 0.2.2 | Like `typing._eval_type`, but lets older Python versions use newer typing features.
+[executing](https://pypi.org/project/executing) | 2.0.1 | Get the currently executing AST node of a frame, and other information
+[faker](https://pypi.org/project/faker) | 36.1.1 | Faker is a Python package that generates fake data for you.
+[fast-histogram](https://pypi.org/project/fast-histogram) | 0.14 | Fast simple 1D and 2D histograms
+[fastapi](https://pypi.org/project/fastapi) | 0.115.8 | FastAPI framework, high performance, easy to learn, fast to code, ready for production
+[fastavro](https://pypi.org/project/fastavro) | 1.10.0 | Fast read/write of AVRO files
+[fastjsonschema](https://pypi.org/project/fastjsonschema) | 2.18.0 | Fastest Python implementation of JSON schema
+[filelock](https://pypi.org/project/filelock) | 3.17.0 | A platform independent file lock.
+[flake8](https://pypi.org/project/flake8) | 7.1.1 | the modular source code checker: pep8 pyflakes and co
+[flask](https://pypi.org/project/flask) | 3.1.0 | A simple framework for building complex web applications.
+[flexcache](https://pypi.org/project/flexcache) | 0.3 | Saves and loads to the cache a transformed versions of a source object.
+[flexparser](https://pypi.org/project/flexparser) | 0.4 | Parsing made fun ... using typing.
+[flit](https://pypi.org/project/flit) | 3.10.1 | A simple packaging tool for simple packages.
+[flit-core](https://pypi.org/project/flit-core) | 3.10.1 | Distribution-building parts of Flit. See flit package for more information
+[folium](https://pypi.org/project/folium) | 0.19.5 | Make beautiful maps with Leaflet.js & Python
+[fonttools](https://pypi.org/project/fonttools) | 4.55.3 | Tools to manipulate font files
+[fqdn](https://pypi.org/project/fqdn) | 1.5.1 | Validates fully-qualified domain names against RFC 1123, so that they are acceptable to modern bowsers
+[frozenlist](https://pypi.org/project/frozenlist) | 1.5.0 | A list-like structure which implements collections.abc.MutableSequence
+[fsspec](https://pypi.org/project/fsspec) | 2024.6.1 | File-system specification
+[fuzzywuzzy](https://pypi.org/project/fuzzywuzzy) | 0.18.0 | Fuzzy string matching in python
+[geographiclib](https://pypi.org/project/geographiclib) | 2.0 | The geodesic routines from GeographicLib
+[geopandas](https://pypi.org/project/geopandas) | 1.0.1 | Geographic pandas extensions
+[geopy](https://pypi.org/project/geopy) | 2.4.1 | Python Geocoding Toolbox
+[gitdb](https://pypi.org/project/gitdb) | 4.0.10 | Git Object Database
+[gitpython](https://pypi.org/project/gitpython) | 3.1.32 | GitPython is a Python library used to interact with Git repositories
+[google-auth](https://pypi.org/project/google-auth) | 2.37.0 | Google Authentication Library
+[graphene](https://pypi.org/project/graphene) | 3.3 | GraphQL Framework for Python
+[graphql-core](https://pypi.org/project/graphql-core) | 3.2.3 | GraphQL implementation for Python, a port of GraphQL.js, the JavaScript reference implementation for GraphQL.
+[graphql-relay](https://pypi.org/project/graphql-relay) | 3.2.0 | Relay library for graphql-core
+[greenlet](https://pypi.org/project/greenlet) | 3.1.1 | Lightweight in-process concurrent programming
+[griffe](https://pypi.org/project/griffe) | 1.5.5 | Signatures for entire Python programs.
+[groq](https://pypi.org/project/groq) | 0.13.1 | The official Python library for the groq API
+[guidata](https://pypi.org/project/guidata) | 3.7.1 | Automatic GUI generation for easy dataset editing and display
+[h11](https://pypi.org/project/h11) | 0.14.0 | A pure-Python, bring-your-own-I/O implementation of HTTP/1.1
+[h2](https://pypi.org/project/h2) | 4.1.0 | HTTP/2 State-Machine based protocol implementation
+[h5py](https://pypi.org/project/h5py) | 3.12.1 | Read and write HDF5 files from Python
+[hatchling](https://pypi.org/project/hatchling) | 1.27.0 | Modern, extensible Python build backend
+[holoviews](https://pypi.org/project/holoviews) | 1.20.2 | A high-level plotting API for the PyData ecosystem built on HoloViews.
+[hpack](https://pypi.org/project/hpack) | 4.1.0 | Pure-Python HPACK header encoding
+[html5lib](https://pypi.org/project/html5lib) | 1.1 | HTML parser based on the WHATWG HTML specification
+[httpcore](https://pypi.org/project/httpcore) | 1.0.5 | A minimal low-level HTTP client.
+[httpie](https://pypi.org/project/httpie) | 3.2.4 | HTTPie: modern, user-friendly command-line HTTP client for the API era.
+[httpx](https://pypi.org/project/httpx) | 0.27.2 | The next generation HTTP client.
+[httpx-sse](https://pypi.org/project/httpx-sse) | 0.4.0 | Consume Server-Sent Event (SSE) messages with HTTPX.
+[huggingface-hub](https://pypi.org/project/huggingface-hub) | 0.29.3 | Client library to download and publish models, datasets and other repos on the huggingface.co hub
+[hupper](https://pypi.org/project/hupper) | 1.12 | Integrated process monitor for developing and reloading daemons.
+[hvplot](https://pypi.org/project/hvplot) | 0.11.2 | A high-level plotting API for the PyData ecosystem built on HoloViews.
+[hypercorn](https://pypi.org/project/hypercorn) | 0.17.3 | A ASGI Server based on Hyper libraries and inspired by Gunicorn
+[hyperframe](https://pypi.org/project/hyperframe) | 6.1.0 | Pure-Python HTTP/2 framing
+[hypothesis](https://pypi.org/project/hypothesis) | 6.130.4 | A library for property-based testing
+[id](https://pypi.org/project/id) | 1.5.0 | A tool for generating OIDC identities
+[idna](https://pypi.org/project/idna) | 3.10 | Internationalized Domain Names in Applications (IDNA)
+[imageio](https://pypi.org/project/imageio) | 2.37.0 | Library for reading and writing a wide range of image, video, scientific, and volumetric data formats.
+[imagesize](https://pypi.org/project/imagesize) | 1.4.1 | Getting image size from png/jpeg/jpeg2000/gif file
+[imbalanced-learn](https://pypi.org/project/imbalanced-learn) | 0.13.0 | Toolbox for imbalanced dataset in machine learning
+[importlib-metadata](https://pypi.org/project/importlib-metadata) | 8.6.1 | Read metadata from Python packages
+[inflection](https://pypi.org/project/inflection) | 0.5.1 | A port of Ruby on Rails inflector to Python
+[iniconfig](https://pypi.org/project/iniconfig) | 2.0.0 | brain-dead simple config-ini parsing
+[intervaltree](https://pypi.org/project/intervaltree) | 3.0.2 | Editable interval tree data structure for Python 2 and 3
+[ipycanvas](https://pypi.org/project/ipycanvas) | 0.13.3 | Interactive widgets library exposing the browser's Canvas API
+[ipykernel](https://pypi.org/project/ipykernel) | 6.29.5 | IPython Kernel for Jupyter
+[ipyleaflet](https://pypi.org/project/ipyleaflet) | 0.19.2 | A Jupyter widget for dynamic Leaflet maps
+[ipympl](https://pypi.org/project/ipympl) | 0.9.7 | Matplotlib Jupyter Extension
+[ipython](https://pypi.org/project/ipython) | 8.34.0 | IPython: Productive Interactive Computing
+[ipython-genutils](https://pypi.org/project/ipython-genutils) | 0.2.0 | Vestigial utilities from IPython
+[ipython-sql](https://pypi.org/project/ipython-sql) | 0.5.0 | RDBMS access via IPython
+[ipywidgets](https://pypi.org/project/ipywidgets) | 8.1.6 | Jupyter interactive widgets
+[isoduration](https://pypi.org/project/isoduration) | 20.11.0 | Operations with ISO 8601 durations
+[isort](https://pypi.org/project/isort) | 5.13.2 | A Python utility / library to sort Python imports.
+[itsdangerous](https://pypi.org/project/itsdangerous) | 2.2.0 | Safely pass data to untrusted environments and back.
+[janus](https://pypi.org/project/janus) | 2.0.0 | Mixed sync-async queue to interoperate between asyncio tasks and classic threads
+[jaraco-classes](https://pypi.org/project/jaraco-classes) | 3.4.0 | Utility functions for Python class constructs
+[jaraco-context](https://pypi.org/project/jaraco-context) | 6.0.1 | Useful decorators and context managers
+[jaraco-functools](https://pypi.org/project/jaraco-functools) | 4.1.0 | Functools like those found in stdlib
+[jedi](https://pypi.org/project/jedi) | 0.19.2 | An autocompletion tool for Python that can be used for text editors.
+[jellyfish](https://pypi.org/project/jellyfish) | 1.1.3 | Approximate and phonetic matching of strings.
+[jinja2](https://pypi.org/project/jinja2) | 3.1.2 | A very fast and expressive template engine.
+[jiter](https://pypi.org/project/jiter) | 0.8.2 | Fast iterable JSON parser.
+[joblib](https://pypi.org/project/joblib) | 1.4.2 | Lightweight pipelining with Python functions
+[json5](https://pypi.org/project/json5) | 0.9.14 | A Python implementation of the JSON5 data format.
+[jsonpatch](https://pypi.org/project/jsonpatch) | 1.33 | Apply JSON-Patches (RFC 6902)
+[jsonpath-python](https://pypi.org/project/jsonpath-python) | 1.0.6 | A more powerful JSONPath implementation in modern python
+[jsonpointer](https://pypi.org/project/jsonpointer) | 2.4 | Identify specific nodes in a JSON document (RFC 6901)
+[jsonschema](https://pypi.org/project/jsonschema) | 4.19.2 | An implementation of JSON Schema validation for Python
+[jsonschema-specifications](https://pypi.org/project/jsonschema-specifications) | 2023.12.1 | The JSON Schema meta-schemas and vocabularies, exposed as a Registry
+[julia](https://pypi.org/project/julia) | 0.6.2 | Julia/Python bridge with IPython support.
+[jupyter](https://pypi.org/project/jupyter) | 1.1.1 | Jupyter metapackage. Install all the Jupyter components in one go.
+[jupyter-bokeh](https://pypi.org/project/jupyter-bokeh) | 4.0.5 | A Jupyter extension for rendering Bokeh content.
+[jupyter-client](https://pypi.org/project/jupyter-client) | 8.6.3 | Jupyter protocol implementation and client libraries
+[jupyter-console](https://pypi.org/project/jupyter-console) | 6.6.3 | Jupyter terminal console
+[jupyter-core](https://pypi.org/project/jupyter-core) | 5.7.2 | Jupyter core package. A base package on which Jupyter projects rely.
+[jupyter-events](https://pypi.org/project/jupyter-events) | 0.12.0 | Jupyter Event System library
+[jupyter-leaflet](https://pypi.org/project/jupyter-leaflet) | 0.19.2 | ipyleaflet extensions for JupyterLab and Jupyter Notebook
+[jupyter-lsp](https://pypi.org/project/jupyter-lsp) | 2.2.5 | Multi-Language Server WebSocket proxy for Jupyter Notebook/Lab server
+[jupyter-server](https://pypi.org/project/jupyter-server) | 2.14.2 | The backend—i.e. core services, APIs, and REST endpoints—to Jupyter web applications.
+[jupyter-server-terminals](https://pypi.org/project/jupyter-server-terminals) | 0.5.3 | A Jupyter Server Extension Providing Terminals.
+[jupyterlab](https://pypi.org/project/jupyterlab) | 4.4.1 | JupyterLab computational environment
+[jupyterlab-pygments](https://pypi.org/project/jupyterlab-pygments) | 0.3.0 | Pygments theme using JupyterLab CSS variables
+[jupyterlab-server](https://pypi.org/project/jupyterlab-server) | 2.27.3 | A set of server components for JupyterLab and JupyterLab like applications.
+[jupyterlab-widgets](https://pypi.org/project/jupyterlab-widgets) | 3.0.14 | Jupyter interactive widgets for JupyterLab
+[keras](https://pypi.org/project/keras) | 3.9.2 | Multi-backend Keras
+[keyring](https://pypi.org/project/keyring) | 25.6.0 | Store and access your passwords safely.
+[kiwisolver](https://pypi.org/project/kiwisolver) | 1.4.8 | A fast implementation of the Cassowary constraint solver
+[langchain](https://pypi.org/project/langchain) | 0.3.23 | Building applications with LLMs through composability
+[langchain-core](https://pypi.org/project/langchain-core) | 0.3.51 | Building applications with LLMs through composability
+[langchain-text-splitters](https://pypi.org/project/langchain-text-splitters) | 0.3.8 | LangChain text splitting utilities
+[langsmith](https://pypi.org/project/langsmith) | 0.3.24 | Client library to connect to the LangSmith LLM Tracing and Evaluation Platform.
+[lazy-loader](https://pypi.org/project/lazy-loader) | 0.4 | Makes it easy to load subpackages and functions on demand.
+[linkify-it-py](https://pypi.org/project/linkify-it-py) | 2.0.2 | Links recognition library with FULL unicode support.
+[llvmlite](https://pypi.org/project/llvmlite) | 0.44.0 | lightweight wrapper around basic LLVM functionality
+[lmfit](https://pypi.org/project/lmfit) | 1.3.1 | Least-Squares Minimization with Bounds and Constraints
+[locket](https://pypi.org/project/locket) | 1.0.0 | File-based locks for Python on Linux and Windows
+[logfire-api](https://pypi.org/project/logfire-api) | 3.5.3 | Shim for the Logfire SDK which does nothing unless Logfire is installed
+[lxml](https://pypi.org/project/lxml) | 5.3.0 | Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API.
+[mako](https://pypi.org/project/mako) | 1.3.5 | A super-fast templating language that borrows the best ideas from the existing templating languages.
+[markdown](https://pypi.org/project/markdown) | 3.7 | Python implementation of John Gruber's Markdown.
+[markdown-it-py](https://pypi.org/project/markdown-it-py) | 2.2.0 | Python port of markdown-it. Markdown parsing, done right!
+[markupsafe](https://pypi.org/project/markupsafe) | 3.0.2 | Safely add untrusted strings to HTML/XML markup.
+[matplotlib](https://pypi.org/project/matplotlib) | 3.10.1 | Python plotting package
+[matplotlib-inline](https://pypi.org/project/matplotlib-inline) | 0.1.7 | Inline Matplotlib backend for Jupyter
+[maturin](https://pypi.org/project/maturin) | 1.8.1 | Build and publish crates with pyo3, cffi and uniffi bindings as well as rust binaries as python packages
+[mccabe](https://pypi.org/project/mccabe) | 0.7.0 | McCabe checker, plugin for flake8
+[mdit-py-plugins](https://pypi.org/project/mdit-py-plugins) | 0.3.5 | Collection of plugins for markdown-it-py
+[mdurl](https://pypi.org/project/mdurl) | 0.1.2 | Markdown URL utilities
+[mercantile](https://pypi.org/project/mercantile) | 1.2.1 | Web mercator XYZ tile utilities
+[mergedeep](https://pypi.org/project/mergedeep) | 1.3.4 | A deep merge function for 🐍.
+[missingno](https://pypi.org/project/missingno) | 0.5.1 | Missing data visualization module for Python.
+[mistralai](https://pypi.org/project/mistralai) | 1.2.5 | Python Client SDK for the Mistral AI API.
+[mistune](https://pypi.org/project/mistune) | 2.0.5 | A sane Markdown parser with useful plugins and renderers
+[mizani](https://pypi.org/project/mizani) | 0.11.4 | Scales for Python
+[ml-dtypes](https://pypi.org/project/ml-dtypes) | 0.5.0 |
+[mlxtend](https://pypi.org/project/mlxtend) | 0.23.3 | Machine Learning Library Extensions
+[more-itertools](https://pypi.org/project/more-itertools) | 10.2.0 | More routines for operating on iterables, beyond itertools
+[mpl-scatter-density](https://pypi.org/project/mpl-scatter-density) | 0.7 | Matplotlib helpers to make density scatter plots
+[mpld3](https://pypi.org/project/mpld3) | 0.5.8 | D3 Viewer for Matplotlib
+[mpmath](https://pypi.org/project/mpmath) | 1.3.0 | Python library for arbitrary-precision floating-point arithmetic
+[msal](https://pypi.org/project/msal) | 1.30.0 | The Microsoft Authentication Library (MSAL) for Python library enables your app to access the Microsoft Cloud by supporting authentication of us
+[msal-extensions](https://pypi.org/project/msal-extensions) | 1.2.0 | Microsoft Authentication Library extensions (MSAL EX) provides a persistence API that can save your data on disk, encrypted on Windows, macOS an
+[msgpack](https://pypi.org/project/msgpack) | 1.1.0 | MessagePack serializer
+[multidict](https://pypi.org/project/multidict) | 6.1.0 | multidict implementation
+[multipledispatch](https://pypi.org/project/multipledispatch) | 1.0.0 | Multiple dispatch
+[mypy](https://pypi.org/project/mypy) | 1.15.0 | Optional static typing for Python
+[mypy-extensions](https://pypi.org/project/mypy-extensions) | 1.0.0 | Type system extensions for programs checked with the mypy type checker.
+[mysql-connector-python](https://pypi.org/project/mysql-connector-python) | 9.2.0 | A self-contained Python driver for communicating with MySQL servers, using an API that is compliant with the Python Database API Specification v
+[namex](https://pypi.org/project/namex) | 0.0.8 | A simple utility to separate the implementation of your Python package and its public API surface.
+[narwhals](https://pypi.org/project/narwhals) | 1.30.0 | Extremely lightweight compatibility layer between dataframe libraries
+[nbclient](https://pypi.org/project/nbclient) | 0.10.0 | A client library for executing notebooks. Formerly nbconvert's ExecutePreprocessor.
+[nbconvert](https://pypi.org/project/nbconvert) | 7.16.1 | Converting Jupyter Notebooks (.ipynb files) to other formats. Output formats include asciidoc, html, latex, markdown, pdf, py, rst, script.
+[nbformat](https://pypi.org/project/nbformat) | 5.10.4 | The Jupyter Notebook format
+[nest-asyncio](https://pypi.org/project/nest-asyncio) | 1.6.0 | Patch asyncio to allow nested event loops
+[networkx](https://pypi.org/project/networkx) | 3.4.2 | Python package for creating and manipulating graphs and networks
+[nh3](https://pypi.org/project/nh3) | 0.2.18 | Python bindings to the ammonia HTML sanitization library.
+[nltk](https://pypi.org/project/nltk) | 3.9.1 | Natural Language Toolkit
+[notebook](https://pypi.org/project/notebook) | 7.4.0 | Jupyter Notebook - A web-based notebook environment for interactive computing
+[notebook-shim](https://pypi.org/project/notebook-shim) | 0.2.4 | A shim layer for notebook traits and config
+[numba](https://pypi.org/project/numba) | 0.61.2 | compiling Python code using LLVM
+[numpy](https://pypi.org/project/numpy) | 2.2.4 | Fundamental package for array computing in Python
+[numpydoc](https://pypi.org/project/numpydoc) | 1.6.0 | Sphinx extension to support docstrings in Numpy format
+[openai](https://pypi.org/project/openai) | 1.72.0 | The official Python library for the openai API
+[opencv-python](https://pypi.org/project/opencv-python) | 4.11.0.86 | Wrapper package for OpenCV python bindings.
+[openpyxl](https://pypi.org/project/openpyxl) | 3.1.2 | A Python library to read/write Excel 2010 xlsx/xlsm files
+[optree](https://pypi.org/project/optree) | 0.14.0 | Optimized PyTree Utilities.
+[optuna](https://pypi.org/project/optuna) | 3.6.1 | A hyperparameter optimization framework
+[orjson](https://pypi.org/project/orjson) | 3.10.12 | Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy
+[osqp](https://pypi.org/project/osqp) | 0.6.7.post3 | OSQP: The Operator Splitting QP Solver
+[outcome](https://pypi.org/project/outcome) | 1.3.0.post0 | Capture the outcome of Python function calls.
+[overrides](https://pypi.org/project/overrides) | 7.7.0 | A decorator to automatically detect mismatch when overriding a method.
+[packaging](https://pypi.org/project/packaging) | 24.2 | Core utilities for Python packages
+[pandas](https://pypi.org/project/pandas) | 2.2.3 | Powerful data structures for data analysis, time series, and statistics
+[pandocfilters](https://pypi.org/project/pandocfilters) | 1.5.0 | Utilities for writing pandoc filters in python
+[panel](https://pypi.org/project/panel) | 1.6.2 | The powerful data exploration & web app framework for Python.
+[papermill](https://pypi.org/project/papermill) | 2.6.0 | Parameterize and run Jupyter and nteract Notebooks
+[param](https://pypi.org/project/param) | 2.2.0 | Make your Python code clearer and more reliable by declaring Parameters.
+[parso](https://pypi.org/project/parso) | 0.8.4 | A Python Parser
+[partd](https://pypi.org/project/partd) | 1.4.0 | Appendable key-value storage
+[pathspec](https://pypi.org/project/pathspec) | 0.11.0 | Utility library for gitignore style pattern matching of file paths.
+[patsy](https://pypi.org/project/patsy) | 0.5.6 | A Python package for describing statistical models and for building design matrices.
+[pep8](https://pypi.org/project/pep8) | 1.7.1 | Python style guide checker
+[pexpect](https://pypi.org/project/pexpect) | 4.8.0 | Pexpect allows easy control of interactive console applications.
+[pg8000](https://pypi.org/project/pg8000) | 1.23.0 | PostgreSQL interface library
+[pickleshare](https://pypi.org/project/pickleshare) | 0.7.5 | Tiny 'shelve'-like database with concurrency support
+[pillow](https://pypi.org/project/pillow) | 11.1.0 | Python Imaging Library (Fork)
+[pip](https://pypi.org/project/pip) | 25.0.1 | The PyPA recommended tool for installing Python packages.
+[platformdirs](https://pypi.org/project/platformdirs) | 4.3.6 | A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`.
+[plotly](https://pypi.org/project/plotly) | 6.0.1 | An open-source interactive data visualization library for Python
+[plotnine](https://pypi.org/project/plotnine) | 0.13.6 | A Grammar of Graphics for Python
+[plotpy](https://pypi.org/project/plotpy) | 2.7.2 | Curve and image plotting tools for Python/Qt applications
+[pluggy](https://pypi.org/project/pluggy) | 1.5.0 | plugin and hook calling mechanisms for python
+[ply](https://pypi.org/project/ply) | 3.11 | Python Lex & Yacc
+[polars](https://pypi.org/project/polars) | 1.27.1 | Blazingly fast DataFrame library
+[portalocker](https://pypi.org/project/portalocker) | 2.7.0 | Wraps the portalocker recipe for easy usage
+[prettytable](https://pypi.org/project/prettytable) | 3.3.0 | A simple Python library for easily displaying tabular data in a visually appealing ASCII table format
+[prince](https://pypi.org/project/prince) | 0.15.0 | Factor analysis in Python: PCA, CA, MCA, MFA, FAMD, GPA
+[priority](https://pypi.org/project/priority) | 2.0.0 | A pure-Python implementation of the HTTP/2 priority tree
+[prometheus-client](https://pypi.org/project/prometheus-client) | 0.21.1 | Python client for the Prometheus monitoring system.
+[prompt-toolkit](https://pypi.org/project/prompt-toolkit) | 3.0.50 | Library for building powerful interactive command lines in Python
+[propcache](https://pypi.org/project/propcache) | 0.2.1 | Accelerated property cache
+[protobuf](https://pypi.org/project/protobuf) | 5.27.3 |
+[psutil](https://pypi.org/project/psutil) | 5.9.8 | Cross-platform lib for process and system monitoring in Python.
+[psygnal](https://pypi.org/project/psygnal) | 0.11.1 | Fast python callback/event system modeled after Qt Signals
+[ptpython](https://pypi.org/project/ptpython) | 3.0.29 | Python REPL build on top of prompt_toolkit
+[ptyprocess](https://pypi.org/project/ptyprocess) | 0.7.0 | Run a subprocess in a pseudo terminal
+[pure-eval](https://pypi.org/project/pure-eval) | 0.2.2 | Safely evaluate AST nodes without side effects
+[pyarrow](https://pypi.org/project/pyarrow) | 19.0.1 | Python library for Apache Arrow
+[pyasn1](https://pypi.org/project/pyasn1) | 0.6.1 | Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208)
+[pyasn1-modules](https://pypi.org/project/pyasn1-modules) | 0.4.1 | A collection of ASN.1-based protocols modules
+[pybind11](https://pypi.org/project/pybind11) | 2.13.6 | Seamless operability between C++11 and Python
+[pycodestyle](https://pypi.org/project/pycodestyle) | 2.12.0 | Python style guide checker
+[pycparser](https://pypi.org/project/pycparser) | 2.22 | C parser in Python
+[pyct](https://pypi.org/project/pyct) | 0.5.0 | Python package common tasks for users (e.g. copy examples, fetch data, ...)
+[pydantic](https://pypi.org/project/pydantic) | 2.10.6 | Data validation using Python type hints
+[pydantic-ai](https://pypi.org/project/pydantic-ai) | 0.0.24 | Agent Framework / shim to use Pydantic with LLMs
+[pydantic-ai-slim](https://pypi.org/project/pydantic-ai-slim) | 0.0.24 | Agent Framework / shim to use Pydantic with LLMs, slim package
+[pydantic-core](https://pypi.org/project/pydantic-core) | 2.27.2 | Core functionality for Pydantic validation and serialization
+[pydantic-graph](https://pypi.org/project/pydantic-graph) | 0.0.24 | Graph and state machine library
+[pydeck](https://pypi.org/project/pydeck) | 0.9.1 | Widget for deck.gl maps
+[pydocstyle](https://pypi.org/project/pydocstyle) | 6.3.0 | Python docstring style checker
+[pydub](https://pypi.org/project/pydub) | 0.25.1 | Manipulate audio with an simple and easy high level interface
+[pyerfa](https://pypi.org/project/pyerfa) | 2.0.1.4 | Python bindings for ERFA
+[pyflakes](https://pypi.org/project/pyflakes) | 3.2.0 | passive checker of Python programs
+[pygithub](https://pypi.org/project/pygithub) | 2.6.1 | Use the full Github API v3
+[pygments](https://pypi.org/project/pygments) | 2.19.1 | Pygments is a syntax highlighting package written in Python.
+[pyjwt](https://pypi.org/project/pyjwt) | 2.10.1 | JSON Web Token implementation in Python
+[pylint](https://pypi.org/project/pylint) | 3.1.0 | python code static checker
+[pylint-venv](https://pypi.org/project/pylint-venv) | 3.0.3 | pylint-venv provides a Pylint init-hook to use the same Pylint installation with different virtual environments.
+[pyls-spyder](https://pypi.org/project/pyls-spyder) | 0.4.0 | Spyder extensions for the python-lsp-server
+[pymongo](https://pypi.org/project/pymongo) | 4.10.1 | Python driver for MongoDB
+[pympler](https://pypi.org/project/pympler) | 1.1 | A development tool to measure, monitor and analyze the memory behavior of Python objects.
+[pynacl](https://pypi.org/project/pynacl) | 1.5.0 | Python binding to the Networking and Cryptography (NaCl) library
+[pynndescent](https://pypi.org/project/pynndescent) | 0.5.12 | Nearest Neighbor Descent
+[pyodbc](https://pypi.org/project/pyodbc) | 5.2.0 | DB API module for ODBC
+[pyogrio](https://pypi.org/project/pyogrio) | 0.10.0 | Vectorized spatial vector file format I/O using GDAL/OGR
+[pyomo](https://pypi.org/project/pyomo) | 6.9.1 | Pyomo: Python Optimization Modeling Objects
+[pypandoc](https://pypi.org/project/pypandoc) | 1.15 | Thin wrapper for pandoc.
+[pyparsing](https://pypi.org/project/pyparsing) | 3.2.1 | pyparsing module - Classes and methods to define and execute parsing grammars
+[pypdf](https://pypi.org/project/pypdf) | 5.1.0 | A pure-python PDF library capable of splitting, merging, cropping, and transforming PDF files
+[pyproj](https://pypi.org/project/pyproj) | 3.7.0 | Python interface to PROJ (cartographic projections and coordinate transformations library)
+[pyproject-hooks](https://pypi.org/project/pyproject-hooks) | 1.1.0 | Wrappers to call pyproject.toml-based build backend hooks.
+[pyqt5](https://pypi.org/project/pyqt5) | 5.15.10 | Python bindings for the Qt cross platform application toolkit
+[pyqt5-qt5](https://pypi.org/project/pyqt5-qt5) | 5.15.2 | The subset of a Qt installation needed by PyQt5.
+[pyqt5-sip](https://pypi.org/project/pyqt5-sip) | 12.16.1 | The sip module support for PyQt5
+[pyqtgraph](https://pypi.org/project/pyqtgraph) | 0.13.7 | Scientific Graphics and GUI Library for Python
+[pyqtwebengine](https://pypi.org/project/pyqtwebengine) | 5.15.6 | Python bindings for the Qt WebEngine framework
+[pyqtwebengine-qt5](https://pypi.org/project/pyqtwebengine-qt5) | 5.15.2 | The subset of a Qt installation needed by PyQtWebEngine.
+[pyserial](https://pypi.org/project/pyserial) | 3.5 | Python Serial Port Extension
+[pysocks](https://pypi.org/project/pysocks) | 1.7.1 | A Python SOCKS client module. See https://github.com/Anorov/PySocks for more information.
+[pyspnego](https://pypi.org/project/pyspnego) | 0.11.2 | Windows Negotiate Authentication Client and Server
+[pytest](https://pypi.org/project/pytest) | 8.3.4 | pytest: simple powerful testing with Python
+[python-barcode](https://pypi.org/project/python-barcode) | 0.15.1 | Create standard barcodes with Python. No external modules needed. (optional Pillow support included).
+[python-dateutil](https://pypi.org/project/python-dateutil) | 2.8.2 | Extensions to the standard Python datetime module
+[python-dotenv](https://pypi.org/project/python-dotenv) | 1.0.1 | Read key-value pairs from a .env file and set them as environment variables
+[python-json-logger](https://pypi.org/project/python-json-logger) | 2.0.7 | A python library adding a json log formatter
+[python-lsp-black](https://pypi.org/project/python-lsp-black) | 2.0.0 | Black plugin for the Python LSP Server
+[python-lsp-jsonrpc](https://pypi.org/project/python-lsp-jsonrpc) | 1.1.2 | JSON RPC 2.0 server library
+[python-lsp-server](https://pypi.org/project/python-lsp-server) | 1.12.0 | Python Language Server for the Language Server Protocol
+[python-multipart](https://pypi.org/project/python-multipart) | 0.0.9 | A streaming multipart parser for Python
+[python-slugify](https://pypi.org/project/python-slugify) | 8.0.4 | A Python slugify application that also handles Unicode
+[pythonqwt](https://pypi.org/project/pythonqwt) | 0.14.4 | Qt plotting widgets for Python
+[pytoolconfig](https://pypi.org/project/pytoolconfig) | 1.3.1 | Python tool configuration
+[pytz](https://pypi.org/project/pytz) | 2024.2 | World timezone definitions, modern and historical
+[pyuca](https://pypi.org/project/pyuca) | 1.2 | a Python implementation of the Unicode Collation Algorithm
+[pyusb](https://pypi.org/project/pyusb) | 1.3.1 | Easy USB access for Python
+[pyviz-comms](https://pypi.org/project/pyviz-comms) | 3.0.3 | A JupyterLab extension for rendering HoloViz content.
+[pywavelets](https://pypi.org/project/pywavelets) | 1.8.0 | PyWavelets, wavelet transform module
+[pywin32](https://pypi.org/project/pywin32) | 308 | Python for Window Extensions
+[pywin32-ctypes](https://pypi.org/project/pywin32-ctypes) | 0.2.2 | A (partial) reimplementation of pywin32 using ctypes/cffi
+[pywinpty](https://pypi.org/project/pywinpty) | 2.0.14 | Pseudo terminal support for Windows from Python.
+[pyyaml](https://pypi.org/project/pyyaml) | 6.0.2 | YAML parser and emitter for Python
+[pyzmq](https://pypi.org/project/pyzmq) | 26.2.1 | Python bindings for 0MQ
+[qdarkstyle](https://pypi.org/project/qdarkstyle) | 3.2.3 | The most complete dark/light style sheet for C++/Python and Qt applications
+[qdldl](https://pypi.org/project/qdldl) | 0.1.7.post5 | QDLDL, a free LDL factorization routine.
+[qrcode](https://pypi.org/project/qrcode) | 8.0 | QR Code image generator
+[qstylizer](https://pypi.org/project/qstylizer) | 0.2.2 | Stylesheet Generator for PyQt{4-5}/PySide{1-2}
+[qtawesome](https://pypi.org/project/qtawesome) | 1.4.0 | FontAwesome icons in PyQt and PySide applications
+[qtconsole](https://pypi.org/project/qtconsole) | 5.6.1 | Jupyter Qt console
+[qtpy](https://pypi.org/project/qtpy) | 2.4.1 | Provides an abstraction layer on top of the various Qt bindings (PyQt5/6 and PySide2/6).
+[quantecon](https://pypi.org/project/quantecon) | 0.7.2 | Import the main names to top level.
+[quart](https://pypi.org/project/quart) | 0.20.0 | A Python ASGI web framework with the same API as Flask
+[rapidfuzz](https://pypi.org/project/rapidfuzz) | 3.9.6 | rapid fuzzy string matching
+[readme-renderer](https://pypi.org/project/readme-renderer) | 44.0 | readme_renderer is a library for rendering readme descriptions for Warehouse
+[redis](https://pypi.org/project/redis) | 5.0.8 | Python client for Redis database and key-value store
+[referencing](https://pypi.org/project/referencing) | 0.35.1 | JSON Referencing + Python
+[regex](https://pypi.org/project/regex) | 2024.11.6 | Alternative regular expression module, to replace re.
+[reportlab](https://pypi.org/project/reportlab) | 4.2.5 | The Reportlab Toolkit
+[requests](https://pypi.org/project/requests) | 2.32.3 | Python HTTP for Humans.
+[requests-ntlm](https://pypi.org/project/requests-ntlm) | 1.3.0 | This package allows for HTTP NTLM authentication using the requests library.
+[requests-toolbelt](https://pypi.org/project/requests-toolbelt) | 1.0.0 | A utility belt for advanced users of python-requests
+[rfc3339-validator](https://pypi.org/project/rfc3339-validator) | 0.1.4 | A pure python RFC3339 validator
+[rfc3986](https://pypi.org/project/rfc3986) | 2.0.0 | Validating URI References per RFC 3986
+[rfc3986-validator](https://pypi.org/project/rfc3986-validator) | 0.1.1 | Pure python rfc3986 validator
+[rich](https://pypi.org/project/rich) | 13.9.4 | Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal
+[rope](https://pypi.org/project/rope) | 1.12.0 | a python refactoring library...
+[rpds-py](https://pypi.org/project/rpds-py) | 0.22.3 | Python bindings to Rust's persistent data structures (rpds)
+[rsa](https://pypi.org/project/rsa) | 4.7.2 | Pure-Python RSA implementation
+[rtree](https://pypi.org/project/rtree) | 1.3.0 | R-Tree spatial index for Python GIS
+[rx](https://pypi.org/project/rx) | 3.2.0 | Reactive Extensions (Rx) for Python
+[scikit-image](https://pypi.org/project/scikit-image) | 0.25.2 | Image processing in Python
+[scikit-learn](https://pypi.org/project/scikit-learn) | 1.6.1 | A set of python modules for machine learning and data mining
+[scipy](https://pypi.org/project/scipy) | 1.15.2 | Fundamental algorithms for scientific computing in Python
+[scramp](https://pypi.org/project/scramp) | 1.4.5 | An implementation of the SCRAM protocol.
+[scs](https://pypi.org/project/scs) | 3.2.7.post2 | Splitting conic solver
+[seaborn](https://pypi.org/project/seaborn) | 0.13.2 | Statistical data visualization
+[send2trash](https://pypi.org/project/send2trash) | 1.8.3 | Send file to trash natively under Mac OS X, Windows and Linux
+[setuptools](https://pypi.org/project/setuptools) | 75.8.2 | Easily download, build, install, upgrade, and uninstall Python packages
+[shapely](https://pypi.org/project/shapely) | 2.0.6 | Manipulation and analysis of geometric objects
+[shellingham](https://pypi.org/project/shellingham) | 1.5.4 | Tool to Detect Surrounding Shell
+[simplejson](https://pypi.org/project/simplejson) | 3.19.3 | Simple, fast, extensible JSON encoder/decoder for Python
+[simpy](https://pypi.org/project/simpy) | 4.1.1 | Event discrete, process based simulation for Python.
+[six](https://pypi.org/project/six) | 1.16.0 | Python 2 and 3 compatibility utilities
+[sklearn-compat](https://pypi.org/project/sklearn-compat) | 0.1.3 | Ease support for compatible scikit-learn estimators across versions
+[skrub](https://pypi.org/project/skrub) | 0.5.1 | Prepping tables for machine learning
+[smmap](https://pypi.org/project/smmap) | 5.0.0 | A pure Python implementation of a sliding window memory map manager
+[sniffio](https://pypi.org/project/sniffio) | 1.3.0 | Sniff out which async library your code is running under
+[snowballstemmer](https://pypi.org/project/snowballstemmer) | 2.2.0 | This package provides 29 stemmers for 28 languages generated from Snowball algorithms.
+[sortedcontainers](https://pypi.org/project/sortedcontainers) | 2.4.0 | Sorted Containers -- Sorted List, Sorted Dict, Sorted Set
+[sounddevice](https://pypi.org/project/sounddevice) | 0.5.1 | Play and Record Sound with Python
+[soupsieve](https://pypi.org/project/soupsieve) | 2.6 | A modern CSS selector implementation for Beautiful Soup.
+[sphinx](https://pypi.org/project/sphinx) | 7.3.7 | Python documentation generator
+[sphinx-rtd-theme](https://pypi.org/project/sphinx-rtd-theme) | 3.0.2 | Read the Docs theme for Sphinx
+[sphinxcontrib-applehelp](https://pypi.org/project/sphinxcontrib-applehelp) | 2.0.0 | sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books
+[sphinxcontrib-devhelp](https://pypi.org/project/sphinxcontrib-devhelp) | 2.0.0 | sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp documents
+[sphinxcontrib-htmlhelp](https://pypi.org/project/sphinxcontrib-htmlhelp) | 2.1.0 | sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files
+[sphinxcontrib-jquery](https://pypi.org/project/sphinxcontrib-jquery) | 4.1 | Extension to include jQuery on newer Sphinx releases
+[sphinxcontrib-jsmath](https://pypi.org/project/sphinxcontrib-jsmath) | 1.0.1 | A sphinx extension which renders display math in HTML via JavaScript
+[sphinxcontrib-qthelp](https://pypi.org/project/sphinxcontrib-qthelp) | 2.0.0 | sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp documents
+[sphinxcontrib-serializinghtml](https://pypi.org/project/sphinxcontrib-serializinghtml) | 2.0.0 | sphinxcontrib-serializinghtml is a sphinx extension which outputs "serialized" HTML files (json and pickle)
+[spyder](https://pypi.org/project/spyder) | 6.0.5 | The Scientific Python Development Environment
+[spyder-kernels](https://pypi.org/project/spyder-kernels) | 3.0.3 | Jupyter kernels for Spyder's console
+[sqlalchemy](https://pypi.org/project/sqlalchemy) | 2.0.38 | Database Abstraction Library
+[sqlite-bro](https://pypi.org/project/sqlite-bro) | 0.13.1 | a graphic SQLite Client in 1 Python file
+[sqlite-fts4](https://pypi.org/project/sqlite-fts4) | 1.0.3 | Python functions for working with SQLite FTS4 search
+[sqlite-utils](https://pypi.org/project/sqlite-utils) | 3.38 | CLI tool and Python library for manipulating SQLite databases
+[sqlparse](https://pypi.org/project/sqlparse) | 0.5.3 | A non-validating SQL parser.
+[squarify](https://pypi.org/project/squarify) | 0.4.4 | Pure Python implementation of the squarify treemap layout algorithm
+[sspilib](https://pypi.org/project/sspilib) | 0.2.0 | SSPI API bindings for Python
+[stack-data](https://pypi.org/project/stack-data) | 0.6.3 | Extract data from python stack frames and tracebacks for informative displays
+[starlette](https://pypi.org/project/starlette) | 0.45.3 | The little ASGI library that shines.
+[statsmodels](https://pypi.org/project/statsmodels) | 0.14.4 | Statistical computations and models for Python
+[streamlit](https://pypi.org/project/streamlit) | 1.44.0 | A faster way to build and share data apps
+[superqt](https://pypi.org/project/superqt) | 0.7.1 | Missing widgets and components for PyQt/PySide
+[sv-ttk](https://pypi.org/project/sv-ttk) | 2.6.0 | A gorgeous theme for Tkinter, based on Windows 11's UI
+[sympy](https://pypi.org/project/sympy) | 1.13.3 | Computer algebra system (CAS) in Python
+[tabulate](https://pypi.org/project/tabulate) | 0.9.0 | Pretty-print tabular data
+[tblib](https://pypi.org/project/tblib) | 3.0.0 | Traceback serialization library.
+[tenacity](https://pypi.org/project/tenacity) | 9.0.0 | Retry code until it succeeds
+[termcolor](https://pypi.org/project/termcolor) | 2.5.0 | ANSI color formatting for output in terminal
+[terminado](https://pypi.org/project/terminado) | 0.18.1 | Tornado websocket backend for the Xterm.js Javascript terminal emulator library.
+[text-unidecode](https://pypi.org/project/text-unidecode) | 1.3 | The most basic Text::Unidecode port
+[textdistance](https://pypi.org/project/textdistance) | 4.6.3 | Compute distance between the two texts.
+[thefuzz](https://pypi.org/project/thefuzz) | 0.22.1 | Fuzzy string matching in python
+[threadpoolctl](https://pypi.org/project/threadpoolctl) | 3.5.0 | threadpoolctl
+[three-merge](https://pypi.org/project/three-merge) | 0.1.1 | Simple library for merging two strings with respect to a base one
+[tifffile](https://pypi.org/project/tifffile) | 2025.1.10 | Read and write TIFF files
+[tiktoken](https://pypi.org/project/tiktoken) | 0.8.0 | tiktoken is a fast BPE tokeniser for use with OpenAI's models
+[tinycss2](https://pypi.org/project/tinycss2) | 1.4.0 | A tiny CSS parser
+[tokenizers](https://pypi.org/project/tokenizers) | 0.21.0 |
+[toml](https://pypi.org/project/toml) | 0.10.2 | Python Library for Tom's Obvious, Minimal Language
+[tomli](https://pypi.org/project/tomli) | 2.2.1 | A lil' TOML parser
+[tomli-w](https://pypi.org/project/tomli-w) | 1.2.0 | A lil' TOML writer
+[tomlkit](https://pypi.org/project/tomlkit) | 0.13.2 | Style preserving TOML library
+[toolz](https://pypi.org/project/toolz) | 1.0.0 | List processing tools and functional utilities
+[tornado](https://pypi.org/project/tornado) | 6.4.2 | Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed.
+[tqdm](https://pypi.org/project/tqdm) | 4.66.4 | Fast, Extensible Progress Meter
+[traitlets](https://pypi.org/project/traitlets) | 5.14.1 | Traitlets Python configuration system
+[traittypes](https://pypi.org/project/traittypes) | 0.2.1 | Scipy trait types
+[trio](https://pypi.org/project/trio) | 0.29.0 | A friendly Python library for async concurrency and I/O
+[trove-classifiers](https://pypi.org/project/trove-classifiers) | 2024.10.21.16 | Canonical source for classifiers on PyPI (pypi.org).
+[twine](https://pypi.org/project/twine) | 6.1.0 | Collection of utilities for publishing packages on PyPI
+[typer](https://pypi.org/project/typer) | 0.15.2 | Typer, build great CLIs. Easy to code. Based on Python type hints.
+[types-python-dateutil](https://pypi.org/project/types-python-dateutil) | 2.9.0.20240316 | Typing stubs for python-dateutil
+[types-requests](https://pypi.org/project/types-requests) | 2.32.0.20241016 | Typing stubs for requests
+[typing-extensions](https://pypi.org/project/typing-extensions) | 4.12.2 | Backported and Experimental Type Hints for Python 3.8+
+[typing-inspect](https://pypi.org/project/typing-inspect) | 0.9.0 | Runtime inspection utilities for typing module.
+[tzdata](https://pypi.org/project/tzdata) | 2024.1 | Provider of IANA time zone data
+[tzlocal](https://pypi.org/project/tzlocal) | 5.2 | tzinfo object for the local timezone
+[uc-micro-py](https://pypi.org/project/uc-micro-py) | 1.0.1 | Micro subset of unicode data files for linkify-it-py projects.
+[ujson](https://pypi.org/project/ujson) | 5.10.0 | Ultra fast JSON encoder and decoder for Python
+[umap-learn](https://pypi.org/project/umap-learn) | 0.5.6 | Uniform Manifold Approximation and Projection
+[uncertainties](https://pypi.org/project/uncertainties) | 3.2.2 | calculations with values with uncertainties, error propagation
+[uri-template](https://pypi.org/project/uri-template) | 1.3.0 | RFC 6570 URI Template Processor
+[urllib3](https://pypi.org/project/urllib3) | 2.2.3 | HTTP library with thread-safe connection pooling, file post, and more.
+[uvicorn](https://pypi.org/project/uvicorn) | 0.34.0 | The lightning-fast ASGI server.
+[vega-datasets](https://pypi.org/project/vega-datasets) | 0.9.0 | A Python package for offline access to Vega datasets
+[waitress](https://pypi.org/project/waitress) | 3.0.0 | Waitress WSGI server
+[watchdog](https://pypi.org/project/watchdog) | 6.0.0 | Filesystem events monitoring
+[wcwidth](https://pypi.org/project/wcwidth) | 0.2.13 | Measures the displayed width of unicode strings in a terminal
+[webcolors](https://pypi.org/project/webcolors) | 24.11.1 | A library for working with the color formats defined by HTML and CSS.
+[webencodings](https://pypi.org/project/webencodings) | 0.5.1 | Character encoding aliases for legacy web content
+[websocket-client](https://pypi.org/project/websocket-client) | 1.8.0 | WebSocket client for Python with low level API options
+[werkzeug](https://pypi.org/project/werkzeug) | 3.1.3 | The comprehensive WSGI web application library.
+[whatthepatch](https://pypi.org/project/whatthepatch) | 1.0.7 | A patch parsing and application library.
+[wheel](https://pypi.org/project/wheel) | 0.45.1 | A built-package format for Python
+[widgetsnbextension](https://pypi.org/project/widgetsnbextension) | 4.0.14 | Jupyter interactive widgets for Jupyter Notebook
+[winpython](https://pypi.org/project/winpython) | 15.3.20250425 | WinPython distribution tools, including WPPM
+[wordcloud](https://pypi.org/project/wordcloud) | 1.9.4 | A little word cloud generator
+[wrapt](https://pypi.org/project/wrapt) | 1.16.0 | Module for decorators, wrappers and monkey patching.
+[wsproto](https://pypi.org/project/wsproto) | 1.2.0 | WebSockets state-machine based protocol implementation
+[xarray](https://pypi.org/project/xarray) | 2025.3.0 | N-D labeled arrays and datasets in Python
+[xlsxwriter](https://pypi.org/project/xlsxwriter) | 3.1.9 | A Python module for creating Excel XLSX files.
+[xyzservices](https://pypi.org/project/xyzservices) | 2023.10.1 | Source of XYZ tiles providers
+[yapf](https://pypi.org/project/yapf) | 0.40.1 | A formatter for Python code.
+[yarl](https://pypi.org/project/yarl) | 1.18.3 | Yet another URL library
+[yt-dlp](https://pypi.org/project/yt-dlp) | 2025.2.19 | A feature-rich command-line audio/video downloader
+[zict](https://pypi.org/project/zict) | 3.0.0 | Mutable mapping tools
+[zipp](https://pypi.org/project/zipp) | 3.21.0 | Backport of pathlib-compatible object wrapper for zip files
+[zstandard](https://pypi.org/project/zstandard) | 0.23.0 | Zstandard bindings for Python
+
+
diff --git a/changelogs/WinPythonslim-64bit-3.12.10.0_History.md b/changelogs/WinPythonslim-64bit-3.12.10.0_History.md
new file mode 100644
index 00000000..07147b6d
--- /dev/null
+++ b/changelogs/WinPythonslim-64bit-3.12.10.0_History.md
@@ -0,0 +1,147 @@
+## History of changes for WinPython-64bit 3.12.10.0slim
+
+The following changes were made to WinPython-64bit distribution since version 3.12.9.0slim.
+
+
+
+### Tools
+
+New packages:
+
+ * [Pandoc](https://pandoc.org) 3.1.9 (an universal document converter)
+
+### Python packages
+
+New packages:
+
+ * [asyncssh](https://pypi.org/project/asyncssh) 2.20.0 (AsyncSSH: Asynchronous SSHv2 client and server library)
+ * [deprecated](https://pypi.org/project/deprecated) 1.2.14 (Python @deprecated decorator to deprecate old python classes, functions or methods.)
+ * [flexcache](https://pypi.org/project/flexcache) 0.3 (Saves and loads to the cache a transformed versions of a source object.)
+ * [flexparser](https://pypi.org/project/flexparser) 0.4 (Parsing made fun ... using typing.)
+ * [id](https://pypi.org/project/id) 1.5.0 (A tool for generating OIDC identities)
+ * [pygithub](https://pypi.org/project/pygithub) 2.6.1 (Use the full Github API v3)
+ * [pyuca](https://pypi.org/project/pyuca) 1.2 (a Python implementation of the Unicode Collation Algorithm)
+ * [shellingham](https://pypi.org/project/shellingham) 1.5.4 (Tool to Detect Surrounding Shell)
+ * [skrub](https://pypi.org/project/skrub) 0.5.1 (Prepping tables for machine learning)
+ * [superqt](https://pypi.org/project/superqt) 0.7.1 (Missing widgets and components for PyQt/PySide)
+ * [sv-ttk](https://pypi.org/project/sv-ttk) 2.6.0 (A gorgeous theme for Tkinter, based on Windows 11's UI)
+ * [typer](https://pypi.org/project/typer) 0.15.2 (Typer, build great CLIs. Easy to code. Based on Python type hints.)
+ * [wrapt](https://pypi.org/project/wrapt) 1.16.0 (Module for decorators, wrappers and monkey patching.)
+
+Upgraded packages:
+
+ * [alembic](https://pypi.org/project/alembic) 1.13.1 → 1.15.1 (A database migration tool for SQLAlchemy.)
+ * [anthropic](https://pypi.org/project/anthropic) 0.42.0 → 0.49.0 (The official Python library for the anthropic API)
+ * [anyio](https://pypi.org/project/anyio) 4.7.0 → 4.8.0 (High level compatibility layer for multiple asynchronous event loop implementations)
+ * [array-api-compat](https://pypi.org/project/array-api-compat) 1.10.0 → 1.11.1 (A wrapper around NumPy and other array libraries to make them compatible with the Array API standard)
+ * [azure-core](https://pypi.org/project/azure-core) 1.30.2 → 1.32.0 (Microsoft Azure Core Library for Python)
+ * [azure-cosmos](https://pypi.org/project/azure-cosmos) 4.7.0 → 4.9.0 (Microsoft Azure Cosmos Client Library for Python)
+ * [azure-identity](https://pypi.org/project/azure-identity) 1.16.1 → 1.21.0 (Microsoft Azure Identity Library for Python)
+ * [black](https://pypi.org/project/black) 24.10.0 → 25.1.0 (The uncompromising code formatter.)
+ * [bokeh](https://pypi.org/project/bokeh) 3.6.3 → 3.7.2 (Interactive plots and applications in the browser from Python)
+ * [cachetools](https://pypi.org/project/cachetools) 5.4.0 → 5.5.2 (Extensible memoizing collections and decorators)
+ * [certifi](https://pypi.org/project/certifi) 2024.6.2 → 2025.1.31 (Python package for providing Mozilla's CA Bundle.)
+ * [click](https://pypi.org/project/click) 8.1.7 → 8.1.8 (Composable command line interface toolkit)
+ * [cloudpickle](https://pypi.org/project/cloudpickle) 3.0.0 → 3.1.1 (Pickler class to extend the standard pickle.Pickler functionality)
+ * [cvxpy](https://pypi.org/project/cvxpy) 1.6.0 → 1.6.4 (A domain-specific language for modeling convex optimization problems in Python.)
+ * [cython](https://pypi.org/project/cython) 3.0.11 → 3.0.12 (The Cython compiler for writing C extensions in the Python language.)
+ * [dask](https://pypi.org/project/dask) 2024.12.1 → 2025.3.0 (Parallel PyData with Task Scheduling)
+ * [datasette](https://pypi.org/project/datasette) 0.64.8 → 0.65.1 (An open source multi-tool for exploring and publishing data)
+ * [datashader](https://pypi.org/project/datashader) 0.16.3 → 0.17.0 (Data visualization toolchain based on aggregating into a grid)
+ * [diff-match-patch](https://pypi.org/project/diff-match-patch) 20230430 → 20241021 (Repackaging of Google's Diff Match and Patch libraries.)
+ * [distributed](https://pypi.org/project/distributed) 2024.12.1 → 2025.3.0 (Distributed scheduler for Dask)
+ * [docstring-to-markdown](https://pypi.org/project/docstring-to-markdown) 0.13 → 0.15 (On the fly conversion of Python docstrings to markdown)
+ * [duckdb](https://pypi.org/project/duckdb) 1.2.0 → 1.2.2 (DuckDB in-process database)
+ * [faker](https://pypi.org/project/faker) 33.3.1 → 36.1.1 (Faker is a Python package that generates fake data for you.)
+ * [fastapi](https://pypi.org/project/fastapi) 0.115.6 → 0.115.8 (FastAPI framework, high performance, easy to learn, fast to code, ready for production)
+ * [filelock](https://pypi.org/project/filelock) 3.14.0 → 3.17.0 (A platform independent file lock.)
+ * [folium](https://pypi.org/project/folium) 0.18.0 → 0.19.5 (Make beautiful maps with Leaflet.js & Python)
+ * [holoviews](https://pypi.org/project/holoviews) 1.20.0 → 1.20.2 (A high-level plotting API for the PyData ecosystem built on HoloViews.)
+ * [hpack](https://pypi.org/project/hpack) 4.0.0 → 4.1.0 (Pure-Python HPACK header encoding)
+ * [huggingface-hub](https://pypi.org/project/huggingface-hub) 0.28.1 → 0.29.3 (Client library to download and publish models, datasets and other repos on the huggingface.co hub)
+ * [hypercorn](https://pypi.org/project/hypercorn) 0.16.0 → 0.17.3 (A ASGI Server based on Hyper libraries and inspired by Gunicorn)
+ * [hyperframe](https://pypi.org/project/hyperframe) 6.0.1 → 6.1.0 (Pure-Python HTTP/2 framing)
+ * [hypothesis](https://pypi.org/project/hypothesis) 6.122.3 → 6.130.4 (A library for property-based testing)
+ * [idna](https://pypi.org/project/idna) 3.7 → 3.10 (Internationalized Domain Names in Applications (IDNA))
+ * [imageio](https://pypi.org/project/imageio) 2.33.1 → 2.37.0 (Library for reading and writing a wide range of image, video, scientific, and volumetric data formats.)
+ * [importlib-metadata](https://pypi.org/project/importlib-metadata) 7.1.0 → 8.6.1 (Read metadata from Python packages)
+ * [ipympl](https://pypi.org/project/ipympl) 0.9.6 → 0.9.7 (Matplotlib Jupyter Extension)
+ * [ipython](https://pypi.org/project/ipython) 8.32.0 → 8.34.0 (IPython: Productive Interactive Computing)
+ * [ipywidgets](https://pypi.org/project/ipywidgets) 8.1.5 → 8.1.6 (Jupyter interactive widgets)
+ * [jupyter-client](https://pypi.org/project/jupyter-client) 8.6.2 → 8.6.3 (Jupyter protocol implementation and client libraries)
+ * [jupyter-events](https://pypi.org/project/jupyter-events) 0.10.0 → 0.12.0 (Jupyter Event System library)
+ * [jupyterlab](https://pypi.org/project/jupyterlab) 4.3.5 → 4.4.1 (JupyterLab computational environment)
+ * [jupyterlab-widgets](https://pypi.org/project/jupyterlab-widgets) 3.0.13 → 3.0.14 (Jupyter interactive widgets for JupyterLab)
+ * [keras](https://pypi.org/project/keras) 3.8.0 → 3.9.2 (Multi-backend Keras)
+ * [langchain](https://pypi.org/project/langchain) 0.3.18 → 0.3.23 (Building applications with LLMs through composability)
+ * [langchain-core](https://pypi.org/project/langchain-core) 0.3.34 → 0.3.51 (Building applications with LLMs through composability)
+ * [langchain-text-splitters](https://pypi.org/project/langchain-text-splitters) 0.3.6 → 0.3.8 (LangChain text splitting utilities)
+ * [langsmith](https://pypi.org/project/langsmith) 0.2.11 → 0.3.24 (Client library to connect to the LangSmith LLM Tracing and Evaluation Platform.)
+ * [markdown](https://pypi.org/project/markdown) 3.5.1 → 3.7 (Python implementation of John Gruber's Markdown.)
+ * [matplotlib](https://pypi.org/project/matplotlib) 3.10.0 → 3.10.1 (Python plotting package)
+ * [mypy](https://pypi.org/project/mypy) 1.14.0 → 1.15.0 (Optional static typing for Python)
+ * [mysql-connector-python](https://pypi.org/project/mysql-connector-python) 8.0.21 → 9.2.0 (A self-contained Python driver for communicating with MySQL servers, using an API that is compliant with the Python Database API Specification v)
+ * [narwhals](https://pypi.org/project/narwhals) 1.21.1 → 1.30.0 (Extremely lightweight compatibility layer between dataframe libraries)
+ * [notebook](https://pypi.org/project/notebook) 7.3.1 → 7.4.0 (Jupyter Notebook - A web-based notebook environment for interactive computing)
+ * [numba](https://pypi.org/project/numba) 0.61.0 → 0.61.2 (compiling Python code using LLVM)
+ * [numpy](https://pypi.org/project/numpy) 2.1.3 → 2.2.4 (Fundamental package for array computing in Python)
+ * [openai](https://pypi.org/project/openai) 1.61.1 → 1.72.0 (The official Python library for the openai API)
+ * [opencv-python](https://pypi.org/project/opencv-python) 4.10.0.84 → 4.11.0.86 (Wrapper package for OpenCV python bindings.)
+ * [optree](https://pypi.org/project/optree) 0.13.1 → 0.14.0 (Optimized PyTree Utilities.)
+ * [panel](https://pypi.org/project/panel) 1.6.0 → 1.6.2 (The powerful data exploration & web app framework for Python.)
+ * [param](https://pypi.org/project/param) 2.1.1 → 2.2.0 (Make your Python code clearer and more reliable by declaring Parameters.)
+ * [pip](https://pypi.org/project/pip) 24.3.1 → 25.0.1 (The PyPA recommended tool for installing Python packages.)
+ * [platformdirs](https://pypi.org/project/platformdirs) 4.2.2 → 4.3.6 (A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`.)
+ * [plotly](https://pypi.org/project/plotly) 5.24.1 → 6.0.1 (An open-source interactive data visualization library for Python)
+ * [polars](https://pypi.org/project/polars) 1.22.0 → 1.27.1 (Blazingly fast DataFrame library)
+ * [prometheus-client](https://pypi.org/project/prometheus-client) 0.18.0 → 0.21.1 (Python client for the Prometheus monitoring system.)
+ * [prompt-toolkit](https://pypi.org/project/prompt-toolkit) 3.0.48 → 3.0.50 (Library for building powerful interactive command lines in Python)
+ * [pyarrow](https://pypi.org/project/pyarrow) 19.0.0 → 19.0.1 (Python library for Apache Arrow)
+ * [pyasn1](https://pypi.org/project/pyasn1) 0.4.8 → 0.6.1 (Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208))
+ * [pyasn1-modules](https://pypi.org/project/pyasn1-modules) 0.2.8 → 0.4.1 (A collection of ASN.1-based protocols modules)
+ * [pyjwt](https://pypi.org/project/pyjwt) 2.8.0 → 2.10.1 (JSON Web Token implementation in Python)
+ * [pympler](https://pypi.org/project/pympler) 1.0.1 → 1.1 (A development tool to measure, monitor and analyze the memory behavior of Python objects.)
+ * [pyomo](https://pypi.org/project/pyomo) 6.8.2 → 6.9.1 (Pyomo: Python Optimization Modeling Objects)
+ * [pypandoc](https://pypi.org/project/pypandoc) 1.5 → 1.15 (Thin wrapper for pandoc.)
+ * [pytest](https://pypi.org/project/pytest) 8.2.2 → 8.3.4 (pytest: simple powerful testing with Python)
+ * [Python](http://www.python.org/) 3.12.9 → 3.12.10 (Python programming language with standard library)
+ * [pytz](https://pypi.org/project/pytz) 2024.1 → 2024.2 (World timezone definitions, modern and historical)
+ * [pyzmq](https://pypi.org/project/pyzmq) 26.2.0 → 26.2.1 (Python bindings for 0MQ)
+ * [qtawesome](https://pypi.org/project/qtawesome) 1.3.1 → 1.4.0 (FontAwesome icons in PyQt and PySide applications)
+ * [qtconsole](https://pypi.org/project/qtconsole) 5.5.2 → 5.6.1 (Jupyter Qt console)
+ * [quart](https://pypi.org/project/quart) 0.19.4 → 0.20.0 (A Python ASGI web framework with the same API as Flask)
+ * [rtree](https://pypi.org/project/rtree) 1.1.0 → 1.3.0 (R-Tree spatial index for Python GIS)
+ * [rx](https://pypi.org/project/rx) 3.1.1 → 3.2.0 (Reactive Extensions (Rx) for Python)
+ * [scikit-image](https://pypi.org/project/scikit-image) 0.25.0 → 0.25.2 (Image processing in Python)
+ * [scipy](https://pypi.org/project/scipy) 1.15.1 → 1.15.2 (Fundamental algorithms for scientific computing in Python)
+ * [send2trash](https://pypi.org/project/send2trash) 1.8.2 → 1.8.3 (Send file to trash natively under Mac OS X, Windows and Linux)
+ * [setuptools](https://pypi.org/project/setuptools) 75.6.0 → 75.8.2 (Easily download, build, install, upgrade, and uninstall Python packages)
+ * [simpy](https://pypi.org/project/simpy) 4.0.1 → 4.1.1 (Event discrete, process based simulation for Python.)
+ * [spyder](https://pypi.org/project/spyder) 5.5.6 → 6.0.5 (The Scientific Python Development Environment)
+ * [spyder-kernels](https://pypi.org/project/spyder-kernels) 2.5.2 → 3.0.3 (Jupyter kernels for Spyder's console)
+ * [sqlalchemy](https://pypi.org/project/sqlalchemy) 2.0.35 → 2.0.38 (Database Abstraction Library)
+ * [starlette](https://pypi.org/project/starlette) 0.41.3 → 0.45.3 (The little ASGI library that shines.)
+ * [streamlit](https://pypi.org/project/streamlit) 1.41.1 → 1.44.0 (A faster way to build and share data apps)
+ * [tomli-w](https://pypi.org/project/tomli-w) 1.1.0 → 1.2.0 (A lil' TOML writer)
+ * [trio](https://pypi.org/project/trio) 0.28.0 → 0.29.0 (A friendly Python library for async concurrency and I/O)
+ * [twine](https://pypi.org/project/twine) 6.0.1 → 6.1.0 (Collection of utilities for publishing packages on PyPI)
+ * [widgetsnbextension](https://pypi.org/project/widgetsnbextension) 4.0.13 → 4.0.14 (Jupyter interactive widgets for Jupyter Notebook)
+ * [winpython](https://pypi.org/project/winpython) 13.1.20250222 → 15.3.20250425 (WinPython distribution tools, including WPPM)
+ * [xarray](https://pypi.org/project/xarray) 2025.1.1 → 2025.3.0 (N-D labeled arrays and datasets in Python)
+ * [yt-dlp](https://pypi.org/project/yt-dlp) 2023.7.6 → 2025.2.19 (A feature-rich command-line audio/video downloader)
+
+Removed packages:
+
+ * [bcrypt](https://pypi.org/project/bcrypt) 4.0.1 (Modern password hashing for your software and your servers)
+ * [dask_expr](https://pypi.org/project/dask_expr) 1.1.21 (High Level Expressions for Dask )
+ * [mutagen](https://pypi.org/project/mutagen) 1.47.0 (read and write audio tags for many formats)
+ * [paramiko](https://pypi.org/project/paramiko) 2.8.0 (SSH2 protocol library)
+ * [pint](https://pypi.org/project/pint) 0.23 (Physical quantities module)
+ * [pkginfo](https://pypi.org/project/pkginfo) 1.11.2 (Query metadata from sdists / bdists / installed packages.)
+ * [pycryptodomex](https://pypi.org/project/pycryptodomex) 3.20.0 (Cryptographic library for Python)
+ * [streamz](https://pypi.org/project/streamz) 0.6.3 (Streams)
+ * [websockets](https://pypi.org/project/websockets) 14.2 (An implementation of the WebSocket Protocol (RFC 6455 & 7692))
+
+
+
+* * *
diff --git a/changelogs/WinPythonslim-64bit-3.12.8.1.md b/changelogs/WinPythonslim-64bit-3.12.8.1.md
new file mode 100644
index 00000000..897798ea
--- /dev/null
+++ b/changelogs/WinPythonslim-64bit-3.12.8.1.md
@@ -0,0 +1,522 @@
+## WinPython 3.12.8.1slim
+
+The following packages are included in WinPython-64bit v3.12.8.1slim b3.
+
+
+
+### Tools
+
+Name | Version | Description
+-----|---------|------------
+
+
+### Python packages
+
+Name | Version | Description
+-----|---------|------------
+[Python](http://www.python.org/) | 3.12.8 | Python programming language with standard library
+[absl_py](https://pypi.org/project/absl_py) | 2.0.0 | Abseil Python Common Libraries, see https://github.com/abseil/abseil-py.
+[adbc_driver_manager](https://pypi.org/project/adbc_driver_manager) | 1.3.0 | A generic entrypoint for ADBC drivers.
+[adodbapi](https://pypi.org/project/adodbapi) | 2.6.1.3 | A pure Python package implementing PEP 249 DB-API using Microsoft ADO.
+[aiofiles](https://pypi.org/project/aiofiles) | 23.2.1 | File support for asyncio.
+[aiohappyeyeballs](https://pypi.org/project/aiohappyeyeballs) | 2.4.4 | Happy Eyeballs for asyncio
+[aiohttp](https://pypi.org/project/aiohttp) | 3.11.11 | Async http client/server framework (asyncio)
+[aiosignal](https://pypi.org/project/aiosignal) | 1.3.1 | aiosignal: a list of registered asynchronous callbacks
+[aiosqlite](https://pypi.org/project/aiosqlite) | 0.20.0 | asyncio bridge to the standard sqlite3 module
+[alabaster](https://pypi.org/project/alabaster) | 0.7.16 | A light, configurable Sphinx theme
+[alembic](https://pypi.org/project/alembic) | 1.13.1 | A database migration tool for SQLAlchemy.
+[altair](https://pypi.org/project/altair) | 5.5.0 | Vega-Altair: A declarative statistical visualization library for Python.
+[aniso8601](https://pypi.org/project/aniso8601) | 9.0.1 | A library for parsing ISO 8601 strings.
+[annotated_types](https://pypi.org/project/annotated_types) | 0.6.0 | Reusable constraint types to use with typing.Annotated
+[ansicolors](https://pypi.org/project/ansicolors) | 1.1.8 | ANSI colors for Python
+[anthropic](https://pypi.org/project/anthropic) | 0.42.0 | The official Python library for the anthropic API
+[anyio](https://pypi.org/project/anyio) | 4.7.0 | High level compatibility layer for multiple asynchronous event loop implementations
+[anywidget](https://pypi.org/project/anywidget) | 0.9.12 | custom jupyter widgets made easy
+[appdirs](https://pypi.org/project/appdirs) | 1.4.4 | A small Python module for determining appropriate platform-specific dirs, e.g. a "user data dir".
+[argon2_cffi](https://pypi.org/project/argon2_cffi) | 23.1.0 | Argon2 for Python
+[argon2_cffi_bindings](https://pypi.org/project/argon2_cffi_bindings) | 21.2.0 | Low-level CFFI bindings for Argon2
+[array_api_compat](https://pypi.org/project/array_api_compat) | 1.10.0 | A wrapper around NumPy and other array libraries to make them compatible with the Array API standard
+[arrow](https://pypi.org/project/arrow) | 1.3.0 | Better dates & times for Python
+[asgi_csrf](https://pypi.org/project/asgi_csrf) | 0.9 | ASGI middleware for protecting against CSRF attacks
+[asgiref](https://pypi.org/project/asgiref) | 3.8.1 | ASGI specs, helper code, and adapters
+[asn1crypto](https://pypi.org/project/asn1crypto) | 1.5.1 | Fast ASN.1 parser and serializer with definitions for private keys, public keys, certificates, CRL, OCSP, CMS, PKCS#3, PKCS#7, PKCS#8, PKCS#12,
+[asteval](https://pypi.org/project/asteval) | 0.9.31 | Safe, minimalistic evaluator of python expression using ast module
+[astroid](https://pypi.org/project/astroid) | 3.1.0 | An abstract syntax tree for Python with inference support.
+[astropy](https://pypi.org/project/astropy) | 6.1.6 | Astronomy and astrophysics core library
+[astropy_iers_data](https://pypi.org/project/astropy_iers_data) | 0.2024.12.23.0.33.24 | IERS Earth Rotation and Leap Second tables for the astropy core package
+[asttokens](https://pypi.org/project/asttokens) | 2.4.1 | Annotate AST trees with source code positions
+[async_lru](https://pypi.org/project/async_lru) | 2.0.4 | Simple LRU cache for asyncio
+[atomicwrites](https://pypi.org/project/atomicwrites) | 1.4.0 | Atomic file writes.
+[attrs](https://pypi.org/project/attrs) | 23.2.0 | Classes Without Boilerplate
+[autopep8](https://pypi.org/project/autopep8) | 2.0.4 | A tool that automatically formats Python code to conform to the PEP 8 style guide
+[azure_core](https://pypi.org/project/azure_core) | 1.30.2 | Microsoft Azure Core Library for Python
+[azure_cosmos](https://pypi.org/project/azure_cosmos) | 4.7.0 | Microsoft Azure Cosmos Client Library for Python
+[azure_identity](https://pypi.org/project/azure_identity) | 1.16.1 | Microsoft Azure Identity Library for Python
+[babel](https://pypi.org/project/babel) | 2.16.0 | Internationalization utilities
+[baresql](https://pypi.org/project/baresql) | 0.8.0 | playing SQL directly on Python datas
+[bcrypt](https://pypi.org/project/bcrypt) | 4.0.1 | Modern password hashing for your software and your servers
+[beautifulsoup4](https://pypi.org/project/beautifulsoup4) | 4.12.2 | Screen-scraping library
+[binaryornot](https://pypi.org/project/binaryornot) | 0.4.4 | Ultra-lightweight pure Python package to check if a file is binary or text.
+[black](https://pypi.org/project/black) | 24.10.0 | The uncompromising code formatter.
+[bleach](https://pypi.org/project/bleach) | 6.1.0 | An easy safelist-based HTML-sanitizing tool.
+[blinker](https://pypi.org/project/blinker) | 1.7.0 | Fast, simple object-to-object and broadcast signaling
+[bokeh](https://pypi.org/project/bokeh) | 3.6.2 | Interactive plots and applications in the browser from Python
+[branca](https://pypi.org/project/branca) | 0.8.0 | Generate complex HTML+JS pages with Python
+[brotli](https://pypi.org/project/brotli) | 1.1.0 | Python bindings for the Brotli compression library
+[build](https://pypi.org/project/build) | 1.2.2.post1 | A simple, correct Python build frontend
+[cachelib](https://pypi.org/project/cachelib) | 0.13.0 | A collection of cache libraries in the same API interface.
+[cachetools](https://pypi.org/project/cachetools) | 5.4.0 | Extensible memoizing collections and decorators
+[certifi](https://pypi.org/project/certifi) | 2024.6.2 | Python package for providing Mozilla's CA Bundle.
+[cffi](https://pypi.org/project/cffi) | 1.17.1 | Foreign Function Interface for Python calling C code.
+[chardet](https://pypi.org/project/chardet) | 5.2.0 | Universal encoding detector for Python 3
+[charset_normalizer](https://pypi.org/project/charset_normalizer) | 3.4.0 | The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet.
+[clarabel](https://pypi.org/project/clarabel) | 0.9.0 | Clarabel Conic Interior Point Solver for Rust / Python
+[click](https://pypi.org/project/click) | 8.1.7 | Composable command line interface toolkit
+[click_default_group](https://pypi.org/project/click_default_group) | 1.2.4 | click_default_group
+[cloudpickle](https://pypi.org/project/cloudpickle) | 3.0.0 | Pickler class to extend the standard pickle.Pickler functionality
+[colorama](https://pypi.org/project/colorama) | 0.4.6 | Cross-platform colored terminal text.
+[colorcet](https://pypi.org/project/colorcet) | 3.1.0 | Collection of perceptually uniform colormaps
+[colorlog](https://pypi.org/project/colorlog) | 6.8.2 | Add colours to the output of Python's logging module.
+[comm](https://pypi.org/project/comm) | 0.2.2 | Jupyter Python Comm implementation, for usage in ipykernel, xeus-python etc.
+[contourpy](https://pypi.org/project/contourpy) | 1.3.1 | Python library for calculating contours of 2D quadrilateral grids
+[cookiecutter](https://pypi.org/project/cookiecutter) | 2.6.0 | A command-line utility that creates projects from project templates, e.g
+[cryptography](https://pypi.org/project/cryptography) | 44.0.0 | cryptography is a package which provides cryptographic recipes and primitives to Python developers.
+[cvxopt](https://pypi.org/project/cvxopt) | 1.3.2 | Convex optimization package
+[cvxpy](https://pypi.org/project/cvxpy) | 1.6.0 | A domain-specific language for modeling convex optimization problems in Python.
+[cycler](https://pypi.org/project/cycler) | 0.12.1 | Composable style cycles
+[cython](https://pypi.org/project/cython) | 3.0.11 | The Cython compiler for writing C extensions in the Python language.
+[cytoolz](https://pypi.org/project/cytoolz) | 1.0.1 | Cython implementation of Toolz: High performance functional utilities
+[dask](https://pypi.org/project/dask) | 2024.12.1 | Parallel PyData with Task Scheduling
+[dask_expr](https://pypi.org/project/dask_expr) | 1.1.21 | High Level Expressions for Dask
+[datasette](https://pypi.org/project/datasette) | 0.64.8 | An open source multi-tool for exploring and publishing data
+[datasette_graphql](https://pypi.org/project/datasette_graphql) | 2.2 | Datasette plugin providing an automatic GraphQL API for your SQLite databases
+[datashader](https://pypi.org/project/datashader) | 0.16.3 | Data visualization toolchain based on aggregating into a grid
+[db_py](https://pypi.org/project/db_py) | 0.5.4b1 | a db package that doesn't suck
+[deap](https://pypi.org/project/deap) | 1.4.2 | Distributed Evolutionary Algorithms in Python
+[debugpy](https://pypi.org/project/debugpy) | 1.8.0 | An implementation of the Debug Adapter Protocol for Python
+[decorator](https://pypi.org/project/decorator) | 5.1.1 | Decorators for Humans
+[defusedxml](https://pypi.org/project/defusedxml) | 0.7.1 | XML bomb protection for Python stdlib modules
+[diff_match_patch](https://pypi.org/project/diff_match_patch) | 20230430 | Diff Match and Patch
+[dill](https://pypi.org/project/dill) | 0.3.7 | serialize all of Python
+[distributed](https://pypi.org/project/distributed) | 2024.12.1 | Distributed scheduler for Dask
+[distro](https://pypi.org/project/distro) | 1.8.0 | Distro - an OS platform information API
+[django](https://pypi.org/project/django) | 5.0.7 | A high-level Python web framework that encourages rapid development and clean, pragmatic design.
+[dnspython](https://pypi.org/project/dnspython) | 2.6.1 | DNS toolkit
+[docopt](https://pypi.org/project/docopt) | 0.6.2 | Pythonic argument parser, that will make you smile
+[docstring_to_markdown](https://pypi.org/project/docstring_to_markdown) | 0.13 | On the fly conversion of Python docstrings to markdown
+[docutils](https://pypi.org/project/docutils) | 0.20.1 | Docutils -- Python Documentation Utilities
+[duckdb](https://pypi.org/project/duckdb) | 1.1.3 | DuckDB in-process database
+[entrypoints](https://pypi.org/project/entrypoints) | 0.4 | Discover and load entry points from installed packages.
+[et_xmlfile](https://pypi.org/project/et_xmlfile) | 1.1.0 | An implementation of lxml.xmlfile for the standard library
+[eval_type_backport](https://pypi.org/project/eval_type_backport) | 0.2.2 | Like `typing._eval_type`, but lets older Python versions use newer typing features.
+[executing](https://pypi.org/project/executing) | 2.0.1 | Get the currently executing AST node of a frame, and other information
+[faker](https://pypi.org/project/faker) | 33.3.1 | Faker is a Python package that generates fake data for you.
+[fast_histogram](https://pypi.org/project/fast_histogram) | 0.14 | Fast simple 1D and 2D histograms
+[fastapi](https://pypi.org/project/fastapi) | 0.115.6 | FastAPI framework, high performance, easy to learn, fast to code, ready for production
+[fastjsonschema](https://pypi.org/project/fastjsonschema) | 2.18.0 | Fastest Python implementation of JSON schema
+[filelock](https://pypi.org/project/filelock) | 3.14.0 | A platform independent file lock.
+[filterpy](https://pypi.org/project/filterpy) | 1.4.5 | Kalman filtering and optimal estimation library
+[flake8](https://pypi.org/project/flake8) | 7.1.1 | the modular source code checker: pep8 pyflakes and co
+[flask](https://pypi.org/project/flask) | 3.0.3 | A simple framework for building complex web applications.
+[flask_mail](https://pypi.org/project/flask_mail) | 0.9.1 | Flask extension for sending email
+[flask_session](https://pypi.org/project/flask_session) | 0.5.0 | Server-side session support for Flask
+[flask_sqlalchemy](https://pypi.org/project/flask_sqlalchemy) | 3.0.5 | Add SQLAlchemy support to your Flask application.
+[flit](https://pypi.org/project/flit) | 3.9.0 | A simple packaging tool for simple packages.
+[flit_core](https://pypi.org/project/flit_core) | 3.9.0 | Distribution-building parts of Flit. See flit package for more information
+[folium](https://pypi.org/project/folium) | 0.18.0 | Make beautiful maps with Leaflet.js & Python
+[fonttools](https://pypi.org/project/fonttools) | 4.55.3 | Tools to manipulate font files
+[formlayout](https://pypi.org/project/formlayout) | 1.2.1a1 | The most easy way to create Qt form dialogs and widgets with Python
+[fqdn](https://pypi.org/project/fqdn) | 1.5.1 | Validates fully-qualified domain names against RFC 1123, so that they are acceptable to modern bowsers
+[frozenlist](https://pypi.org/project/frozenlist) | 1.5.0 | A list-like structure which implements collections.abc.MutableSequence
+[fsspec](https://pypi.org/project/fsspec) | 2024.6.1 | File-system specification
+[future](https://pypi.org/project/future) | 0.18.2 | Clean single-source support for Python 3 and 2
+[fuzzywuzzy](https://pypi.org/project/fuzzywuzzy) | 0.18.0 | Fuzzy string matching in python
+[geographiclib](https://pypi.org/project/geographiclib) | 2.0 | The geodesic routines from GeographicLib
+[geopandas](https://pypi.org/project/geopandas) | 1.0.1 | Geographic pandas extensions
+[geopy](https://pypi.org/project/geopy) | 2.4.1 | Python Geocoding Toolbox
+[gitdb](https://pypi.org/project/gitdb) | 4.0.10 | Git Object Database
+[gitpython](https://pypi.org/project/gitpython) | 3.1.32 | GitPython is a Python library used to interact with Git repositories
+[google_auth](https://pypi.org/project/google_auth) | 2.37.0 | Google Authentication Library
+[graphene](https://pypi.org/project/graphene) | 3.3 | GraphQL Framework for Python
+[graphql_core](https://pypi.org/project/graphql_core) | 3.2.3 | GraphQL implementation for Python, a port of GraphQL.js, the JavaScript reference implementation for GraphQL.
+[graphql_relay](https://pypi.org/project/graphql_relay) | 3.2.0 | Relay library for graphql-core
+[greenlet](https://pypi.org/project/greenlet) | 3.1.1 | Lightweight in-process concurrent programming
+[griffe](https://pypi.org/project/griffe) | 1.5.4 | Signatures for entire Python programs
+[groq](https://pypi.org/project/groq) | 0.13.1 | The official Python library for the groq API
+[guidata](https://pypi.org/project/guidata) | 3.7.1 | Automatic GUI generation for easy dataset editing and display
+[h11](https://pypi.org/project/h11) | 0.14.0 | A pure-Python, bring-your-own-I/O implementation of HTTP/1.1
+[h2](https://pypi.org/project/h2) | 4.1.0 | HTTP/2 State-Machine based protocol implementation
+[h5py](https://pypi.org/project/h5py) | 3.12.1 | Read and write HDF5 files from Python
+[hatchling](https://pypi.org/project/hatchling) | 1.27.0 | Modern, extensible Python build backend
+[holoviews](https://pypi.org/project/holoviews) | 1.20.0 | A high-level plotting API for the PyData ecosystem built on HoloViews.
+[hpack](https://pypi.org/project/hpack) | 4.0.0 | Pure-Python HPACK header compression
+[html5lib](https://pypi.org/project/html5lib) | 1.1 | HTML parser based on the WHATWG HTML specification
+[httpcore](https://pypi.org/project/httpcore) | 1.0.5 | A minimal low-level HTTP client.
+[httpie](https://pypi.org/project/httpie) | 3.2.4 | HTTPie: modern, user-friendly command-line HTTP client for the API era.
+[httpx](https://pypi.org/project/httpx) | 0.27.2 | The next generation HTTP client.
+[huggingface_hub](https://pypi.org/project/huggingface_hub) | 0.27.0 | Client library to download and publish models, datasets and other repos on the huggingface.co hub
+[hupper](https://pypi.org/project/hupper) | 1.12 | Integrated process monitor for developing and reloading daemons.
+[hvplot](https://pypi.org/project/hvplot) | 0.11.2 | A high-level plotting API for the PyData ecosystem built on HoloViews.
+[hypercorn](https://pypi.org/project/hypercorn) | 0.16.0 | A ASGI Server based on Hyper libraries and inspired by Gunicorn
+[hyperframe](https://pypi.org/project/hyperframe) | 6.0.1 | HTTP/2 framing layer for Python
+[hypothesis](https://pypi.org/project/hypothesis) | 6.122.3 | A library for property-based testing
+[idna](https://pypi.org/project/idna) | 3.7 | Internationalized Domain Names in Applications (IDNA)
+[imageio](https://pypi.org/project/imageio) | 2.33.1 | Library for reading and writing a wide range of image, video, scientific, and volumetric data formats.
+[imagesize](https://pypi.org/project/imagesize) | 1.4.1 | Getting image size from png/jpeg/jpeg2000/gif file
+[imbalanced_learn](https://pypi.org/project/imbalanced_learn) | 0.13.0 | Toolbox for imbalanced dataset in machine learning
+[importlib_metadata](https://pypi.org/project/importlib_metadata) | 7.1.0 | Read metadata from Python packages
+[inflection](https://pypi.org/project/inflection) | 0.5.1 | A port of Ruby on Rails inflector to Python
+[iniconfig](https://pypi.org/project/iniconfig) | 2.0.0 | brain-dead simple config-ini parsing
+[intervaltree](https://pypi.org/project/intervaltree) | 3.0.2 | Editable interval tree data structure for Python 2 and 3
+[ipycanvas](https://pypi.org/project/ipycanvas) | 0.13.2 | Interactive widgets library exposing the browser's Canvas API
+[ipykernel](https://pypi.org/project/ipykernel) | 6.29.5 | IPython Kernel for Jupyter
+[ipyleaflet](https://pypi.org/project/ipyleaflet) | 0.19.2 | A Jupyter widget for dynamic Leaflet maps
+[ipympl](https://pypi.org/project/ipympl) | 0.9.4 | Matplotlib Jupyter Extension
+[ipython](https://pypi.org/project/ipython) | 8.31.0 | IPython: Productive Interactive Computing
+[ipython_genutils](https://pypi.org/project/ipython_genutils) | 0.2.0 | Vestigial utilities from IPython
+[ipython_sql](https://pypi.org/project/ipython_sql) | 0.5.0 | RDBMS access via IPython
+[ipywidgets](https://pypi.org/project/ipywidgets) | 8.1.5 | Jupyter interactive widgets
+[isoduration](https://pypi.org/project/isoduration) | 20.11.0 | Operations with ISO 8601 durations
+[isort](https://pypi.org/project/isort) | 5.13.2 | A Python utility / library to sort Python imports.
+[itsdangerous](https://pypi.org/project/itsdangerous) | 2.2.0 | Safely pass data to untrusted environments and back.
+[janus](https://pypi.org/project/janus) | 2.0.0 | Mixed sync-async queue to interoperate between asyncio tasks and classic threads
+[jaraco_classes](https://pypi.org/project/jaraco_classes) | 3.4.0 | Utility functions for Python class constructs
+[jaraco_context](https://pypi.org/project/jaraco_context) | 6.0.1 | Useful decorators and context managers
+[jaraco_functools](https://pypi.org/project/jaraco_functools) | 4.1.0 | Functools like those found in stdlib
+[jedi](https://pypi.org/project/jedi) | 0.19.2 | An autocompletion tool for Python that can be used for text editors.
+[jellyfish](https://pypi.org/project/jellyfish) | 1.1.3 | Approximate and phonetic matching of strings.
+[jinja2](https://pypi.org/project/jinja2) | 3.1.2 | A very fast and expressive template engine.
+[jiter](https://pypi.org/project/jiter) | 0.8.2 | Fast iterable JSON parser.
+[joblib](https://pypi.org/project/joblib) | 1.4.2 | Lightweight pipelining with Python functions
+[json5](https://pypi.org/project/json5) | 0.9.14 | A Python implementation of the JSON5 data format.
+[jsonpatch](https://pypi.org/project/jsonpatch) | 1.33 | Apply JSON-Patches (RFC 6902)
+[jsonpath_python](https://pypi.org/project/jsonpath_python) | 1.0.6 | A more powerful JSONPath implementation in modern python
+[jsonpointer](https://pypi.org/project/jsonpointer) | 2.4 | Identify specific nodes in a JSON document (RFC 6901)
+[jsonschema](https://pypi.org/project/jsonschema) | 4.19.2 | An implementation of JSON Schema validation for Python
+[jsonschema_specifications](https://pypi.org/project/jsonschema_specifications) | 2023.12.1 | The JSON Schema meta-schemas and vocabularies, exposed as a Registry
+[julia](https://pypi.org/project/julia) | 0.6.2 | Julia/Python bridge with IPython support.
+[jupyter](https://pypi.org/project/jupyter) | 1.1.1 | Jupyter metapackage. Install all the Jupyter components in one go.
+[jupyter_bokeh](https://pypi.org/project/jupyter_bokeh) | 4.0.5 | A Jupyter extension for rendering Bokeh content.
+[jupyter_client](https://pypi.org/project/jupyter_client) | 8.6.2 | Jupyter protocol implementation and client libraries
+[jupyter_console](https://pypi.org/project/jupyter_console) | 6.6.3 | Jupyter terminal console
+[jupyter_core](https://pypi.org/project/jupyter_core) | 5.7.2 | Jupyter core package. A base package on which Jupyter projects rely.
+[jupyter_events](https://pypi.org/project/jupyter_events) | 0.10.0 | Jupyter Event System library
+[jupyter_leaflet](https://pypi.org/project/jupyter_leaflet) | 0.19.2 | ipyleaflet extensions for JupyterLab and Jupyter Notebook
+[jupyter_lsp](https://pypi.org/project/jupyter_lsp) | 2.2.5 | Multi-Language Server WebSocket proxy for Jupyter Notebook/Lab server
+[jupyter_server](https://pypi.org/project/jupyter_server) | 2.14.2 | The backend—i.e. core services, APIs, and REST endpoints—to Jupyter web applications.
+[jupyter_server_terminals](https://pypi.org/project/jupyter_server_terminals) | 0.5.3 | A Jupyter Server Extension Providing Terminals.
+[jupyterlab](https://pypi.org/project/jupyterlab) | 4.3.4 | JupyterLab computational environment
+[jupyterlab_pygments](https://pypi.org/project/jupyterlab_pygments) | 0.3.0 | Pygments theme using JupyterLab CSS variables
+[jupyterlab_server](https://pypi.org/project/jupyterlab_server) | 2.27.3 | A set of server components for JupyterLab and JupyterLab like applications.
+[jupyterlab_widgets](https://pypi.org/project/jupyterlab_widgets) | 3.0.13 | Jupyter interactive widgets for JupyterLab
+[keras](https://pypi.org/project/keras) | 3.8.0 | Multi-backend Keras
+[keyring](https://pypi.org/project/keyring) | 25.6.0 | Store and access your passwords safely.
+[kiwisolver](https://pypi.org/project/kiwisolver) | 1.4.7 | A fast implementation of the Cassowary constraint solver
+[langchain](https://pypi.org/project/langchain) | 0.3.13 | Building applications with LLMs through composability
+[langchain_core](https://pypi.org/project/langchain_core) | 0.3.28 | Building applications with LLMs through composability
+[langchain_text_splitters](https://pypi.org/project/langchain_text_splitters) | 0.3.4 | LangChain text splitting utilities
+[langsmith](https://pypi.org/project/langsmith) | 0.2.6 | Client library to connect to the LangSmith LLM Tracing and Evaluation Platform.
+[lazy_loader](https://pypi.org/project/lazy_loader) | 0.4 | Makes it easy to load subpackages and functions on demand.
+[linkify_it_py](https://pypi.org/project/linkify_it_py) | 2.0.2 | Links recognition library with FULL unicode support.
+[llvmlite](https://pypi.org/project/llvmlite) | 0.44.0 | lightweight wrapper around basic LLVM functionality
+[lmfit](https://pypi.org/project/lmfit) | 1.3.1 | Least-Squares Minimization with Bounds and Constraints
+[locket](https://pypi.org/project/locket) | 1.0.0 | File-based locks for Python on Linux and Windows
+[logfire_api](https://pypi.org/project/logfire_api) | 2.11.0 | Shim for the Logfire SDK which does nothing unless Logfire is installed
+[lxml](https://pypi.org/project/lxml) | 5.3.0 | Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API.
+[mako](https://pypi.org/project/mako) | 1.3.5 | A super-fast templating language that borrows the best ideas from the existing templating languages.
+[markdown](https://pypi.org/project/markdown) | 3.5.1 | Python implementation of John Gruber's Markdown.
+[markdown_it_py](https://pypi.org/project/markdown_it_py) | 2.2.0 | Python port of markdown-it. Markdown parsing, done right!
+[markupsafe](https://pypi.org/project/markupsafe) | 2.1.1 | Safely add untrusted strings to HTML/XML markup.
+[matplotlib](https://pypi.org/project/matplotlib) | 3.10.0 | Python plotting package
+[matplotlib_inline](https://pypi.org/project/matplotlib_inline) | 0.1.7 | Inline Matplotlib backend for Jupyter
+[maturin](https://pypi.org/project/maturin) | 1.8.1 | Build and publish crates with pyo3, cffi and uniffi bindings as well as rust binaries as python packages
+[mccabe](https://pypi.org/project/mccabe) | 0.7.0 | McCabe checker, plugin for flake8
+[mdit_py_plugins](https://pypi.org/project/mdit_py_plugins) | 0.3.5 | Collection of plugins for markdown-it-py
+[mdurl](https://pypi.org/project/mdurl) | 0.1.2 | Markdown URL utilities
+[mercantile](https://pypi.org/project/mercantile) | 1.2.1 | Web mercator XYZ tile utilities
+[mergedeep](https://pypi.org/project/mergedeep) | 1.3.4 | A deep merge function for 🐍.
+[missingno](https://pypi.org/project/missingno) | 0.5.1 | Missing data visualization module for Python.
+[mistralai](https://pypi.org/project/mistralai) | 1.2.5 | Python Client SDK for the Mistral AI API.
+[mistune](https://pypi.org/project/mistune) | 2.0.5 | A sane Markdown parser with useful plugins and renderers
+[mizani](https://pypi.org/project/mizani) | 0.11.4 | Scales for Python
+[ml_dtypes](https://pypi.org/project/ml_dtypes) | 0.5.0 |
+[mlxtend](https://pypi.org/project/mlxtend) | 0.23.3 | Machine Learning Library Extensions
+[more_itertools](https://pypi.org/project/more_itertools) | 10.2.0 | More routines for operating on iterables, beyond itertools
+[mpl_scatter_density](https://pypi.org/project/mpl_scatter_density) | 0.7 | Matplotlib helpers to make density scatter plots
+[mpld3](https://pypi.org/project/mpld3) | 0.5.8 | D3 Viewer for Matplotlib
+[mpmath](https://pypi.org/project/mpmath) | 1.3.0 | Python library for arbitrary-precision floating-point arithmetic
+[msal](https://pypi.org/project/msal) | 1.30.0 | The Microsoft Authentication Library (MSAL) for Python library enables your app to access the Microsoft Cloud by supporting authentication of us
+[msal_extensions](https://pypi.org/project/msal_extensions) | 1.2.0 | Microsoft Authentication Library extensions (MSAL EX) provides a persistence API that can save your data on disk, encrypted on Windows, macOS an
+[msgpack](https://pypi.org/project/msgpack) | 1.0.4 | MessagePack serializer
+[multidict](https://pypi.org/project/multidict) | 6.1.0 | multidict implementation
+[multipledispatch](https://pypi.org/project/multipledispatch) | 1.0.0 | Multiple dispatch
+[mutagen](https://pypi.org/project/mutagen) | 1.47.0 | read and write audio tags for many formats
+[mypy](https://pypi.org/project/mypy) | 1.14.0 | Optional static typing for Python
+[mypy_extensions](https://pypi.org/project/mypy_extensions) | 1.0.0 | Type system extensions for programs checked with the mypy type checker.
+[mysql_connector_python](https://pypi.org/project/mysql_connector_python) | 8.0.21 | MySQL driver written in Python
+[namex](https://pypi.org/project/namex) | 0.0.8 | A simple utility to separate the implementation of your Python package and its public API surface.
+[narwhals](https://pypi.org/project/narwhals) | 1.21.1 | Extremely lightweight compatibility layer between dataframe libraries
+[nbclient](https://pypi.org/project/nbclient) | 0.10.0 | A client library for executing notebooks. Formerly nbconvert's ExecutePreprocessor.
+[nbconvert](https://pypi.org/project/nbconvert) | 7.16.1 | Converting Jupyter Notebooks (.ipynb files) to other formats
+[nbformat](https://pypi.org/project/nbformat) | 5.10.4 | The Jupyter Notebook format
+[nest_asyncio](https://pypi.org/project/nest_asyncio) | 1.6.0 | Patch asyncio to allow nested event loops
+[networkx](https://pypi.org/project/networkx) | 3.4.2 | Python package for creating and manipulating graphs and networks
+[nltk](https://pypi.org/project/nltk) | 3.9.1 | Natural Language Toolkit
+[notebook](https://pypi.org/project/notebook) | 7.3.1 | Jupyter Notebook - A web-based notebook environment for interactive computing
+[notebook_shim](https://pypi.org/project/notebook_shim) | 0.2.4 | A shim layer for notebook traits and config
+[numba](https://pypi.org/project/numba) | 0.61.0 | compiling Python code using LLVM
+[numpy](https://pypi.org/project/numpy) | 2.1.3 | Fundamental package for array computing in Python
+[numpydoc](https://pypi.org/project/numpydoc) | 1.6.0 | Sphinx extension to support docstrings in Numpy format
+[openai](https://pypi.org/project/openai) | 1.58.1 | The official Python library for the openai API
+[opencv_python](https://pypi.org/project/opencv_python) | 4.10.0.84 | Wrapper package for OpenCV python bindings.
+[openpyxl](https://pypi.org/project/openpyxl) | 3.1.2 | A Python library to read/write Excel 2010 xlsx/xlsm files
+[optree](https://pypi.org/project/optree) | 0.13.1 | Optimized PyTree Utilities.
+[optuna](https://pypi.org/project/optuna) | 3.6.1 | A hyperparameter optimization framework
+[orjson](https://pypi.org/project/orjson) | 3.10.12 | Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy
+[osqp](https://pypi.org/project/osqp) | 0.6.7.post3 | OSQP: The Operator Splitting QP Solver
+[outcome](https://pypi.org/project/outcome) | 1.3.0.post0 | Capture the outcome of Python function calls.
+[overrides](https://pypi.org/project/overrides) | 7.7.0 | A decorator to automatically detect mismatch when overriding a method.
+[packaging](https://pypi.org/project/packaging) | 24.2 | Core utilities for Python packages
+[pandas](https://pypi.org/project/pandas) | 2.2.3 | Powerful data structures for data analysis, time series, and statistics
+[pandocfilters](https://pypi.org/project/pandocfilters) | 1.5.0 | Utilities for writing pandoc filters in python
+[panel](https://pypi.org/project/panel) | 1.5.4 | The powerful data exploration & web app framework for Python.
+[papermill](https://pypi.org/project/papermill) | 2.6.0 | Parameterize and run Jupyter and nteract Notebooks
+[param](https://pypi.org/project/param) | 2.1.1 | Make your Python code clearer and more reliable by declaring Parameters.
+[paramiko](https://pypi.org/project/paramiko) | 2.8.0 | SSH2 protocol library
+[parso](https://pypi.org/project/parso) | 0.8.4 | A Python Parser
+[partd](https://pypi.org/project/partd) | 1.4.0 | Appendable key-value storage
+[pathspec](https://pypi.org/project/pathspec) | 0.11.0 | Utility library for gitignore style pattern matching of file paths.
+[patsy](https://pypi.org/project/patsy) | 0.5.6 | A Python package for describing statistical models and for building design matrices.
+[pdfrw](https://pypi.org/project/pdfrw) | 0.4.post2 | PDF file reader/writer library
+[pep8](https://pypi.org/project/pep8) | 1.7.1 | Python style guide checker
+[pexpect](https://pypi.org/project/pexpect) | 4.8.0 | Pexpect allows easy control of interactive console applications.
+[pg8000](https://pypi.org/project/pg8000) | 1.23.0 | PostgreSQL interface library
+[pickleshare](https://pypi.org/project/pickleshare) | 0.7.5 | Tiny 'shelve'-like database with concurrency support
+[pillow](https://pypi.org/project/pillow) | 11.1.0 | Python Imaging Library (Fork)
+[pint](https://pypi.org/project/pint) | 0.23 | Physical quantities module
+[pip](https://pypi.org/project/pip) | 24.3.1 | The PyPA recommended tool for installing Python packages.
+[pkginfo](https://pypi.org/project/pkginfo) | 1.11.2 | Query metadata from sdists / bdists / installed packages.
+[platformdirs](https://pypi.org/project/platformdirs) | 4.2.2 | A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`.
+[plotly](https://pypi.org/project/plotly) | 5.24.1 | An open-source, interactive data visualization library for Python
+[plotnine](https://pypi.org/project/plotnine) | 0.13.6 | A Grammar of Graphics for Python
+[plotpy](https://pypi.org/project/plotpy) | 2.7.0 | Curve and image plotting tools for Python/Qt applications
+[pluggy](https://pypi.org/project/pluggy) | 1.5.0 | plugin and hook calling mechanisms for python
+[ply](https://pypi.org/project/ply) | 3.11 | Python Lex & Yacc
+[polars](https://pypi.org/project/polars) | 1.20.0 | Blazingly fast DataFrame library
+[portalocker](https://pypi.org/project/portalocker) | 2.7.0 | Wraps the portalocker recipe for easy usage
+[ppci](https://pypi.org/project/ppci) | 0.5.9 | A compiler for ARM, X86, MSP430, xtensa and more implemented in pure Python
+[prettytable](https://pypi.org/project/prettytable) | 3.3.0 | A simple Python library for easily displaying tabular data in a visually appealing ASCII table format
+[prince](https://pypi.org/project/prince) | 0.15.0 | Factor analysis in Python: PCA, CA, MCA, MFA, FAMD, GPA
+[priority](https://pypi.org/project/priority) | 2.0.0 | A pure-Python implementation of the HTTP/2 priority tree
+[prometheus_client](https://pypi.org/project/prometheus_client) | 0.18.0 | Python client for the Prometheus monitoring system.
+[prompt_toolkit](https://pypi.org/project/prompt_toolkit) | 3.0.48 | Library for building powerful interactive command lines in Python
+[propcache](https://pypi.org/project/propcache) | 0.2.1 | Accelerated property cache
+[protobuf](https://pypi.org/project/protobuf) | 5.27.3 |
+[psutil](https://pypi.org/project/psutil) | 5.9.8 | Cross-platform lib for process and system monitoring in Python.
+[psygnal](https://pypi.org/project/psygnal) | 0.11.1 | Fast python callback/event system modeled after Qt Signals
+[ptpython](https://pypi.org/project/ptpython) | 3.0.29 | Python REPL build on top of prompt_toolkit
+[ptyprocess](https://pypi.org/project/ptyprocess) | 0.7.0 | Run a subprocess in a pseudo terminal
+[pure_eval](https://pypi.org/project/pure_eval) | 0.2.2 | Safely evaluate AST nodes without side effects
+[pyarrow](https://pypi.org/project/pyarrow) | 19.0.0 | Python library for Apache Arrow
+[pyasn1](https://pypi.org/project/pyasn1) | 0.4.8 | ASN.1 types and codecs
+[pyasn1_modules](https://pypi.org/project/pyasn1_modules) | 0.2.8 | A collection of ASN.1-based protocols modules.
+[pybars3](https://pypi.org/project/pybars3) | 0.9.7 | Handlebars.js templating for Python 3 and 2
+[pybind11](https://pypi.org/project/pybind11) | 2.13.6 | Seamless operability between C++11 and Python
+[pycodestyle](https://pypi.org/project/pycodestyle) | 2.12.0 | Python style guide checker
+[pycparser](https://pypi.org/project/pycparser) | 2.22 | C parser in Python
+[pycryptodomex](https://pypi.org/project/pycryptodomex) | 3.20.0 | Cryptographic library for Python
+[pyct](https://pypi.org/project/pyct) | 0.5.0 | Python package common tasks for users (e.g. copy examples, fetch data, ...)
+[pydantic](https://pypi.org/project/pydantic) | 2.10.4 | Data validation using Python type hints
+[pydantic_ai](https://pypi.org/project/pydantic_ai) | 0.0.15 | Agent Framework / shim to use Pydantic with LLMs
+[pydantic_ai_slim](https://pypi.org/project/pydantic_ai_slim) | 0.0.15 | Agent Framework / shim to use Pydantic with LLMs, slim package
+[pydantic_core](https://pypi.org/project/pydantic_core) | 2.27.2 | Core functionality for Pydantic validation and serialization
+[pydeck](https://pypi.org/project/pydeck) | 0.9.1 | Widget for deck.gl maps
+[pydocstyle](https://pypi.org/project/pydocstyle) | 6.3.0 | Python docstring style checker
+[pydub](https://pypi.org/project/pydub) | 0.25.1 | Manipulate audio with an simple and easy high level interface
+[pyerfa](https://pypi.org/project/pyerfa) | 2.0.1.4 | Python bindings for ERFA
+[pyflakes](https://pypi.org/project/pyflakes) | 3.2.0 | passive checker of Python programs
+[pygments](https://pypi.org/project/pygments) | 2.19.1 | Pygments is a syntax highlighting package written in Python.
+[pyjwt](https://pypi.org/project/pyjwt) | 2.8.0 | JSON Web Token implementation in Python
+[pylint](https://pypi.org/project/pylint) | 3.1.0 | python code static checker
+[pylint_venv](https://pypi.org/project/pylint_venv) | 3.0.3 | pylint-venv provides a Pylint init-hook to use the same Pylint installation with different virtual environments.
+[pyls_spyder](https://pypi.org/project/pyls_spyder) | 0.4.0 | Spyder extensions for the python-lsp-server
+[pymeta3](https://pypi.org/project/pymeta3) | 0.5.1 | Pattern-matching language based on OMeta for Python 3 and 2
+[pymongo](https://pypi.org/project/pymongo) | 4.10.1 | Python driver for MongoDB
+[pympler](https://pypi.org/project/pympler) | 1.0.1 | A development tool to measure, monitor and analyze the memory behavior of Python objects.
+[pynacl](https://pypi.org/project/pynacl) | 1.5.0 | Python binding to the Networking and Cryptography (NaCl) library
+[pynndescent](https://pypi.org/project/pynndescent) | 0.5.12 | Nearest Neighbor Descent
+[pyodbc](https://pypi.org/project/pyodbc) | 5.2.0 | DB API module for ODBC
+[pyogrio](https://pypi.org/project/pyogrio) | 0.10.0 | Vectorized spatial vector file format I/O using GDAL/OGR
+[pyomo](https://pypi.org/project/pyomo) | 6.8.0 | Pyomo: Python Optimization Modeling Objects
+[pypandoc](https://pypi.org/project/pypandoc) | 1.5 | Thin wrapper for pandoc.
+[pyparsing](https://pypi.org/project/pyparsing) | 3.2.1 | pyparsing module - Classes and methods to define and execute parsing grammars
+[pypdf](https://pypi.org/project/pypdf) | 3.15.2 | A pure-python PDF library capable of splitting, merging, cropping, and transforming PDF files
+[pyproj](https://pypi.org/project/pyproj) | 3.7.0 | Python interface to PROJ (cartographic projections and coordinate transformations library)
+[pyproject_hooks](https://pypi.org/project/pyproject_hooks) | 1.1.0 | Wrappers to call pyproject.toml-based build backend hooks.
+[pyqt5](https://pypi.org/project/pyqt5) | 5.15.10 | Python bindings for the Qt cross platform application toolkit
+[pyqt5_qt5](https://pypi.org/project/pyqt5_qt5) | 5.15.2 | The subset of a Qt installation needed by PyQt5.
+[pyqt5_sip](https://pypi.org/project/pyqt5_sip) | 12.13.0 | The sip module support for PyQt5
+[pyqtgraph](https://pypi.org/project/pyqtgraph) | 0.13.7 | Scientific Graphics and GUI Library for Python
+[pyqtwebengine](https://pypi.org/project/pyqtwebengine) | 5.15.6 | Python bindings for the Qt WebEngine framework
+[pyqtwebengine_qt5](https://pypi.org/project/pyqtwebengine_qt5) | 5.15.2 | The subset of a Qt installation needed by PyQtWebEngine.
+[pyserial](https://pypi.org/project/pyserial) | 3.5 | Python Serial Port Extension
+[pysimplegui](https://pypi.org/project/pysimplegui) | 4.60.4 | Python GUIs for Humans
+[pysocks](https://pypi.org/project/pysocks) | 1.7.1 | A Python SOCKS client module. See https://github.com/Anorov/PySocks for more information.
+[pyspnego](https://pypi.org/project/pyspnego) | 0.11.2 | Windows Negotiate Authentication Client and Server
+[pytest](https://pypi.org/project/pytest) | 8.2.2 | pytest: simple powerful testing with Python
+[python_barcode](https://pypi.org/project/python_barcode) | 0.15.1 | Create standard barcodes with Python. No external modules needed. (optional Pillow support included).
+[python_dateutil](https://pypi.org/project/python_dateutil) | 2.8.2 | Extensions to the standard Python datetime module
+[python_dotenv](https://pypi.org/project/python_dotenv) | 1.0.1 | Read key-value pairs from a .env file and set them as environment variables
+[python_json_logger](https://pypi.org/project/python_json_logger) | 2.0.7 | A python library adding a json log formatter
+[python_lsp_black](https://pypi.org/project/python_lsp_black) | 2.0.0 | Black plugin for the Python LSP Server
+[python_lsp_jsonrpc](https://pypi.org/project/python_lsp_jsonrpc) | 1.1.2 | JSON RPC 2.0 server library
+[python_lsp_server](https://pypi.org/project/python_lsp_server) | 1.12.0 | Python Language Server for the Language Server Protocol
+[python_multipart](https://pypi.org/project/python_multipart) | 0.0.9 | A streaming multipart parser for Python
+[python_slugify](https://pypi.org/project/python_slugify) | 8.0.4 | A Python slugify application that also handles Unicode
+[pythonqwt](https://pypi.org/project/pythonqwt) | 0.14.2 | Qt plotting widgets for Python
+[pytoolconfig](https://pypi.org/project/pytoolconfig) | 1.3.1 | Python tool configuration
+[pytz](https://pypi.org/project/pytz) | 2024.1 | World timezone definitions, modern and historical
+[pyviz_comms](https://pypi.org/project/pyviz_comms) | 3.0.3 | A JupyterLab extension for rendering HoloViz content.
+[pywavelets](https://pypi.org/project/pywavelets) | 1.8.0 | PyWavelets, wavelet transform module
+[pywin32](https://pypi.org/project/pywin32) | 308 | Python for Window Extensions
+[pywin32_ctypes](https://pypi.org/project/pywin32_ctypes) | 0.2.2 | A (partial) reimplementation of pywin32 using ctypes/cffi
+[pywinpty](https://pypi.org/project/pywinpty) | 2.0.14 | Pseudo terminal support for Windows from Python.
+[pywinusb](https://pypi.org/project/pywinusb) | 0.4.2 | A package that simplifies USB/HID communications on windows
+[pyyaml](https://pypi.org/project/pyyaml) | 6.0.2 | YAML parser and emitter for Python
+[pyzmq](https://pypi.org/project/pyzmq) | 26.2.0 | Python bindings for 0MQ
+[qdarkstyle](https://pypi.org/project/qdarkstyle) | 3.2.3 | The most complete dark/light style sheet for C++/Python and Qt applications
+[qdldl](https://pypi.org/project/qdldl) | 0.1.7.post5 | QDLDL, a free LDL factorization routine.
+[qrcode](https://pypi.org/project/qrcode) | 8.0 | QR Code image generator
+[qstylizer](https://pypi.org/project/qstylizer) | 0.2.2 | Stylesheet Generator for PyQt{4-5}/PySide{1-2}
+[qtawesome](https://pypi.org/project/qtawesome) | 1.3.1 | FontAwesome icons in PyQt and PySide applications
+[qtconsole](https://pypi.org/project/qtconsole) | 5.5.2 | Jupyter Qt console
+[qtpy](https://pypi.org/project/qtpy) | 2.4.1 | Provides an abstraction layer on top of the various Qt bindings (PyQt5/6 and PySide2/6).
+[quantecon](https://pypi.org/project/quantecon) | 0.7.2 | Import the main names to top level.
+[quart](https://pypi.org/project/quart) | 0.19.4 | A Python ASGI web microframework with the same API as Flask
+[rapidfuzz](https://pypi.org/project/rapidfuzz) | 3.9.6 | rapid fuzzy string matching
+[readme_renderer](https://pypi.org/project/readme_renderer) | 35.0 | readme_renderer is a library for rendering "readme" descriptions for Warehouse
+[redis](https://pypi.org/project/redis) | 5.0.3 | Python client for Redis database and key-value store
+[referencing](https://pypi.org/project/referencing) | 0.35.1 | JSON Referencing + Python
+[regex](https://pypi.org/project/regex) | 2024.11.6 | Alternative regular expression module, to replace re.
+[reportlab](https://pypi.org/project/reportlab) | 4.2.2 | The Reportlab Toolkit
+[requests](https://pypi.org/project/requests) | 2.32.3 | Python HTTP for Humans.
+[requests_ntlm](https://pypi.org/project/requests_ntlm) | 1.3.0 | This package allows for HTTP NTLM authentication using the requests library.
+[requests_toolbelt](https://pypi.org/project/requests_toolbelt) | 1.0.0 | A utility belt for advanced users of python-requests
+[rfc3339_validator](https://pypi.org/project/rfc3339_validator) | 0.1.4 | A pure python RFC3339 validator
+[rfc3986](https://pypi.org/project/rfc3986) | 2.0.0 | Validating URI References per RFC 3986
+[rfc3986_validator](https://pypi.org/project/rfc3986_validator) | 0.1.1 | Pure python rfc3986 validator
+[rich](https://pypi.org/project/rich) | 13.9.4 | Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal
+[rope](https://pypi.org/project/rope) | 1.12.0 | a python refactoring library...
+[rpds_py](https://pypi.org/project/rpds_py) | 0.22.3 | Python bindings to Rust's persistent data structures (rpds)
+[rsa](https://pypi.org/project/rsa) | 4.7.2 | Pure-Python RSA implementation
+[rtree](https://pypi.org/project/rtree) | 1.1.0 | R-Tree spatial index for Python GIS
+[rx](https://pypi.org/project/rx) | 3.1.1 | Reactive Extensions (Rx) for Python
+[scikit_image](https://pypi.org/project/scikit_image) | 0.25.0 | Image processing in Python
+[scikit_learn](https://pypi.org/project/scikit_learn) | 1.6.1 | A set of python modules for machine learning and data mining
+[scipy](https://pypi.org/project/scipy) | 1.15.1 | Fundamental algorithms for scientific computing in Python
+[scramp](https://pypi.org/project/scramp) | 1.4.1 | An implementation of the SCRAM protocol.
+[scs](https://pypi.org/project/scs) | 3.2.7 | Splitting conic solver
+[seaborn](https://pypi.org/project/seaborn) | 0.13.2 | Statistical data visualization
+[send2trash](https://pypi.org/project/send2trash) | 1.8.2 | Send file to trash natively under Mac OS X, Windows and Linux
+[setuptools](https://pypi.org/project/setuptools) | 75.6.0 | Easily download, build, install, upgrade, and uninstall Python packages
+[shapely](https://pypi.org/project/shapely) | 2.0.6 | Manipulation and analysis of geometric objects
+[simplegeneric](https://pypi.org/project/simplegeneric) | 0.8.1 | Simple generic functions (similar to Python's own len(), pickle.dump(), etc.)
+[simplejson](https://pypi.org/project/simplejson) | 3.19.3 | Simple, fast, extensible JSON encoder/decoder for Python
+[simpy](https://pypi.org/project/simpy) | 4.0.1 | Event discrete, process based simulation for Python.
+[six](https://pypi.org/project/six) | 1.16.0 | Python 2 and 3 compatibility utilities
+[sklearn_compat](https://pypi.org/project/sklearn_compat) | 0.1.3 | Ease support for compatible scikit-learn estimators across versions
+[smmap](https://pypi.org/project/smmap) | 5.0.0 | A pure Python implementation of a sliding window memory map manager
+[sniffio](https://pypi.org/project/sniffio) | 1.3.0 | Sniff out which async library your code is running under
+[snowballstemmer](https://pypi.org/project/snowballstemmer) | 2.2.0 | This package provides 29 stemmers for 28 languages generated from Snowball algorithms.
+[sortedcontainers](https://pypi.org/project/sortedcontainers) | 2.4.0 | Sorted Containers -- Sorted List, Sorted Dict, Sorted Set
+[sounddevice](https://pypi.org/project/sounddevice) | 0.4.6 | Play and Record Sound with Python
+[soupsieve](https://pypi.org/project/soupsieve) | 2.5 | A modern CSS selector implementation for Beautiful Soup.
+[sphinx](https://pypi.org/project/sphinx) | 7.3.7 | Python documentation generator
+[sphinx_rtd_theme](https://pypi.org/project/sphinx_rtd_theme) | 2.0.0 | Read the Docs theme for Sphinx
+[sphinxcontrib_applehelp](https://pypi.org/project/sphinxcontrib_applehelp) | 1.0.8 | sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books
+[sphinxcontrib_devhelp](https://pypi.org/project/sphinxcontrib_devhelp) | 1.0.6 | sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp documents
+[sphinxcontrib_htmlhelp](https://pypi.org/project/sphinxcontrib_htmlhelp) | 2.0.5 | sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files
+[sphinxcontrib_jquery](https://pypi.org/project/sphinxcontrib_jquery) | 4.1 | Extension to include jQuery on newer Sphinx releases
+[sphinxcontrib_jsmath](https://pypi.org/project/sphinxcontrib_jsmath) | 1.0.1 | A sphinx extension which renders display math in HTML via JavaScript
+[sphinxcontrib_qthelp](https://pypi.org/project/sphinxcontrib_qthelp) | 1.0.7 | sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp documents
+[sphinxcontrib_serializinghtml](https://pypi.org/project/sphinxcontrib_serializinghtml) | 1.1.9 | sphinxcontrib-serializinghtml is a sphinx extension which outputs "serialized" HTML files (json and pickle)
+[spyder](https://pypi.org/project/spyder) | 5.5.6 | The Scientific Python Development Environment
+[spyder_kernels](https://pypi.org/project/spyder_kernels) | 2.5.2 | Jupyter kernels for Spyder's console
+[sqlalchemy](https://pypi.org/project/sqlalchemy) | 2.0.35 | Database Abstraction Library
+[sqlite_bro](https://pypi.org/project/sqlite_bro) | 0.13.1 | a graphic SQLite Client in 1 Python file
+[sqlite_fts4](https://pypi.org/project/sqlite_fts4) | 1.0.3 | Python functions for working with SQLite FTS4 search
+[sqlite_utils](https://pypi.org/project/sqlite_utils) | 3.38 | CLI tool and Python library for manipulating SQLite databases
+[sqlparse](https://pypi.org/project/sqlparse) | 0.5.3 | A non-validating SQL parser.
+[squarify](https://pypi.org/project/squarify) | 0.4.4 | Pure Python implementation of the squarify treemap layout algorithm
+[sspilib](https://pypi.org/project/sspilib) | 0.2.0 | SSPI API bindings for Python
+[sspyrs](https://pypi.org/project/sspyrs) | 0.3 | Lightweight interface for SSRS reports to python
+[stack_data](https://pypi.org/project/stack_data) | 0.6.3 | Extract data from python stack frames and tracebacks for informative displays
+[starlette](https://pypi.org/project/starlette) | 0.41.3 | The little ASGI library that shines.
+[statsmodels](https://pypi.org/project/statsmodels) | 0.14.4 | Statistical computations and models for Python
+[streamlit](https://pypi.org/project/streamlit) | 1.41.1 | A faster way to build and share data apps
+[streamz](https://pypi.org/project/streamz) | 0.6.3 | Streams
+[sympy](https://pypi.org/project/sympy) | 1.13.2 | Computer algebra system (CAS) in Python
+[tabulate](https://pypi.org/project/tabulate) | 0.9.0 | Pretty-print tabular data
+[tblib](https://pypi.org/project/tblib) | 3.0.0 | Traceback serialization library.
+[tenacity](https://pypi.org/project/tenacity) | 8.5.0 | Retry code until it succeeds
+[termcolor](https://pypi.org/project/termcolor) | 2.5.0 | ANSI color formatting for output in terminal
+[terminado](https://pypi.org/project/terminado) | 0.18.1 | Tornado websocket backend for the Xterm.js Javascript terminal emulator library.
+[text_unidecode](https://pypi.org/project/text_unidecode) | 1.3 | The most basic Text::Unidecode port
+[textdistance](https://pypi.org/project/textdistance) | 4.6.2 | Compute distance between the two texts.
+[thefuzz](https://pypi.org/project/thefuzz) | 0.22.1 | Fuzzy string matching in python
+[threadpoolctl](https://pypi.org/project/threadpoolctl) | 3.5.0 | threadpoolctl
+[three_merge](https://pypi.org/project/three_merge) | 0.1.1 | Simple library for merging two strings with respect to a base one
+[tifffile](https://pypi.org/project/tifffile) | 2025.1.10 | Read and write TIFF files
+[tiktoken](https://pypi.org/project/tiktoken) | 0.8.0 | tiktoken is a fast BPE tokeniser for use with OpenAI's models
+[tinycss2](https://pypi.org/project/tinycss2) | 1.3.0 | A tiny CSS parser
+[toml](https://pypi.org/project/toml) | 0.10.2 | Python Library for Tom's Obvious, Minimal Language
+[tomli](https://pypi.org/project/tomli) | 2.0.1 | A lil' TOML parser
+[tomli_w](https://pypi.org/project/tomli_w) | 1.0.0 | A lil' TOML writer
+[tomlkit](https://pypi.org/project/tomlkit) | 0.12.3 | Style preserving TOML library
+[toolz](https://pypi.org/project/toolz) | 1.0.0 | List processing tools and functional utilities
+[tornado](https://pypi.org/project/tornado) | 6.4.2 | Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed.
+[tqdm](https://pypi.org/project/tqdm) | 4.66.4 | Fast, Extensible Progress Meter
+[traitlets](https://pypi.org/project/traitlets) | 5.14.1 | Traitlets Python configuration system
+[traittypes](https://pypi.org/project/traittypes) | 0.2.1 | Scipy trait types
+[trio](https://pypi.org/project/trio) | 0.28.0 | A friendly Python library for async concurrency and I/O
+[trove_classifiers](https://pypi.org/project/trove_classifiers) | 2024.10.21.16 | Canonical source for classifiers on PyPI (pypi.org).
+[twine](https://pypi.org/project/twine) | 6.0.1 | Collection of utilities for publishing packages on PyPI
+[types_python_dateutil](https://pypi.org/project/types_python_dateutil) | 2.9.0.20240316 | Typing stubs for python-dateutil
+[typing_extensions](https://pypi.org/project/typing_extensions) | 4.12.2 | Backported and Experimental Type Hints for Python 3.8+
+[typing_inspect](https://pypi.org/project/typing_inspect) | 0.9.0 | Runtime inspection utilities for typing module.
+[tzdata](https://pypi.org/project/tzdata) | 2024.1 | Provider of IANA time zone data
+[tzlocal](https://pypi.org/project/tzlocal) | 5.2 | tzinfo object for the local timezone
+[uc_micro_py](https://pypi.org/project/uc_micro_py) | 1.0.1 | Micro subset of unicode data files for linkify-it-py projects.
+[ujson](https://pypi.org/project/ujson) | 5.10.0 | Ultra fast JSON encoder and decoder for Python
+[umap_learn](https://pypi.org/project/umap_learn) | 0.5.6 | Uniform Manifold Approximation and Projection
+[uncertainties](https://pypi.org/project/uncertainties) | 3.1.7 | Transparent calculations with uncertainties on the quantities involved (aka error propagation); fast calculation of derivatives
+[uri_template](https://pypi.org/project/uri_template) | 1.3.0 | RFC 6570 URI Template Processor
+[urllib3](https://pypi.org/project/urllib3) | 2.0.3 | HTTP library with thread-safe connection pooling, file post, and more.
+[uvicorn](https://pypi.org/project/uvicorn) | 0.30.3 | The lightning-fast ASGI server.
+[vega_datasets](https://pypi.org/project/vega_datasets) | 0.9.0 | A Python package for offline access to Vega datasets
+[waitress](https://pypi.org/project/waitress) | 3.0.0 | Waitress WSGI server
+[watchdog](https://pypi.org/project/watchdog) | 6.0.0 | Filesystem events monitoring
+[wcwidth](https://pypi.org/project/wcwidth) | 0.2.13 | Measures the displayed width of unicode strings in a terminal
+[webcolors](https://pypi.org/project/webcolors) | 24.11.1 | A library for working with the color formats defined by HTML and CSS.
+[webencodings](https://pypi.org/project/webencodings) | 0.5.1 | Character encoding aliases for legacy web content
+[websocket_client](https://pypi.org/project/websocket_client) | 1.8.0 | WebSocket client for Python with low level API options
+[websockets](https://pypi.org/project/websockets) | 14.2 | An implementation of the WebSocket Protocol (RFC 6455 & 7692)
+[werkzeug](https://pypi.org/project/werkzeug) | 3.1.3 | The comprehensive WSGI web application library.
+[whatthepatch](https://pypi.org/project/whatthepatch) | 1.0.7 | A patch parsing and application library.
+[wheel](https://pypi.org/project/wheel) | 0.45.1 | A built-package format for Python
+[widgetsnbextension](https://pypi.org/project/widgetsnbextension) | 4.0.13 | Jupyter interactive widgets for Jupyter Notebook
+[winpython](https://pypi.org/project/winpython) | 12.0.20250201 | WinPython distribution tools, including WPPM
+[wordcloud](https://pypi.org/project/wordcloud) | 1.9.4 | A little word cloud generator
+[wsproto](https://pypi.org/project/wsproto) | 1.2.0 | WebSockets state-machine based protocol implementation
+[xarray](https://pypi.org/project/xarray) | 2025.1.1 | N-D labeled arrays and datasets in Python
+[xlsxwriter](https://pypi.org/project/xlsxwriter) | 3.1.9 | A Python module for creating Excel XLSX files.
+[xmltodict](https://pypi.org/project/xmltodict) | 0.13.0 | Makes working with XML feel like you are working with JSON
+[xyzservices](https://pypi.org/project/xyzservices) | 2023.10.1 | Source of XYZ tiles providers
+[yapf](https://pypi.org/project/yapf) | 0.40.1 | A formatter for Python code.
+[yarl](https://pypi.org/project/yarl) | 1.18.3 | Yet another URL library
+[yt_dlp](https://pypi.org/project/yt_dlp) | 2023.7.6 | A youtube-dl fork with additional features and patches
+[zict](https://pypi.org/project/zict) | 3.0.0 | Mutable mapping tools
+[zipp](https://pypi.org/project/zipp) | 3.21.0 | Backport of pathlib-compatible object wrapper for zip files
+[zstandard](https://pypi.org/project/zstandard) | 0.23.0 | Zstandard bindings for Python
+
+
diff --git a/changelogs/WinPythonslim-64bit-3.12.8.1_History.md b/changelogs/WinPythonslim-64bit-3.12.8.1_History.md
new file mode 100644
index 00000000..72a872d2
--- /dev/null
+++ b/changelogs/WinPythonslim-64bit-3.12.8.1_History.md
@@ -0,0 +1,112 @@
+## History of changes for WinPython-64bit 3.12.8.1slim
+
+The following changes were made to WinPython-64bit distribution since version 3.12.8.0slim.
+
+
+### Tools
+
+Removed packages:
+
+ * [Pandoc](https://pandoc.org/) 3.1.9 (a universal document converter)
+
+### Python packages
+
+New packages:
+
+ * [faker](https://pypi.org/project/faker) 33.3.1 (Faker is a Python package that generates fake data for you.)
+ * [prince](https://pypi.org/project/prince) 0.15.0 (Factor analysis in Python: PCA, CA, MCA, MFA, FAMD, GPA)
+ * [pyogrio](https://pypi.org/project/pyogrio) 0.10.0 (Vectorized spatial vector file format I/O using GDAL/OGR)
+ * [pyspnego](https://pypi.org/project/pyspnego) 0.11.2 (Windows Negotiate Authentication Client and Server)
+ * [pywavelets](https://pypi.org/project/pywavelets) 1.8.0 (PyWavelets, wavelet transform module)
+ * [sklearn_compat](https://pypi.org/project/sklearn_compat) 0.1.3 (Ease support for compatible scikit-learn estimators across versions)
+ * [squarify](https://pypi.org/project/squarify) 0.4.4 (Pure Python implementation of the squarify treemap layout algorithm)
+ * [sspilib](https://pypi.org/project/sspilib) 0.2.0 (SSPI API bindings for Python)
+ * [thefuzz](https://pypi.org/project/thefuzz) 0.22.1 (Fuzzy string matching in python)
+
+Upgraded packages:
+
+ * [array_api_compat](https://pypi.org/project/array_api_compat) 1.8 → 1.10.0 (A wrapper around NumPy and other array libraries to make them compatible with the Array API standard)
+ * [bokeh](https://pypi.org/project/bokeh) 3.6.1 → 3.6.2 (Interactive plots and applications in the browser from Python)
+ * [cryptography](https://pypi.org/project/cryptography) 41.0.5 → 44.0.0 (cryptography is a package which provides cryptographic recipes and primitives to Python developers.)
+ * [cytoolz](https://pypi.org/project/cytoolz) 0.12.3 → 1.0.1 (Cython implementation of Toolz: High performance functional utilities)
+ * [deap](https://pypi.org/project/deap) 1.4.1 → 1.4.2 (Distributed Evolutionary Algorithms in Python)
+ * [geopandas](https://pypi.org/project/geopandas) 0.14.4 → 1.0.1 (Geographic pandas extensions)
+ * [hypothesis](https://pypi.org/project/hypothesis) 6.108.5 → 6.122.3 (A library for property-based testing)
+ * [imbalanced_learn](https://pypi.org/project/imbalanced_learn) 0.12.3 → 0.13.0 (Toolbox for imbalanced dataset in machine learning)
+ * [ipython](https://pypi.org/project/ipython) 8.26.0 → 8.31.0 (IPython: Productive Interactive Computing)
+ * [janus](https://pypi.org/project/janus) 1.0.0 → 2.0.0 (Mixed sync-async queue to interoperate between asyncio tasks and classic threads)
+ * [jaraco_context](https://pypi.org/project/jaraco_context) 5.3.0 → 6.0.1 (Useful decorators and context managers)
+ * [jaraco_functools](https://pypi.org/project/jaraco_functools) 4.0.1 → 4.1.0 (Functools like those found in stdlib)
+ * [jedi](https://pypi.org/project/jedi) 0.19.1 → 0.19.2 (An autocompletion tool for Python that can be used for text editors.)
+ * [keras](https://pypi.org/project/keras) 3.7.0 → 3.8.0 (Multi-backend Keras)
+ * [keyring](https://pypi.org/project/keyring) 25.2.1 → 25.6.0 (Store and access your passwords safely.)
+ * [llvmlite](https://pypi.org/project/llvmlite) 0.44.0rc2 → 0.44.0 (lightweight wrapper around basic LLVM functionality)
+ * [maturin](https://pypi.org/project/maturin) 1.7.0 → 1.8.1 (Build and publish crates with pyo3, cffi and uniffi bindings as well as rust binaries as python packages)
+ * [mlxtend](https://pypi.org/project/mlxtend) 0.22.0 → 0.23.3 (Machine Learning Library Extensions)
+ * [narwhals](https://pypi.org/project/narwhals) 1.15.2 → 1.21.1 (Extremely lightweight compatibility layer between dataframe libraries)
+ * [numba](https://pypi.org/project/numba) 0.61.0rc2 → 0.61.0 (compiling Python code using LLVM)
+ * [osqp](https://pypi.org/project/osqp) 0.6.7.post1 → 0.6.7.post3 (OSQP: The Operator Splitting QP Solver)
+ * [pillow](https://pypi.org/project/pillow) 11.0.0 → 11.1.0 (Python Imaging Library (Fork))
+ * [polars](https://pypi.org/project/polars) 1.18.0 → 1.20.0 (Blazingly fast DataFrame library)
+ * [pyarrow](https://pypi.org/project/pyarrow) 18.1.0 → 19.0.0 (Python library for Apache Arrow)
+ * [pygments](https://pypi.org/project/pygments) 2.18.0 → 2.19.1 (Pygments is a syntax highlighting package written in Python.)
+ * [pyparsing](https://pypi.org/project/pyparsing) 3.1.2 → 3.2.1 (pyparsing module - Classes and methods to define and execute parsing grammars)
+ * [pyproj](https://pypi.org/project/pyproj) 3.6.1 → 3.7.0 (Python interface to PROJ (cartographic projections and coordinate transformations library))
+ * [qdldl](https://pypi.org/project/qdldl) 0.1.7.post4 → 0.1.7.post5 (QDLDL, a free LDL factorization routine.)
+ * [qrcode](https://pypi.org/project/qrcode) 7.4.2 → 8.0 (QR Code image generator)
+ * [requests_ntlm](https://pypi.org/project/requests_ntlm) 1.1.0 → 1.3.0 (This package allows for HTTP NTLM authentication using the requests library.)
+ * [scikit_learn](https://pypi.org/project/scikit_learn) 1.6.0 → 1.6.1 (A set of python modules for machine learning and data mining)
+ * [scipy](https://pypi.org/project/scipy) 1.14.1 → 1.15.1 (Fundamental algorithms for scientific computing in Python)
+ * [shapely](https://pypi.org/project/shapely) 2.0.4 → 2.0.6 (Manipulation and analysis of geometric objects)
+ * [sqlite_utils](https://pypi.org/project/sqlite_utils) 3.37 → 3.38 (CLI tool and Python library for manipulating SQLite databases)
+ * [sqlparse](https://pypi.org/project/sqlparse) 0.4.3 → 0.5.3 (A non-validating SQL parser.)
+ * [tifffile](https://pypi.org/project/tifffile) 2024.7.2 → 2025.1.10 (Read and write TIFF files)
+ * [toolz](https://pypi.org/project/toolz) 0.12.0 → 1.0.0 (List processing tools and functional utilities)
+ * [tornado](https://pypi.org/project/tornado) 6.4.1 → 6.4.2 (Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed.)
+ * [trio](https://pypi.org/project/trio) 0.27.0 → 0.28.0 (A friendly Python library for async concurrency and I/O)
+ * [twine](https://pypi.org/project/twine) 4.0.1 → 6.0.1 (Collection of utilities for publishing packages on PyPI)
+ * [watchdog](https://pypi.org/project/watchdog) 4.0.1 → 6.0.0 (Filesystem events monitoring)
+ * [webcolors](https://pypi.org/project/webcolors) 1.12 → 24.11.1 (A library for working with the color formats defined by HTML and CSS.)
+ * [websockets](https://pypi.org/project/websockets) 13.1 → 14.2 (An implementation of the WebSocket Protocol (RFC 6455 & 7692))
+ * [werkzeug](https://pypi.org/project/werkzeug) 3.0.3 → 3.1.3 (The comprehensive WSGI web application library.)
+ * [whatthepatch](https://pypi.org/project/whatthepatch) 1.0.2 → 1.0.7 (A patch parsing and application library.)
+ * [wheel](https://pypi.org/project/wheel) 0.44.0 → 0.45.1 (A built-package format for Python)
+ * [winpython](https://pypi.org/project/winpython) 11.2.20241228 → 12.0.20250201 (WinPython distribution tools, including WPPM)
+ * [xarray](https://pypi.org/project/xarray) 2024.11.0 → 2025.1.1 (N-D labeled arrays and datasets in Python)
+ * [zipp](https://pypi.org/project/zipp) 3.17.0 → 3.21.0 (Backport of pathlib-compatible object wrapper for zip files)
+
+Removed packages:
+
+ * [about_time](https://pypi.org/project/about_time) 4.2.1 (Easily measure timing and throughput of code blocks, with beautiful human friendly representations.)
+ * [affine](https://pypi.org/project/affine) 2.3.1 (Matrices describing affine transformation of the plane.)
+ * [alive_progress](https://pypi.org/project/alive_progress) 3.1.5 (A new kind of Progress Bar, with real-time throughput, ETA, and very cool animations!)
+ * [autograd](https://pypi.org/project/autograd) 1.6.2 (Efficiently computes derivatives of numpy code.)
+ * [cartopy](https://pypi.org/project/cartopy) 0.23.0 (A Python library for cartographic visualizations with Matplotlib)
+ * [cftime](https://pypi.org/project/cftime) 1.6.3 (Time-handling functionality from netcdf4-python)
+ * [click_plugins](https://pypi.org/project/click_plugins) 1.1.1 (An extension module for click to enable registering CLI commands via setuptools entry-points.)
+ * [cligj](https://pypi.org/project/cligj) 0.7.2 (Click params for commmand line interfaces to GeoJSON)
+ * [clr_loader](https://pypi.org/project/clr_loader) 0.2.6 (Generic pure Python loader for .NET runtimes)
+ * [clrmagic](https://pypi.org/project/clrmagic) 0.0.1a2 (IPython cell magic to use .NET languages)
+ * [cma](https://pypi.org/project/cma) 3.2.2 (CMA-ES, Covariance Matrix Adaptation Evolution Strategy for non-linear numerical optimization in Python)
+ * [deprecated](https://pypi.org/project/deprecated) 1.2.13 (Python @deprecated decorator to deprecate old python classes, functions or methods.)
+ * [ecos](https://pypi.org/project/ecos) 2.0.13 (This is the Python package for ECOS: Embedded Cone Solver. See Github page for more information.)
+ * [fiona](https://pypi.org/project/fiona) 1.10.1 (Fiona reads and writes spatial data files)
+ * [grapheme](https://pypi.org/project/grapheme) 0.6.0 (Unicode grapheme helpers)
+ * [netcdf4](https://pypi.org/project/netcdf4) 1.7.1.post2 (Provides an object-oriented python interface to the netCDF version 4 library)
+ * [ntlm_auth](https://pypi.org/project/ntlm_auth) 1.5.0 (Creates NTLM authentication structures)
+ * [numexpr](https://pypi.org/project/numexpr) 2.10.1 (Fast numerical expression evaluator for NumPy)
+ * [pulp](https://pypi.org/project/pulp) 2.6.0 (PuLP is an LP modeler written in python)
+ * [pyaudio](https://pypi.org/project/pyaudio) 0.2.14 (Cross-platform audio I/O with PortAudio)
+ * [pycosat](https://pypi.org/project/pycosat) 0.6.6 (bindings to picosat (a SAT solver))
+ * [pymoo](https://pypi.org/project/pymoo) 0.6.1.3 (Multi-Objective Optimization in Python)
+ * [pypng](https://pypi.org/project/pypng) 0.20220715.0 (Pure Python library for saving and loading PNG images)
+ * [pyshp](https://pypi.org/project/pyshp) 2.3.1 (Pure Python read/write support for ESRI Shapefile format)
+ * [pythonnet](https://pypi.org/project/pythonnet) 3.0.3 (.NET and Mono integration for Python)
+ * [rasterio](https://pypi.org/project/rasterio) 1.3.10 (Fast and direct raster I/O for use with Numpy and SciPy)
+ * [snuggs](https://pypi.org/project/snuggs) 1.4.7 (Snuggs are s-expressions for Numpy)
+ * [wrapt](https://pypi.org/project/wrapt) 1.16.0 (Module for decorators, wrappers and monkey patching.)
+ * [xlwings](https://pypi.org/project/xlwings) 0.24.7 (Make Excel fly: Interact with Excel from Python and vice versa.)
+
+
+
+* * *
diff --git a/changelogs/WinPythonslim-64bit-3.12.9.0.md b/changelogs/WinPythonslim-64bit-3.12.9.0.md
new file mode 100644
index 00000000..9f11f9cb
--- /dev/null
+++ b/changelogs/WinPythonslim-64bit-3.12.9.0.md
@@ -0,0 +1,511 @@
+## WinPython 3.12.9.0slim
+
+The following packages are included in WinPython-64bit v3.12.9.0slim .
+
+
+
+### Tools
+
+Name | Version | Description
+-----|---------|------------
+
+
+### Python packages
+
+Name | Version | Description
+-----|---------|------------
+[Python](http://www.python.org/) | 3.12.9 | Python programming language with standard library
+[absl_py](https://pypi.org/project/absl_py) | 2.0.0 | Abseil Python Common Libraries, see https://github.com/abseil/abseil-py.
+[adbc_driver_manager](https://pypi.org/project/adbc_driver_manager) | 1.3.0 | A generic entrypoint for ADBC drivers.
+[aiofiles](https://pypi.org/project/aiofiles) | 23.2.1 | File support for asyncio.
+[aiohappyeyeballs](https://pypi.org/project/aiohappyeyeballs) | 2.4.4 | Happy Eyeballs for asyncio
+[aiohttp](https://pypi.org/project/aiohttp) | 3.11.11 | Async http client/server framework (asyncio)
+[aiosignal](https://pypi.org/project/aiosignal) | 1.3.1 | aiosignal: a list of registered asynchronous callbacks
+[aiosqlite](https://pypi.org/project/aiosqlite) | 0.20.0 | asyncio bridge to the standard sqlite3 module
+[alabaster](https://pypi.org/project/alabaster) | 0.7.16 | A light, configurable Sphinx theme
+[alembic](https://pypi.org/project/alembic) | 1.13.1 | A database migration tool for SQLAlchemy.
+[altair](https://pypi.org/project/altair) | 5.5.0 | Vega-Altair: A declarative statistical visualization library for Python.
+[aniso8601](https://pypi.org/project/aniso8601) | 9.0.1 | A library for parsing ISO 8601 strings.
+[annotated_types](https://pypi.org/project/annotated_types) | 0.6.0 | Reusable constraint types to use with typing.Annotated
+[ansicolors](https://pypi.org/project/ansicolors) | 1.1.8 | ANSI colors for Python
+[anthropic](https://pypi.org/project/anthropic) | 0.42.0 | The official Python library for the anthropic API
+[anyio](https://pypi.org/project/anyio) | 4.7.0 | High level compatibility layer for multiple asynchronous event loop implementations
+[anywidget](https://pypi.org/project/anywidget) | 0.9.12 | custom jupyter widgets made easy
+[appdirs](https://pypi.org/project/appdirs) | 1.4.4 | A small Python module for determining appropriate platform-specific dirs, e.g. a "user data dir".
+[argon2_cffi](https://pypi.org/project/argon2_cffi) | 23.1.0 | Argon2 for Python
+[argon2_cffi_bindings](https://pypi.org/project/argon2_cffi_bindings) | 21.2.0 | Low-level CFFI bindings for Argon2
+[array_api_compat](https://pypi.org/project/array_api_compat) | 1.10.0 | A wrapper around NumPy and other array libraries to make them compatible with the Array API standard
+[arrow](https://pypi.org/project/arrow) | 1.3.0 | Better dates & times for Python
+[asgi_csrf](https://pypi.org/project/asgi_csrf) | 0.9 | ASGI middleware for protecting against CSRF attacks
+[asgiref](https://pypi.org/project/asgiref) | 3.8.1 | ASGI specs, helper code, and adapters
+[asn1crypto](https://pypi.org/project/asn1crypto) | 1.5.1 | Fast ASN.1 parser and serializer with definitions for private keys, public keys, certificates, CRL, OCSP, CMS, PKCS#3, PKCS#7, PKCS#8, PKCS#12,
+[asteval](https://pypi.org/project/asteval) | 0.9.31 | Safe, minimalistic evaluator of python expression using ast module
+[astroid](https://pypi.org/project/astroid) | 3.1.0 | An abstract syntax tree for Python with inference support.
+[astropy](https://pypi.org/project/astropy) | 6.1.6 | Astronomy and astrophysics core library
+[astropy_iers_data](https://pypi.org/project/astropy_iers_data) | 0.2024.12.23.0.33.24 | IERS Earth Rotation and Leap Second tables for the astropy core package
+[asttokens](https://pypi.org/project/asttokens) | 2.4.1 | Annotate AST trees with source code positions
+[async_lru](https://pypi.org/project/async_lru) | 2.0.4 | Simple LRU cache for asyncio
+[atomicwrites](https://pypi.org/project/atomicwrites) | 1.4.0 | Atomic file writes.
+[attrs](https://pypi.org/project/attrs) | 23.2.0 | Classes Without Boilerplate
+[autopep8](https://pypi.org/project/autopep8) | 2.0.4 | A tool that automatically formats Python code to conform to the PEP 8 style guide
+[azure_core](https://pypi.org/project/azure_core) | 1.30.2 | Microsoft Azure Core Library for Python
+[azure_cosmos](https://pypi.org/project/azure_cosmos) | 4.7.0 | Microsoft Azure Cosmos Client Library for Python
+[azure_identity](https://pypi.org/project/azure_identity) | 1.16.1 | Microsoft Azure Identity Library for Python
+[babel](https://pypi.org/project/babel) | 2.16.0 | Internationalization utilities
+[baresql](https://pypi.org/project/baresql) | 1.0.0 | playing SQL directly on Python datas
+[bcrypt](https://pypi.org/project/bcrypt) | 4.0.1 | Modern password hashing for your software and your servers
+[beautifulsoup4](https://pypi.org/project/beautifulsoup4) | 4.12.2 | Screen-scraping library
+[binaryornot](https://pypi.org/project/binaryornot) | 0.4.4 | Ultra-lightweight pure Python package to check if a file is binary or text.
+[black](https://pypi.org/project/black) | 24.10.0 | The uncompromising code formatter.
+[bleach](https://pypi.org/project/bleach) | 6.1.0 | An easy safelist-based HTML-sanitizing tool.
+[blinker](https://pypi.org/project/blinker) | 1.9.0 | Fast, simple object-to-object and broadcast signaling
+[bokeh](https://pypi.org/project/bokeh) | 3.6.3 | Interactive plots and applications in the browser from Python
+[branca](https://pypi.org/project/branca) | 0.8.0 | Generate complex HTML+JS pages with Python
+[brotli](https://pypi.org/project/brotli) | 1.1.0 | Python bindings for the Brotli compression library
+[build](https://pypi.org/project/build) | 1.2.2.post1 | A simple, correct Python build frontend
+[cachetools](https://pypi.org/project/cachetools) | 5.4.0 | Extensible memoizing collections and decorators
+[certifi](https://pypi.org/project/certifi) | 2024.6.2 | Python package for providing Mozilla's CA Bundle.
+[cffi](https://pypi.org/project/cffi) | 1.17.1 | Foreign Function Interface for Python calling C code.
+[chardet](https://pypi.org/project/chardet) | 5.2.0 | Universal encoding detector for Python 3
+[charset_normalizer](https://pypi.org/project/charset_normalizer) | 3.4.0 | The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet.
+[clarabel](https://pypi.org/project/clarabel) | 0.10.0 | Clarabel Conic Interior Point Solver for Rust / Python
+[click](https://pypi.org/project/click) | 8.1.7 | Composable command line interface toolkit
+[click_default_group](https://pypi.org/project/click_default_group) | 1.2.4 | click_default_group
+[cloudpickle](https://pypi.org/project/cloudpickle) | 3.0.0 | Pickler class to extend the standard pickle.Pickler functionality
+[cohere](https://pypi.org/project/cohere) | 5.13.12 |
+[colorama](https://pypi.org/project/colorama) | 0.4.6 | Cross-platform colored terminal text.
+[colorcet](https://pypi.org/project/colorcet) | 3.1.0 | Collection of perceptually uniform colormaps
+[colorlog](https://pypi.org/project/colorlog) | 6.8.2 | Add colours to the output of Python's logging module.
+[comm](https://pypi.org/project/comm) | 0.2.2 | Jupyter Python Comm implementation, for usage in ipykernel, xeus-python etc.
+[contourpy](https://pypi.org/project/contourpy) | 1.3.1 | Python library for calculating contours of 2D quadrilateral grids
+[cookiecutter](https://pypi.org/project/cookiecutter) | 2.6.0 | A command-line utility that creates projects from project templates, e.g
+[cryptography](https://pypi.org/project/cryptography) | 44.0.0 | cryptography is a package which provides cryptographic recipes and primitives to Python developers.
+[cvxopt](https://pypi.org/project/cvxopt) | 1.3.2 | Convex optimization package
+[cvxpy](https://pypi.org/project/cvxpy) | 1.6.0 | A domain-specific language for modeling convex optimization problems in Python.
+[cycler](https://pypi.org/project/cycler) | 0.12.1 | Composable style cycles
+[cython](https://pypi.org/project/cython) | 3.0.11 | The Cython compiler for writing C extensions in the Python language.
+[cytoolz](https://pypi.org/project/cytoolz) | 1.0.1 | Cython implementation of Toolz: High performance functional utilities
+[dask](https://pypi.org/project/dask) | 2024.12.1 | Parallel PyData with Task Scheduling
+[dask_expr](https://pypi.org/project/dask_expr) | 1.1.21 | High Level Expressions for Dask
+[datasette](https://pypi.org/project/datasette) | 0.64.8 | An open source multi-tool for exploring and publishing data
+[datasette_graphql](https://pypi.org/project/datasette_graphql) | 2.2 | Datasette plugin providing an automatic GraphQL API for your SQLite databases
+[datashader](https://pypi.org/project/datashader) | 0.16.3 | Data visualization toolchain based on aggregating into a grid
+[deap](https://pypi.org/project/deap) | 1.4.2 | Distributed Evolutionary Algorithms in Python
+[debugpy](https://pypi.org/project/debugpy) | 1.8.0 | An implementation of the Debug Adapter Protocol for Python
+[decorator](https://pypi.org/project/decorator) | 5.1.1 | Decorators for Humans
+[defusedxml](https://pypi.org/project/defusedxml) | 0.7.1 | XML bomb protection for Python stdlib modules
+[diff_match_patch](https://pypi.org/project/diff_match_patch) | 20230430 | Diff Match and Patch
+[dill](https://pypi.org/project/dill) | 0.3.9 | serialize all of Python
+[distributed](https://pypi.org/project/distributed) | 2024.12.1 | Distributed scheduler for Dask
+[distro](https://pypi.org/project/distro) | 1.8.0 | Distro - an OS platform information API
+[django](https://pypi.org/project/django) | 5.0.7 | A high-level Python web framework that encourages rapid development and clean, pragmatic design.
+[dnspython](https://pypi.org/project/dnspython) | 2.6.1 | DNS toolkit
+[docstring_to_markdown](https://pypi.org/project/docstring_to_markdown) | 0.13 | On the fly conversion of Python docstrings to markdown
+[docutils](https://pypi.org/project/docutils) | 0.21.2 | Docutils -- Python Documentation Utilities
+[duckdb](https://pypi.org/project/duckdb) | 1.2.0 | DuckDB in-process database
+[entrypoints](https://pypi.org/project/entrypoints) | 0.4 | Discover and load entry points from installed packages.
+[et_xmlfile](https://pypi.org/project/et_xmlfile) | 1.1.0 | An implementation of lxml.xmlfile for the standard library
+[eval_type_backport](https://pypi.org/project/eval_type_backport) | 0.2.2 | Like `typing._eval_type`, but lets older Python versions use newer typing features.
+[executing](https://pypi.org/project/executing) | 2.0.1 | Get the currently executing AST node of a frame, and other information
+[faker](https://pypi.org/project/faker) | 33.3.1 | Faker is a Python package that generates fake data for you.
+[fast_histogram](https://pypi.org/project/fast_histogram) | 0.14 | Fast simple 1D and 2D histograms
+[fastapi](https://pypi.org/project/fastapi) | 0.115.6 | FastAPI framework, high performance, easy to learn, fast to code, ready for production
+[fastavro](https://pypi.org/project/fastavro) | 1.10.0 | Fast read/write of AVRO files
+[fastjsonschema](https://pypi.org/project/fastjsonschema) | 2.18.0 | Fastest Python implementation of JSON schema
+[filelock](https://pypi.org/project/filelock) | 3.14.0 | A platform independent file lock.
+[flake8](https://pypi.org/project/flake8) | 7.1.1 | the modular source code checker: pep8 pyflakes and co
+[flask](https://pypi.org/project/flask) | 3.1.0 | A simple framework for building complex web applications.
+[flit](https://pypi.org/project/flit) | 3.10.1 | A simple packaging tool for simple packages.
+[flit_core](https://pypi.org/project/flit_core) | 3.10.1 | Distribution-building parts of Flit. See flit package for more information
+[folium](https://pypi.org/project/folium) | 0.18.0 | Make beautiful maps with Leaflet.js & Python
+[fonttools](https://pypi.org/project/fonttools) | 4.55.3 | Tools to manipulate font files
+[fqdn](https://pypi.org/project/fqdn) | 1.5.1 | Validates fully-qualified domain names against RFC 1123, so that they are acceptable to modern bowsers
+[frozenlist](https://pypi.org/project/frozenlist) | 1.5.0 | A list-like structure which implements collections.abc.MutableSequence
+[fsspec](https://pypi.org/project/fsspec) | 2024.6.1 | File-system specification
+[fuzzywuzzy](https://pypi.org/project/fuzzywuzzy) | 0.18.0 | Fuzzy string matching in python
+[geographiclib](https://pypi.org/project/geographiclib) | 2.0 | The geodesic routines from GeographicLib
+[geopandas](https://pypi.org/project/geopandas) | 1.0.1 | Geographic pandas extensions
+[geopy](https://pypi.org/project/geopy) | 2.4.1 | Python Geocoding Toolbox
+[gitdb](https://pypi.org/project/gitdb) | 4.0.10 | Git Object Database
+[gitpython](https://pypi.org/project/gitpython) | 3.1.32 | GitPython is a Python library used to interact with Git repositories
+[google_auth](https://pypi.org/project/google_auth) | 2.37.0 | Google Authentication Library
+[graphene](https://pypi.org/project/graphene) | 3.3 | GraphQL Framework for Python
+[graphql_core](https://pypi.org/project/graphql_core) | 3.2.3 | GraphQL implementation for Python, a port of GraphQL.js, the JavaScript reference implementation for GraphQL.
+[graphql_relay](https://pypi.org/project/graphql_relay) | 3.2.0 | Relay library for graphql-core
+[greenlet](https://pypi.org/project/greenlet) | 3.1.1 | Lightweight in-process concurrent programming
+[griffe](https://pypi.org/project/griffe) | 1.5.5 | Signatures for entire Python programs
+[groq](https://pypi.org/project/groq) | 0.13.1 | The official Python library for the groq API
+[guidata](https://pypi.org/project/guidata) | 3.7.1 | Automatic GUI generation for easy dataset editing and display
+[h11](https://pypi.org/project/h11) | 0.14.0 | A pure-Python, bring-your-own-I/O implementation of HTTP/1.1
+[h2](https://pypi.org/project/h2) | 4.1.0 | HTTP/2 State-Machine based protocol implementation
+[h5py](https://pypi.org/project/h5py) | 3.12.1 | Read and write HDF5 files from Python
+[hatchling](https://pypi.org/project/hatchling) | 1.27.0 | Modern, extensible Python build backend
+[holoviews](https://pypi.org/project/holoviews) | 1.20.0 | A high-level plotting API for the PyData ecosystem built on HoloViews.
+[hpack](https://pypi.org/project/hpack) | 4.0.0 | Pure-Python HPACK header compression
+[html5lib](https://pypi.org/project/html5lib) | 1.1 | HTML parser based on the WHATWG HTML specification
+[httpcore](https://pypi.org/project/httpcore) | 1.0.5 | A minimal low-level HTTP client.
+[httpie](https://pypi.org/project/httpie) | 3.2.4 | HTTPie: modern, user-friendly command-line HTTP client for the API era.
+[httpx](https://pypi.org/project/httpx) | 0.27.2 | The next generation HTTP client.
+[httpx_sse](https://pypi.org/project/httpx_sse) | 0.4.0 | Consume Server-Sent Event (SSE) messages with HTTPX.
+[huggingface_hub](https://pypi.org/project/huggingface_hub) | 0.28.1 | Client library to download and publish models, datasets and other repos on the huggingface.co hub
+[hupper](https://pypi.org/project/hupper) | 1.12 | Integrated process monitor for developing and reloading daemons.
+[hvplot](https://pypi.org/project/hvplot) | 0.11.2 | A high-level plotting API for the PyData ecosystem built on HoloViews.
+[hypercorn](https://pypi.org/project/hypercorn) | 0.16.0 | A ASGI Server based on Hyper libraries and inspired by Gunicorn
+[hyperframe](https://pypi.org/project/hyperframe) | 6.0.1 | HTTP/2 framing layer for Python
+[hypothesis](https://pypi.org/project/hypothesis) | 6.122.3 | A library for property-based testing
+[idna](https://pypi.org/project/idna) | 3.7 | Internationalized Domain Names in Applications (IDNA)
+[imageio](https://pypi.org/project/imageio) | 2.33.1 | Library for reading and writing a wide range of image, video, scientific, and volumetric data formats.
+[imagesize](https://pypi.org/project/imagesize) | 1.4.1 | Getting image size from png/jpeg/jpeg2000/gif file
+[imbalanced_learn](https://pypi.org/project/imbalanced_learn) | 0.13.0 | Toolbox for imbalanced dataset in machine learning
+[importlib_metadata](https://pypi.org/project/importlib_metadata) | 7.1.0 | Read metadata from Python packages
+[inflection](https://pypi.org/project/inflection) | 0.5.1 | A port of Ruby on Rails inflector to Python
+[iniconfig](https://pypi.org/project/iniconfig) | 2.0.0 | brain-dead simple config-ini parsing
+[intervaltree](https://pypi.org/project/intervaltree) | 3.0.2 | Editable interval tree data structure for Python 2 and 3
+[ipycanvas](https://pypi.org/project/ipycanvas) | 0.13.3 | Interactive widgets library exposing the browser's Canvas API
+[ipykernel](https://pypi.org/project/ipykernel) | 6.29.5 | IPython Kernel for Jupyter
+[ipyleaflet](https://pypi.org/project/ipyleaflet) | 0.19.2 | A Jupyter widget for dynamic Leaflet maps
+[ipympl](https://pypi.org/project/ipympl) | 0.9.6 | Matplotlib Jupyter Extension
+[ipython](https://pypi.org/project/ipython) | 8.32.0 | IPython: Productive Interactive Computing
+[ipython_genutils](https://pypi.org/project/ipython_genutils) | 0.2.0 | Vestigial utilities from IPython
+[ipython_sql](https://pypi.org/project/ipython_sql) | 0.5.0 | RDBMS access via IPython
+[ipywidgets](https://pypi.org/project/ipywidgets) | 8.1.5 | Jupyter interactive widgets
+[isoduration](https://pypi.org/project/isoduration) | 20.11.0 | Operations with ISO 8601 durations
+[isort](https://pypi.org/project/isort) | 5.13.2 | A Python utility / library to sort Python imports.
+[itsdangerous](https://pypi.org/project/itsdangerous) | 2.2.0 | Safely pass data to untrusted environments and back.
+[janus](https://pypi.org/project/janus) | 2.0.0 | Mixed sync-async queue to interoperate between asyncio tasks and classic threads
+[jaraco_classes](https://pypi.org/project/jaraco_classes) | 3.4.0 | Utility functions for Python class constructs
+[jaraco_context](https://pypi.org/project/jaraco_context) | 6.0.1 | Useful decorators and context managers
+[jaraco_functools](https://pypi.org/project/jaraco_functools) | 4.1.0 | Functools like those found in stdlib
+[jedi](https://pypi.org/project/jedi) | 0.19.2 | An autocompletion tool for Python that can be used for text editors.
+[jellyfish](https://pypi.org/project/jellyfish) | 1.1.3 | Approximate and phonetic matching of strings.
+[jinja2](https://pypi.org/project/jinja2) | 3.1.2 | A very fast and expressive template engine.
+[jiter](https://pypi.org/project/jiter) | 0.8.2 | Fast iterable JSON parser.
+[joblib](https://pypi.org/project/joblib) | 1.4.2 | Lightweight pipelining with Python functions
+[json5](https://pypi.org/project/json5) | 0.9.14 | A Python implementation of the JSON5 data format.
+[jsonpatch](https://pypi.org/project/jsonpatch) | 1.33 | Apply JSON-Patches (RFC 6902)
+[jsonpath_python](https://pypi.org/project/jsonpath_python) | 1.0.6 | A more powerful JSONPath implementation in modern python
+[jsonpointer](https://pypi.org/project/jsonpointer) | 2.4 | Identify specific nodes in a JSON document (RFC 6901)
+[jsonschema](https://pypi.org/project/jsonschema) | 4.19.2 | An implementation of JSON Schema validation for Python
+[jsonschema_specifications](https://pypi.org/project/jsonschema_specifications) | 2023.12.1 | The JSON Schema meta-schemas and vocabularies, exposed as a Registry
+[julia](https://pypi.org/project/julia) | 0.6.2 | Julia/Python bridge with IPython support.
+[jupyter](https://pypi.org/project/jupyter) | 1.1.1 | Jupyter metapackage. Install all the Jupyter components in one go.
+[jupyter_bokeh](https://pypi.org/project/jupyter_bokeh) | 4.0.5 | A Jupyter extension for rendering Bokeh content.
+[jupyter_client](https://pypi.org/project/jupyter_client) | 8.6.2 | Jupyter protocol implementation and client libraries
+[jupyter_console](https://pypi.org/project/jupyter_console) | 6.6.3 | Jupyter terminal console
+[jupyter_core](https://pypi.org/project/jupyter_core) | 5.7.2 | Jupyter core package. A base package on which Jupyter projects rely.
+[jupyter_events](https://pypi.org/project/jupyter_events) | 0.10.0 | Jupyter Event System library
+[jupyter_leaflet](https://pypi.org/project/jupyter_leaflet) | 0.19.2 | ipyleaflet extensions for JupyterLab and Jupyter Notebook
+[jupyter_lsp](https://pypi.org/project/jupyter_lsp) | 2.2.5 | Multi-Language Server WebSocket proxy for Jupyter Notebook/Lab server
+[jupyter_server](https://pypi.org/project/jupyter_server) | 2.14.2 | The backend—i.e. core services, APIs, and REST endpoints—to Jupyter web applications.
+[jupyter_server_terminals](https://pypi.org/project/jupyter_server_terminals) | 0.5.3 | A Jupyter Server Extension Providing Terminals.
+[jupyterlab](https://pypi.org/project/jupyterlab) | 4.3.5 | JupyterLab computational environment
+[jupyterlab_pygments](https://pypi.org/project/jupyterlab_pygments) | 0.3.0 | Pygments theme using JupyterLab CSS variables
+[jupyterlab_server](https://pypi.org/project/jupyterlab_server) | 2.27.3 | A set of server components for JupyterLab and JupyterLab like applications.
+[jupyterlab_widgets](https://pypi.org/project/jupyterlab_widgets) | 3.0.13 | Jupyter interactive widgets for JupyterLab
+[keras](https://pypi.org/project/keras) | 3.8.0 | Multi-backend Keras
+[keyring](https://pypi.org/project/keyring) | 25.6.0 | Store and access your passwords safely.
+[kiwisolver](https://pypi.org/project/kiwisolver) | 1.4.8 | A fast implementation of the Cassowary constraint solver
+[langchain](https://pypi.org/project/langchain) | 0.3.18 | Building applications with LLMs through composability
+[langchain_core](https://pypi.org/project/langchain_core) | 0.3.34 | Building applications with LLMs through composability
+[langchain_text_splitters](https://pypi.org/project/langchain_text_splitters) | 0.3.6 | LangChain text splitting utilities
+[langsmith](https://pypi.org/project/langsmith) | 0.2.11 | Client library to connect to the LangSmith LLM Tracing and Evaluation Platform.
+[lazy_loader](https://pypi.org/project/lazy_loader) | 0.4 | Makes it easy to load subpackages and functions on demand.
+[linkify_it_py](https://pypi.org/project/linkify_it_py) | 2.0.2 | Links recognition library with FULL unicode support.
+[llvmlite](https://pypi.org/project/llvmlite) | 0.44.0 | lightweight wrapper around basic LLVM functionality
+[lmfit](https://pypi.org/project/lmfit) | 1.3.1 | Least-Squares Minimization with Bounds and Constraints
+[locket](https://pypi.org/project/locket) | 1.0.0 | File-based locks for Python on Linux and Windows
+[logfire_api](https://pypi.org/project/logfire_api) | 3.5.3 | Shim for the Logfire SDK which does nothing unless Logfire is installed
+[lxml](https://pypi.org/project/lxml) | 5.3.0 | Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API.
+[mako](https://pypi.org/project/mako) | 1.3.5 | A super-fast templating language that borrows the best ideas from the existing templating languages.
+[markdown](https://pypi.org/project/markdown) | 3.5.1 | Python implementation of John Gruber's Markdown.
+[markdown_it_py](https://pypi.org/project/markdown_it_py) | 2.2.0 | Python port of markdown-it. Markdown parsing, done right!
+[markupsafe](https://pypi.org/project/markupsafe) | 3.0.2 | Safely add untrusted strings to HTML/XML markup.
+[matplotlib](https://pypi.org/project/matplotlib) | 3.10.0 | Python plotting package
+[matplotlib_inline](https://pypi.org/project/matplotlib_inline) | 0.1.7 | Inline Matplotlib backend for Jupyter
+[maturin](https://pypi.org/project/maturin) | 1.8.1 | Build and publish crates with pyo3, cffi and uniffi bindings as well as rust binaries as python packages
+[mccabe](https://pypi.org/project/mccabe) | 0.7.0 | McCabe checker, plugin for flake8
+[mdit_py_plugins](https://pypi.org/project/mdit_py_plugins) | 0.3.5 | Collection of plugins for markdown-it-py
+[mdurl](https://pypi.org/project/mdurl) | 0.1.2 | Markdown URL utilities
+[mercantile](https://pypi.org/project/mercantile) | 1.2.1 | Web mercator XYZ tile utilities
+[mergedeep](https://pypi.org/project/mergedeep) | 1.3.4 | A deep merge function for 🐍.
+[missingno](https://pypi.org/project/missingno) | 0.5.1 | Missing data visualization module for Python.
+[mistralai](https://pypi.org/project/mistralai) | 1.2.5 | Python Client SDK for the Mistral AI API.
+[mistune](https://pypi.org/project/mistune) | 2.0.5 | A sane Markdown parser with useful plugins and renderers
+[mizani](https://pypi.org/project/mizani) | 0.11.4 | Scales for Python
+[ml_dtypes](https://pypi.org/project/ml_dtypes) | 0.5.0 |
+[mlxtend](https://pypi.org/project/mlxtend) | 0.23.3 | Machine Learning Library Extensions
+[more_itertools](https://pypi.org/project/more_itertools) | 10.2.0 | More routines for operating on iterables, beyond itertools
+[mpl_scatter_density](https://pypi.org/project/mpl_scatter_density) | 0.7 | Matplotlib helpers to make density scatter plots
+[mpld3](https://pypi.org/project/mpld3) | 0.5.8 | D3 Viewer for Matplotlib
+[mpmath](https://pypi.org/project/mpmath) | 1.3.0 | Python library for arbitrary-precision floating-point arithmetic
+[msal](https://pypi.org/project/msal) | 1.30.0 | The Microsoft Authentication Library (MSAL) for Python library enables your app to access the Microsoft Cloud by supporting authentication of us
+[msal_extensions](https://pypi.org/project/msal_extensions) | 1.2.0 | Microsoft Authentication Library extensions (MSAL EX) provides a persistence API that can save your data on disk, encrypted on Windows, macOS an
+[msgpack](https://pypi.org/project/msgpack) | 1.1.0 | MessagePack serializer
+[multidict](https://pypi.org/project/multidict) | 6.1.0 | multidict implementation
+[multipledispatch](https://pypi.org/project/multipledispatch) | 1.0.0 | Multiple dispatch
+[mutagen](https://pypi.org/project/mutagen) | 1.47.0 | read and write audio tags for many formats
+[mypy](https://pypi.org/project/mypy) | 1.14.0 | Optional static typing for Python
+[mypy_extensions](https://pypi.org/project/mypy_extensions) | 1.0.0 | Type system extensions for programs checked with the mypy type checker.
+[mysql_connector_python](https://pypi.org/project/mysql_connector_python) | 8.0.21 | MySQL driver written in Python
+[namex](https://pypi.org/project/namex) | 0.0.8 | A simple utility to separate the implementation of your Python package and its public API surface.
+[narwhals](https://pypi.org/project/narwhals) | 1.21.1 | Extremely lightweight compatibility layer between dataframe libraries
+[nbclient](https://pypi.org/project/nbclient) | 0.10.0 | A client library for executing notebooks. Formerly nbconvert's ExecutePreprocessor.
+[nbconvert](https://pypi.org/project/nbconvert) | 7.16.1 | Converting Jupyter Notebooks (.ipynb files) to other formats
+[nbformat](https://pypi.org/project/nbformat) | 5.10.4 | The Jupyter Notebook format
+[nest_asyncio](https://pypi.org/project/nest_asyncio) | 1.6.0 | Patch asyncio to allow nested event loops
+[networkx](https://pypi.org/project/networkx) | 3.4.2 | Python package for creating and manipulating graphs and networks
+[nh3](https://pypi.org/project/nh3) | 0.2.18 | Python bindings to the ammonia HTML sanitization library.
+[nltk](https://pypi.org/project/nltk) | 3.9.1 | Natural Language Toolkit
+[notebook](https://pypi.org/project/notebook) | 7.3.1 | Jupyter Notebook - A web-based notebook environment for interactive computing
+[notebook_shim](https://pypi.org/project/notebook_shim) | 0.2.4 | A shim layer for notebook traits and config
+[numba](https://pypi.org/project/numba) | 0.61.0 | compiling Python code using LLVM
+[numpy](https://pypi.org/project/numpy) | 2.1.3 | Fundamental package for array computing in Python
+[numpydoc](https://pypi.org/project/numpydoc) | 1.6.0 | Sphinx extension to support docstrings in Numpy format
+[openai](https://pypi.org/project/openai) | 1.61.1 | The official Python library for the openai API
+[opencv_python](https://pypi.org/project/opencv_python) | 4.10.0.84 | Wrapper package for OpenCV python bindings.
+[openpyxl](https://pypi.org/project/openpyxl) | 3.1.2 | A Python library to read/write Excel 2010 xlsx/xlsm files
+[optree](https://pypi.org/project/optree) | 0.13.1 | Optimized PyTree Utilities.
+[optuna](https://pypi.org/project/optuna) | 3.6.1 | A hyperparameter optimization framework
+[orjson](https://pypi.org/project/orjson) | 3.10.12 | Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy
+[osqp](https://pypi.org/project/osqp) | 0.6.7.post3 | OSQP: The Operator Splitting QP Solver
+[outcome](https://pypi.org/project/outcome) | 1.3.0.post0 | Capture the outcome of Python function calls.
+[overrides](https://pypi.org/project/overrides) | 7.7.0 | A decorator to automatically detect mismatch when overriding a method.
+[packaging](https://pypi.org/project/packaging) | 24.2 | Core utilities for Python packages
+[pandas](https://pypi.org/project/pandas) | 2.2.3 | Powerful data structures for data analysis, time series, and statistics
+[pandocfilters](https://pypi.org/project/pandocfilters) | 1.5.0 | Utilities for writing pandoc filters in python
+[panel](https://pypi.org/project/panel) | 1.6.0 | The powerful data exploration & web app framework for Python.
+[papermill](https://pypi.org/project/papermill) | 2.6.0 | Parameterize and run Jupyter and nteract Notebooks
+[param](https://pypi.org/project/param) | 2.1.1 | Make your Python code clearer and more reliable by declaring Parameters.
+[paramiko](https://pypi.org/project/paramiko) | 2.8.0 | SSH2 protocol library
+[parso](https://pypi.org/project/parso) | 0.8.4 | A Python Parser
+[partd](https://pypi.org/project/partd) | 1.4.0 | Appendable key-value storage
+[pathspec](https://pypi.org/project/pathspec) | 0.11.0 | Utility library for gitignore style pattern matching of file paths.
+[patsy](https://pypi.org/project/patsy) | 0.5.6 | A Python package for describing statistical models and for building design matrices.
+[pep8](https://pypi.org/project/pep8) | 1.7.1 | Python style guide checker
+[pexpect](https://pypi.org/project/pexpect) | 4.8.0 | Pexpect allows easy control of interactive console applications.
+[pg8000](https://pypi.org/project/pg8000) | 1.23.0 | PostgreSQL interface library
+[pickleshare](https://pypi.org/project/pickleshare) | 0.7.5 | Tiny 'shelve'-like database with concurrency support
+[pillow](https://pypi.org/project/pillow) | 11.1.0 | Python Imaging Library (Fork)
+[pint](https://pypi.org/project/pint) | 0.23 | Physical quantities module
+[pip](https://pypi.org/project/pip) | 24.3.1 | The PyPA recommended tool for installing Python packages.
+[pkginfo](https://pypi.org/project/pkginfo) | 1.11.2 | Query metadata from sdists / bdists / installed packages.
+[platformdirs](https://pypi.org/project/platformdirs) | 4.2.2 | A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`.
+[plotly](https://pypi.org/project/plotly) | 5.24.1 | An open-source, interactive data visualization library for Python
+[plotnine](https://pypi.org/project/plotnine) | 0.13.6 | A Grammar of Graphics for Python
+[plotpy](https://pypi.org/project/plotpy) | 2.7.2 | Curve and image plotting tools for Python/Qt applications
+[pluggy](https://pypi.org/project/pluggy) | 1.5.0 | plugin and hook calling mechanisms for python
+[ply](https://pypi.org/project/ply) | 3.11 | Python Lex & Yacc
+[polars](https://pypi.org/project/polars) | 1.22.0 | Blazingly fast DataFrame library
+[portalocker](https://pypi.org/project/portalocker) | 2.7.0 | Wraps the portalocker recipe for easy usage
+[prettytable](https://pypi.org/project/prettytable) | 3.3.0 | A simple Python library for easily displaying tabular data in a visually appealing ASCII table format
+[prince](https://pypi.org/project/prince) | 0.15.0 | Factor analysis in Python: PCA, CA, MCA, MFA, FAMD, GPA
+[priority](https://pypi.org/project/priority) | 2.0.0 | A pure-Python implementation of the HTTP/2 priority tree
+[prometheus_client](https://pypi.org/project/prometheus_client) | 0.18.0 | Python client for the Prometheus monitoring system.
+[prompt_toolkit](https://pypi.org/project/prompt_toolkit) | 3.0.48 | Library for building powerful interactive command lines in Python
+[propcache](https://pypi.org/project/propcache) | 0.2.1 | Accelerated property cache
+[protobuf](https://pypi.org/project/protobuf) | 5.27.3 |
+[psutil](https://pypi.org/project/psutil) | 5.9.8 | Cross-platform lib for process and system monitoring in Python.
+[psygnal](https://pypi.org/project/psygnal) | 0.11.1 | Fast python callback/event system modeled after Qt Signals
+[ptpython](https://pypi.org/project/ptpython) | 3.0.29 | Python REPL build on top of prompt_toolkit
+[ptyprocess](https://pypi.org/project/ptyprocess) | 0.7.0 | Run a subprocess in a pseudo terminal
+[pure_eval](https://pypi.org/project/pure_eval) | 0.2.2 | Safely evaluate AST nodes without side effects
+[pyarrow](https://pypi.org/project/pyarrow) | 19.0.0 | Python library for Apache Arrow
+[pyasn1](https://pypi.org/project/pyasn1) | 0.4.8 | ASN.1 types and codecs
+[pyasn1_modules](https://pypi.org/project/pyasn1_modules) | 0.2.8 | A collection of ASN.1-based protocols modules.
+[pybind11](https://pypi.org/project/pybind11) | 2.13.6 | Seamless operability between C++11 and Python
+[pycodestyle](https://pypi.org/project/pycodestyle) | 2.12.0 | Python style guide checker
+[pycparser](https://pypi.org/project/pycparser) | 2.22 | C parser in Python
+[pycryptodomex](https://pypi.org/project/pycryptodomex) | 3.20.0 | Cryptographic library for Python
+[pyct](https://pypi.org/project/pyct) | 0.5.0 | Python package common tasks for users (e.g. copy examples, fetch data, ...)
+[pydantic](https://pypi.org/project/pydantic) | 2.10.6 | Data validation using Python type hints
+[pydantic_ai](https://pypi.org/project/pydantic_ai) | 0.0.24 | Agent Framework / shim to use Pydantic with LLMs
+[pydantic_ai_slim](https://pypi.org/project/pydantic_ai_slim) | 0.0.24 | Agent Framework / shim to use Pydantic with LLMs, slim package
+[pydantic_core](https://pypi.org/project/pydantic_core) | 2.27.2 | Core functionality for Pydantic validation and serialization
+[pydantic_graph](https://pypi.org/project/pydantic_graph) | 0.0.24 | Graph and state machine library
+[pydeck](https://pypi.org/project/pydeck) | 0.9.1 | Widget for deck.gl maps
+[pydocstyle](https://pypi.org/project/pydocstyle) | 6.3.0 | Python docstring style checker
+[pydub](https://pypi.org/project/pydub) | 0.25.1 | Manipulate audio with an simple and easy high level interface
+[pyerfa](https://pypi.org/project/pyerfa) | 2.0.1.4 | Python bindings for ERFA
+[pyflakes](https://pypi.org/project/pyflakes) | 3.2.0 | passive checker of Python programs
+[pygments](https://pypi.org/project/pygments) | 2.19.1 | Pygments is a syntax highlighting package written in Python.
+[pyjwt](https://pypi.org/project/pyjwt) | 2.8.0 | JSON Web Token implementation in Python
+[pylint](https://pypi.org/project/pylint) | 3.1.0 | python code static checker
+[pylint_venv](https://pypi.org/project/pylint_venv) | 3.0.3 | pylint-venv provides a Pylint init-hook to use the same Pylint installation with different virtual environments.
+[pyls_spyder](https://pypi.org/project/pyls_spyder) | 0.4.0 | Spyder extensions for the python-lsp-server
+[pymongo](https://pypi.org/project/pymongo) | 4.10.1 | Python driver for MongoDB
+[pympler](https://pypi.org/project/pympler) | 1.0.1 | A development tool to measure, monitor and analyze the memory behavior of Python objects.
+[pynacl](https://pypi.org/project/pynacl) | 1.5.0 | Python binding to the Networking and Cryptography (NaCl) library
+[pynndescent](https://pypi.org/project/pynndescent) | 0.5.12 | Nearest Neighbor Descent
+[pyodbc](https://pypi.org/project/pyodbc) | 5.2.0 | DB API module for ODBC
+[pyogrio](https://pypi.org/project/pyogrio) | 0.10.0 | Vectorized spatial vector file format I/O using GDAL/OGR
+[pyomo](https://pypi.org/project/pyomo) | 6.8.2 | Pyomo: Python Optimization Modeling Objects
+[pypandoc](https://pypi.org/project/pypandoc) | 1.5 | Thin wrapper for pandoc.
+[pyparsing](https://pypi.org/project/pyparsing) | 3.2.1 | pyparsing module - Classes and methods to define and execute parsing grammars
+[pypdf](https://pypi.org/project/pypdf) | 5.1.0 | A pure-python PDF library capable of splitting, merging, cropping, and transforming PDF files
+[pyproj](https://pypi.org/project/pyproj) | 3.7.0 | Python interface to PROJ (cartographic projections and coordinate transformations library)
+[pyproject_hooks](https://pypi.org/project/pyproject_hooks) | 1.1.0 | Wrappers to call pyproject.toml-based build backend hooks.
+[pyqt5](https://pypi.org/project/pyqt5) | 5.15.10 | Python bindings for the Qt cross platform application toolkit
+[pyqt5_qt5](https://pypi.org/project/pyqt5_qt5) | 5.15.2 | The subset of a Qt installation needed by PyQt5.
+[pyqt5_sip](https://pypi.org/project/pyqt5_sip) | 12.16.1 | The sip module support for PyQt5
+[pyqtgraph](https://pypi.org/project/pyqtgraph) | 0.13.7 | Scientific Graphics and GUI Library for Python
+[pyqtwebengine](https://pypi.org/project/pyqtwebengine) | 5.15.6 | Python bindings for the Qt WebEngine framework
+[pyqtwebengine_qt5](https://pypi.org/project/pyqtwebengine_qt5) | 5.15.2 | The subset of a Qt installation needed by PyQtWebEngine.
+[pyserial](https://pypi.org/project/pyserial) | 3.5 | Python Serial Port Extension
+[pysocks](https://pypi.org/project/pysocks) | 1.7.1 | A Python SOCKS client module. See https://github.com/Anorov/PySocks for more information.
+[pyspnego](https://pypi.org/project/pyspnego) | 0.11.2 | Windows Negotiate Authentication Client and Server
+[pytest](https://pypi.org/project/pytest) | 8.2.2 | pytest: simple powerful testing with Python
+[python_barcode](https://pypi.org/project/python_barcode) | 0.15.1 | Create standard barcodes with Python. No external modules needed. (optional Pillow support included).
+[python_dateutil](https://pypi.org/project/python_dateutil) | 2.8.2 | Extensions to the standard Python datetime module
+[python_dotenv](https://pypi.org/project/python_dotenv) | 1.0.1 | Read key-value pairs from a .env file and set them as environment variables
+[python_json_logger](https://pypi.org/project/python_json_logger) | 2.0.7 | A python library adding a json log formatter
+[python_lsp_black](https://pypi.org/project/python_lsp_black) | 2.0.0 | Black plugin for the Python LSP Server
+[python_lsp_jsonrpc](https://pypi.org/project/python_lsp_jsonrpc) | 1.1.2 | JSON RPC 2.0 server library
+[python_lsp_server](https://pypi.org/project/python_lsp_server) | 1.12.0 | Python Language Server for the Language Server Protocol
+[python_multipart](https://pypi.org/project/python_multipart) | 0.0.9 | A streaming multipart parser for Python
+[python_slugify](https://pypi.org/project/python_slugify) | 8.0.4 | A Python slugify application that also handles Unicode
+[pythonqwt](https://pypi.org/project/pythonqwt) | 0.14.4 | Qt plotting widgets for Python
+[pytoolconfig](https://pypi.org/project/pytoolconfig) | 1.3.1 | Python tool configuration
+[pytz](https://pypi.org/project/pytz) | 2024.1 | World timezone definitions, modern and historical
+[pyusb](https://pypi.org/project/pyusb) | 1.3.1 | Easy USB access for Python
+[pyviz_comms](https://pypi.org/project/pyviz_comms) | 3.0.3 | A JupyterLab extension for rendering HoloViz content.
+[pywavelets](https://pypi.org/project/pywavelets) | 1.8.0 | PyWavelets, wavelet transform module
+[pywin32](https://pypi.org/project/pywin32) | 308 | Python for Window Extensions
+[pywin32_ctypes](https://pypi.org/project/pywin32_ctypes) | 0.2.2 | A (partial) reimplementation of pywin32 using ctypes/cffi
+[pywinpty](https://pypi.org/project/pywinpty) | 2.0.14 | Pseudo terminal support for Windows from Python.
+[pyyaml](https://pypi.org/project/pyyaml) | 6.0.2 | YAML parser and emitter for Python
+[pyzmq](https://pypi.org/project/pyzmq) | 26.2.0 | Python bindings for 0MQ
+[qdarkstyle](https://pypi.org/project/qdarkstyle) | 3.2.3 | The most complete dark/light style sheet for C++/Python and Qt applications
+[qdldl](https://pypi.org/project/qdldl) | 0.1.7.post5 | QDLDL, a free LDL factorization routine.
+[qrcode](https://pypi.org/project/qrcode) | 8.0 | QR Code image generator
+[qstylizer](https://pypi.org/project/qstylizer) | 0.2.2 | Stylesheet Generator for PyQt{4-5}/PySide{1-2}
+[qtawesome](https://pypi.org/project/qtawesome) | 1.3.1 | FontAwesome icons in PyQt and PySide applications
+[qtconsole](https://pypi.org/project/qtconsole) | 5.5.2 | Jupyter Qt console
+[qtpy](https://pypi.org/project/qtpy) | 2.4.1 | Provides an abstraction layer on top of the various Qt bindings (PyQt5/6 and PySide2/6).
+[quantecon](https://pypi.org/project/quantecon) | 0.7.2 | Import the main names to top level.
+[quart](https://pypi.org/project/quart) | 0.19.4 | A Python ASGI web microframework with the same API as Flask
+[rapidfuzz](https://pypi.org/project/rapidfuzz) | 3.9.6 | rapid fuzzy string matching
+[readme_renderer](https://pypi.org/project/readme_renderer) | 44.0 | readme_renderer is a library for rendering readme descriptions for Warehouse
+[redis](https://pypi.org/project/redis) | 5.0.8 | Python client for Redis database and key-value store
+[referencing](https://pypi.org/project/referencing) | 0.35.1 | JSON Referencing + Python
+[regex](https://pypi.org/project/regex) | 2024.11.6 | Alternative regular expression module, to replace re.
+[reportlab](https://pypi.org/project/reportlab) | 4.2.5 | The Reportlab Toolkit
+[requests](https://pypi.org/project/requests) | 2.32.3 | Python HTTP for Humans.
+[requests_ntlm](https://pypi.org/project/requests_ntlm) | 1.3.0 | This package allows for HTTP NTLM authentication using the requests library.
+[requests_toolbelt](https://pypi.org/project/requests_toolbelt) | 1.0.0 | A utility belt for advanced users of python-requests
+[rfc3339_validator](https://pypi.org/project/rfc3339_validator) | 0.1.4 | A pure python RFC3339 validator
+[rfc3986](https://pypi.org/project/rfc3986) | 2.0.0 | Validating URI References per RFC 3986
+[rfc3986_validator](https://pypi.org/project/rfc3986_validator) | 0.1.1 | Pure python rfc3986 validator
+[rich](https://pypi.org/project/rich) | 13.9.4 | Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal
+[rope](https://pypi.org/project/rope) | 1.12.0 | a python refactoring library...
+[rpds_py](https://pypi.org/project/rpds_py) | 0.22.3 | Python bindings to Rust's persistent data structures (rpds)
+[rsa](https://pypi.org/project/rsa) | 4.7.2 | Pure-Python RSA implementation
+[rtree](https://pypi.org/project/rtree) | 1.1.0 | R-Tree spatial index for Python GIS
+[rx](https://pypi.org/project/rx) | 3.1.1 | Reactive Extensions (Rx) for Python
+[scikit_image](https://pypi.org/project/scikit_image) | 0.25.0 | Image processing in Python
+[scikit_learn](https://pypi.org/project/scikit_learn) | 1.6.1 | A set of python modules for machine learning and data mining
+[scipy](https://pypi.org/project/scipy) | 1.15.1 | Fundamental algorithms for scientific computing in Python
+[scramp](https://pypi.org/project/scramp) | 1.4.5 | An implementation of the SCRAM protocol.
+[scs](https://pypi.org/project/scs) | 3.2.7.post2 | Splitting conic solver
+[seaborn](https://pypi.org/project/seaborn) | 0.13.2 | Statistical data visualization
+[send2trash](https://pypi.org/project/send2trash) | 1.8.2 | Send file to trash natively under Mac OS X, Windows and Linux
+[setuptools](https://pypi.org/project/setuptools) | 75.6.0 | Easily download, build, install, upgrade, and uninstall Python packages
+[shapely](https://pypi.org/project/shapely) | 2.0.6 | Manipulation and analysis of geometric objects
+[simplejson](https://pypi.org/project/simplejson) | 3.19.3 | Simple, fast, extensible JSON encoder/decoder for Python
+[simpy](https://pypi.org/project/simpy) | 4.0.1 | Event discrete, process based simulation for Python.
+[six](https://pypi.org/project/six) | 1.16.0 | Python 2 and 3 compatibility utilities
+[sklearn_compat](https://pypi.org/project/sklearn_compat) | 0.1.3 | Ease support for compatible scikit-learn estimators across versions
+[smmap](https://pypi.org/project/smmap) | 5.0.0 | A pure Python implementation of a sliding window memory map manager
+[sniffio](https://pypi.org/project/sniffio) | 1.3.0 | Sniff out which async library your code is running under
+[snowballstemmer](https://pypi.org/project/snowballstemmer) | 2.2.0 | This package provides 29 stemmers for 28 languages generated from Snowball algorithms.
+[sortedcontainers](https://pypi.org/project/sortedcontainers) | 2.4.0 | Sorted Containers -- Sorted List, Sorted Dict, Sorted Set
+[sounddevice](https://pypi.org/project/sounddevice) | 0.5.1 | Play and Record Sound with Python
+[soupsieve](https://pypi.org/project/soupsieve) | 2.6 | A modern CSS selector implementation for Beautiful Soup.
+[sphinx](https://pypi.org/project/sphinx) | 7.3.7 | Python documentation generator
+[sphinx_rtd_theme](https://pypi.org/project/sphinx_rtd_theme) | 3.0.2 | Read the Docs theme for Sphinx
+[sphinxcontrib_applehelp](https://pypi.org/project/sphinxcontrib_applehelp) | 2.0.0 | sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books
+[sphinxcontrib_devhelp](https://pypi.org/project/sphinxcontrib_devhelp) | 2.0.0 | sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp documents
+[sphinxcontrib_htmlhelp](https://pypi.org/project/sphinxcontrib_htmlhelp) | 2.1.0 | sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files
+[sphinxcontrib_jquery](https://pypi.org/project/sphinxcontrib_jquery) | 4.1 | Extension to include jQuery on newer Sphinx releases
+[sphinxcontrib_jsmath](https://pypi.org/project/sphinxcontrib_jsmath) | 1.0.1 | A sphinx extension which renders display math in HTML via JavaScript
+[sphinxcontrib_qthelp](https://pypi.org/project/sphinxcontrib_qthelp) | 2.0.0 | sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp documents
+[sphinxcontrib_serializinghtml](https://pypi.org/project/sphinxcontrib_serializinghtml) | 2.0.0 | sphinxcontrib-serializinghtml is a sphinx extension which outputs "serialized" HTML files (json and pickle)
+[spyder](https://pypi.org/project/spyder) | 5.5.6 | The Scientific Python Development Environment
+[spyder_kernels](https://pypi.org/project/spyder_kernels) | 2.5.2 | Jupyter kernels for Spyder's console
+[sqlalchemy](https://pypi.org/project/sqlalchemy) | 2.0.35 | Database Abstraction Library
+[sqlite_bro](https://pypi.org/project/sqlite_bro) | 0.13.1 | a graphic SQLite Client in 1 Python file
+[sqlite_fts4](https://pypi.org/project/sqlite_fts4) | 1.0.3 | Python functions for working with SQLite FTS4 search
+[sqlite_utils](https://pypi.org/project/sqlite_utils) | 3.38 | CLI tool and Python library for manipulating SQLite databases
+[sqlparse](https://pypi.org/project/sqlparse) | 0.5.3 | A non-validating SQL parser.
+[squarify](https://pypi.org/project/squarify) | 0.4.4 | Pure Python implementation of the squarify treemap layout algorithm
+[sspilib](https://pypi.org/project/sspilib) | 0.2.0 | SSPI API bindings for Python
+[stack_data](https://pypi.org/project/stack_data) | 0.6.3 | Extract data from python stack frames and tracebacks for informative displays
+[starlette](https://pypi.org/project/starlette) | 0.41.3 | The little ASGI library that shines.
+[statsmodels](https://pypi.org/project/statsmodels) | 0.14.4 | Statistical computations and models for Python
+[streamlit](https://pypi.org/project/streamlit) | 1.41.1 | A faster way to build and share data apps
+[streamz](https://pypi.org/project/streamz) | 0.6.3 | Streams
+[sympy](https://pypi.org/project/sympy) | 1.13.3 | Computer algebra system (CAS) in Python
+[tabulate](https://pypi.org/project/tabulate) | 0.9.0 | Pretty-print tabular data
+[tblib](https://pypi.org/project/tblib) | 3.0.0 | Traceback serialization library.
+[tenacity](https://pypi.org/project/tenacity) | 9.0.0 | Retry code until it succeeds
+[termcolor](https://pypi.org/project/termcolor) | 2.5.0 | ANSI color formatting for output in terminal
+[terminado](https://pypi.org/project/terminado) | 0.18.1 | Tornado websocket backend for the Xterm.js Javascript terminal emulator library.
+[text_unidecode](https://pypi.org/project/text_unidecode) | 1.3 | The most basic Text::Unidecode port
+[textdistance](https://pypi.org/project/textdistance) | 4.6.3 | Compute distance between the two texts.
+[thefuzz](https://pypi.org/project/thefuzz) | 0.22.1 | Fuzzy string matching in python
+[threadpoolctl](https://pypi.org/project/threadpoolctl) | 3.5.0 | threadpoolctl
+[three_merge](https://pypi.org/project/three_merge) | 0.1.1 | Simple library for merging two strings with respect to a base one
+[tifffile](https://pypi.org/project/tifffile) | 2025.1.10 | Read and write TIFF files
+[tiktoken](https://pypi.org/project/tiktoken) | 0.8.0 | tiktoken is a fast BPE tokeniser for use with OpenAI's models
+[tinycss2](https://pypi.org/project/tinycss2) | 1.4.0 | A tiny CSS parser
+[tokenizers](https://pypi.org/project/tokenizers) | 0.21.0 |
+[toml](https://pypi.org/project/toml) | 0.10.2 | Python Library for Tom's Obvious, Minimal Language
+[tomli](https://pypi.org/project/tomli) | 2.2.1 | A lil' TOML parser
+[tomli_w](https://pypi.org/project/tomli_w) | 1.1.0 | A lil' TOML writer
+[tomlkit](https://pypi.org/project/tomlkit) | 0.13.2 | Style preserving TOML library
+[toolz](https://pypi.org/project/toolz) | 1.0.0 | List processing tools and functional utilities
+[tornado](https://pypi.org/project/tornado) | 6.4.2 | Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed.
+[tqdm](https://pypi.org/project/tqdm) | 4.66.4 | Fast, Extensible Progress Meter
+[traitlets](https://pypi.org/project/traitlets) | 5.14.1 | Traitlets Python configuration system
+[traittypes](https://pypi.org/project/traittypes) | 0.2.1 | Scipy trait types
+[trio](https://pypi.org/project/trio) | 0.28.0 | A friendly Python library for async concurrency and I/O
+[trove_classifiers](https://pypi.org/project/trove_classifiers) | 2024.10.21.16 | Canonical source for classifiers on PyPI (pypi.org).
+[twine](https://pypi.org/project/twine) | 6.0.1 | Collection of utilities for publishing packages on PyPI
+[types_python_dateutil](https://pypi.org/project/types_python_dateutil) | 2.9.0.20240316 | Typing stubs for python-dateutil
+[types_requests](https://pypi.org/project/types_requests) | 2.32.0.20241016 | Typing stubs for requests
+[typing_extensions](https://pypi.org/project/typing_extensions) | 4.12.2 | Backported and Experimental Type Hints for Python 3.8+
+[typing_inspect](https://pypi.org/project/typing_inspect) | 0.9.0 | Runtime inspection utilities for typing module.
+[tzdata](https://pypi.org/project/tzdata) | 2024.1 | Provider of IANA time zone data
+[tzlocal](https://pypi.org/project/tzlocal) | 5.2 | tzinfo object for the local timezone
+[uc_micro_py](https://pypi.org/project/uc_micro_py) | 1.0.1 | Micro subset of unicode data files for linkify-it-py projects.
+[ujson](https://pypi.org/project/ujson) | 5.10.0 | Ultra fast JSON encoder and decoder for Python
+[umap_learn](https://pypi.org/project/umap_learn) | 0.5.6 | Uniform Manifold Approximation and Projection
+[uncertainties](https://pypi.org/project/uncertainties) | 3.2.2 | calculations with values with uncertainties, error propagation
+[uri_template](https://pypi.org/project/uri_template) | 1.3.0 | RFC 6570 URI Template Processor
+[urllib3](https://pypi.org/project/urllib3) | 2.2.3 | HTTP library with thread-safe connection pooling, file post, and more.
+[uvicorn](https://pypi.org/project/uvicorn) | 0.34.0 | The lightning-fast ASGI server.
+[vega_datasets](https://pypi.org/project/vega_datasets) | 0.9.0 | A Python package for offline access to Vega datasets
+[waitress](https://pypi.org/project/waitress) | 3.0.0 | Waitress WSGI server
+[watchdog](https://pypi.org/project/watchdog) | 6.0.0 | Filesystem events monitoring
+[wcwidth](https://pypi.org/project/wcwidth) | 0.2.13 | Measures the displayed width of unicode strings in a terminal
+[webcolors](https://pypi.org/project/webcolors) | 24.11.1 | A library for working with the color formats defined by HTML and CSS.
+[webencodings](https://pypi.org/project/webencodings) | 0.5.1 | Character encoding aliases for legacy web content
+[websocket_client](https://pypi.org/project/websocket_client) | 1.8.0 | WebSocket client for Python with low level API options
+[websockets](https://pypi.org/project/websockets) | 14.2 | An implementation of the WebSocket Protocol (RFC 6455 & 7692)
+[werkzeug](https://pypi.org/project/werkzeug) | 3.1.3 | The comprehensive WSGI web application library.
+[whatthepatch](https://pypi.org/project/whatthepatch) | 1.0.7 | A patch parsing and application library.
+[wheel](https://pypi.org/project/wheel) | 0.45.1 | A built-package format for Python
+[widgetsnbextension](https://pypi.org/project/widgetsnbextension) | 4.0.13 | Jupyter interactive widgets for Jupyter Notebook
+[winpython](https://pypi.org/project/winpython) | 13.1.20250222 | WinPython distribution tools, including WPPM
+[wordcloud](https://pypi.org/project/wordcloud) | 1.9.4 | A little word cloud generator
+[wsproto](https://pypi.org/project/wsproto) | 1.2.0 | WebSockets state-machine based protocol implementation
+[xarray](https://pypi.org/project/xarray) | 2025.1.1 | N-D labeled arrays and datasets in Python
+[xlsxwriter](https://pypi.org/project/xlsxwriter) | 3.1.9 | A Python module for creating Excel XLSX files.
+[xyzservices](https://pypi.org/project/xyzservices) | 2023.10.1 | Source of XYZ tiles providers
+[yapf](https://pypi.org/project/yapf) | 0.40.1 | A formatter for Python code.
+[yarl](https://pypi.org/project/yarl) | 1.18.3 | Yet another URL library
+[yt_dlp](https://pypi.org/project/yt_dlp) | 2023.7.6 | A youtube-dl fork with additional features and patches
+[zict](https://pypi.org/project/zict) | 3.0.0 | Mutable mapping tools
+[zipp](https://pypi.org/project/zipp) | 3.21.0 | Backport of pathlib-compatible object wrapper for zip files
+[zstandard](https://pypi.org/project/zstandard) | 0.23.0 | Zstandard bindings for Python
+
+
diff --git a/changelogs/WinPythonslim-64bit-3.12.9.0_History.md b/changelogs/WinPythonslim-64bit-3.12.9.0_History.md
new file mode 100644
index 00000000..aa21a9ba
--- /dev/null
+++ b/changelogs/WinPythonslim-64bit-3.12.9.0_History.md
@@ -0,0 +1,195 @@
+## History of changes for WinPython-64bit 3.12.9.0slim
+
+The following changes were made to WinPython-64bit distribution since version 3.12.8.0slim.
+
+
+### Tools
+
+Removed packages:
+
+ * [Pandoc](https://pandoc.org/) 3.1.9 (a universal document converter)
+
+### Python packages
+
+New packages:
+
+ * [cohere](https://pypi.org/project/cohere) 5.13.12 ()
+ * [faker](https://pypi.org/project/faker) 33.3.1 (Faker is a Python package that generates fake data for you.)
+ * [fastavro](https://pypi.org/project/fastavro) 1.10.0 (Fast read/write of AVRO files)
+ * [httpx_sse](https://pypi.org/project/httpx_sse) 0.4.0 (Consume Server-Sent Event (SSE) messages with HTTPX.)
+ * [nh3](https://pypi.org/project/nh3) 0.2.18 (Python bindings to the ammonia HTML sanitization library.)
+ * [prince](https://pypi.org/project/prince) 0.15.0 (Factor analysis in Python: PCA, CA, MCA, MFA, FAMD, GPA)
+ * [pydantic_graph](https://pypi.org/project/pydantic_graph) 0.0.24 (Graph and state machine library)
+ * [pyogrio](https://pypi.org/project/pyogrio) 0.10.0 (Vectorized spatial vector file format I/O using GDAL/OGR)
+ * [pyspnego](https://pypi.org/project/pyspnego) 0.11.2 (Windows Negotiate Authentication Client and Server)
+ * [pyusb](https://pypi.org/project/pyusb) 1.3.1 (Easy USB access for Python)
+ * [pywavelets](https://pypi.org/project/pywavelets) 1.8.0 (PyWavelets, wavelet transform module)
+ * [sklearn_compat](https://pypi.org/project/sklearn_compat) 0.1.3 (Ease support for compatible scikit-learn estimators across versions)
+ * [squarify](https://pypi.org/project/squarify) 0.4.4 (Pure Python implementation of the squarify treemap layout algorithm)
+ * [sspilib](https://pypi.org/project/sspilib) 0.2.0 (SSPI API bindings for Python)
+ * [thefuzz](https://pypi.org/project/thefuzz) 0.22.1 (Fuzzy string matching in python)
+ * [tokenizers](https://pypi.org/project/tokenizers) 0.21.0 ()
+ * [types_requests](https://pypi.org/project/types_requests) 2.32.0.20241016 (Typing stubs for requests)
+
+Upgraded packages:
+
+ * [array_api_compat](https://pypi.org/project/array_api_compat) 1.8 → 1.10.0 (A wrapper around NumPy and other array libraries to make them compatible with the Array API standard)
+ * [baresql](https://pypi.org/project/baresql) 0.8.0 → 1.0.0 (playing SQL directly on Python datas)
+ * [blinker](https://pypi.org/project/blinker) 1.7.0 → 1.9.0 (Fast, simple object-to-object and broadcast signaling)
+ * [bokeh](https://pypi.org/project/bokeh) 3.6.1 → 3.6.3 (Interactive plots and applications in the browser from Python)
+ * [clarabel](https://pypi.org/project/clarabel) 0.9.0 → 0.10.0 (Clarabel Conic Interior Point Solver for Rust / Python)
+ * [cryptography](https://pypi.org/project/cryptography) 41.0.5 → 44.0.0 (cryptography is a package which provides cryptographic recipes and primitives to Python developers.)
+ * [cytoolz](https://pypi.org/project/cytoolz) 0.12.3 → 1.0.1 (Cython implementation of Toolz: High performance functional utilities)
+ * [deap](https://pypi.org/project/deap) 1.4.1 → 1.4.2 (Distributed Evolutionary Algorithms in Python)
+ * [dill](https://pypi.org/project/dill) 0.3.7 → 0.3.9 (serialize all of Python)
+ * [docutils](https://pypi.org/project/docutils) 0.20.1 → 0.21.2 (Docutils -- Python Documentation Utilities)
+ * [duckdb](https://pypi.org/project/duckdb) 1.1.3 → 1.2.0 (DuckDB in-process database)
+ * [flask](https://pypi.org/project/flask) 3.0.3 → 3.1.0 (A simple framework for building complex web applications.)
+ * [flit](https://pypi.org/project/flit) 3.9.0 → 3.10.1 (A simple packaging tool for simple packages.)
+ * [flit_core](https://pypi.org/project/flit_core) 3.9.0 → 3.10.1 (Distribution-building parts of Flit. See flit package for more information)
+ * [geopandas](https://pypi.org/project/geopandas) 0.14.4 → 1.0.1 (Geographic pandas extensions)
+ * [griffe](https://pypi.org/project/griffe) 1.5.4 → 1.5.5 (Signatures for entire Python programs)
+ * [huggingface_hub](https://pypi.org/project/huggingface_hub) 0.27.0 → 0.28.1 (Client library to download and publish models, datasets and other repos on the huggingface.co hub)
+ * [hypothesis](https://pypi.org/project/hypothesis) 6.108.5 → 6.122.3 (A library for property-based testing)
+ * [imbalanced_learn](https://pypi.org/project/imbalanced_learn) 0.12.3 → 0.13.0 (Toolbox for imbalanced dataset in machine learning)
+ * [ipycanvas](https://pypi.org/project/ipycanvas) 0.13.2 → 0.13.3 (Interactive widgets library exposing the browser's Canvas API)
+ * [ipympl](https://pypi.org/project/ipympl) 0.9.4 → 0.9.6 (Matplotlib Jupyter Extension)
+ * [ipython](https://pypi.org/project/ipython) 8.26.0 → 8.32.0 (IPython: Productive Interactive Computing)
+ * [janus](https://pypi.org/project/janus) 1.0.0 → 2.0.0 (Mixed sync-async queue to interoperate between asyncio tasks and classic threads)
+ * [jaraco_context](https://pypi.org/project/jaraco_context) 5.3.0 → 6.0.1 (Useful decorators and context managers)
+ * [jaraco_functools](https://pypi.org/project/jaraco_functools) 4.0.1 → 4.1.0 (Functools like those found in stdlib)
+ * [jedi](https://pypi.org/project/jedi) 0.19.1 → 0.19.2 (An autocompletion tool for Python that can be used for text editors.)
+ * [jupyterlab](https://pypi.org/project/jupyterlab) 4.3.4 → 4.3.5 (JupyterLab computational environment)
+ * [keras](https://pypi.org/project/keras) 3.7.0 → 3.8.0 (Multi-backend Keras)
+ * [keyring](https://pypi.org/project/keyring) 25.2.1 → 25.6.0 (Store and access your passwords safely.)
+ * [kiwisolver](https://pypi.org/project/kiwisolver) 1.4.7 → 1.4.8 (A fast implementation of the Cassowary constraint solver)
+ * [langchain](https://pypi.org/project/langchain) 0.3.13 → 0.3.18 (Building applications with LLMs through composability)
+ * [langchain_core](https://pypi.org/project/langchain_core) 0.3.28 → 0.3.34 (Building applications with LLMs through composability)
+ * [langchain_text_splitters](https://pypi.org/project/langchain_text_splitters) 0.3.4 → 0.3.6 (LangChain text splitting utilities)
+ * [langsmith](https://pypi.org/project/langsmith) 0.2.6 → 0.2.11 (Client library to connect to the LangSmith LLM Tracing and Evaluation Platform.)
+ * [llvmlite](https://pypi.org/project/llvmlite) 0.44.0rc2 → 0.44.0 (lightweight wrapper around basic LLVM functionality)
+ * [logfire_api](https://pypi.org/project/logfire_api) 2.11.0 → 3.5.3 (Shim for the Logfire SDK which does nothing unless Logfire is installed)
+ * [markupsafe](https://pypi.org/project/markupsafe) 2.1.1 → 3.0.2 (Safely add untrusted strings to HTML/XML markup.)
+ * [maturin](https://pypi.org/project/maturin) 1.7.0 → 1.8.1 (Build and publish crates with pyo3, cffi and uniffi bindings as well as rust binaries as python packages)
+ * [mlxtend](https://pypi.org/project/mlxtend) 0.22.0 → 0.23.3 (Machine Learning Library Extensions)
+ * [msgpack](https://pypi.org/project/msgpack) 1.0.4 → 1.1.0 (MessagePack serializer)
+ * [narwhals](https://pypi.org/project/narwhals) 1.15.2 → 1.21.1 (Extremely lightweight compatibility layer between dataframe libraries)
+ * [numba](https://pypi.org/project/numba) 0.61.0rc2 → 0.61.0 (compiling Python code using LLVM)
+ * [openai](https://pypi.org/project/openai) 1.58.1 → 1.61.1 (The official Python library for the openai API)
+ * [osqp](https://pypi.org/project/osqp) 0.6.7.post1 → 0.6.7.post3 (OSQP: The Operator Splitting QP Solver)
+ * [panel](https://pypi.org/project/panel) 1.5.4 → 1.6.0 (The powerful data exploration & web app framework for Python.)
+ * [pillow](https://pypi.org/project/pillow) 11.0.0 → 11.1.0 (Python Imaging Library (Fork))
+ * [plotpy](https://pypi.org/project/plotpy) 2.7.0 → 2.7.2 (Curve and image plotting tools for Python/Qt applications)
+ * [polars](https://pypi.org/project/polars) 1.18.0 → 1.22.0 (Blazingly fast DataFrame library)
+ * [pyarrow](https://pypi.org/project/pyarrow) 18.1.0 → 19.0.0 (Python library for Apache Arrow)
+ * [pydantic](https://pypi.org/project/pydantic) 2.10.4 → 2.10.6 (Data validation using Python type hints)
+ * [pydantic_ai](https://pypi.org/project/pydantic_ai) 0.0.15 → 0.0.24 (Agent Framework / shim to use Pydantic with LLMs)
+ * [pydantic_ai_slim](https://pypi.org/project/pydantic_ai_slim) 0.0.15 → 0.0.24 (Agent Framework / shim to use Pydantic with LLMs, slim package)
+ * [pygments](https://pypi.org/project/pygments) 2.18.0 → 2.19.1 (Pygments is a syntax highlighting package written in Python.)
+ * [pyomo](https://pypi.org/project/pyomo) 6.8.0 → 6.8.2 (Pyomo: Python Optimization Modeling Objects)
+ * [pyparsing](https://pypi.org/project/pyparsing) 3.1.2 → 3.2.1 (pyparsing module - Classes and methods to define and execute parsing grammars)
+ * [pypdf](https://pypi.org/project/pypdf) 3.15.2 → 5.1.0 (A pure-python PDF library capable of splitting, merging, cropping, and transforming PDF files)
+ * [pyproj](https://pypi.org/project/pyproj) 3.6.1 → 3.7.0 (Python interface to PROJ (cartographic projections and coordinate transformations library))
+ * [pyqt5_sip](https://pypi.org/project/pyqt5_sip) 12.13.0 → 12.16.1 (The sip module support for PyQt5)
+ * [Python](http://www.python.org/) 3.12.8 → 3.12.9 (Python programming language with standard library)
+ * [pythonqwt](https://pypi.org/project/pythonqwt) 0.14.2 → 0.14.4 (Qt plotting widgets for Python)
+ * [qdldl](https://pypi.org/project/qdldl) 0.1.7.post4 → 0.1.7.post5 (QDLDL, a free LDL factorization routine.)
+ * [qrcode](https://pypi.org/project/qrcode) 7.4.2 → 8.0 (QR Code image generator)
+ * [readme_renderer](https://pypi.org/project/readme_renderer) 35.0 → 44.0 (readme_renderer is a library for rendering readme descriptions for Warehouse)
+ * [redis](https://pypi.org/project/redis) 5.0.3 → 5.0.8 (Python client for Redis database and key-value store)
+ * [reportlab](https://pypi.org/project/reportlab) 4.2.2 → 4.2.5 (The Reportlab Toolkit)
+ * [requests_ntlm](https://pypi.org/project/requests_ntlm) 1.1.0 → 1.3.0 (This package allows for HTTP NTLM authentication using the requests library.)
+ * [scikit_learn](https://pypi.org/project/scikit_learn) 1.6.0 → 1.6.1 (A set of python modules for machine learning and data mining)
+ * [scipy](https://pypi.org/project/scipy) 1.14.1 → 1.15.1 (Fundamental algorithms for scientific computing in Python)
+ * [scramp](https://pypi.org/project/scramp) 1.4.1 → 1.4.5 (An implementation of the SCRAM protocol.)
+ * [scs](https://pypi.org/project/scs) 3.2.7 → 3.2.7.post2 (Splitting conic solver)
+ * [shapely](https://pypi.org/project/shapely) 2.0.4 → 2.0.6 (Manipulation and analysis of geometric objects)
+ * [sounddevice](https://pypi.org/project/sounddevice) 0.4.6 → 0.5.1 (Play and Record Sound with Python)
+ * [soupsieve](https://pypi.org/project/soupsieve) 2.5 → 2.6 (A modern CSS selector implementation for Beautiful Soup.)
+ * [sphinx_rtd_theme](https://pypi.org/project/sphinx_rtd_theme) 2.0.0 → 3.0.2 (Read the Docs theme for Sphinx)
+ * [sphinxcontrib_applehelp](https://pypi.org/project/sphinxcontrib_applehelp) 1.0.8 → 2.0.0 (sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books)
+ * [sphinxcontrib_devhelp](https://pypi.org/project/sphinxcontrib_devhelp) 1.0.6 → 2.0.0 (sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp documents)
+ * [sphinxcontrib_htmlhelp](https://pypi.org/project/sphinxcontrib_htmlhelp) 2.0.5 → 2.1.0 (sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files)
+ * [sphinxcontrib_qthelp](https://pypi.org/project/sphinxcontrib_qthelp) 1.0.7 → 2.0.0 (sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp documents)
+ * [sphinxcontrib_serializinghtml](https://pypi.org/project/sphinxcontrib_serializinghtml) 1.1.9 → 2.0.0 (sphinxcontrib-serializinghtml is a sphinx extension which outputs "serialized" HTML files (json and pickle))
+ * [sqlite_utils](https://pypi.org/project/sqlite_utils) 3.37 → 3.38 (CLI tool and Python library for manipulating SQLite databases)
+ * [sqlparse](https://pypi.org/project/sqlparse) 0.4.3 → 0.5.3 (A non-validating SQL parser.)
+ * [sympy](https://pypi.org/project/sympy) 1.13.2 → 1.13.3 (Computer algebra system (CAS) in Python)
+ * [tenacity](https://pypi.org/project/tenacity) 8.5.0 → 9.0.0 (Retry code until it succeeds)
+ * [textdistance](https://pypi.org/project/textdistance) 4.6.2 → 4.6.3 (Compute distance between the two texts.)
+ * [tifffile](https://pypi.org/project/tifffile) 2024.7.2 → 2025.1.10 (Read and write TIFF files)
+ * [tinycss2](https://pypi.org/project/tinycss2) 1.3.0 → 1.4.0 (A tiny CSS parser)
+ * [tomli](https://pypi.org/project/tomli) 2.0.1 → 2.2.1 (A lil' TOML parser)
+ * [tomli_w](https://pypi.org/project/tomli_w) 1.0.0 → 1.1.0 (A lil' TOML writer)
+ * [tomlkit](https://pypi.org/project/tomlkit) 0.12.3 → 0.13.2 (Style preserving TOML library)
+ * [toolz](https://pypi.org/project/toolz) 0.12.0 → 1.0.0 (List processing tools and functional utilities)
+ * [tornado](https://pypi.org/project/tornado) 6.4.1 → 6.4.2 (Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed.)
+ * [trio](https://pypi.org/project/trio) 0.27.0 → 0.28.0 (A friendly Python library for async concurrency and I/O)
+ * [twine](https://pypi.org/project/twine) 4.0.1 → 6.0.1 (Collection of utilities for publishing packages on PyPI)
+ * [uncertainties](https://pypi.org/project/uncertainties) 3.1.7 → 3.2.2 (calculations with values with uncertainties, error propagation)
+ * [urllib3](https://pypi.org/project/urllib3) 2.0.3 → 2.2.3 (HTTP library with thread-safe connection pooling, file post, and more.)
+ * [uvicorn](https://pypi.org/project/uvicorn) 0.30.3 → 0.34.0 (The lightning-fast ASGI server.)
+ * [watchdog](https://pypi.org/project/watchdog) 4.0.1 → 6.0.0 (Filesystem events monitoring)
+ * [webcolors](https://pypi.org/project/webcolors) 1.12 → 24.11.1 (A library for working with the color formats defined by HTML and CSS.)
+ * [websockets](https://pypi.org/project/websockets) 13.1 → 14.2 (An implementation of the WebSocket Protocol (RFC 6455 & 7692))
+ * [werkzeug](https://pypi.org/project/werkzeug) 3.0.3 → 3.1.3 (The comprehensive WSGI web application library.)
+ * [whatthepatch](https://pypi.org/project/whatthepatch) 1.0.2 → 1.0.7 (A patch parsing and application library.)
+ * [wheel](https://pypi.org/project/wheel) 0.44.0 → 0.45.1 (A built-package format for Python)
+ * [winpython](https://pypi.org/project/winpython) 11.2.20241228 → 13.1.20250222 (WinPython distribution tools, including WPPM)
+ * [xarray](https://pypi.org/project/xarray) 2024.11.0 → 2025.1.1 (N-D labeled arrays and datasets in Python)
+ * [zipp](https://pypi.org/project/zipp) 3.17.0 → 3.21.0 (Backport of pathlib-compatible object wrapper for zip files)
+
+Removed packages:
+
+ * [about_time](https://pypi.org/project/about_time) 4.2.1 (Easily measure timing and throughput of code blocks, with beautiful human friendly representations.)
+ * [adodbapi](https://pypi.org/project/adodbapi) 2.6.1.3 (A pure Python package implementing PEP 249 DB-API using Microsoft ADO.)
+ * [affine](https://pypi.org/project/affine) 2.3.1 (Matrices describing affine transformation of the plane.)
+ * [alive_progress](https://pypi.org/project/alive_progress) 3.1.5 (A new kind of Progress Bar, with real-time throughput, ETA, and very cool animations!)
+ * [autograd](https://pypi.org/project/autograd) 1.6.2 (Efficiently computes derivatives of numpy code.)
+ * [cachelib](https://pypi.org/project/cachelib) 0.13.0 (A collection of cache libraries in the same API interface.)
+ * [cartopy](https://pypi.org/project/cartopy) 0.23.0 (A Python library for cartographic visualizations with Matplotlib)
+ * [cftime](https://pypi.org/project/cftime) 1.6.3 (Time-handling functionality from netcdf4-python)
+ * [click_plugins](https://pypi.org/project/click_plugins) 1.1.1 (An extension module for click to enable registering CLI commands via setuptools entry-points.)
+ * [cligj](https://pypi.org/project/cligj) 0.7.2 (Click params for commmand line interfaces to GeoJSON)
+ * [clr_loader](https://pypi.org/project/clr_loader) 0.2.6 (Generic pure Python loader for .NET runtimes)
+ * [clrmagic](https://pypi.org/project/clrmagic) 0.0.1a2 (IPython cell magic to use .NET languages)
+ * [cma](https://pypi.org/project/cma) 3.2.2 (CMA-ES, Covariance Matrix Adaptation Evolution Strategy for non-linear numerical optimization in Python)
+ * [db_py](https://pypi.org/project/db_py) 0.5.4b1 (a db package that doesn't suck)
+ * [deprecated](https://pypi.org/project/deprecated) 1.2.13 (Python @deprecated decorator to deprecate old python classes, functions or methods.)
+ * [docopt](https://pypi.org/project/docopt) 0.6.2 (Pythonic argument parser, that will make you smile)
+ * [ecos](https://pypi.org/project/ecos) 2.0.13 (This is the Python package for ECOS: Embedded Cone Solver. See Github page for more information.)
+ * [filterpy](https://pypi.org/project/filterpy) 1.4.5 (Kalman filtering and optimal estimation library)
+ * [fiona](https://pypi.org/project/fiona) 1.10.1 (Fiona reads and writes spatial data files)
+ * [flask_mail](https://pypi.org/project/flask_mail) 0.9.1 (Flask extension for sending email)
+ * [flask_session](https://pypi.org/project/flask_session) 0.5.0 (Server-side session support for Flask)
+ * [flask_sqlalchemy](https://pypi.org/project/flask_sqlalchemy) 3.0.5 (Add SQLAlchemy support to your Flask application.)
+ * [formlayout](https://pypi.org/project/formlayout) 1.2.1a1 (The most easy way to create Qt form dialogs and widgets with Python)
+ * [future](https://pypi.org/project/future) 0.18.2 (Clean single-source support for Python 3 and 2)
+ * [grapheme](https://pypi.org/project/grapheme) 0.6.0 (Unicode grapheme helpers)
+ * [netcdf4](https://pypi.org/project/netcdf4) 1.7.1.post2 (Provides an object-oriented python interface to the netCDF version 4 library)
+ * [ntlm_auth](https://pypi.org/project/ntlm_auth) 1.5.0 (Creates NTLM authentication structures)
+ * [numexpr](https://pypi.org/project/numexpr) 2.10.1 (Fast numerical expression evaluator for NumPy)
+ * [pdfrw](https://pypi.org/project/pdfrw) 0.4.post2 (PDF file reader/writer library)
+ * [ppci](https://pypi.org/project/ppci) 0.5.9 (A compiler for ARM, X86, MSP430, xtensa and more implemented in pure Python)
+ * [pulp](https://pypi.org/project/pulp) 2.6.0 (PuLP is an LP modeler written in python)
+ * [pyaudio](https://pypi.org/project/pyaudio) 0.2.14 (Cross-platform audio I/O with PortAudio)
+ * [pybars3](https://pypi.org/project/pybars3) 0.9.7 (Handlebars.js templating for Python 3 and 2)
+ * [pycosat](https://pypi.org/project/pycosat) 0.6.6 (bindings to picosat (a SAT solver))
+ * [pymeta3](https://pypi.org/project/pymeta3) 0.5.1 (Pattern-matching language based on OMeta for Python 3 and 2)
+ * [pymoo](https://pypi.org/project/pymoo) 0.6.1.3 (Multi-Objective Optimization in Python)
+ * [pypng](https://pypi.org/project/pypng) 0.20220715.0 (Pure Python library for saving and loading PNG images)
+ * [pyshp](https://pypi.org/project/pyshp) 2.3.1 (Pure Python read/write support for ESRI Shapefile format)
+ * [pysimplegui](https://pypi.org/project/pysimplegui) 4.60.4 (Python GUIs for Humans)
+ * [pythonnet](https://pypi.org/project/pythonnet) 3.0.3 (.NET and Mono integration for Python)
+ * [pywinusb](https://pypi.org/project/pywinusb) 0.4.2 (A package that simplifies USB/HID communications on windows)
+ * [rasterio](https://pypi.org/project/rasterio) 1.3.10 (Fast and direct raster I/O for use with Numpy and SciPy)
+ * [simplegeneric](https://pypi.org/project/simplegeneric) 0.8.1 (Simple generic functions (similar to Python's own len(), pickle.dump(), etc.))
+ * [snuggs](https://pypi.org/project/snuggs) 1.4.7 (Snuggs are s-expressions for Numpy)
+ * [sspyrs](https://pypi.org/project/sspyrs) 0.3 (Lightweight interface for SSRS reports to python)
+ * [wrapt](https://pypi.org/project/wrapt) 1.16.0 (Module for decorators, wrappers and monkey patching.)
+ * [xlwings](https://pypi.org/project/xlwings) 0.24.7 (Make Excel fly: Interact with Excel from Python and vice versa.)
+ * [xmltodict](https://pypi.org/project/xmltodict) 0.13.0 (Makes working with XML feel like you are working with JSON)
+
+
+
+* * *
diff --git a/changelogs/WinPythonslim-64bit-3.13.2.0.md b/changelogs/WinPythonslim-64bit-3.13.2.0.md
new file mode 100644
index 00000000..c0701b8a
--- /dev/null
+++ b/changelogs/WinPythonslim-64bit-3.13.2.0.md
@@ -0,0 +1,511 @@
+## WinPython 3.13.2.0slim
+
+The following packages are included in WinPython-64bit v3.13.2.0slim .
+
+
+
+### Tools
+
+Name | Version | Description
+-----|---------|------------
+
+
+### Python packages
+
+Name | Version | Description
+-----|---------|------------
+[Python](http://www.python.org/) | 3.13.2 | Python programming language with standard library
+[absl_py](https://pypi.org/project/absl_py) | 2.0.0 | Abseil Python Common Libraries, see https://github.com/abseil/abseil-py.
+[adbc_driver_manager](https://pypi.org/project/adbc_driver_manager) | 1.3.0 | A generic entrypoint for ADBC drivers.
+[aiofiles](https://pypi.org/project/aiofiles) | 23.2.1 | File support for asyncio.
+[aiohappyeyeballs](https://pypi.org/project/aiohappyeyeballs) | 2.4.4 | Happy Eyeballs for asyncio
+[aiohttp](https://pypi.org/project/aiohttp) | 3.11.11 | Async http client/server framework (asyncio)
+[aiosignal](https://pypi.org/project/aiosignal) | 1.3.1 | aiosignal: a list of registered asynchronous callbacks
+[aiosqlite](https://pypi.org/project/aiosqlite) | 0.20.0 | asyncio bridge to the standard sqlite3 module
+[alabaster](https://pypi.org/project/alabaster) | 0.7.16 | A light, configurable Sphinx theme
+[alembic](https://pypi.org/project/alembic) | 1.13.1 | A database migration tool for SQLAlchemy.
+[altair](https://pypi.org/project/altair) | 5.5.0 | Vega-Altair: A declarative statistical visualization library for Python.
+[aniso8601](https://pypi.org/project/aniso8601) | 9.0.1 | A library for parsing ISO 8601 strings.
+[annotated_types](https://pypi.org/project/annotated_types) | 0.6.0 | Reusable constraint types to use with typing.Annotated
+[ansicolors](https://pypi.org/project/ansicolors) | 1.1.8 | ANSI colors for Python
+[anthropic](https://pypi.org/project/anthropic) | 0.42.0 | The official Python library for the anthropic API
+[anyio](https://pypi.org/project/anyio) | 4.7.0 | High level compatibility layer for multiple asynchronous event loop implementations
+[anywidget](https://pypi.org/project/anywidget) | 0.9.12 | custom jupyter widgets made easy
+[appdirs](https://pypi.org/project/appdirs) | 1.4.4 | A small Python module for determining appropriate platform-specific dirs, e.g. a "user data dir".
+[argon2_cffi](https://pypi.org/project/argon2_cffi) | 23.1.0 | Argon2 for Python
+[argon2_cffi_bindings](https://pypi.org/project/argon2_cffi_bindings) | 21.2.0 | Low-level CFFI bindings for Argon2
+[array_api_compat](https://pypi.org/project/array_api_compat) | 1.10.0 | A wrapper around NumPy and other array libraries to make them compatible with the Array API standard
+[arrow](https://pypi.org/project/arrow) | 1.3.0 | Better dates & times for Python
+[asgi_csrf](https://pypi.org/project/asgi_csrf) | 0.9 | ASGI middleware for protecting against CSRF attacks
+[asgiref](https://pypi.org/project/asgiref) | 3.8.1 | ASGI specs, helper code, and adapters
+[asn1crypto](https://pypi.org/project/asn1crypto) | 1.5.1 | Fast ASN.1 parser and serializer with definitions for private keys, public keys, certificates, CRL, OCSP, CMS, PKCS#3, PKCS#7, PKCS#8, PKCS#12,
+[asteval](https://pypi.org/project/asteval) | 0.9.31 | Safe, minimalistic evaluator of python expression using ast module
+[astroid](https://pypi.org/project/astroid) | 3.1.0 | An abstract syntax tree for Python with inference support.
+[astropy](https://pypi.org/project/astropy) | 6.1.6 | Astronomy and astrophysics core library
+[astropy_iers_data](https://pypi.org/project/astropy_iers_data) | 0.2024.12.23.0.33.24 | IERS Earth Rotation and Leap Second tables for the astropy core package
+[asttokens](https://pypi.org/project/asttokens) | 2.4.1 | Annotate AST trees with source code positions
+[async_lru](https://pypi.org/project/async_lru) | 2.0.4 | Simple LRU cache for asyncio
+[atomicwrites](https://pypi.org/project/atomicwrites) | 1.4.0 | Atomic file writes.
+[attrs](https://pypi.org/project/attrs) | 23.2.0 | Classes Without Boilerplate
+[autopep8](https://pypi.org/project/autopep8) | 2.0.4 | A tool that automatically formats Python code to conform to the PEP 8 style guide
+[azure_core](https://pypi.org/project/azure_core) | 1.30.2 | Microsoft Azure Core Library for Python
+[azure_cosmos](https://pypi.org/project/azure_cosmos) | 4.7.0 | Microsoft Azure Cosmos Client Library for Python
+[azure_identity](https://pypi.org/project/azure_identity) | 1.16.1 | Microsoft Azure Identity Library for Python
+[babel](https://pypi.org/project/babel) | 2.16.0 | Internationalization utilities
+[baresql](https://pypi.org/project/baresql) | 1.0.0 | playing SQL directly on Python datas
+[bcrypt](https://pypi.org/project/bcrypt) | 4.0.1 | Modern password hashing for your software and your servers
+[beautifulsoup4](https://pypi.org/project/beautifulsoup4) | 4.12.2 | Screen-scraping library
+[binaryornot](https://pypi.org/project/binaryornot) | 0.4.4 | Ultra-lightweight pure Python package to check if a file is binary or text.
+[black](https://pypi.org/project/black) | 24.10.0 | The uncompromising code formatter.
+[bleach](https://pypi.org/project/bleach) | 6.1.0 | An easy safelist-based HTML-sanitizing tool.
+[blinker](https://pypi.org/project/blinker) | 1.9.0 | Fast, simple object-to-object and broadcast signaling
+[bokeh](https://pypi.org/project/bokeh) | 3.6.3 | Interactive plots and applications in the browser from Python
+[branca](https://pypi.org/project/branca) | 0.8.0 | Generate complex HTML+JS pages with Python
+[brotli](https://pypi.org/project/brotli) | 1.1.0 | Python bindings for the Brotli compression library
+[build](https://pypi.org/project/build) | 1.2.2.post1 | A simple, correct Python build frontend
+[cachetools](https://pypi.org/project/cachetools) | 5.4.0 | Extensible memoizing collections and decorators
+[certifi](https://pypi.org/project/certifi) | 2024.6.2 | Python package for providing Mozilla's CA Bundle.
+[cffi](https://pypi.org/project/cffi) | 1.17.1 | Foreign Function Interface for Python calling C code.
+[chardet](https://pypi.org/project/chardet) | 5.2.0 | Universal encoding detector for Python 3
+[charset_normalizer](https://pypi.org/project/charset_normalizer) | 3.4.0 | The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet.
+[clarabel](https://pypi.org/project/clarabel) | 0.10.0 | Clarabel Conic Interior Point Solver for Rust / Python
+[click](https://pypi.org/project/click) | 8.1.7 | Composable command line interface toolkit
+[click_default_group](https://pypi.org/project/click_default_group) | 1.2.4 | click_default_group
+[cloudpickle](https://pypi.org/project/cloudpickle) | 3.0.0 | Pickler class to extend the standard pickle.Pickler functionality
+[cohere](https://pypi.org/project/cohere) | 5.13.12 |
+[colorama](https://pypi.org/project/colorama) | 0.4.6 | Cross-platform colored terminal text.
+[colorcet](https://pypi.org/project/colorcet) | 3.1.0 | Collection of perceptually uniform colormaps
+[colorlog](https://pypi.org/project/colorlog) | 6.8.2 | Add colours to the output of Python's logging module.
+[comm](https://pypi.org/project/comm) | 0.2.2 | Jupyter Python Comm implementation, for usage in ipykernel, xeus-python etc.
+[contourpy](https://pypi.org/project/contourpy) | 1.3.1 | Python library for calculating contours of 2D quadrilateral grids
+[cookiecutter](https://pypi.org/project/cookiecutter) | 2.6.0 | A command-line utility that creates projects from project templates, e.g
+[cryptography](https://pypi.org/project/cryptography) | 44.0.0 | cryptography is a package which provides cryptographic recipes and primitives to Python developers.
+[cvxopt](https://pypi.org/project/cvxopt) | 1.3.2 | Convex optimization package
+[cvxpy](https://pypi.org/project/cvxpy) | 1.6.0 | A domain-specific language for modeling convex optimization problems in Python.
+[cycler](https://pypi.org/project/cycler) | 0.12.1 | Composable style cycles
+[cython](https://pypi.org/project/cython) | 3.0.11 | The Cython compiler for writing C extensions in the Python language.
+[cytoolz](https://pypi.org/project/cytoolz) | 1.0.1 | Cython implementation of Toolz: High performance functional utilities
+[dask](https://pypi.org/project/dask) | 2024.12.1 | Parallel PyData with Task Scheduling
+[dask_expr](https://pypi.org/project/dask_expr) | 1.1.21 | High Level Expressions for Dask
+[datasette](https://pypi.org/project/datasette) | 0.64.8 | An open source multi-tool for exploring and publishing data
+[datasette_graphql](https://pypi.org/project/datasette_graphql) | 2.2 | Datasette plugin providing an automatic GraphQL API for your SQLite databases
+[datashader](https://pypi.org/project/datashader) | 0.16.3 | Data visualization toolchain based on aggregating into a grid
+[deap](https://pypi.org/project/deap) | 1.4.2 | Distributed Evolutionary Algorithms in Python
+[debugpy](https://pypi.org/project/debugpy) | 1.8.0 | An implementation of the Debug Adapter Protocol for Python
+[decorator](https://pypi.org/project/decorator) | 5.1.1 | Decorators for Humans
+[defusedxml](https://pypi.org/project/defusedxml) | 0.7.1 | XML bomb protection for Python stdlib modules
+[diff_match_patch](https://pypi.org/project/diff_match_patch) | 20230430 | Diff Match and Patch
+[dill](https://pypi.org/project/dill) | 0.3.9 | serialize all of Python
+[distributed](https://pypi.org/project/distributed) | 2024.12.1 | Distributed scheduler for Dask
+[distro](https://pypi.org/project/distro) | 1.8.0 | Distro - an OS platform information API
+[django](https://pypi.org/project/django) | 5.0.7 | A high-level Python web framework that encourages rapid development and clean, pragmatic design.
+[dnspython](https://pypi.org/project/dnspython) | 2.6.1 | DNS toolkit
+[docstring_to_markdown](https://pypi.org/project/docstring_to_markdown) | 0.13 | On the fly conversion of Python docstrings to markdown
+[docutils](https://pypi.org/project/docutils) | 0.21.2 | Docutils -- Python Documentation Utilities
+[duckdb](https://pypi.org/project/duckdb) | 1.2.0 | DuckDB in-process database
+[entrypoints](https://pypi.org/project/entrypoints) | 0.4 | Discover and load entry points from installed packages.
+[et_xmlfile](https://pypi.org/project/et_xmlfile) | 1.1.0 | An implementation of lxml.xmlfile for the standard library
+[eval_type_backport](https://pypi.org/project/eval_type_backport) | 0.2.2 | Like `typing._eval_type`, but lets older Python versions use newer typing features.
+[executing](https://pypi.org/project/executing) | 2.0.1 | Get the currently executing AST node of a frame, and other information
+[faker](https://pypi.org/project/faker) | 33.3.1 | Faker is a Python package that generates fake data for you.
+[fast_histogram](https://pypi.org/project/fast_histogram) | 0.14 | Fast simple 1D and 2D histograms
+[fastapi](https://pypi.org/project/fastapi) | 0.115.6 | FastAPI framework, high performance, easy to learn, fast to code, ready for production
+[fastavro](https://pypi.org/project/fastavro) | 1.10.0 | Fast read/write of AVRO files
+[fastjsonschema](https://pypi.org/project/fastjsonschema) | 2.18.0 | Fastest Python implementation of JSON schema
+[filelock](https://pypi.org/project/filelock) | 3.14.0 | A platform independent file lock.
+[flake8](https://pypi.org/project/flake8) | 7.1.1 | the modular source code checker: pep8 pyflakes and co
+[flask](https://pypi.org/project/flask) | 3.1.0 | A simple framework for building complex web applications.
+[flit](https://pypi.org/project/flit) | 3.10.1 | A simple packaging tool for simple packages.
+[flit_core](https://pypi.org/project/flit_core) | 3.10.1 | Distribution-building parts of Flit. See flit package for more information
+[folium](https://pypi.org/project/folium) | 0.18.0 | Make beautiful maps with Leaflet.js & Python
+[fonttools](https://pypi.org/project/fonttools) | 4.55.3 | Tools to manipulate font files
+[fqdn](https://pypi.org/project/fqdn) | 1.5.1 | Validates fully-qualified domain names against RFC 1123, so that they are acceptable to modern bowsers
+[frozenlist](https://pypi.org/project/frozenlist) | 1.5.0 | A list-like structure which implements collections.abc.MutableSequence
+[fsspec](https://pypi.org/project/fsspec) | 2024.6.1 | File-system specification
+[fuzzywuzzy](https://pypi.org/project/fuzzywuzzy) | 0.18.0 | Fuzzy string matching in python
+[geographiclib](https://pypi.org/project/geographiclib) | 2.0 | The geodesic routines from GeographicLib
+[geopandas](https://pypi.org/project/geopandas) | 1.0.1 | Geographic pandas extensions
+[geopy](https://pypi.org/project/geopy) | 2.4.1 | Python Geocoding Toolbox
+[gitdb](https://pypi.org/project/gitdb) | 4.0.10 | Git Object Database
+[gitpython](https://pypi.org/project/gitpython) | 3.1.32 | GitPython is a Python library used to interact with Git repositories
+[google_auth](https://pypi.org/project/google_auth) | 2.37.0 | Google Authentication Library
+[graphene](https://pypi.org/project/graphene) | 3.3 | GraphQL Framework for Python
+[graphql_core](https://pypi.org/project/graphql_core) | 3.2.3 | GraphQL implementation for Python, a port of GraphQL.js, the JavaScript reference implementation for GraphQL.
+[graphql_relay](https://pypi.org/project/graphql_relay) | 3.2.0 | Relay library for graphql-core
+[greenlet](https://pypi.org/project/greenlet) | 3.1.1 | Lightweight in-process concurrent programming
+[griffe](https://pypi.org/project/griffe) | 1.5.5 | Signatures for entire Python programs
+[groq](https://pypi.org/project/groq) | 0.13.1 | The official Python library for the groq API
+[guidata](https://pypi.org/project/guidata) | 3.7.1 | Automatic GUI generation for easy dataset editing and display
+[h11](https://pypi.org/project/h11) | 0.14.0 | A pure-Python, bring-your-own-I/O implementation of HTTP/1.1
+[h2](https://pypi.org/project/h2) | 4.1.0 | HTTP/2 State-Machine based protocol implementation
+[h5py](https://pypi.org/project/h5py) | 3.12.1 | Read and write HDF5 files from Python
+[hatchling](https://pypi.org/project/hatchling) | 1.27.0 | Modern, extensible Python build backend
+[holoviews](https://pypi.org/project/holoviews) | 1.20.0 | A high-level plotting API for the PyData ecosystem built on HoloViews.
+[hpack](https://pypi.org/project/hpack) | 4.0.0 | Pure-Python HPACK header compression
+[html5lib](https://pypi.org/project/html5lib) | 1.1 | HTML parser based on the WHATWG HTML specification
+[httpcore](https://pypi.org/project/httpcore) | 1.0.5 | A minimal low-level HTTP client.
+[httpie](https://pypi.org/project/httpie) | 3.2.4 | HTTPie: modern, user-friendly command-line HTTP client for the API era.
+[httpx](https://pypi.org/project/httpx) | 0.27.2 | The next generation HTTP client.
+[httpx_sse](https://pypi.org/project/httpx_sse) | 0.4.0 | Consume Server-Sent Event (SSE) messages with HTTPX.
+[huggingface_hub](https://pypi.org/project/huggingface_hub) | 0.28.1 | Client library to download and publish models, datasets and other repos on the huggingface.co hub
+[hupper](https://pypi.org/project/hupper) | 1.12 | Integrated process monitor for developing and reloading daemons.
+[hvplot](https://pypi.org/project/hvplot) | 0.11.2 | A high-level plotting API for the PyData ecosystem built on HoloViews.
+[hypercorn](https://pypi.org/project/hypercorn) | 0.16.0 | A ASGI Server based on Hyper libraries and inspired by Gunicorn
+[hyperframe](https://pypi.org/project/hyperframe) | 6.0.1 | HTTP/2 framing layer for Python
+[hypothesis](https://pypi.org/project/hypothesis) | 6.122.3 | A library for property-based testing
+[idna](https://pypi.org/project/idna) | 3.7 | Internationalized Domain Names in Applications (IDNA)
+[imageio](https://pypi.org/project/imageio) | 2.33.1 | Library for reading and writing a wide range of image, video, scientific, and volumetric data formats.
+[imagesize](https://pypi.org/project/imagesize) | 1.4.1 | Getting image size from png/jpeg/jpeg2000/gif file
+[imbalanced_learn](https://pypi.org/project/imbalanced_learn) | 0.13.0 | Toolbox for imbalanced dataset in machine learning
+[importlib_metadata](https://pypi.org/project/importlib_metadata) | 7.1.0 | Read metadata from Python packages
+[inflection](https://pypi.org/project/inflection) | 0.5.1 | A port of Ruby on Rails inflector to Python
+[iniconfig](https://pypi.org/project/iniconfig) | 2.0.0 | brain-dead simple config-ini parsing
+[intervaltree](https://pypi.org/project/intervaltree) | 3.0.2 | Editable interval tree data structure for Python 2 and 3
+[ipycanvas](https://pypi.org/project/ipycanvas) | 0.13.3 | Interactive widgets library exposing the browser's Canvas API
+[ipykernel](https://pypi.org/project/ipykernel) | 6.29.5 | IPython Kernel for Jupyter
+[ipyleaflet](https://pypi.org/project/ipyleaflet) | 0.19.2 | A Jupyter widget for dynamic Leaflet maps
+[ipympl](https://pypi.org/project/ipympl) | 0.9.6 | Matplotlib Jupyter Extension
+[ipython](https://pypi.org/project/ipython) | 8.32.0 | IPython: Productive Interactive Computing
+[ipython_genutils](https://pypi.org/project/ipython_genutils) | 0.2.0 | Vestigial utilities from IPython
+[ipython_sql](https://pypi.org/project/ipython_sql) | 0.5.0 | RDBMS access via IPython
+[ipywidgets](https://pypi.org/project/ipywidgets) | 8.1.5 | Jupyter interactive widgets
+[isoduration](https://pypi.org/project/isoduration) | 20.11.0 | Operations with ISO 8601 durations
+[isort](https://pypi.org/project/isort) | 5.13.2 | A Python utility / library to sort Python imports.
+[itsdangerous](https://pypi.org/project/itsdangerous) | 2.2.0 | Safely pass data to untrusted environments and back.
+[janus](https://pypi.org/project/janus) | 2.0.0 | Mixed sync-async queue to interoperate between asyncio tasks and classic threads
+[jaraco_classes](https://pypi.org/project/jaraco_classes) | 3.4.0 | Utility functions for Python class constructs
+[jaraco_context](https://pypi.org/project/jaraco_context) | 6.0.1 | Useful decorators and context managers
+[jaraco_functools](https://pypi.org/project/jaraco_functools) | 4.1.0 | Functools like those found in stdlib
+[jedi](https://pypi.org/project/jedi) | 0.19.2 | An autocompletion tool for Python that can be used for text editors.
+[jellyfish](https://pypi.org/project/jellyfish) | 1.1.3 | Approximate and phonetic matching of strings.
+[jinja2](https://pypi.org/project/jinja2) | 3.1.2 | A very fast and expressive template engine.
+[jiter](https://pypi.org/project/jiter) | 0.8.2 | Fast iterable JSON parser.
+[joblib](https://pypi.org/project/joblib) | 1.4.2 | Lightweight pipelining with Python functions
+[json5](https://pypi.org/project/json5) | 0.9.14 | A Python implementation of the JSON5 data format.
+[jsonpatch](https://pypi.org/project/jsonpatch) | 1.33 | Apply JSON-Patches (RFC 6902)
+[jsonpath_python](https://pypi.org/project/jsonpath_python) | 1.0.6 | A more powerful JSONPath implementation in modern python
+[jsonpointer](https://pypi.org/project/jsonpointer) | 2.4 | Identify specific nodes in a JSON document (RFC 6901)
+[jsonschema](https://pypi.org/project/jsonschema) | 4.19.2 | An implementation of JSON Schema validation for Python
+[jsonschema_specifications](https://pypi.org/project/jsonschema_specifications) | 2023.12.1 | The JSON Schema meta-schemas and vocabularies, exposed as a Registry
+[julia](https://pypi.org/project/julia) | 0.6.2 | Julia/Python bridge with IPython support.
+[jupyter](https://pypi.org/project/jupyter) | 1.1.1 | Jupyter metapackage. Install all the Jupyter components in one go.
+[jupyter_bokeh](https://pypi.org/project/jupyter_bokeh) | 4.0.5 | A Jupyter extension for rendering Bokeh content.
+[jupyter_client](https://pypi.org/project/jupyter_client) | 8.6.2 | Jupyter protocol implementation and client libraries
+[jupyter_console](https://pypi.org/project/jupyter_console) | 6.6.3 | Jupyter terminal console
+[jupyter_core](https://pypi.org/project/jupyter_core) | 5.7.2 | Jupyter core package. A base package on which Jupyter projects rely.
+[jupyter_events](https://pypi.org/project/jupyter_events) | 0.10.0 | Jupyter Event System library
+[jupyter_leaflet](https://pypi.org/project/jupyter_leaflet) | 0.19.2 | ipyleaflet extensions for JupyterLab and Jupyter Notebook
+[jupyter_lsp](https://pypi.org/project/jupyter_lsp) | 2.2.5 | Multi-Language Server WebSocket proxy for Jupyter Notebook/Lab server
+[jupyter_server](https://pypi.org/project/jupyter_server) | 2.14.2 | The backend—i.e. core services, APIs, and REST endpoints—to Jupyter web applications.
+[jupyter_server_terminals](https://pypi.org/project/jupyter_server_terminals) | 0.5.3 | A Jupyter Server Extension Providing Terminals.
+[jupyterlab](https://pypi.org/project/jupyterlab) | 4.3.5 | JupyterLab computational environment
+[jupyterlab_pygments](https://pypi.org/project/jupyterlab_pygments) | 0.3.0 | Pygments theme using JupyterLab CSS variables
+[jupyterlab_server](https://pypi.org/project/jupyterlab_server) | 2.27.3 | A set of server components for JupyterLab and JupyterLab like applications.
+[jupyterlab_widgets](https://pypi.org/project/jupyterlab_widgets) | 3.0.13 | Jupyter interactive widgets for JupyterLab
+[keras](https://pypi.org/project/keras) | 3.8.0 | Multi-backend Keras
+[keyring](https://pypi.org/project/keyring) | 25.6.0 | Store and access your passwords safely.
+[kiwisolver](https://pypi.org/project/kiwisolver) | 1.4.8 | A fast implementation of the Cassowary constraint solver
+[langchain](https://pypi.org/project/langchain) | 0.3.18 | Building applications with LLMs through composability
+[langchain_core](https://pypi.org/project/langchain_core) | 0.3.34 | Building applications with LLMs through composability
+[langchain_text_splitters](https://pypi.org/project/langchain_text_splitters) | 0.3.6 | LangChain text splitting utilities
+[langsmith](https://pypi.org/project/langsmith) | 0.2.11 | Client library to connect to the LangSmith LLM Tracing and Evaluation Platform.
+[lazy_loader](https://pypi.org/project/lazy_loader) | 0.4 | Makes it easy to load subpackages and functions on demand.
+[linkify_it_py](https://pypi.org/project/linkify_it_py) | 2.0.2 | Links recognition library with FULL unicode support.
+[llvmlite](https://pypi.org/project/llvmlite) | 0.44.0 | lightweight wrapper around basic LLVM functionality
+[lmfit](https://pypi.org/project/lmfit) | 1.3.1 | Least-Squares Minimization with Bounds and Constraints
+[locket](https://pypi.org/project/locket) | 1.0.0 | File-based locks for Python on Linux and Windows
+[logfire_api](https://pypi.org/project/logfire_api) | 3.5.3 | Shim for the Logfire SDK which does nothing unless Logfire is installed
+[lxml](https://pypi.org/project/lxml) | 5.3.0 | Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API.
+[mako](https://pypi.org/project/mako) | 1.3.5 | A super-fast templating language that borrows the best ideas from the existing templating languages.
+[markdown](https://pypi.org/project/markdown) | 3.5.1 | Python implementation of John Gruber's Markdown.
+[markdown_it_py](https://pypi.org/project/markdown_it_py) | 2.2.0 | Python port of markdown-it. Markdown parsing, done right!
+[markupsafe](https://pypi.org/project/markupsafe) | 3.0.2 | Safely add untrusted strings to HTML/XML markup.
+[matplotlib](https://pypi.org/project/matplotlib) | 3.10.0 | Python plotting package
+[matplotlib_inline](https://pypi.org/project/matplotlib_inline) | 0.1.7 | Inline Matplotlib backend for Jupyter
+[maturin](https://pypi.org/project/maturin) | 1.8.1 | Build and publish crates with pyo3, cffi and uniffi bindings as well as rust binaries as python packages
+[mccabe](https://pypi.org/project/mccabe) | 0.7.0 | McCabe checker, plugin for flake8
+[mdit_py_plugins](https://pypi.org/project/mdit_py_plugins) | 0.3.5 | Collection of plugins for markdown-it-py
+[mdurl](https://pypi.org/project/mdurl) | 0.1.2 | Markdown URL utilities
+[mercantile](https://pypi.org/project/mercantile) | 1.2.1 | Web mercator XYZ tile utilities
+[mergedeep](https://pypi.org/project/mergedeep) | 1.3.4 | A deep merge function for 🐍.
+[missingno](https://pypi.org/project/missingno) | 0.5.1 | Missing data visualization module for Python.
+[mistralai](https://pypi.org/project/mistralai) | 1.2.5 | Python Client SDK for the Mistral AI API.
+[mistune](https://pypi.org/project/mistune) | 2.0.5 | A sane Markdown parser with useful plugins and renderers
+[mizani](https://pypi.org/project/mizani) | 0.11.4 | Scales for Python
+[ml_dtypes](https://pypi.org/project/ml_dtypes) | 0.5.0 |
+[mlxtend](https://pypi.org/project/mlxtend) | 0.23.3 | Machine Learning Library Extensions
+[more_itertools](https://pypi.org/project/more_itertools) | 10.2.0 | More routines for operating on iterables, beyond itertools
+[mpl_scatter_density](https://pypi.org/project/mpl_scatter_density) | 0.7 | Matplotlib helpers to make density scatter plots
+[mpld3](https://pypi.org/project/mpld3) | 0.5.8 | D3 Viewer for Matplotlib
+[mpmath](https://pypi.org/project/mpmath) | 1.3.0 | Python library for arbitrary-precision floating-point arithmetic
+[msal](https://pypi.org/project/msal) | 1.30.0 | The Microsoft Authentication Library (MSAL) for Python library enables your app to access the Microsoft Cloud by supporting authentication of us
+[msal_extensions](https://pypi.org/project/msal_extensions) | 1.2.0 | Microsoft Authentication Library extensions (MSAL EX) provides a persistence API that can save your data on disk, encrypted on Windows, macOS an
+[msgpack](https://pypi.org/project/msgpack) | 1.1.0 | MessagePack serializer
+[multidict](https://pypi.org/project/multidict) | 6.1.0 | multidict implementation
+[multipledispatch](https://pypi.org/project/multipledispatch) | 1.0.0 | Multiple dispatch
+[mutagen](https://pypi.org/project/mutagen) | 1.47.0 | read and write audio tags for many formats
+[mypy](https://pypi.org/project/mypy) | 1.14.0 | Optional static typing for Python
+[mypy_extensions](https://pypi.org/project/mypy_extensions) | 1.0.0 | Type system extensions for programs checked with the mypy type checker.
+[mysql_connector_python](https://pypi.org/project/mysql_connector_python) | 8.0.21 | MySQL driver written in Python
+[namex](https://pypi.org/project/namex) | 0.0.8 | A simple utility to separate the implementation of your Python package and its public API surface.
+[narwhals](https://pypi.org/project/narwhals) | 1.21.1 | Extremely lightweight compatibility layer between dataframe libraries
+[nbclient](https://pypi.org/project/nbclient) | 0.10.0 | A client library for executing notebooks. Formerly nbconvert's ExecutePreprocessor.
+[nbconvert](https://pypi.org/project/nbconvert) | 7.16.1 | Converting Jupyter Notebooks (.ipynb files) to other formats
+[nbformat](https://pypi.org/project/nbformat) | 5.10.4 | The Jupyter Notebook format
+[nest_asyncio](https://pypi.org/project/nest_asyncio) | 1.6.0 | Patch asyncio to allow nested event loops
+[networkx](https://pypi.org/project/networkx) | 3.4.2 | Python package for creating and manipulating graphs and networks
+[nh3](https://pypi.org/project/nh3) | 0.2.18 | Python bindings to the ammonia HTML sanitization library.
+[nltk](https://pypi.org/project/nltk) | 3.9.1 | Natural Language Toolkit
+[notebook](https://pypi.org/project/notebook) | 7.3.1 | Jupyter Notebook - A web-based notebook environment for interactive computing
+[notebook_shim](https://pypi.org/project/notebook_shim) | 0.2.4 | A shim layer for notebook traits and config
+[numba](https://pypi.org/project/numba) | 0.61.0 | compiling Python code using LLVM
+[numpy](https://pypi.org/project/numpy) | 2.1.3 | Fundamental package for array computing in Python
+[numpydoc](https://pypi.org/project/numpydoc) | 1.6.0 | Sphinx extension to support docstrings in Numpy format
+[openai](https://pypi.org/project/openai) | 1.61.1 | The official Python library for the openai API
+[opencv_python](https://pypi.org/project/opencv_python) | 4.10.0.84 | Wrapper package for OpenCV python bindings.
+[openpyxl](https://pypi.org/project/openpyxl) | 3.1.2 | A Python library to read/write Excel 2010 xlsx/xlsm files
+[optree](https://pypi.org/project/optree) | 0.13.1 | Optimized PyTree Utilities.
+[optuna](https://pypi.org/project/optuna) | 3.6.1 | A hyperparameter optimization framework
+[orjson](https://pypi.org/project/orjson) | 3.10.12 | Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy
+[osqp](https://pypi.org/project/osqp) | 0.6.7.post3 | OSQP: The Operator Splitting QP Solver
+[outcome](https://pypi.org/project/outcome) | 1.3.0.post0 | Capture the outcome of Python function calls.
+[overrides](https://pypi.org/project/overrides) | 7.7.0 | A decorator to automatically detect mismatch when overriding a method.
+[packaging](https://pypi.org/project/packaging) | 24.2 | Core utilities for Python packages
+[pandas](https://pypi.org/project/pandas) | 2.2.3 | Powerful data structures for data analysis, time series, and statistics
+[pandocfilters](https://pypi.org/project/pandocfilters) | 1.5.0 | Utilities for writing pandoc filters in python
+[panel](https://pypi.org/project/panel) | 1.6.0 | The powerful data exploration & web app framework for Python.
+[papermill](https://pypi.org/project/papermill) | 2.6.0 | Parameterize and run Jupyter and nteract Notebooks
+[param](https://pypi.org/project/param) | 2.1.1 | Make your Python code clearer and more reliable by declaring Parameters.
+[paramiko](https://pypi.org/project/paramiko) | 2.8.0 | SSH2 protocol library
+[parso](https://pypi.org/project/parso) | 0.8.4 | A Python Parser
+[partd](https://pypi.org/project/partd) | 1.4.0 | Appendable key-value storage
+[pathspec](https://pypi.org/project/pathspec) | 0.11.0 | Utility library for gitignore style pattern matching of file paths.
+[patsy](https://pypi.org/project/patsy) | 0.5.6 | A Python package for describing statistical models and for building design matrices.
+[pep8](https://pypi.org/project/pep8) | 1.7.1 | Python style guide checker
+[pexpect](https://pypi.org/project/pexpect) | 4.8.0 | Pexpect allows easy control of interactive console applications.
+[pg8000](https://pypi.org/project/pg8000) | 1.23.0 | PostgreSQL interface library
+[pickleshare](https://pypi.org/project/pickleshare) | 0.7.5 | Tiny 'shelve'-like database with concurrency support
+[pillow](https://pypi.org/project/pillow) | 11.1.0 | Python Imaging Library (Fork)
+[pint](https://pypi.org/project/pint) | 0.23 | Physical quantities module
+[pip](https://pypi.org/project/pip) | 24.3.1 | The PyPA recommended tool for installing Python packages.
+[pkginfo](https://pypi.org/project/pkginfo) | 1.11.2 | Query metadata from sdists / bdists / installed packages.
+[platformdirs](https://pypi.org/project/platformdirs) | 4.2.2 | A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`.
+[plotly](https://pypi.org/project/plotly) | 5.24.1 | An open-source, interactive data visualization library for Python
+[plotnine](https://pypi.org/project/plotnine) | 0.13.6 | A Grammar of Graphics for Python
+[plotpy](https://pypi.org/project/plotpy) | 2.7.2 | Curve and image plotting tools for Python/Qt applications
+[pluggy](https://pypi.org/project/pluggy) | 1.5.0 | plugin and hook calling mechanisms for python
+[ply](https://pypi.org/project/ply) | 3.11 | Python Lex & Yacc
+[polars](https://pypi.org/project/polars) | 1.22.0 | Blazingly fast DataFrame library
+[portalocker](https://pypi.org/project/portalocker) | 2.7.0 | Wraps the portalocker recipe for easy usage
+[prettytable](https://pypi.org/project/prettytable) | 3.3.0 | A simple Python library for easily displaying tabular data in a visually appealing ASCII table format
+[prince](https://pypi.org/project/prince) | 0.15.0 | Factor analysis in Python: PCA, CA, MCA, MFA, FAMD, GPA
+[priority](https://pypi.org/project/priority) | 2.0.0 | A pure-Python implementation of the HTTP/2 priority tree
+[prometheus_client](https://pypi.org/project/prometheus_client) | 0.18.0 | Python client for the Prometheus monitoring system.
+[prompt_toolkit](https://pypi.org/project/prompt_toolkit) | 3.0.48 | Library for building powerful interactive command lines in Python
+[propcache](https://pypi.org/project/propcache) | 0.2.1 | Accelerated property cache
+[protobuf](https://pypi.org/project/protobuf) | 5.27.3 |
+[psutil](https://pypi.org/project/psutil) | 5.9.8 | Cross-platform lib for process and system monitoring in Python.
+[psygnal](https://pypi.org/project/psygnal) | 0.11.1 | Fast python callback/event system modeled after Qt Signals
+[ptpython](https://pypi.org/project/ptpython) | 3.0.29 | Python REPL build on top of prompt_toolkit
+[ptyprocess](https://pypi.org/project/ptyprocess) | 0.7.0 | Run a subprocess in a pseudo terminal
+[pure_eval](https://pypi.org/project/pure_eval) | 0.2.2 | Safely evaluate AST nodes without side effects
+[pyarrow](https://pypi.org/project/pyarrow) | 19.0.0 | Python library for Apache Arrow
+[pyasn1](https://pypi.org/project/pyasn1) | 0.4.8 | ASN.1 types and codecs
+[pyasn1_modules](https://pypi.org/project/pyasn1_modules) | 0.2.8 | A collection of ASN.1-based protocols modules.
+[pybind11](https://pypi.org/project/pybind11) | 2.13.6 | Seamless operability between C++11 and Python
+[pycodestyle](https://pypi.org/project/pycodestyle) | 2.12.0 | Python style guide checker
+[pycparser](https://pypi.org/project/pycparser) | 2.22 | C parser in Python
+[pycryptodomex](https://pypi.org/project/pycryptodomex) | 3.20.0 | Cryptographic library for Python
+[pyct](https://pypi.org/project/pyct) | 0.5.0 | Python package common tasks for users (e.g. copy examples, fetch data, ...)
+[pydantic](https://pypi.org/project/pydantic) | 2.10.6 | Data validation using Python type hints
+[pydantic_ai](https://pypi.org/project/pydantic_ai) | 0.0.24 | Agent Framework / shim to use Pydantic with LLMs
+[pydantic_ai_slim](https://pypi.org/project/pydantic_ai_slim) | 0.0.24 | Agent Framework / shim to use Pydantic with LLMs, slim package
+[pydantic_core](https://pypi.org/project/pydantic_core) | 2.27.2 | Core functionality for Pydantic validation and serialization
+[pydantic_graph](https://pypi.org/project/pydantic_graph) | 0.0.24 | Graph and state machine library
+[pydeck](https://pypi.org/project/pydeck) | 0.9.1 | Widget for deck.gl maps
+[pydocstyle](https://pypi.org/project/pydocstyle) | 6.3.0 | Python docstring style checker
+[pydub](https://pypi.org/project/pydub) | 0.25.1 | Manipulate audio with an simple and easy high level interface
+[pyerfa](https://pypi.org/project/pyerfa) | 2.0.1.4 | Python bindings for ERFA
+[pyflakes](https://pypi.org/project/pyflakes) | 3.2.0 | passive checker of Python programs
+[pygments](https://pypi.org/project/pygments) | 2.19.1 | Pygments is a syntax highlighting package written in Python.
+[pyjwt](https://pypi.org/project/pyjwt) | 2.8.0 | JSON Web Token implementation in Python
+[pylint](https://pypi.org/project/pylint) | 3.1.0 | python code static checker
+[pylint_venv](https://pypi.org/project/pylint_venv) | 3.0.3 | pylint-venv provides a Pylint init-hook to use the same Pylint installation with different virtual environments.
+[pyls_spyder](https://pypi.org/project/pyls_spyder) | 0.4.0 | Spyder extensions for the python-lsp-server
+[pymongo](https://pypi.org/project/pymongo) | 4.10.1 | Python driver for MongoDB
+[pympler](https://pypi.org/project/pympler) | 1.0.1 | A development tool to measure, monitor and analyze the memory behavior of Python objects.
+[pynacl](https://pypi.org/project/pynacl) | 1.5.0 | Python binding to the Networking and Cryptography (NaCl) library
+[pynndescent](https://pypi.org/project/pynndescent) | 0.5.12 | Nearest Neighbor Descent
+[pyodbc](https://pypi.org/project/pyodbc) | 5.2.0 | DB API module for ODBC
+[pyogrio](https://pypi.org/project/pyogrio) | 0.10.0 | Vectorized spatial vector file format I/O using GDAL/OGR
+[pyomo](https://pypi.org/project/pyomo) | 6.8.2 | Pyomo: Python Optimization Modeling Objects
+[pypandoc](https://pypi.org/project/pypandoc) | 1.5 | Thin wrapper for pandoc.
+[pyparsing](https://pypi.org/project/pyparsing) | 3.2.1 | pyparsing module - Classes and methods to define and execute parsing grammars
+[pypdf](https://pypi.org/project/pypdf) | 5.1.0 | A pure-python PDF library capable of splitting, merging, cropping, and transforming PDF files
+[pyproj](https://pypi.org/project/pyproj) | 3.7.0 | Python interface to PROJ (cartographic projections and coordinate transformations library)
+[pyproject_hooks](https://pypi.org/project/pyproject_hooks) | 1.1.0 | Wrappers to call pyproject.toml-based build backend hooks.
+[pyqt5](https://pypi.org/project/pyqt5) | 5.15.10 | Python bindings for the Qt cross platform application toolkit
+[pyqt5_qt5](https://pypi.org/project/pyqt5_qt5) | 5.15.2 | The subset of a Qt installation needed by PyQt5.
+[pyqt5_sip](https://pypi.org/project/pyqt5_sip) | 12.16.1 | The sip module support for PyQt5
+[pyqtgraph](https://pypi.org/project/pyqtgraph) | 0.13.7 | Scientific Graphics and GUI Library for Python
+[pyqtwebengine](https://pypi.org/project/pyqtwebengine) | 5.15.6 | Python bindings for the Qt WebEngine framework
+[pyqtwebengine_qt5](https://pypi.org/project/pyqtwebengine_qt5) | 5.15.2 | The subset of a Qt installation needed by PyQtWebEngine.
+[pyserial](https://pypi.org/project/pyserial) | 3.5 | Python Serial Port Extension
+[pysocks](https://pypi.org/project/pysocks) | 1.7.1 | A Python SOCKS client module. See https://github.com/Anorov/PySocks for more information.
+[pyspnego](https://pypi.org/project/pyspnego) | 0.11.2 | Windows Negotiate Authentication Client and Server
+[pytest](https://pypi.org/project/pytest) | 8.2.2 | pytest: simple powerful testing with Python
+[python_barcode](https://pypi.org/project/python_barcode) | 0.15.1 | Create standard barcodes with Python. No external modules needed. (optional Pillow support included).
+[python_dateutil](https://pypi.org/project/python_dateutil) | 2.8.2 | Extensions to the standard Python datetime module
+[python_dotenv](https://pypi.org/project/python_dotenv) | 1.0.1 | Read key-value pairs from a .env file and set them as environment variables
+[python_json_logger](https://pypi.org/project/python_json_logger) | 2.0.7 | A python library adding a json log formatter
+[python_lsp_black](https://pypi.org/project/python_lsp_black) | 2.0.0 | Black plugin for the Python LSP Server
+[python_lsp_jsonrpc](https://pypi.org/project/python_lsp_jsonrpc) | 1.1.2 | JSON RPC 2.0 server library
+[python_lsp_server](https://pypi.org/project/python_lsp_server) | 1.12.0 | Python Language Server for the Language Server Protocol
+[python_multipart](https://pypi.org/project/python_multipart) | 0.0.9 | A streaming multipart parser for Python
+[python_slugify](https://pypi.org/project/python_slugify) | 8.0.4 | A Python slugify application that also handles Unicode
+[pythonqwt](https://pypi.org/project/pythonqwt) | 0.14.4 | Qt plotting widgets for Python
+[pytoolconfig](https://pypi.org/project/pytoolconfig) | 1.3.1 | Python tool configuration
+[pytz](https://pypi.org/project/pytz) | 2024.1 | World timezone definitions, modern and historical
+[pyusb](https://pypi.org/project/pyusb) | 1.3.1 | Easy USB access for Python
+[pyviz_comms](https://pypi.org/project/pyviz_comms) | 3.0.3 | A JupyterLab extension for rendering HoloViz content.
+[pywavelets](https://pypi.org/project/pywavelets) | 1.8.0 | PyWavelets, wavelet transform module
+[pywin32](https://pypi.org/project/pywin32) | 308 | Python for Window Extensions
+[pywin32_ctypes](https://pypi.org/project/pywin32_ctypes) | 0.2.2 | A (partial) reimplementation of pywin32 using ctypes/cffi
+[pywinpty](https://pypi.org/project/pywinpty) | 2.0.14 | Pseudo terminal support for Windows from Python.
+[pyyaml](https://pypi.org/project/pyyaml) | 6.0.2 | YAML parser and emitter for Python
+[pyzmq](https://pypi.org/project/pyzmq) | 26.2.0 | Python bindings for 0MQ
+[qdarkstyle](https://pypi.org/project/qdarkstyle) | 3.2.3 | The most complete dark/light style sheet for C++/Python and Qt applications
+[qdldl](https://pypi.org/project/qdldl) | 0.1.7.post5 | QDLDL, a free LDL factorization routine.
+[qrcode](https://pypi.org/project/qrcode) | 8.0 | QR Code image generator
+[qstylizer](https://pypi.org/project/qstylizer) | 0.2.2 | Stylesheet Generator for PyQt{4-5}/PySide{1-2}
+[qtawesome](https://pypi.org/project/qtawesome) | 1.3.1 | FontAwesome icons in PyQt and PySide applications
+[qtconsole](https://pypi.org/project/qtconsole) | 5.5.2 | Jupyter Qt console
+[qtpy](https://pypi.org/project/qtpy) | 2.4.1 | Provides an abstraction layer on top of the various Qt bindings (PyQt5/6 and PySide2/6).
+[quantecon](https://pypi.org/project/quantecon) | 0.7.2 | Import the main names to top level.
+[quart](https://pypi.org/project/quart) | 0.19.4 | A Python ASGI web microframework with the same API as Flask
+[rapidfuzz](https://pypi.org/project/rapidfuzz) | 3.9.6 | rapid fuzzy string matching
+[readme_renderer](https://pypi.org/project/readme_renderer) | 44.0 | readme_renderer is a library for rendering readme descriptions for Warehouse
+[redis](https://pypi.org/project/redis) | 5.0.8 | Python client for Redis database and key-value store
+[referencing](https://pypi.org/project/referencing) | 0.35.1 | JSON Referencing + Python
+[regex](https://pypi.org/project/regex) | 2024.11.6 | Alternative regular expression module, to replace re.
+[reportlab](https://pypi.org/project/reportlab) | 4.2.5 | The Reportlab Toolkit
+[requests](https://pypi.org/project/requests) | 2.32.3 | Python HTTP for Humans.
+[requests_ntlm](https://pypi.org/project/requests_ntlm) | 1.3.0 | This package allows for HTTP NTLM authentication using the requests library.
+[requests_toolbelt](https://pypi.org/project/requests_toolbelt) | 1.0.0 | A utility belt for advanced users of python-requests
+[rfc3339_validator](https://pypi.org/project/rfc3339_validator) | 0.1.4 | A pure python RFC3339 validator
+[rfc3986](https://pypi.org/project/rfc3986) | 2.0.0 | Validating URI References per RFC 3986
+[rfc3986_validator](https://pypi.org/project/rfc3986_validator) | 0.1.1 | Pure python rfc3986 validator
+[rich](https://pypi.org/project/rich) | 13.9.4 | Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal
+[rope](https://pypi.org/project/rope) | 1.12.0 | a python refactoring library...
+[rpds_py](https://pypi.org/project/rpds_py) | 0.22.3 | Python bindings to Rust's persistent data structures (rpds)
+[rsa](https://pypi.org/project/rsa) | 4.7.2 | Pure-Python RSA implementation
+[rtree](https://pypi.org/project/rtree) | 1.1.0 | R-Tree spatial index for Python GIS
+[rx](https://pypi.org/project/rx) | 3.1.1 | Reactive Extensions (Rx) for Python
+[scikit_image](https://pypi.org/project/scikit_image) | 0.25.0 | Image processing in Python
+[scikit_learn](https://pypi.org/project/scikit_learn) | 1.6.1 | A set of python modules for machine learning and data mining
+[scipy](https://pypi.org/project/scipy) | 1.15.1 | Fundamental algorithms for scientific computing in Python
+[scramp](https://pypi.org/project/scramp) | 1.4.5 | An implementation of the SCRAM protocol.
+[scs](https://pypi.org/project/scs) | 3.2.7.post2 | Splitting conic solver
+[seaborn](https://pypi.org/project/seaborn) | 0.13.2 | Statistical data visualization
+[send2trash](https://pypi.org/project/send2trash) | 1.8.2 | Send file to trash natively under Mac OS X, Windows and Linux
+[setuptools](https://pypi.org/project/setuptools) | 75.6.0 | Easily download, build, install, upgrade, and uninstall Python packages
+[shapely](https://pypi.org/project/shapely) | 2.0.6 | Manipulation and analysis of geometric objects
+[simplejson](https://pypi.org/project/simplejson) | 3.19.3 | Simple, fast, extensible JSON encoder/decoder for Python
+[simpy](https://pypi.org/project/simpy) | 4.0.1 | Event discrete, process based simulation for Python.
+[six](https://pypi.org/project/six) | 1.16.0 | Python 2 and 3 compatibility utilities
+[sklearn_compat](https://pypi.org/project/sklearn_compat) | 0.1.3 | Ease support for compatible scikit-learn estimators across versions
+[smmap](https://pypi.org/project/smmap) | 5.0.0 | A pure Python implementation of a sliding window memory map manager
+[sniffio](https://pypi.org/project/sniffio) | 1.3.0 | Sniff out which async library your code is running under
+[snowballstemmer](https://pypi.org/project/snowballstemmer) | 2.2.0 | This package provides 29 stemmers for 28 languages generated from Snowball algorithms.
+[sortedcontainers](https://pypi.org/project/sortedcontainers) | 2.4.0 | Sorted Containers -- Sorted List, Sorted Dict, Sorted Set
+[sounddevice](https://pypi.org/project/sounddevice) | 0.5.1 | Play and Record Sound with Python
+[soupsieve](https://pypi.org/project/soupsieve) | 2.6 | A modern CSS selector implementation for Beautiful Soup.
+[sphinx](https://pypi.org/project/sphinx) | 7.3.7 | Python documentation generator
+[sphinx_rtd_theme](https://pypi.org/project/sphinx_rtd_theme) | 3.0.2 | Read the Docs theme for Sphinx
+[sphinxcontrib_applehelp](https://pypi.org/project/sphinxcontrib_applehelp) | 2.0.0 | sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books
+[sphinxcontrib_devhelp](https://pypi.org/project/sphinxcontrib_devhelp) | 2.0.0 | sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp documents
+[sphinxcontrib_htmlhelp](https://pypi.org/project/sphinxcontrib_htmlhelp) | 2.1.0 | sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files
+[sphinxcontrib_jquery](https://pypi.org/project/sphinxcontrib_jquery) | 4.1 | Extension to include jQuery on newer Sphinx releases
+[sphinxcontrib_jsmath](https://pypi.org/project/sphinxcontrib_jsmath) | 1.0.1 | A sphinx extension which renders display math in HTML via JavaScript
+[sphinxcontrib_qthelp](https://pypi.org/project/sphinxcontrib_qthelp) | 2.0.0 | sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp documents
+[sphinxcontrib_serializinghtml](https://pypi.org/project/sphinxcontrib_serializinghtml) | 2.0.0 | sphinxcontrib-serializinghtml is a sphinx extension which outputs "serialized" HTML files (json and pickle)
+[spyder](https://pypi.org/project/spyder) | 5.5.6 | The Scientific Python Development Environment
+[spyder_kernels](https://pypi.org/project/spyder_kernels) | 2.5.2 | Jupyter kernels for Spyder's console
+[sqlalchemy](https://pypi.org/project/sqlalchemy) | 2.0.35 | Database Abstraction Library
+[sqlite_bro](https://pypi.org/project/sqlite_bro) | 0.13.1 | a graphic SQLite Client in 1 Python file
+[sqlite_fts4](https://pypi.org/project/sqlite_fts4) | 1.0.3 | Python functions for working with SQLite FTS4 search
+[sqlite_utils](https://pypi.org/project/sqlite_utils) | 3.38 | CLI tool and Python library for manipulating SQLite databases
+[sqlparse](https://pypi.org/project/sqlparse) | 0.5.3 | A non-validating SQL parser.
+[squarify](https://pypi.org/project/squarify) | 0.4.4 | Pure Python implementation of the squarify treemap layout algorithm
+[sspilib](https://pypi.org/project/sspilib) | 0.2.0 | SSPI API bindings for Python
+[stack_data](https://pypi.org/project/stack_data) | 0.6.3 | Extract data from python stack frames and tracebacks for informative displays
+[starlette](https://pypi.org/project/starlette) | 0.41.3 | The little ASGI library that shines.
+[statsmodels](https://pypi.org/project/statsmodels) | 0.14.4 | Statistical computations and models for Python
+[streamlit](https://pypi.org/project/streamlit) | 1.41.1 | A faster way to build and share data apps
+[streamz](https://pypi.org/project/streamz) | 0.6.3 | Streams
+[sympy](https://pypi.org/project/sympy) | 1.13.3 | Computer algebra system (CAS) in Python
+[tabulate](https://pypi.org/project/tabulate) | 0.9.0 | Pretty-print tabular data
+[tblib](https://pypi.org/project/tblib) | 3.0.0 | Traceback serialization library.
+[tenacity](https://pypi.org/project/tenacity) | 9.0.0 | Retry code until it succeeds
+[termcolor](https://pypi.org/project/termcolor) | 2.5.0 | ANSI color formatting for output in terminal
+[terminado](https://pypi.org/project/terminado) | 0.18.1 | Tornado websocket backend for the Xterm.js Javascript terminal emulator library.
+[text_unidecode](https://pypi.org/project/text_unidecode) | 1.3 | The most basic Text::Unidecode port
+[textdistance](https://pypi.org/project/textdistance) | 4.6.3 | Compute distance between the two texts.
+[thefuzz](https://pypi.org/project/thefuzz) | 0.22.1 | Fuzzy string matching in python
+[threadpoolctl](https://pypi.org/project/threadpoolctl) | 3.5.0 | threadpoolctl
+[three_merge](https://pypi.org/project/three_merge) | 0.1.1 | Simple library for merging two strings with respect to a base one
+[tifffile](https://pypi.org/project/tifffile) | 2025.1.10 | Read and write TIFF files
+[tiktoken](https://pypi.org/project/tiktoken) | 0.8.0 | tiktoken is a fast BPE tokeniser for use with OpenAI's models
+[tinycss2](https://pypi.org/project/tinycss2) | 1.4.0 | A tiny CSS parser
+[tokenizers](https://pypi.org/project/tokenizers) | 0.21.0 |
+[toml](https://pypi.org/project/toml) | 0.10.2 | Python Library for Tom's Obvious, Minimal Language
+[tomli](https://pypi.org/project/tomli) | 2.2.1 | A lil' TOML parser
+[tomli_w](https://pypi.org/project/tomli_w) | 1.1.0 | A lil' TOML writer
+[tomlkit](https://pypi.org/project/tomlkit) | 0.13.2 | Style preserving TOML library
+[toolz](https://pypi.org/project/toolz) | 1.0.0 | List processing tools and functional utilities
+[tornado](https://pypi.org/project/tornado) | 6.4.2 | Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed.
+[tqdm](https://pypi.org/project/tqdm) | 4.66.4 | Fast, Extensible Progress Meter
+[traitlets](https://pypi.org/project/traitlets) | 5.14.1 | Traitlets Python configuration system
+[traittypes](https://pypi.org/project/traittypes) | 0.2.1 | Scipy trait types
+[trio](https://pypi.org/project/trio) | 0.28.0 | A friendly Python library for async concurrency and I/O
+[trove_classifiers](https://pypi.org/project/trove_classifiers) | 2024.10.21.16 | Canonical source for classifiers on PyPI (pypi.org).
+[twine](https://pypi.org/project/twine) | 6.0.1 | Collection of utilities for publishing packages on PyPI
+[types_python_dateutil](https://pypi.org/project/types_python_dateutil) | 2.9.0.20240316 | Typing stubs for python-dateutil
+[types_requests](https://pypi.org/project/types_requests) | 2.32.0.20241016 | Typing stubs for requests
+[typing_extensions](https://pypi.org/project/typing_extensions) | 4.12.2 | Backported and Experimental Type Hints for Python 3.8+
+[typing_inspect](https://pypi.org/project/typing_inspect) | 0.9.0 | Runtime inspection utilities for typing module.
+[tzdata](https://pypi.org/project/tzdata) | 2024.1 | Provider of IANA time zone data
+[tzlocal](https://pypi.org/project/tzlocal) | 5.2 | tzinfo object for the local timezone
+[uc_micro_py](https://pypi.org/project/uc_micro_py) | 1.0.1 | Micro subset of unicode data files for linkify-it-py projects.
+[ujson](https://pypi.org/project/ujson) | 5.10.0 | Ultra fast JSON encoder and decoder for Python
+[umap_learn](https://pypi.org/project/umap_learn) | 0.5.6 | Uniform Manifold Approximation and Projection
+[uncertainties](https://pypi.org/project/uncertainties) | 3.2.2 | calculations with values with uncertainties, error propagation
+[uri_template](https://pypi.org/project/uri_template) | 1.3.0 | RFC 6570 URI Template Processor
+[urllib3](https://pypi.org/project/urllib3) | 2.2.3 | HTTP library with thread-safe connection pooling, file post, and more.
+[uvicorn](https://pypi.org/project/uvicorn) | 0.34.0 | The lightning-fast ASGI server.
+[vega_datasets](https://pypi.org/project/vega_datasets) | 0.9.0 | A Python package for offline access to Vega datasets
+[waitress](https://pypi.org/project/waitress) | 3.0.0 | Waitress WSGI server
+[watchdog](https://pypi.org/project/watchdog) | 6.0.0 | Filesystem events monitoring
+[wcwidth](https://pypi.org/project/wcwidth) | 0.2.13 | Measures the displayed width of unicode strings in a terminal
+[webcolors](https://pypi.org/project/webcolors) | 24.11.1 | A library for working with the color formats defined by HTML and CSS.
+[webencodings](https://pypi.org/project/webencodings) | 0.5.1 | Character encoding aliases for legacy web content
+[websocket_client](https://pypi.org/project/websocket_client) | 1.8.0 | WebSocket client for Python with low level API options
+[websockets](https://pypi.org/project/websockets) | 14.2 | An implementation of the WebSocket Protocol (RFC 6455 & 7692)
+[werkzeug](https://pypi.org/project/werkzeug) | 3.1.3 | The comprehensive WSGI web application library.
+[whatthepatch](https://pypi.org/project/whatthepatch) | 1.0.7 | A patch parsing and application library.
+[wheel](https://pypi.org/project/wheel) | 0.45.1 | A built-package format for Python
+[widgetsnbextension](https://pypi.org/project/widgetsnbextension) | 4.0.13 | Jupyter interactive widgets for Jupyter Notebook
+[winpython](https://pypi.org/project/winpython) | 13.1.20250222 | WinPython distribution tools, including WPPM
+[wordcloud](https://pypi.org/project/wordcloud) | 1.9.4 | A little word cloud generator
+[wsproto](https://pypi.org/project/wsproto) | 1.2.0 | WebSockets state-machine based protocol implementation
+[xarray](https://pypi.org/project/xarray) | 2025.1.1 | N-D labeled arrays and datasets in Python
+[xlsxwriter](https://pypi.org/project/xlsxwriter) | 3.1.9 | A Python module for creating Excel XLSX files.
+[xyzservices](https://pypi.org/project/xyzservices) | 2023.10.1 | Source of XYZ tiles providers
+[yapf](https://pypi.org/project/yapf) | 0.40.1 | A formatter for Python code.
+[yarl](https://pypi.org/project/yarl) | 1.18.3 | Yet another URL library
+[yt_dlp](https://pypi.org/project/yt_dlp) | 2023.7.6 | A youtube-dl fork with additional features and patches
+[zict](https://pypi.org/project/zict) | 3.0.0 | Mutable mapping tools
+[zipp](https://pypi.org/project/zipp) | 3.21.0 | Backport of pathlib-compatible object wrapper for zip files
+[zstandard](https://pypi.org/project/zstandard) | 0.23.0 | Zstandard bindings for Python
+
+
diff --git a/changelogs/WinPythonslim-64bit-3.13.2.0_History.md b/changelogs/WinPythonslim-64bit-3.13.2.0_History.md
new file mode 100644
index 00000000..5fdad5b4
--- /dev/null
+++ b/changelogs/WinPythonslim-64bit-3.13.2.0_History.md
@@ -0,0 +1,170 @@
+## History of changes for WinPython-64bit 3.13.2.0slim
+
+The following changes were made to WinPython-64bit distribution since version 3.13.1.0slim.
+
+
+### Tools
+
+Removed packages:
+
+ * [Pandoc](https://pandoc.org/) 3.1.9 (a universal document converter)
+
+### Python packages
+
+New packages:
+
+ * [cohere](https://pypi.org/project/cohere) 5.13.12 ()
+ * [cvxpy](https://pypi.org/project/cvxpy) 1.6.0 (A domain-specific language for modeling convex optimization problems in Python.)
+ * [cytoolz](https://pypi.org/project/cytoolz) 1.0.1 (Cython implementation of Toolz: High performance functional utilities)
+ * [deap](https://pypi.org/project/deap) 1.4.2 (Distributed Evolutionary Algorithms in Python)
+ * [faker](https://pypi.org/project/faker) 33.3.1 (Faker is a Python package that generates fake data for you.)
+ * [fastavro](https://pypi.org/project/fastavro) 1.10.0 (Fast read/write of AVRO files)
+ * [geopandas](https://pypi.org/project/geopandas) 1.0.1 (Geographic pandas extensions)
+ * [httpx_sse](https://pypi.org/project/httpx_sse) 0.4.0 (Consume Server-Sent Event (SSE) messages with HTTPX.)
+ * [nh3](https://pypi.org/project/nh3) 0.2.18 (Python bindings to the ammonia HTML sanitization library.)
+ * [osqp](https://pypi.org/project/osqp) 0.6.7.post3 (OSQP: The Operator Splitting QP Solver)
+ * [prince](https://pypi.org/project/prince) 0.15.0 (Factor analysis in Python: PCA, CA, MCA, MFA, FAMD, GPA)
+ * [pydantic_graph](https://pypi.org/project/pydantic_graph) 0.0.24 (Graph and state machine library)
+ * [pyogrio](https://pypi.org/project/pyogrio) 0.10.0 (Vectorized spatial vector file format I/O using GDAL/OGR)
+ * [pyproj](https://pypi.org/project/pyproj) 3.7.0 (Python interface to PROJ (cartographic projections and coordinate transformations library))
+ * [pyspnego](https://pypi.org/project/pyspnego) 0.11.2 (Windows Negotiate Authentication Client and Server)
+ * [pyusb](https://pypi.org/project/pyusb) 1.3.1 (Easy USB access for Python)
+ * [pywavelets](https://pypi.org/project/pywavelets) 1.8.0 (PyWavelets, wavelet transform module)
+ * [qdldl](https://pypi.org/project/qdldl) 0.1.7.post5 (QDLDL, a free LDL factorization routine.)
+ * [scs](https://pypi.org/project/scs) 3.2.7.post2 (Splitting conic solver)
+ * [shapely](https://pypi.org/project/shapely) 2.0.6 (Manipulation and analysis of geometric objects)
+ * [sklearn_compat](https://pypi.org/project/sklearn_compat) 0.1.3 (Ease support for compatible scikit-learn estimators across versions)
+ * [squarify](https://pypi.org/project/squarify) 0.4.4 (Pure Python implementation of the squarify treemap layout algorithm)
+ * [sspilib](https://pypi.org/project/sspilib) 0.2.0 (SSPI API bindings for Python)
+ * [termcolor](https://pypi.org/project/termcolor) 2.5.0 (ANSI color formatting for output in terminal)
+ * [thefuzz](https://pypi.org/project/thefuzz) 0.22.1 (Fuzzy string matching in python)
+ * [tiktoken](https://pypi.org/project/tiktoken) 0.8.0 (tiktoken is a fast BPE tokeniser for use with OpenAI's models)
+ * [tokenizers](https://pypi.org/project/tokenizers) 0.21.0 ()
+ * [types_requests](https://pypi.org/project/types_requests) 2.32.0.20241016 (Typing stubs for requests)
+
+Upgraded packages:
+
+ * [array_api_compat](https://pypi.org/project/array_api_compat) 1.8 → 1.10.0 (A wrapper around NumPy and other array libraries to make them compatible with the Array API standard)
+ * [baresql](https://pypi.org/project/baresql) 0.8.0 → 1.0.0 (playing SQL directly on Python datas)
+ * [blinker](https://pypi.org/project/blinker) 1.7.0 → 1.9.0 (Fast, simple object-to-object and broadcast signaling)
+ * [bokeh](https://pypi.org/project/bokeh) 3.6.1 → 3.6.3 (Interactive plots and applications in the browser from Python)
+ * [clarabel](https://pypi.org/project/clarabel) 0.9.0 → 0.10.0 (Clarabel Conic Interior Point Solver for Rust / Python)
+ * [cryptography](https://pypi.org/project/cryptography) 41.0.5 → 44.0.0 (cryptography is a package which provides cryptographic recipes and primitives to Python developers.)
+ * [dill](https://pypi.org/project/dill) 0.3.7 → 0.3.9 (serialize all of Python)
+ * [docutils](https://pypi.org/project/docutils) 0.20.1 → 0.21.2 (Docutils -- Python Documentation Utilities)
+ * [duckdb](https://pypi.org/project/duckdb) 1.1.3 → 1.2.0 (DuckDB in-process database)
+ * [flask](https://pypi.org/project/flask) 3.0.3 → 3.1.0 (A simple framework for building complex web applications.)
+ * [flit](https://pypi.org/project/flit) 3.9.0 → 3.10.1 (A simple packaging tool for simple packages.)
+ * [flit_core](https://pypi.org/project/flit_core) 3.9.0 → 3.10.1 (Distribution-building parts of Flit. See flit package for more information)
+ * [griffe](https://pypi.org/project/griffe) 1.5.4 → 1.5.5 (Signatures for entire Python programs)
+ * [huggingface_hub](https://pypi.org/project/huggingface_hub) 0.27.0 → 0.28.1 (Client library to download and publish models, datasets and other repos on the huggingface.co hub)
+ * [hypothesis](https://pypi.org/project/hypothesis) 6.108.5 → 6.122.3 (A library for property-based testing)
+ * [imbalanced_learn](https://pypi.org/project/imbalanced_learn) 0.12.3 → 0.13.0 (Toolbox for imbalanced dataset in machine learning)
+ * [ipycanvas](https://pypi.org/project/ipycanvas) 0.13.2 → 0.13.3 (Interactive widgets library exposing the browser's Canvas API)
+ * [ipympl](https://pypi.org/project/ipympl) 0.9.4 → 0.9.6 (Matplotlib Jupyter Extension)
+ * [ipython](https://pypi.org/project/ipython) 8.26.0 → 8.32.0 (IPython: Productive Interactive Computing)
+ * [janus](https://pypi.org/project/janus) 1.0.0 → 2.0.0 (Mixed sync-async queue to interoperate between asyncio tasks and classic threads)
+ * [jaraco_context](https://pypi.org/project/jaraco_context) 5.3.0 → 6.0.1 (Useful decorators and context managers)
+ * [jaraco_functools](https://pypi.org/project/jaraco_functools) 4.0.1 → 4.1.0 (Functools like those found in stdlib)
+ * [jedi](https://pypi.org/project/jedi) 0.19.1 → 0.19.2 (An autocompletion tool for Python that can be used for text editors.)
+ * [jupyterlab](https://pypi.org/project/jupyterlab) 4.3.4 → 4.3.5 (JupyterLab computational environment)
+ * [keras](https://pypi.org/project/keras) 3.7.0 → 3.8.0 (Multi-backend Keras)
+ * [keyring](https://pypi.org/project/keyring) 25.2.1 → 25.6.0 (Store and access your passwords safely.)
+ * [kiwisolver](https://pypi.org/project/kiwisolver) 1.4.7 → 1.4.8 (A fast implementation of the Cassowary constraint solver)
+ * [langchain](https://pypi.org/project/langchain) 0.3.13 → 0.3.18 (Building applications with LLMs through composability)
+ * [langchain_core](https://pypi.org/project/langchain_core) 0.3.28 → 0.3.34 (Building applications with LLMs through composability)
+ * [langchain_text_splitters](https://pypi.org/project/langchain_text_splitters) 0.3.4 → 0.3.6 (LangChain text splitting utilities)
+ * [langsmith](https://pypi.org/project/langsmith) 0.2.6 → 0.2.11 (Client library to connect to the LangSmith LLM Tracing and Evaluation Platform.)
+ * [llvmlite](https://pypi.org/project/llvmlite) 0.44.0rc2 → 0.44.0 (lightweight wrapper around basic LLVM functionality)
+ * [logfire_api](https://pypi.org/project/logfire_api) 2.11.0 → 3.5.3 (Shim for the Logfire SDK which does nothing unless Logfire is installed)
+ * [markupsafe](https://pypi.org/project/markupsafe) 2.1.1 → 3.0.2 (Safely add untrusted strings to HTML/XML markup.)
+ * [maturin](https://pypi.org/project/maturin) 1.7.0 → 1.8.1 (Build and publish crates with pyo3, cffi and uniffi bindings as well as rust binaries as python packages)
+ * [mlxtend](https://pypi.org/project/mlxtend) 0.22.0 → 0.23.3 (Machine Learning Library Extensions)
+ * [msgpack](https://pypi.org/project/msgpack) 1.0.4 → 1.1.0 (MessagePack serializer)
+ * [narwhals](https://pypi.org/project/narwhals) 1.15.2 → 1.21.1 (Extremely lightweight compatibility layer between dataframe libraries)
+ * [numba](https://pypi.org/project/numba) 0.61.0rc2 → 0.61.0 (compiling Python code using LLVM)
+ * [openai](https://pypi.org/project/openai) 1.58.1 → 1.61.1 (The official Python library for the openai API)
+ * [panel](https://pypi.org/project/panel) 1.5.4 → 1.6.0 (The powerful data exploration & web app framework for Python.)
+ * [pillow](https://pypi.org/project/pillow) 11.0.0 → 11.1.0 (Python Imaging Library (Fork))
+ * [plotpy](https://pypi.org/project/plotpy) 2.7.0 → 2.7.2 (Curve and image plotting tools for Python/Qt applications)
+ * [polars](https://pypi.org/project/polars) 1.18.0 → 1.22.0 (Blazingly fast DataFrame library)
+ * [pyarrow](https://pypi.org/project/pyarrow) 18.1.0 → 19.0.0 (Python library for Apache Arrow)
+ * [pydantic](https://pypi.org/project/pydantic) 2.10.4 → 2.10.6 (Data validation using Python type hints)
+ * [pydantic_ai](https://pypi.org/project/pydantic_ai) 0.0.15 → 0.0.24 (Agent Framework / shim to use Pydantic with LLMs)
+ * [pydantic_ai_slim](https://pypi.org/project/pydantic_ai_slim) 0.0.15 → 0.0.24 (Agent Framework / shim to use Pydantic with LLMs, slim package)
+ * [pygments](https://pypi.org/project/pygments) 2.18.0 → 2.19.1 (Pygments is a syntax highlighting package written in Python.)
+ * [pyomo](https://pypi.org/project/pyomo) 6.8.0 → 6.8.2 (Pyomo: Python Optimization Modeling Objects)
+ * [pyparsing](https://pypi.org/project/pyparsing) 3.1.2 → 3.2.1 (pyparsing module - Classes and methods to define and execute parsing grammars)
+ * [pypdf](https://pypi.org/project/pypdf) 3.15.2 → 5.1.0 (A pure-python PDF library capable of splitting, merging, cropping, and transforming PDF files)
+ * [Python](http://www.python.org/) 3.13.1 → 3.13.2 (Python programming language with standard library)
+ * [pythonqwt](https://pypi.org/project/pythonqwt) 0.14.2 → 0.14.4 (Qt plotting widgets for Python)
+ * [qrcode](https://pypi.org/project/qrcode) 7.4.2 → 8.0 (QR Code image generator)
+ * [readme_renderer](https://pypi.org/project/readme_renderer) 35.0 → 44.0 (readme_renderer is a library for rendering readme descriptions for Warehouse)
+ * [redis](https://pypi.org/project/redis) 5.0.3 → 5.0.8 (Python client for Redis database and key-value store)
+ * [reportlab](https://pypi.org/project/reportlab) 4.2.2 → 4.2.5 (The Reportlab Toolkit)
+ * [requests_ntlm](https://pypi.org/project/requests_ntlm) 1.1.0 → 1.3.0 (This package allows for HTTP NTLM authentication using the requests library.)
+ * [scikit_learn](https://pypi.org/project/scikit_learn) 1.6.0 → 1.6.1 (A set of python modules for machine learning and data mining)
+ * [scipy](https://pypi.org/project/scipy) 1.14.1 → 1.15.1 (Fundamental algorithms for scientific computing in Python)
+ * [scramp](https://pypi.org/project/scramp) 1.4.1 → 1.4.5 (An implementation of the SCRAM protocol.)
+ * [sounddevice](https://pypi.org/project/sounddevice) 0.4.6 → 0.5.1 (Play and Record Sound with Python)
+ * [soupsieve](https://pypi.org/project/soupsieve) 2.5 → 2.6 (A modern CSS selector implementation for Beautiful Soup.)
+ * [sphinx_rtd_theme](https://pypi.org/project/sphinx_rtd_theme) 2.0.0 → 3.0.2 (Read the Docs theme for Sphinx)
+ * [sphinxcontrib_applehelp](https://pypi.org/project/sphinxcontrib_applehelp) 1.0.8 → 2.0.0 (sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books)
+ * [sphinxcontrib_devhelp](https://pypi.org/project/sphinxcontrib_devhelp) 1.0.6 → 2.0.0 (sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp documents)
+ * [sphinxcontrib_htmlhelp](https://pypi.org/project/sphinxcontrib_htmlhelp) 2.0.5 → 2.1.0 (sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files)
+ * [sphinxcontrib_qthelp](https://pypi.org/project/sphinxcontrib_qthelp) 1.0.7 → 2.0.0 (sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp documents)
+ * [sphinxcontrib_serializinghtml](https://pypi.org/project/sphinxcontrib_serializinghtml) 1.1.9 → 2.0.0 (sphinxcontrib-serializinghtml is a sphinx extension which outputs "serialized" HTML files (json and pickle))
+ * [sqlite_utils](https://pypi.org/project/sqlite_utils) 3.37 → 3.38 (CLI tool and Python library for manipulating SQLite databases)
+ * [sqlparse](https://pypi.org/project/sqlparse) 0.4.3 → 0.5.3 (A non-validating SQL parser.)
+ * [sympy](https://pypi.org/project/sympy) 1.13.2 → 1.13.3 (Computer algebra system (CAS) in Python)
+ * [tenacity](https://pypi.org/project/tenacity) 8.5.0 → 9.0.0 (Retry code until it succeeds)
+ * [textdistance](https://pypi.org/project/textdistance) 4.6.2 → 4.6.3 (Compute distance between the two texts.)
+ * [tifffile](https://pypi.org/project/tifffile) 2024.7.2 → 2025.1.10 (Read and write TIFF files)
+ * [tinycss2](https://pypi.org/project/tinycss2) 1.3.0 → 1.4.0 (A tiny CSS parser)
+ * [tomli](https://pypi.org/project/tomli) 2.0.1 → 2.2.1 (A lil' TOML parser)
+ * [tomli_w](https://pypi.org/project/tomli_w) 1.0.0 → 1.1.0 (A lil' TOML writer)
+ * [tomlkit](https://pypi.org/project/tomlkit) 0.12.3 → 0.13.2 (Style preserving TOML library)
+ * [toolz](https://pypi.org/project/toolz) 0.12.0 → 1.0.0 (List processing tools and functional utilities)
+ * [tornado](https://pypi.org/project/tornado) 6.4.1 → 6.4.2 (Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed.)
+ * [trio](https://pypi.org/project/trio) 0.27.0 → 0.28.0 (A friendly Python library for async concurrency and I/O)
+ * [twine](https://pypi.org/project/twine) 4.0.1 → 6.0.1 (Collection of utilities for publishing packages on PyPI)
+ * [uncertainties](https://pypi.org/project/uncertainties) 3.1.7 → 3.2.2 (calculations with values with uncertainties, error propagation)
+ * [urllib3](https://pypi.org/project/urllib3) 2.0.3 → 2.2.3 (HTTP library with thread-safe connection pooling, file post, and more.)
+ * [uvicorn](https://pypi.org/project/uvicorn) 0.30.3 → 0.34.0 (The lightning-fast ASGI server.)
+ * [watchdog](https://pypi.org/project/watchdog) 4.0.1 → 6.0.0 (Filesystem events monitoring)
+ * [webcolors](https://pypi.org/project/webcolors) 1.12 → 24.11.1 (A library for working with the color formats defined by HTML and CSS.)
+ * [websockets](https://pypi.org/project/websockets) 13.1 → 14.2 (An implementation of the WebSocket Protocol (RFC 6455 & 7692))
+ * [werkzeug](https://pypi.org/project/werkzeug) 3.0.3 → 3.1.3 (The comprehensive WSGI web application library.)
+ * [whatthepatch](https://pypi.org/project/whatthepatch) 1.0.2 → 1.0.7 (A patch parsing and application library.)
+ * [wheel](https://pypi.org/project/wheel) 0.44.0 → 0.45.1 (A built-package format for Python)
+ * [winpython](https://pypi.org/project/winpython) 11.2.20241228 → 13.1.20250222 (WinPython distribution tools, including WPPM)
+ * [xarray](https://pypi.org/project/xarray) 2024.11.0 → 2025.1.1 (N-D labeled arrays and datasets in Python)
+ * [zipp](https://pypi.org/project/zipp) 3.17.0 → 3.21.0 (Backport of pathlib-compatible object wrapper for zip files)
+
+Removed packages:
+
+ * [adodbapi](https://pypi.org/project/adodbapi) 2.6.1.3 (A pure Python package implementing PEP 249 DB-API using Microsoft ADO.)
+ * [cachelib](https://pypi.org/project/cachelib) 0.13.0 (A collection of cache libraries in the same API interface.)
+ * [db_py](https://pypi.org/project/db_py) 0.5.4b1 (a db package that doesn't suck)
+ * [docopt](https://pypi.org/project/docopt) 0.6.2 (Pythonic argument parser, that will make you smile)
+ * [filterpy](https://pypi.org/project/filterpy) 1.4.5 (Kalman filtering and optimal estimation library)
+ * [flask_mail](https://pypi.org/project/flask_mail) 0.9.1 (Flask extension for sending email)
+ * [flask_session](https://pypi.org/project/flask_session) 0.5.0 (Server-side session support for Flask)
+ * [flask_sqlalchemy](https://pypi.org/project/flask_sqlalchemy) 3.0.5 (Add SQLAlchemy support to your Flask application.)
+ * [formlayout](https://pypi.org/project/formlayout) 1.2.1a1 (The most easy way to create Qt form dialogs and widgets with Python)
+ * [future](https://pypi.org/project/future) 0.18.2 (Clean single-source support for Python 3 and 2)
+ * [ntlm_auth](https://pypi.org/project/ntlm_auth) 1.5.0 (Creates NTLM authentication structures)
+ * [pdfrw](https://pypi.org/project/pdfrw) 0.4.post2 (PDF file reader/writer library)
+ * [ppci](https://pypi.org/project/ppci) 0.5.9 (A compiler for ARM, X86, MSP430, xtensa and more implemented in pure Python)
+ * [pybars3](https://pypi.org/project/pybars3) 0.9.7 (Handlebars.js templating for Python 3 and 2)
+ * [pymeta3](https://pypi.org/project/pymeta3) 0.5.1 (Pattern-matching language based on OMeta for Python 3 and 2)
+ * [pypng](https://pypi.org/project/pypng) 0.20220715.0 (Pure Python library for saving and loading PNG images)
+ * [pysimplegui](https://pypi.org/project/pysimplegui) 4.60.4 (Python GUIs for Humans)
+ * [pywinusb](https://pypi.org/project/pywinusb) 0.4.2 (A package that simplifies USB/HID communications on windows)
+ * [simplegeneric](https://pypi.org/project/simplegeneric) 0.8.1 (Simple generic functions (similar to Python's own len(), pickle.dump(), etc.))
+ * [sspyrs](https://pypi.org/project/sspyrs) 0.3 (Lightweight interface for SSRS reports to python)
+ * [xmltodict](https://pypi.org/project/xmltodict) 0.13.0 (Makes working with XML feel like you are working with JSON)
+
+
+
+* * *
diff --git a/changelogs/WinPythonslim-64bit-3.13.3.0.md b/changelogs/WinPythonslim-64bit-3.13.3.0.md
new file mode 100644
index 00000000..3cc4c6b7
--- /dev/null
+++ b/changelogs/WinPythonslim-64bit-3.13.3.0.md
@@ -0,0 +1,515 @@
+## WinPython 3.13.3.0slim
+
+The following packages are included in WinPython-64bit v3.13.3.0slim .
+
+
+
+### Tools
+
+Name | Version | Description
+-----|---------|------------
+[Pandoc](https://pandoc.org) | 3.1.9 | an universal document converter
+
+### Python packages
+
+Name | Version | Description
+-----|---------|------------
+[Python](http://www.python.org/) | 3.13.3 | Python programming language with standard library
+[absl-py](https://pypi.org/project/absl-py) | 2.0.0 | Abseil Python Common Libraries, see https://github.com/abseil/abseil-py.
+[adbc-driver-manager](https://pypi.org/project/adbc-driver-manager) | 1.3.0 | A generic entrypoint for ADBC drivers.
+[aiofiles](https://pypi.org/project/aiofiles) | 23.2.1 | File support for asyncio.
+[aiohappyeyeballs](https://pypi.org/project/aiohappyeyeballs) | 2.4.4 | Happy Eyeballs for asyncio
+[aiohttp](https://pypi.org/project/aiohttp) | 3.11.11 | Async http client/server framework (asyncio)
+[aiosignal](https://pypi.org/project/aiosignal) | 1.3.1 | aiosignal: a list of registered asynchronous callbacks
+[aiosqlite](https://pypi.org/project/aiosqlite) | 0.20.0 | asyncio bridge to the standard sqlite3 module
+[alabaster](https://pypi.org/project/alabaster) | 0.7.16 | A light, configurable Sphinx theme
+[alembic](https://pypi.org/project/alembic) | 1.15.1 | A database migration tool for SQLAlchemy.
+[altair](https://pypi.org/project/altair) | 5.5.0 | Vega-Altair: A declarative statistical visualization library for Python.
+[aniso8601](https://pypi.org/project/aniso8601) | 9.0.1 | A library for parsing ISO 8601 strings.
+[annotated-types](https://pypi.org/project/annotated-types) | 0.6.0 | Reusable constraint types to use with typing.Annotated
+[ansicolors](https://pypi.org/project/ansicolors) | 1.1.8 | ANSI colors for Python
+[anthropic](https://pypi.org/project/anthropic) | 0.49.0 | The official Python library for the anthropic API
+[anyio](https://pypi.org/project/anyio) | 4.8.0 | High level compatibility layer for multiple asynchronous event loop implementations
+[anywidget](https://pypi.org/project/anywidget) | 0.9.12 | custom jupyter widgets made easy
+[appdirs](https://pypi.org/project/appdirs) | 1.4.4 | A small Python module for determining appropriate platform-specific dirs, e.g. a "user data dir".
+[argon2-cffi](https://pypi.org/project/argon2-cffi) | 23.1.0 | Argon2 for Python
+[argon2-cffi-bindings](https://pypi.org/project/argon2-cffi-bindings) | 21.2.0 | Low-level CFFI bindings for Argon2
+[array-api-compat](https://pypi.org/project/array-api-compat) | 1.11.1 | A wrapper around NumPy and other array libraries to make them compatible with the Array API standard
+[arrow](https://pypi.org/project/arrow) | 1.3.0 | Better dates & times for Python
+[asgi-csrf](https://pypi.org/project/asgi-csrf) | 0.9 | ASGI middleware for protecting against CSRF attacks
+[asgiref](https://pypi.org/project/asgiref) | 3.8.1 | ASGI specs, helper code, and adapters
+[asn1crypto](https://pypi.org/project/asn1crypto) | 1.5.1 | Fast ASN.1 parser and serializer with definitions for private keys, public keys, certificates, CRL, OCSP, CMS, PKCS#3, PKCS#7, PKCS#8, PKCS#12,
+[asteval](https://pypi.org/project/asteval) | 0.9.31 | Safe, minimalistic evaluator of python expression using ast module
+[astroid](https://pypi.org/project/astroid) | 3.1.0 | An abstract syntax tree for Python with inference support.
+[astropy](https://pypi.org/project/astropy) | 6.1.6 | Astronomy and astrophysics core library
+[astropy-iers-data](https://pypi.org/project/astropy-iers-data) | 0.2024.12.23.0.33.24 | IERS Earth Rotation and Leap Second tables for the astropy core package
+[asttokens](https://pypi.org/project/asttokens) | 2.4.1 | Annotate AST trees with source code positions
+[async-lru](https://pypi.org/project/async-lru) | 2.0.4 | Simple LRU cache for asyncio
+[asyncssh](https://pypi.org/project/asyncssh) | 2.20.0 | AsyncSSH: Asynchronous SSHv2 client and server library
+[atomicwrites](https://pypi.org/project/atomicwrites) | 1.4.0 | Atomic file writes.
+[attrs](https://pypi.org/project/attrs) | 23.2.0 | Classes Without Boilerplate
+[autopep8](https://pypi.org/project/autopep8) | 2.0.4 | A tool that automatically formats Python code to conform to the PEP 8 style guide
+[azure-core](https://pypi.org/project/azure-core) | 1.32.0 | Microsoft Azure Core Library for Python
+[azure-cosmos](https://pypi.org/project/azure-cosmos) | 4.9.0 | Microsoft Azure Cosmos Client Library for Python
+[azure-identity](https://pypi.org/project/azure-identity) | 1.21.0 | Microsoft Azure Identity Library for Python
+[babel](https://pypi.org/project/babel) | 2.16.0 | Internationalization utilities
+[baresql](https://pypi.org/project/baresql) | 1.0.0 | playing SQL directly on Python datas
+[beautifulsoup4](https://pypi.org/project/beautifulsoup4) | 4.12.2 | Screen-scraping library
+[binaryornot](https://pypi.org/project/binaryornot) | 0.4.4 | Ultra-lightweight pure Python package to check if a file is binary or text.
+[black](https://pypi.org/project/black) | 25.1.0 | The uncompromising code formatter.
+[bleach](https://pypi.org/project/bleach) | 6.1.0 | An easy safelist-based HTML-sanitizing tool.
+[blinker](https://pypi.org/project/blinker) | 1.9.0 | Fast, simple object-to-object and broadcast signaling
+[bokeh](https://pypi.org/project/bokeh) | 3.7.2 | Interactive plots and applications in the browser from Python
+[branca](https://pypi.org/project/branca) | 0.8.0 | Generate complex HTML+JS pages with Python
+[brotli](https://pypi.org/project/brotli) | 1.1.0 | Python bindings for the Brotli compression library
+[build](https://pypi.org/project/build) | 1.2.2.post1 | A simple, correct Python build frontend
+[cachetools](https://pypi.org/project/cachetools) | 5.5.2 | Extensible memoizing collections and decorators
+[certifi](https://pypi.org/project/certifi) | 2025.1.31 | Python package for providing Mozilla's CA Bundle.
+[cffi](https://pypi.org/project/cffi) | 1.17.1 | Foreign Function Interface for Python calling C code.
+[chardet](https://pypi.org/project/chardet) | 5.2.0 | Universal encoding detector for Python 3
+[charset-normalizer](https://pypi.org/project/charset-normalizer) | 3.4.0 | The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet.
+[clarabel](https://pypi.org/project/clarabel) | 0.10.0 | Clarabel Conic Interior Point Solver for Rust / Python
+[click](https://pypi.org/project/click) | 8.1.8 | Composable command line interface toolkit
+[click-default-group](https://pypi.org/project/click-default-group) | 1.2.4 | click_default_group
+[cloudpickle](https://pypi.org/project/cloudpickle) | 3.1.1 | Pickler class to extend the standard pickle.Pickler functionality
+[cohere](https://pypi.org/project/cohere) | 5.13.12 |
+[colorama](https://pypi.org/project/colorama) | 0.4.6 | Cross-platform colored terminal text.
+[colorcet](https://pypi.org/project/colorcet) | 3.1.0 | Collection of perceptually uniform colormaps
+[colorlog](https://pypi.org/project/colorlog) | 6.8.2 | Add colours to the output of Python's logging module.
+[comm](https://pypi.org/project/comm) | 0.2.2 | Jupyter Python Comm implementation, for usage in ipykernel, xeus-python etc.
+[contourpy](https://pypi.org/project/contourpy) | 1.3.1 | Python library for calculating contours of 2D quadrilateral grids
+[cookiecutter](https://pypi.org/project/cookiecutter) | 2.6.0 | A command-line utility that creates projects from project templates, e.g.
+[cryptography](https://pypi.org/project/cryptography) | 44.0.0 | cryptography is a package which provides cryptographic recipes and primitives to Python developers.
+[cvxopt](https://pypi.org/project/cvxopt) | 1.3.2 | Convex optimization package
+[cvxpy](https://pypi.org/project/cvxpy) | 1.6.4 | A domain-specific language for modeling convex optimization problems in Python.
+[cycler](https://pypi.org/project/cycler) | 0.12.1 | Composable style cycles
+[cython](https://pypi.org/project/cython) | 3.0.12 | The Cython compiler for writing C extensions in the Python language.
+[cytoolz](https://pypi.org/project/cytoolz) | 1.0.1 | Cython implementation of Toolz: High performance functional utilities
+[dask](https://pypi.org/project/dask) | 2025.3.0 | Parallel PyData with Task Scheduling
+[datasette](https://pypi.org/project/datasette) | 0.65.1 | An open source multi-tool for exploring and publishing data
+[datasette-graphql](https://pypi.org/project/datasette-graphql) | 2.2 | Datasette plugin providing an automatic GraphQL API for your SQLite databases
+[datashader](https://pypi.org/project/datashader) | 0.17.0 | Data visualization toolchain based on aggregating into a grid
+[deap](https://pypi.org/project/deap) | 1.4.2 | Distributed Evolutionary Algorithms in Python
+[debugpy](https://pypi.org/project/debugpy) | 1.8.0 | An implementation of the Debug Adapter Protocol for Python
+[decorator](https://pypi.org/project/decorator) | 5.1.1 | Decorators for Humans
+[defusedxml](https://pypi.org/project/defusedxml) | 0.7.1 | XML bomb protection for Python stdlib modules
+[deprecated](https://pypi.org/project/deprecated) | 1.2.14 | Python @deprecated decorator to deprecate old python classes, functions or methods.
+[diff-match-patch](https://pypi.org/project/diff-match-patch) | 20241021 | Repackaging of Google's Diff Match and Patch libraries.
+[dill](https://pypi.org/project/dill) | 0.3.9 | serialize all of Python
+[distributed](https://pypi.org/project/distributed) | 2025.3.0 | Distributed scheduler for Dask
+[distro](https://pypi.org/project/distro) | 1.8.0 | Distro - an OS platform information API
+[django](https://pypi.org/project/django) | 5.0.7 | A high-level Python web framework that encourages rapid development and clean, pragmatic design.
+[dnspython](https://pypi.org/project/dnspython) | 2.6.1 | DNS toolkit
+[docstring-to-markdown](https://pypi.org/project/docstring-to-markdown) | 0.15 | On the fly conversion of Python docstrings to markdown
+[docutils](https://pypi.org/project/docutils) | 0.21.2 | Docutils -- Python Documentation Utilities
+[duckdb](https://pypi.org/project/duckdb) | 1.2.2 | DuckDB in-process database
+[entrypoints](https://pypi.org/project/entrypoints) | 0.4 | Discover and load entry points from installed packages.
+[et-xmlfile](https://pypi.org/project/et-xmlfile) | 1.1.0 | An implementation of lxml.xmlfile for the standard library
+[eval-type-backport](https://pypi.org/project/eval-type-backport) | 0.2.2 | Like `typing._eval_type`, but lets older Python versions use newer typing features.
+[executing](https://pypi.org/project/executing) | 2.2.0 | Get the currently executing AST node of a frame, and other information
+[faker](https://pypi.org/project/faker) | 36.1.1 | Faker is a Python package that generates fake data for you.
+[fast-histogram](https://pypi.org/project/fast-histogram) | 0.14 | Fast simple 1D and 2D histograms
+[fastapi](https://pypi.org/project/fastapi) | 0.115.8 | FastAPI framework, high performance, easy to learn, fast to code, ready for production
+[fastavro](https://pypi.org/project/fastavro) | 1.10.0 | Fast read/write of AVRO files
+[fastjsonschema](https://pypi.org/project/fastjsonschema) | 2.18.0 | Fastest Python implementation of JSON schema
+[filelock](https://pypi.org/project/filelock) | 3.17.0 | A platform independent file lock.
+[flake8](https://pypi.org/project/flake8) | 7.1.1 | the modular source code checker: pep8 pyflakes and co
+[flask](https://pypi.org/project/flask) | 3.1.0 | A simple framework for building complex web applications.
+[flexcache](https://pypi.org/project/flexcache) | 0.3 | Saves and loads to the cache a transformed versions of a source object.
+[flexparser](https://pypi.org/project/flexparser) | 0.4 | Parsing made fun ... using typing.
+[flit](https://pypi.org/project/flit) | 3.10.1 | A simple packaging tool for simple packages.
+[flit-core](https://pypi.org/project/flit-core) | 3.10.1 | Distribution-building parts of Flit. See flit package for more information
+[folium](https://pypi.org/project/folium) | 0.19.5 | Make beautiful maps with Leaflet.js & Python
+[fonttools](https://pypi.org/project/fonttools) | 4.55.3 | Tools to manipulate font files
+[fqdn](https://pypi.org/project/fqdn) | 1.5.1 | Validates fully-qualified domain names against RFC 1123, so that they are acceptable to modern bowsers
+[frozenlist](https://pypi.org/project/frozenlist) | 1.5.0 | A list-like structure which implements collections.abc.MutableSequence
+[fsspec](https://pypi.org/project/fsspec) | 2024.6.1 | File-system specification
+[fuzzywuzzy](https://pypi.org/project/fuzzywuzzy) | 0.18.0 | Fuzzy string matching in python
+[geographiclib](https://pypi.org/project/geographiclib) | 2.0 | The geodesic routines from GeographicLib
+[geopandas](https://pypi.org/project/geopandas) | 1.0.1 | Geographic pandas extensions
+[geopy](https://pypi.org/project/geopy) | 2.4.1 | Python Geocoding Toolbox
+[gitdb](https://pypi.org/project/gitdb) | 4.0.10 | Git Object Database
+[gitpython](https://pypi.org/project/gitpython) | 3.1.32 | GitPython is a Python library used to interact with Git repositories
+[google-auth](https://pypi.org/project/google-auth) | 2.37.0 | Google Authentication Library
+[graphene](https://pypi.org/project/graphene) | 3.3 | GraphQL Framework for Python
+[graphql-core](https://pypi.org/project/graphql-core) | 3.2.3 | GraphQL implementation for Python, a port of GraphQL.js, the JavaScript reference implementation for GraphQL.
+[graphql-relay](https://pypi.org/project/graphql-relay) | 3.2.0 | Relay library for graphql-core
+[greenlet](https://pypi.org/project/greenlet) | 3.1.1 | Lightweight in-process concurrent programming
+[griffe](https://pypi.org/project/griffe) | 1.5.5 | Signatures for entire Python programs.
+[groq](https://pypi.org/project/groq) | 0.13.1 | The official Python library for the groq API
+[guidata](https://pypi.org/project/guidata) | 3.7.1 | Automatic GUI generation for easy dataset editing and display
+[h11](https://pypi.org/project/h11) | 0.14.0 | A pure-Python, bring-your-own-I/O implementation of HTTP/1.1
+[h2](https://pypi.org/project/h2) | 4.1.0 | HTTP/2 State-Machine based protocol implementation
+[h5py](https://pypi.org/project/h5py) | 3.12.1 | Read and write HDF5 files from Python
+[hatchling](https://pypi.org/project/hatchling) | 1.27.0 | Modern, extensible Python build backend
+[holoviews](https://pypi.org/project/holoviews) | 1.20.2 | A high-level plotting API for the PyData ecosystem built on HoloViews.
+[hpack](https://pypi.org/project/hpack) | 4.1.0 | Pure-Python HPACK header encoding
+[html5lib](https://pypi.org/project/html5lib) | 1.1 | HTML parser based on the WHATWG HTML specification
+[httpcore](https://pypi.org/project/httpcore) | 1.0.5 | A minimal low-level HTTP client.
+[httpie](https://pypi.org/project/httpie) | 3.2.4 | HTTPie: modern, user-friendly command-line HTTP client for the API era.
+[httpx](https://pypi.org/project/httpx) | 0.27.2 | The next generation HTTP client.
+[httpx-sse](https://pypi.org/project/httpx-sse) | 0.4.0 | Consume Server-Sent Event (SSE) messages with HTTPX.
+[huggingface-hub](https://pypi.org/project/huggingface-hub) | 0.29.3 | Client library to download and publish models, datasets and other repos on the huggingface.co hub
+[hupper](https://pypi.org/project/hupper) | 1.12 | Integrated process monitor for developing and reloading daemons.
+[hvplot](https://pypi.org/project/hvplot) | 0.11.2 | A high-level plotting API for the PyData ecosystem built on HoloViews.
+[hypercorn](https://pypi.org/project/hypercorn) | 0.17.3 | A ASGI Server based on Hyper libraries and inspired by Gunicorn
+[hyperframe](https://pypi.org/project/hyperframe) | 6.1.0 | Pure-Python HTTP/2 framing
+[hypothesis](https://pypi.org/project/hypothesis) | 6.130.4 | A library for property-based testing
+[id](https://pypi.org/project/id) | 1.5.0 | A tool for generating OIDC identities
+[idna](https://pypi.org/project/idna) | 3.10 | Internationalized Domain Names in Applications (IDNA)
+[imageio](https://pypi.org/project/imageio) | 2.37.0 | Library for reading and writing a wide range of image, video, scientific, and volumetric data formats.
+[imagesize](https://pypi.org/project/imagesize) | 1.4.1 | Getting image size from png/jpeg/jpeg2000/gif file
+[imbalanced-learn](https://pypi.org/project/imbalanced-learn) | 0.13.0 | Toolbox for imbalanced dataset in machine learning
+[importlib-metadata](https://pypi.org/project/importlib-metadata) | 8.6.1 | Read metadata from Python packages
+[inflection](https://pypi.org/project/inflection) | 0.5.1 | A port of Ruby on Rails inflector to Python
+[iniconfig](https://pypi.org/project/iniconfig) | 2.0.0 | brain-dead simple config-ini parsing
+[intervaltree](https://pypi.org/project/intervaltree) | 3.0.2 | Editable interval tree data structure for Python 2 and 3
+[ipycanvas](https://pypi.org/project/ipycanvas) | 0.13.3 | Interactive widgets library exposing the browser's Canvas API
+[ipykernel](https://pypi.org/project/ipykernel) | 6.29.5 | IPython Kernel for Jupyter
+[ipyleaflet](https://pypi.org/project/ipyleaflet) | 0.19.2 | A Jupyter widget for dynamic Leaflet maps
+[ipympl](https://pypi.org/project/ipympl) | 0.9.7 | Matplotlib Jupyter Extension
+[ipython](https://pypi.org/project/ipython) | 8.34.0 | IPython: Productive Interactive Computing
+[ipython-genutils](https://pypi.org/project/ipython-genutils) | 0.2.0 | Vestigial utilities from IPython
+[ipython-sql](https://pypi.org/project/ipython-sql) | 0.5.0 | RDBMS access via IPython
+[ipywidgets](https://pypi.org/project/ipywidgets) | 8.1.6 | Jupyter interactive widgets
+[isoduration](https://pypi.org/project/isoduration) | 20.11.0 | Operations with ISO 8601 durations
+[isort](https://pypi.org/project/isort) | 5.13.2 | A Python utility / library to sort Python imports.
+[itsdangerous](https://pypi.org/project/itsdangerous) | 2.2.0 | Safely pass data to untrusted environments and back.
+[janus](https://pypi.org/project/janus) | 2.0.0 | Mixed sync-async queue to interoperate between asyncio tasks and classic threads
+[jaraco-classes](https://pypi.org/project/jaraco-classes) | 3.4.0 | Utility functions for Python class constructs
+[jaraco-context](https://pypi.org/project/jaraco-context) | 6.0.1 | Useful decorators and context managers
+[jaraco-functools](https://pypi.org/project/jaraco-functools) | 4.1.0 | Functools like those found in stdlib
+[jedi](https://pypi.org/project/jedi) | 0.19.2 | An autocompletion tool for Python that can be used for text editors.
+[jellyfish](https://pypi.org/project/jellyfish) | 1.1.3 | Approximate and phonetic matching of strings.
+[jinja2](https://pypi.org/project/jinja2) | 3.1.2 | A very fast and expressive template engine.
+[jiter](https://pypi.org/project/jiter) | 0.8.2 | Fast iterable JSON parser.
+[joblib](https://pypi.org/project/joblib) | 1.4.2 | Lightweight pipelining with Python functions
+[json5](https://pypi.org/project/json5) | 0.9.14 | A Python implementation of the JSON5 data format.
+[jsonpatch](https://pypi.org/project/jsonpatch) | 1.33 | Apply JSON-Patches (RFC 6902)
+[jsonpath-python](https://pypi.org/project/jsonpath-python) | 1.0.6 | A more powerful JSONPath implementation in modern python
+[jsonpointer](https://pypi.org/project/jsonpointer) | 2.4 | Identify specific nodes in a JSON document (RFC 6901)
+[jsonschema](https://pypi.org/project/jsonschema) | 4.19.2 | An implementation of JSON Schema validation for Python
+[jsonschema-specifications](https://pypi.org/project/jsonschema-specifications) | 2023.12.1 | The JSON Schema meta-schemas and vocabularies, exposed as a Registry
+[julia](https://pypi.org/project/julia) | 0.6.2 | Julia/Python bridge with IPython support.
+[jupyter](https://pypi.org/project/jupyter) | 1.1.1 | Jupyter metapackage. Install all the Jupyter components in one go.
+[jupyter-bokeh](https://pypi.org/project/jupyter-bokeh) | 4.0.5 | A Jupyter extension for rendering Bokeh content.
+[jupyter-client](https://pypi.org/project/jupyter-client) | 8.6.3 | Jupyter protocol implementation and client libraries
+[jupyter-console](https://pypi.org/project/jupyter-console) | 6.6.3 | Jupyter terminal console
+[jupyter-core](https://pypi.org/project/jupyter-core) | 5.7.2 | Jupyter core package. A base package on which Jupyter projects rely.
+[jupyter-events](https://pypi.org/project/jupyter-events) | 0.12.0 | Jupyter Event System library
+[jupyter-leaflet](https://pypi.org/project/jupyter-leaflet) | 0.19.2 | ipyleaflet extensions for JupyterLab and Jupyter Notebook
+[jupyter-lsp](https://pypi.org/project/jupyter-lsp) | 2.2.5 | Multi-Language Server WebSocket proxy for Jupyter Notebook/Lab server
+[jupyter-server](https://pypi.org/project/jupyter-server) | 2.14.2 | The backend—i.e. core services, APIs, and REST endpoints—to Jupyter web applications.
+[jupyter-server-terminals](https://pypi.org/project/jupyter-server-terminals) | 0.5.3 | A Jupyter Server Extension Providing Terminals.
+[jupyterlab](https://pypi.org/project/jupyterlab) | 4.4.1 | JupyterLab computational environment
+[jupyterlab-pygments](https://pypi.org/project/jupyterlab-pygments) | 0.3.0 | Pygments theme using JupyterLab CSS variables
+[jupyterlab-server](https://pypi.org/project/jupyterlab-server) | 2.27.3 | A set of server components for JupyterLab and JupyterLab like applications.
+[jupyterlab-widgets](https://pypi.org/project/jupyterlab-widgets) | 3.0.14 | Jupyter interactive widgets for JupyterLab
+[keras](https://pypi.org/project/keras) | 3.9.2 | Multi-backend Keras
+[keyring](https://pypi.org/project/keyring) | 25.6.0 | Store and access your passwords safely.
+[kiwisolver](https://pypi.org/project/kiwisolver) | 1.4.8 | A fast implementation of the Cassowary constraint solver
+[langchain](https://pypi.org/project/langchain) | 0.3.23 | Building applications with LLMs through composability
+[langchain-core](https://pypi.org/project/langchain-core) | 0.3.51 | Building applications with LLMs through composability
+[langchain-text-splitters](https://pypi.org/project/langchain-text-splitters) | 0.3.8 | LangChain text splitting utilities
+[langsmith](https://pypi.org/project/langsmith) | 0.3.24 | Client library to connect to the LangSmith LLM Tracing and Evaluation Platform.
+[lazy-loader](https://pypi.org/project/lazy-loader) | 0.4 | Makes it easy to load subpackages and functions on demand.
+[linkify-it-py](https://pypi.org/project/linkify-it-py) | 2.0.2 | Links recognition library with FULL unicode support.
+[llvmlite](https://pypi.org/project/llvmlite) | 0.44.0 | lightweight wrapper around basic LLVM functionality
+[lmfit](https://pypi.org/project/lmfit) | 1.3.1 | Least-Squares Minimization with Bounds and Constraints
+[locket](https://pypi.org/project/locket) | 1.0.0 | File-based locks for Python on Linux and Windows
+[logfire-api](https://pypi.org/project/logfire-api) | 3.5.3 | Shim for the Logfire SDK which does nothing unless Logfire is installed
+[lxml](https://pypi.org/project/lxml) | 5.3.0 | Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API.
+[mako](https://pypi.org/project/mako) | 1.3.5 | A super-fast templating language that borrows the best ideas from the existing templating languages.
+[markdown](https://pypi.org/project/markdown) | 3.7 | Python implementation of John Gruber's Markdown.
+[markdown-it-py](https://pypi.org/project/markdown-it-py) | 2.2.0 | Python port of markdown-it. Markdown parsing, done right!
+[markupsafe](https://pypi.org/project/markupsafe) | 3.0.2 | Safely add untrusted strings to HTML/XML markup.
+[matplotlib](https://pypi.org/project/matplotlib) | 3.10.1 | Python plotting package
+[matplotlib-inline](https://pypi.org/project/matplotlib-inline) | 0.1.7 | Inline Matplotlib backend for Jupyter
+[maturin](https://pypi.org/project/maturin) | 1.8.1 | Build and publish crates with pyo3, cffi and uniffi bindings as well as rust binaries as python packages
+[mccabe](https://pypi.org/project/mccabe) | 0.7.0 | McCabe checker, plugin for flake8
+[mdit-py-plugins](https://pypi.org/project/mdit-py-plugins) | 0.3.5 | Collection of plugins for markdown-it-py
+[mdurl](https://pypi.org/project/mdurl) | 0.1.2 | Markdown URL utilities
+[mercantile](https://pypi.org/project/mercantile) | 1.2.1 | Web mercator XYZ tile utilities
+[mergedeep](https://pypi.org/project/mergedeep) | 1.3.4 | A deep merge function for 🐍.
+[missingno](https://pypi.org/project/missingno) | 0.5.1 | Missing data visualization module for Python.
+[mistralai](https://pypi.org/project/mistralai) | 1.2.5 | Python Client SDK for the Mistral AI API.
+[mistune](https://pypi.org/project/mistune) | 2.0.5 | A sane Markdown parser with useful plugins and renderers
+[mizani](https://pypi.org/project/mizani) | 0.11.4 | Scales for Python
+[ml-dtypes](https://pypi.org/project/ml-dtypes) | 0.5.0 |
+[mlxtend](https://pypi.org/project/mlxtend) | 0.23.3 | Machine Learning Library Extensions
+[more-itertools](https://pypi.org/project/more-itertools) | 10.2.0 | More routines for operating on iterables, beyond itertools
+[mpl-scatter-density](https://pypi.org/project/mpl-scatter-density) | 0.7 | Matplotlib helpers to make density scatter plots
+[mpld3](https://pypi.org/project/mpld3) | 0.5.8 | D3 Viewer for Matplotlib
+[mpmath](https://pypi.org/project/mpmath) | 1.3.0 | Python library for arbitrary-precision floating-point arithmetic
+[msal](https://pypi.org/project/msal) | 1.30.0 | The Microsoft Authentication Library (MSAL) for Python library enables your app to access the Microsoft Cloud by supporting authentication of us
+[msal-extensions](https://pypi.org/project/msal-extensions) | 1.2.0 | Microsoft Authentication Library extensions (MSAL EX) provides a persistence API that can save your data on disk, encrypted on Windows, macOS an
+[msgpack](https://pypi.org/project/msgpack) | 1.1.0 | MessagePack serializer
+[multidict](https://pypi.org/project/multidict) | 6.1.0 | multidict implementation
+[multipledispatch](https://pypi.org/project/multipledispatch) | 1.0.0 | Multiple dispatch
+[mypy](https://pypi.org/project/mypy) | 1.15.0 | Optional static typing for Python
+[mypy-extensions](https://pypi.org/project/mypy-extensions) | 1.0.0 | Type system extensions for programs checked with the mypy type checker.
+[mysql-connector-python](https://pypi.org/project/mysql-connector-python) | 9.2.0 | A self-contained Python driver for communicating with MySQL servers, using an API that is compliant with the Python Database API Specification v
+[namex](https://pypi.org/project/namex) | 0.0.8 | A simple utility to separate the implementation of your Python package and its public API surface.
+[narwhals](https://pypi.org/project/narwhals) | 1.30.0 | Extremely lightweight compatibility layer between dataframe libraries
+[nbclient](https://pypi.org/project/nbclient) | 0.10.0 | A client library for executing notebooks. Formerly nbconvert's ExecutePreprocessor.
+[nbconvert](https://pypi.org/project/nbconvert) | 7.16.1 | Converting Jupyter Notebooks (.ipynb files) to other formats. Output formats include asciidoc, html, latex, markdown, pdf, py, rst, script.
+[nbformat](https://pypi.org/project/nbformat) | 5.10.4 | The Jupyter Notebook format
+[nest-asyncio](https://pypi.org/project/nest-asyncio) | 1.6.0 | Patch asyncio to allow nested event loops
+[networkx](https://pypi.org/project/networkx) | 3.4.2 | Python package for creating and manipulating graphs and networks
+[nh3](https://pypi.org/project/nh3) | 0.2.18 | Python bindings to the ammonia HTML sanitization library.
+[nltk](https://pypi.org/project/nltk) | 3.9.1 | Natural Language Toolkit
+[notebook](https://pypi.org/project/notebook) | 7.4.0 | Jupyter Notebook - A web-based notebook environment for interactive computing
+[notebook-shim](https://pypi.org/project/notebook-shim) | 0.2.4 | A shim layer for notebook traits and config
+[numba](https://pypi.org/project/numba) | 0.61.2 | compiling Python code using LLVM
+[numpy](https://pypi.org/project/numpy) | 2.2.4 | Fundamental package for array computing in Python
+[numpydoc](https://pypi.org/project/numpydoc) | 1.6.0 | Sphinx extension to support docstrings in Numpy format
+[openai](https://pypi.org/project/openai) | 1.72.0 | The official Python library for the openai API
+[opencv-python](https://pypi.org/project/opencv-python) | 4.11.0.86 | Wrapper package for OpenCV python bindings.
+[openpyxl](https://pypi.org/project/openpyxl) | 3.1.2 | A Python library to read/write Excel 2010 xlsx/xlsm files
+[optree](https://pypi.org/project/optree) | 0.14.0 | Optimized PyTree Utilities.
+[optuna](https://pypi.org/project/optuna) | 3.6.1 | A hyperparameter optimization framework
+[orjson](https://pypi.org/project/orjson) | 3.10.12 | Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy
+[osqp](https://pypi.org/project/osqp) | 0.6.7.post3 | OSQP: The Operator Splitting QP Solver
+[outcome](https://pypi.org/project/outcome) | 1.3.0.post0 | Capture the outcome of Python function calls.
+[overrides](https://pypi.org/project/overrides) | 7.7.0 | A decorator to automatically detect mismatch when overriding a method.
+[packaging](https://pypi.org/project/packaging) | 24.2 | Core utilities for Python packages
+[pandas](https://pypi.org/project/pandas) | 2.2.3 | Powerful data structures for data analysis, time series, and statistics
+[pandocfilters](https://pypi.org/project/pandocfilters) | 1.5.0 | Utilities for writing pandoc filters in python
+[panel](https://pypi.org/project/panel) | 1.6.2 | The powerful data exploration & web app framework for Python.
+[papermill](https://pypi.org/project/papermill) | 2.6.0 | Parameterize and run Jupyter and nteract Notebooks
+[param](https://pypi.org/project/param) | 2.2.0 | Make your Python code clearer and more reliable by declaring Parameters.
+[parso](https://pypi.org/project/parso) | 0.8.4 | A Python Parser
+[partd](https://pypi.org/project/partd) | 1.4.0 | Appendable key-value storage
+[pathspec](https://pypi.org/project/pathspec) | 0.11.0 | Utility library for gitignore style pattern matching of file paths.
+[patsy](https://pypi.org/project/patsy) | 0.5.6 | A Python package for describing statistical models and for building design matrices.
+[pep8](https://pypi.org/project/pep8) | 1.7.1 | Python style guide checker
+[pexpect](https://pypi.org/project/pexpect) | 4.8.0 | Pexpect allows easy control of interactive console applications.
+[pg8000](https://pypi.org/project/pg8000) | 1.23.0 | PostgreSQL interface library
+[pickleshare](https://pypi.org/project/pickleshare) | 0.7.5 | Tiny 'shelve'-like database with concurrency support
+[pillow](https://pypi.org/project/pillow) | 11.1.0 | Python Imaging Library (Fork)
+[pip](https://pypi.org/project/pip) | 25.0.1 | The PyPA recommended tool for installing Python packages.
+[platformdirs](https://pypi.org/project/platformdirs) | 4.3.6 | A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`.
+[plotly](https://pypi.org/project/plotly) | 6.0.1 | An open-source interactive data visualization library for Python
+[plotnine](https://pypi.org/project/plotnine) | 0.13.6 | A Grammar of Graphics for Python
+[plotpy](https://pypi.org/project/plotpy) | 2.7.2 | Curve and image plotting tools for Python/Qt applications
+[pluggy](https://pypi.org/project/pluggy) | 1.5.0 | plugin and hook calling mechanisms for python
+[ply](https://pypi.org/project/ply) | 3.11 | Python Lex & Yacc
+[polars](https://pypi.org/project/polars) | 1.27.1 | Blazingly fast DataFrame library
+[portalocker](https://pypi.org/project/portalocker) | 2.7.0 | Wraps the portalocker recipe for easy usage
+[prettytable](https://pypi.org/project/prettytable) | 3.3.0 | A simple Python library for easily displaying tabular data in a visually appealing ASCII table format
+[prince](https://pypi.org/project/prince) | 0.15.0 | Factor analysis in Python: PCA, CA, MCA, MFA, FAMD, GPA
+[priority](https://pypi.org/project/priority) | 2.0.0 | A pure-Python implementation of the HTTP/2 priority tree
+[prometheus-client](https://pypi.org/project/prometheus-client) | 0.21.1 | Python client for the Prometheus monitoring system.
+[prompt-toolkit](https://pypi.org/project/prompt-toolkit) | 3.0.50 | Library for building powerful interactive command lines in Python
+[propcache](https://pypi.org/project/propcache) | 0.2.1 | Accelerated property cache
+[protobuf](https://pypi.org/project/protobuf) | 5.27.3 |
+[psutil](https://pypi.org/project/psutil) | 5.9.8 | Cross-platform lib for process and system monitoring in Python.
+[psygnal](https://pypi.org/project/psygnal) | 0.11.1 | Fast python callback/event system modeled after Qt Signals
+[ptpython](https://pypi.org/project/ptpython) | 3.0.29 | Python REPL build on top of prompt_toolkit
+[ptyprocess](https://pypi.org/project/ptyprocess) | 0.7.0 | Run a subprocess in a pseudo terminal
+[pure-eval](https://pypi.org/project/pure-eval) | 0.2.2 | Safely evaluate AST nodes without side effects
+[pyarrow](https://pypi.org/project/pyarrow) | 19.0.1 | Python library for Apache Arrow
+[pyasn1](https://pypi.org/project/pyasn1) | 0.6.1 | Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208)
+[pyasn1-modules](https://pypi.org/project/pyasn1-modules) | 0.4.1 | A collection of ASN.1-based protocols modules
+[pybind11](https://pypi.org/project/pybind11) | 2.13.6 | Seamless operability between C++11 and Python
+[pycodestyle](https://pypi.org/project/pycodestyle) | 2.12.0 | Python style guide checker
+[pycparser](https://pypi.org/project/pycparser) | 2.22 | C parser in Python
+[pyct](https://pypi.org/project/pyct) | 0.5.0 | Python package common tasks for users (e.g. copy examples, fetch data, ...)
+[pydantic](https://pypi.org/project/pydantic) | 2.10.6 | Data validation using Python type hints
+[pydantic-ai](https://pypi.org/project/pydantic-ai) | 0.0.24 | Agent Framework / shim to use Pydantic with LLMs
+[pydantic-ai-slim](https://pypi.org/project/pydantic-ai-slim) | 0.0.24 | Agent Framework / shim to use Pydantic with LLMs, slim package
+[pydantic-core](https://pypi.org/project/pydantic-core) | 2.27.2 | Core functionality for Pydantic validation and serialization
+[pydantic-graph](https://pypi.org/project/pydantic-graph) | 0.0.24 | Graph and state machine library
+[pydeck](https://pypi.org/project/pydeck) | 0.9.1 | Widget for deck.gl maps
+[pydocstyle](https://pypi.org/project/pydocstyle) | 6.3.0 | Python docstring style checker
+[pydub](https://pypi.org/project/pydub) | 0.25.1 | Manipulate audio with an simple and easy high level interface
+[pyerfa](https://pypi.org/project/pyerfa) | 2.0.1.4 | Python bindings for ERFA
+[pyflakes](https://pypi.org/project/pyflakes) | 3.2.0 | passive checker of Python programs
+[pygithub](https://pypi.org/project/pygithub) | 2.6.1 | Use the full Github API v3
+[pygments](https://pypi.org/project/pygments) | 2.19.1 | Pygments is a syntax highlighting package written in Python.
+[pyjwt](https://pypi.org/project/pyjwt) | 2.10.1 | JSON Web Token implementation in Python
+[pylint](https://pypi.org/project/pylint) | 3.1.0 | python code static checker
+[pylint-venv](https://pypi.org/project/pylint-venv) | 3.0.3 | pylint-venv provides a Pylint init-hook to use the same Pylint installation with different virtual environments.
+[pyls-spyder](https://pypi.org/project/pyls-spyder) | 0.4.0 | Spyder extensions for the python-lsp-server
+[pymongo](https://pypi.org/project/pymongo) | 4.10.1 | Python driver for MongoDB
+[pympler](https://pypi.org/project/pympler) | 1.1 | A development tool to measure, monitor and analyze the memory behavior of Python objects.
+[pynacl](https://pypi.org/project/pynacl) | 1.5.0 | Python binding to the Networking and Cryptography (NaCl) library
+[pynndescent](https://pypi.org/project/pynndescent) | 0.5.12 | Nearest Neighbor Descent
+[pyodbc](https://pypi.org/project/pyodbc) | 5.2.0 | DB API module for ODBC
+[pyogrio](https://pypi.org/project/pyogrio) | 0.10.0 | Vectorized spatial vector file format I/O using GDAL/OGR
+[pyomo](https://pypi.org/project/pyomo) | 6.9.1 | Pyomo: Python Optimization Modeling Objects
+[pypandoc](https://pypi.org/project/pypandoc) | 1.15 | Thin wrapper for pandoc.
+[pyparsing](https://pypi.org/project/pyparsing) | 3.2.1 | pyparsing module - Classes and methods to define and execute parsing grammars
+[pypdf](https://pypi.org/project/pypdf) | 5.1.0 | A pure-python PDF library capable of splitting, merging, cropping, and transforming PDF files
+[pyproj](https://pypi.org/project/pyproj) | 3.7.0 | Python interface to PROJ (cartographic projections and coordinate transformations library)
+[pyproject-hooks](https://pypi.org/project/pyproject-hooks) | 1.1.0 | Wrappers to call pyproject.toml-based build backend hooks.
+[pyqt5](https://pypi.org/project/pyqt5) | 5.15.10 | Python bindings for the Qt cross platform application toolkit
+[pyqt5-qt5](https://pypi.org/project/pyqt5-qt5) | 5.15.2 | The subset of a Qt installation needed by PyQt5.
+[pyqt5-sip](https://pypi.org/project/pyqt5-sip) | 12.16.1 | The sip module support for PyQt5
+[pyqtgraph](https://pypi.org/project/pyqtgraph) | 0.13.7 | Scientific Graphics and GUI Library for Python
+[pyqtwebengine](https://pypi.org/project/pyqtwebengine) | 5.15.6 | Python bindings for the Qt WebEngine framework
+[pyqtwebengine-qt5](https://pypi.org/project/pyqtwebengine-qt5) | 5.15.2 | The subset of a Qt installation needed by PyQtWebEngine.
+[pyserial](https://pypi.org/project/pyserial) | 3.5 | Python Serial Port Extension
+[pysocks](https://pypi.org/project/pysocks) | 1.7.1 | A Python SOCKS client module. See https://github.com/Anorov/PySocks for more information.
+[pyspnego](https://pypi.org/project/pyspnego) | 0.11.2 | Windows Negotiate Authentication Client and Server
+[pytest](https://pypi.org/project/pytest) | 8.3.4 | pytest: simple powerful testing with Python
+[python-barcode](https://pypi.org/project/python-barcode) | 0.15.1 | Create standard barcodes with Python. No external modules needed. (optional Pillow support included).
+[python-dateutil](https://pypi.org/project/python-dateutil) | 2.8.2 | Extensions to the standard Python datetime module
+[python-dotenv](https://pypi.org/project/python-dotenv) | 1.0.1 | Read key-value pairs from a .env file and set them as environment variables
+[python-json-logger](https://pypi.org/project/python-json-logger) | 2.0.7 | A python library adding a json log formatter
+[python-lsp-black](https://pypi.org/project/python-lsp-black) | 2.0.0 | Black plugin for the Python LSP Server
+[python-lsp-jsonrpc](https://pypi.org/project/python-lsp-jsonrpc) | 1.1.2 | JSON RPC 2.0 server library
+[python-lsp-server](https://pypi.org/project/python-lsp-server) | 1.12.0 | Python Language Server for the Language Server Protocol
+[python-multipart](https://pypi.org/project/python-multipart) | 0.0.9 | A streaming multipart parser for Python
+[python-slugify](https://pypi.org/project/python-slugify) | 8.0.4 | A Python slugify application that also handles Unicode
+[pythonqwt](https://pypi.org/project/pythonqwt) | 0.14.4 | Qt plotting widgets for Python
+[pytoolconfig](https://pypi.org/project/pytoolconfig) | 1.3.1 | Python tool configuration
+[pytz](https://pypi.org/project/pytz) | 2024.2 | World timezone definitions, modern and historical
+[pyuca](https://pypi.org/project/pyuca) | 1.2 | a Python implementation of the Unicode Collation Algorithm
+[pyusb](https://pypi.org/project/pyusb) | 1.3.1 | Easy USB access for Python
+[pyviz-comms](https://pypi.org/project/pyviz-comms) | 3.0.3 | A JupyterLab extension for rendering HoloViz content.
+[pywavelets](https://pypi.org/project/pywavelets) | 1.8.0 | PyWavelets, wavelet transform module
+[pywin32](https://pypi.org/project/pywin32) | 308 | Python for Window Extensions
+[pywin32-ctypes](https://pypi.org/project/pywin32-ctypes) | 0.2.2 | A (partial) reimplementation of pywin32 using ctypes/cffi
+[pywinpty](https://pypi.org/project/pywinpty) | 2.0.14 | Pseudo terminal support for Windows from Python.
+[pyyaml](https://pypi.org/project/pyyaml) | 6.0.2 | YAML parser and emitter for Python
+[pyzmq](https://pypi.org/project/pyzmq) | 26.2.1 | Python bindings for 0MQ
+[qdarkstyle](https://pypi.org/project/qdarkstyle) | 3.2.3 | The most complete dark/light style sheet for C++/Python and Qt applications
+[qdldl](https://pypi.org/project/qdldl) | 0.1.7.post5 | QDLDL, a free LDL factorization routine.
+[qrcode](https://pypi.org/project/qrcode) | 8.0 | QR Code image generator
+[qstylizer](https://pypi.org/project/qstylizer) | 0.2.2 | Stylesheet Generator for PyQt{4-5}/PySide{1-2}
+[qtawesome](https://pypi.org/project/qtawesome) | 1.4.0 | FontAwesome icons in PyQt and PySide applications
+[qtconsole](https://pypi.org/project/qtconsole) | 5.6.1 | Jupyter Qt console
+[qtpy](https://pypi.org/project/qtpy) | 2.4.1 | Provides an abstraction layer on top of the various Qt bindings (PyQt5/6 and PySide2/6).
+[quantecon](https://pypi.org/project/quantecon) | 0.7.2 | Import the main names to top level.
+[quart](https://pypi.org/project/quart) | 0.20.0 | A Python ASGI web framework with the same API as Flask
+[rapidfuzz](https://pypi.org/project/rapidfuzz) | 3.9.6 | rapid fuzzy string matching
+[readme-renderer](https://pypi.org/project/readme-renderer) | 44.0 | readme_renderer is a library for rendering readme descriptions for Warehouse
+[redis](https://pypi.org/project/redis) | 5.0.8 | Python client for Redis database and key-value store
+[referencing](https://pypi.org/project/referencing) | 0.35.1 | JSON Referencing + Python
+[regex](https://pypi.org/project/regex) | 2024.11.6 | Alternative regular expression module, to replace re.
+[reportlab](https://pypi.org/project/reportlab) | 4.2.5 | The Reportlab Toolkit
+[requests](https://pypi.org/project/requests) | 2.32.3 | Python HTTP for Humans.
+[requests-ntlm](https://pypi.org/project/requests-ntlm) | 1.3.0 | This package allows for HTTP NTLM authentication using the requests library.
+[requests-toolbelt](https://pypi.org/project/requests-toolbelt) | 1.0.0 | A utility belt for advanced users of python-requests
+[rfc3339-validator](https://pypi.org/project/rfc3339-validator) | 0.1.4 | A pure python RFC3339 validator
+[rfc3986](https://pypi.org/project/rfc3986) | 2.0.0 | Validating URI References per RFC 3986
+[rfc3986-validator](https://pypi.org/project/rfc3986-validator) | 0.1.1 | Pure python rfc3986 validator
+[rich](https://pypi.org/project/rich) | 13.9.4 | Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal
+[rope](https://pypi.org/project/rope) | 1.12.0 | a python refactoring library...
+[rpds-py](https://pypi.org/project/rpds-py) | 0.22.3 | Python bindings to Rust's persistent data structures (rpds)
+[rsa](https://pypi.org/project/rsa) | 4.7.2 | Pure-Python RSA implementation
+[rtree](https://pypi.org/project/rtree) | 1.3.0 | R-Tree spatial index for Python GIS
+[rx](https://pypi.org/project/rx) | 3.2.0 | Reactive Extensions (Rx) for Python
+[scikit-image](https://pypi.org/project/scikit-image) | 0.25.2 | Image processing in Python
+[scikit-learn](https://pypi.org/project/scikit-learn) | 1.6.1 | A set of python modules for machine learning and data mining
+[scipy](https://pypi.org/project/scipy) | 1.15.2 | Fundamental algorithms for scientific computing in Python
+[scramp](https://pypi.org/project/scramp) | 1.4.5 | An implementation of the SCRAM protocol.
+[scs](https://pypi.org/project/scs) | 3.2.7.post2 | Splitting conic solver
+[seaborn](https://pypi.org/project/seaborn) | 0.13.2 | Statistical data visualization
+[send2trash](https://pypi.org/project/send2trash) | 1.8.3 | Send file to trash natively under Mac OS X, Windows and Linux
+[setuptools](https://pypi.org/project/setuptools) | 75.8.2 | Easily download, build, install, upgrade, and uninstall Python packages
+[shapely](https://pypi.org/project/shapely) | 2.0.6 | Manipulation and analysis of geometric objects
+[shellingham](https://pypi.org/project/shellingham) | 1.5.4 | Tool to Detect Surrounding Shell
+[simplejson](https://pypi.org/project/simplejson) | 3.19.3 | Simple, fast, extensible JSON encoder/decoder for Python
+[simpy](https://pypi.org/project/simpy) | 4.1.1 | Event discrete, process based simulation for Python.
+[six](https://pypi.org/project/six) | 1.16.0 | Python 2 and 3 compatibility utilities
+[sklearn-compat](https://pypi.org/project/sklearn-compat) | 0.1.3 | Ease support for compatible scikit-learn estimators across versions
+[skrub](https://pypi.org/project/skrub) | 0.5.1 | Prepping tables for machine learning
+[smmap](https://pypi.org/project/smmap) | 5.0.0 | A pure Python implementation of a sliding window memory map manager
+[sniffio](https://pypi.org/project/sniffio) | 1.3.0 | Sniff out which async library your code is running under
+[snowballstemmer](https://pypi.org/project/snowballstemmer) | 2.2.0 | This package provides 29 stemmers for 28 languages generated from Snowball algorithms.
+[sortedcontainers](https://pypi.org/project/sortedcontainers) | 2.4.0 | Sorted Containers -- Sorted List, Sorted Dict, Sorted Set
+[sounddevice](https://pypi.org/project/sounddevice) | 0.5.1 | Play and Record Sound with Python
+[soupsieve](https://pypi.org/project/soupsieve) | 2.6 | A modern CSS selector implementation for Beautiful Soup.
+[sphinx](https://pypi.org/project/sphinx) | 7.3.7 | Python documentation generator
+[sphinx-rtd-theme](https://pypi.org/project/sphinx-rtd-theme) | 3.0.2 | Read the Docs theme for Sphinx
+[sphinxcontrib-applehelp](https://pypi.org/project/sphinxcontrib-applehelp) | 2.0.0 | sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books
+[sphinxcontrib-devhelp](https://pypi.org/project/sphinxcontrib-devhelp) | 2.0.0 | sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp documents
+[sphinxcontrib-htmlhelp](https://pypi.org/project/sphinxcontrib-htmlhelp) | 2.1.0 | sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files
+[sphinxcontrib-jquery](https://pypi.org/project/sphinxcontrib-jquery) | 4.1 | Extension to include jQuery on newer Sphinx releases
+[sphinxcontrib-jsmath](https://pypi.org/project/sphinxcontrib-jsmath) | 1.0.1 | A sphinx extension which renders display math in HTML via JavaScript
+[sphinxcontrib-qthelp](https://pypi.org/project/sphinxcontrib-qthelp) | 2.0.0 | sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp documents
+[sphinxcontrib-serializinghtml](https://pypi.org/project/sphinxcontrib-serializinghtml) | 2.0.0 | sphinxcontrib-serializinghtml is a sphinx extension which outputs "serialized" HTML files (json and pickle)
+[spyder](https://pypi.org/project/spyder) | 6.0.5 | The Scientific Python Development Environment
+[spyder-kernels](https://pypi.org/project/spyder-kernels) | 3.0.3 | Jupyter kernels for Spyder's console
+[sqlalchemy](https://pypi.org/project/sqlalchemy) | 2.0.38 | Database Abstraction Library
+[sqlite-bro](https://pypi.org/project/sqlite-bro) | 0.13.1 | a graphic SQLite Client in 1 Python file
+[sqlite-fts4](https://pypi.org/project/sqlite-fts4) | 1.0.3 | Python functions for working with SQLite FTS4 search
+[sqlite-utils](https://pypi.org/project/sqlite-utils) | 3.38 | CLI tool and Python library for manipulating SQLite databases
+[sqlparse](https://pypi.org/project/sqlparse) | 0.5.3 | A non-validating SQL parser.
+[squarify](https://pypi.org/project/squarify) | 0.4.4 | Pure Python implementation of the squarify treemap layout algorithm
+[sspilib](https://pypi.org/project/sspilib) | 0.2.0 | SSPI API bindings for Python
+[stack-data](https://pypi.org/project/stack-data) | 0.6.3 | Extract data from python stack frames and tracebacks for informative displays
+[starlette](https://pypi.org/project/starlette) | 0.45.3 | The little ASGI library that shines.
+[statsmodels](https://pypi.org/project/statsmodels) | 0.14.4 | Statistical computations and models for Python
+[streamlit](https://pypi.org/project/streamlit) | 1.44.0 | A faster way to build and share data apps
+[superqt](https://pypi.org/project/superqt) | 0.7.1 | Missing widgets and components for PyQt/PySide
+[sv-ttk](https://pypi.org/project/sv-ttk) | 2.6.0 | A gorgeous theme for Tkinter, based on Windows 11's UI
+[sympy](https://pypi.org/project/sympy) | 1.13.3 | Computer algebra system (CAS) in Python
+[tabulate](https://pypi.org/project/tabulate) | 0.9.0 | Pretty-print tabular data
+[tblib](https://pypi.org/project/tblib) | 3.0.0 | Traceback serialization library.
+[tenacity](https://pypi.org/project/tenacity) | 9.0.0 | Retry code until it succeeds
+[termcolor](https://pypi.org/project/termcolor) | 2.5.0 | ANSI color formatting for output in terminal
+[terminado](https://pypi.org/project/terminado) | 0.18.1 | Tornado websocket backend for the Xterm.js Javascript terminal emulator library.
+[text-unidecode](https://pypi.org/project/text-unidecode) | 1.3 | The most basic Text::Unidecode port
+[textdistance](https://pypi.org/project/textdistance) | 4.6.3 | Compute distance between the two texts.
+[thefuzz](https://pypi.org/project/thefuzz) | 0.22.1 | Fuzzy string matching in python
+[threadpoolctl](https://pypi.org/project/threadpoolctl) | 3.5.0 | threadpoolctl
+[three-merge](https://pypi.org/project/three-merge) | 0.1.1 | Simple library for merging two strings with respect to a base one
+[tifffile](https://pypi.org/project/tifffile) | 2025.1.10 | Read and write TIFF files
+[tiktoken](https://pypi.org/project/tiktoken) | 0.8.0 | tiktoken is a fast BPE tokeniser for use with OpenAI's models
+[tinycss2](https://pypi.org/project/tinycss2) | 1.4.0 | A tiny CSS parser
+[tokenizers](https://pypi.org/project/tokenizers) | 0.21.0 |
+[toml](https://pypi.org/project/toml) | 0.10.2 | Python Library for Tom's Obvious, Minimal Language
+[tomli](https://pypi.org/project/tomli) | 2.2.1 | A lil' TOML parser
+[tomli-w](https://pypi.org/project/tomli-w) | 1.2.0 | A lil' TOML writer
+[tomlkit](https://pypi.org/project/tomlkit) | 0.13.2 | Style preserving TOML library
+[toolz](https://pypi.org/project/toolz) | 1.0.0 | List processing tools and functional utilities
+[tornado](https://pypi.org/project/tornado) | 6.4.2 | Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed.
+[tqdm](https://pypi.org/project/tqdm) | 4.66.4 | Fast, Extensible Progress Meter
+[traitlets](https://pypi.org/project/traitlets) | 5.14.1 | Traitlets Python configuration system
+[traittypes](https://pypi.org/project/traittypes) | 0.2.1 | Scipy trait types
+[trio](https://pypi.org/project/trio) | 0.29.0 | A friendly Python library for async concurrency and I/O
+[trove-classifiers](https://pypi.org/project/trove-classifiers) | 2024.10.21.16 | Canonical source for classifiers on PyPI (pypi.org).
+[twine](https://pypi.org/project/twine) | 6.1.0 | Collection of utilities for publishing packages on PyPI
+[typer](https://pypi.org/project/typer) | 0.15.2 | Typer, build great CLIs. Easy to code. Based on Python type hints.
+[types-python-dateutil](https://pypi.org/project/types-python-dateutil) | 2.9.0.20240316 | Typing stubs for python-dateutil
+[types-requests](https://pypi.org/project/types-requests) | 2.32.0.20241016 | Typing stubs for requests
+[typing-extensions](https://pypi.org/project/typing-extensions) | 4.12.2 | Backported and Experimental Type Hints for Python 3.8+
+[typing-inspect](https://pypi.org/project/typing-inspect) | 0.9.0 | Runtime inspection utilities for typing module.
+[tzdata](https://pypi.org/project/tzdata) | 2024.1 | Provider of IANA time zone data
+[tzlocal](https://pypi.org/project/tzlocal) | 5.2 | tzinfo object for the local timezone
+[uc-micro-py](https://pypi.org/project/uc-micro-py) | 1.0.1 | Micro subset of unicode data files for linkify-it-py projects.
+[ujson](https://pypi.org/project/ujson) | 5.10.0 | Ultra fast JSON encoder and decoder for Python
+[umap-learn](https://pypi.org/project/umap-learn) | 0.5.6 | Uniform Manifold Approximation and Projection
+[uncertainties](https://pypi.org/project/uncertainties) | 3.2.2 | calculations with values with uncertainties, error propagation
+[uri-template](https://pypi.org/project/uri-template) | 1.3.0 | RFC 6570 URI Template Processor
+[urllib3](https://pypi.org/project/urllib3) | 2.2.3 | HTTP library with thread-safe connection pooling, file post, and more.
+[uvicorn](https://pypi.org/project/uvicorn) | 0.34.0 | The lightning-fast ASGI server.
+[vega-datasets](https://pypi.org/project/vega-datasets) | 0.9.0 | A Python package for offline access to Vega datasets
+[waitress](https://pypi.org/project/waitress) | 3.0.0 | Waitress WSGI server
+[watchdog](https://pypi.org/project/watchdog) | 6.0.0 | Filesystem events monitoring
+[wcwidth](https://pypi.org/project/wcwidth) | 0.2.13 | Measures the displayed width of unicode strings in a terminal
+[webcolors](https://pypi.org/project/webcolors) | 24.11.1 | A library for working with the color formats defined by HTML and CSS.
+[webencodings](https://pypi.org/project/webencodings) | 0.5.1 | Character encoding aliases for legacy web content
+[websocket-client](https://pypi.org/project/websocket-client) | 1.8.0 | WebSocket client for Python with low level API options
+[werkzeug](https://pypi.org/project/werkzeug) | 3.1.3 | The comprehensive WSGI web application library.
+[whatthepatch](https://pypi.org/project/whatthepatch) | 1.0.7 | A patch parsing and application library.
+[wheel](https://pypi.org/project/wheel) | 0.45.1 | A built-package format for Python
+[widgetsnbextension](https://pypi.org/project/widgetsnbextension) | 4.0.14 | Jupyter interactive widgets for Jupyter Notebook
+[winpython](https://pypi.org/project/winpython) | 15.3.20250425 | WinPython distribution tools, including WPPM
+[wordcloud](https://pypi.org/project/wordcloud) | 1.9.4 | A little word cloud generator
+[wrapt](https://pypi.org/project/wrapt) | 1.16.0 | Module for decorators, wrappers and monkey patching.
+[wsproto](https://pypi.org/project/wsproto) | 1.2.0 | WebSockets state-machine based protocol implementation
+[xarray](https://pypi.org/project/xarray) | 2025.3.0 | N-D labeled arrays and datasets in Python
+[xlsxwriter](https://pypi.org/project/xlsxwriter) | 3.1.9 | A Python module for creating Excel XLSX files.
+[xyzservices](https://pypi.org/project/xyzservices) | 2023.10.1 | Source of XYZ tiles providers
+[yapf](https://pypi.org/project/yapf) | 0.40.1 | A formatter for Python code.
+[yarl](https://pypi.org/project/yarl) | 1.18.3 | Yet another URL library
+[yt-dlp](https://pypi.org/project/yt-dlp) | 2025.2.19 | A feature-rich command-line audio/video downloader
+[zict](https://pypi.org/project/zict) | 3.0.0 | Mutable mapping tools
+[zipp](https://pypi.org/project/zipp) | 3.21.0 | Backport of pathlib-compatible object wrapper for zip files
+[zstandard](https://pypi.org/project/zstandard) | 0.23.0 | Zstandard bindings for Python
+
+
diff --git a/changelogs/WinPythonslim-64bit-3.13.3.0_History.md b/changelogs/WinPythonslim-64bit-3.13.3.0_History.md
new file mode 100644
index 00000000..9767b1e5
--- /dev/null
+++ b/changelogs/WinPythonslim-64bit-3.13.3.0_History.md
@@ -0,0 +1,148 @@
+## History of changes for WinPython-64bit 3.13.3.0slim
+
+The following changes were made to WinPython-64bit distribution since version 3.13.2.0slim.
+
+
+
+### Tools
+
+New packages:
+
+ * [Pandoc](https://pandoc.org) 3.1.9 (an universal document converter)
+
+### Python packages
+
+New packages:
+
+ * [asyncssh](https://pypi.org/project/asyncssh) 2.20.0 (AsyncSSH: Asynchronous SSHv2 client and server library)
+ * [deprecated](https://pypi.org/project/deprecated) 1.2.14 (Python @deprecated decorator to deprecate old python classes, functions or methods.)
+ * [flexcache](https://pypi.org/project/flexcache) 0.3 (Saves and loads to the cache a transformed versions of a source object.)
+ * [flexparser](https://pypi.org/project/flexparser) 0.4 (Parsing made fun ... using typing.)
+ * [id](https://pypi.org/project/id) 1.5.0 (A tool for generating OIDC identities)
+ * [pygithub](https://pypi.org/project/pygithub) 2.6.1 (Use the full Github API v3)
+ * [pyuca](https://pypi.org/project/pyuca) 1.2 (a Python implementation of the Unicode Collation Algorithm)
+ * [shellingham](https://pypi.org/project/shellingham) 1.5.4 (Tool to Detect Surrounding Shell)
+ * [skrub](https://pypi.org/project/skrub) 0.5.1 (Prepping tables for machine learning)
+ * [superqt](https://pypi.org/project/superqt) 0.7.1 (Missing widgets and components for PyQt/PySide)
+ * [sv-ttk](https://pypi.org/project/sv-ttk) 2.6.0 (A gorgeous theme for Tkinter, based on Windows 11's UI)
+ * [typer](https://pypi.org/project/typer) 0.15.2 (Typer, build great CLIs. Easy to code. Based on Python type hints.)
+ * [wrapt](https://pypi.org/project/wrapt) 1.16.0 (Module for decorators, wrappers and monkey patching.)
+
+Upgraded packages:
+
+ * [alembic](https://pypi.org/project/alembic) 1.13.1 → 1.15.1 (A database migration tool for SQLAlchemy.)
+ * [anthropic](https://pypi.org/project/anthropic) 0.42.0 → 0.49.0 (The official Python library for the anthropic API)
+ * [anyio](https://pypi.org/project/anyio) 4.7.0 → 4.8.0 (High level compatibility layer for multiple asynchronous event loop implementations)
+ * [array-api-compat](https://pypi.org/project/array-api-compat) 1.10.0 → 1.11.1 (A wrapper around NumPy and other array libraries to make them compatible with the Array API standard)
+ * [azure-core](https://pypi.org/project/azure-core) 1.30.2 → 1.32.0 (Microsoft Azure Core Library for Python)
+ * [azure-cosmos](https://pypi.org/project/azure-cosmos) 4.7.0 → 4.9.0 (Microsoft Azure Cosmos Client Library for Python)
+ * [azure-identity](https://pypi.org/project/azure-identity) 1.16.1 → 1.21.0 (Microsoft Azure Identity Library for Python)
+ * [black](https://pypi.org/project/black) 24.10.0 → 25.1.0 (The uncompromising code formatter.)
+ * [bokeh](https://pypi.org/project/bokeh) 3.6.3 → 3.7.2 (Interactive plots and applications in the browser from Python)
+ * [cachetools](https://pypi.org/project/cachetools) 5.4.0 → 5.5.2 (Extensible memoizing collections and decorators)
+ * [certifi](https://pypi.org/project/certifi) 2024.6.2 → 2025.1.31 (Python package for providing Mozilla's CA Bundle.)
+ * [click](https://pypi.org/project/click) 8.1.7 → 8.1.8 (Composable command line interface toolkit)
+ * [cloudpickle](https://pypi.org/project/cloudpickle) 3.0.0 → 3.1.1 (Pickler class to extend the standard pickle.Pickler functionality)
+ * [cvxpy](https://pypi.org/project/cvxpy) 1.6.0 → 1.6.4 (A domain-specific language for modeling convex optimization problems in Python.)
+ * [cython](https://pypi.org/project/cython) 3.0.11 → 3.0.12 (The Cython compiler for writing C extensions in the Python language.)
+ * [dask](https://pypi.org/project/dask) 2024.12.1 → 2025.3.0 (Parallel PyData with Task Scheduling)
+ * [datasette](https://pypi.org/project/datasette) 0.64.8 → 0.65.1 (An open source multi-tool for exploring and publishing data)
+ * [datashader](https://pypi.org/project/datashader) 0.16.3 → 0.17.0 (Data visualization toolchain based on aggregating into a grid)
+ * [diff-match-patch](https://pypi.org/project/diff-match-patch) 20230430 → 20241021 (Repackaging of Google's Diff Match and Patch libraries.)
+ * [distributed](https://pypi.org/project/distributed) 2024.12.1 → 2025.3.0 (Distributed scheduler for Dask)
+ * [docstring-to-markdown](https://pypi.org/project/docstring-to-markdown) 0.13 → 0.15 (On the fly conversion of Python docstrings to markdown)
+ * [duckdb](https://pypi.org/project/duckdb) 1.2.0 → 1.2.2 (DuckDB in-process database)
+ * [executing](https://pypi.org/project/executing) 2.0.1 → 2.2.0 (Get the currently executing AST node of a frame, and other information)
+ * [faker](https://pypi.org/project/faker) 33.3.1 → 36.1.1 (Faker is a Python package that generates fake data for you.)
+ * [fastapi](https://pypi.org/project/fastapi) 0.115.6 → 0.115.8 (FastAPI framework, high performance, easy to learn, fast to code, ready for production)
+ * [filelock](https://pypi.org/project/filelock) 3.14.0 → 3.17.0 (A platform independent file lock.)
+ * [folium](https://pypi.org/project/folium) 0.18.0 → 0.19.5 (Make beautiful maps with Leaflet.js & Python)
+ * [holoviews](https://pypi.org/project/holoviews) 1.20.0 → 1.20.2 (A high-level plotting API for the PyData ecosystem built on HoloViews.)
+ * [hpack](https://pypi.org/project/hpack) 4.0.0 → 4.1.0 (Pure-Python HPACK header encoding)
+ * [huggingface-hub](https://pypi.org/project/huggingface-hub) 0.28.1 → 0.29.3 (Client library to download and publish models, datasets and other repos on the huggingface.co hub)
+ * [hypercorn](https://pypi.org/project/hypercorn) 0.16.0 → 0.17.3 (A ASGI Server based on Hyper libraries and inspired by Gunicorn)
+ * [hyperframe](https://pypi.org/project/hyperframe) 6.0.1 → 6.1.0 (Pure-Python HTTP/2 framing)
+ * [hypothesis](https://pypi.org/project/hypothesis) 6.122.3 → 6.130.4 (A library for property-based testing)
+ * [idna](https://pypi.org/project/idna) 3.7 → 3.10 (Internationalized Domain Names in Applications (IDNA))
+ * [imageio](https://pypi.org/project/imageio) 2.33.1 → 2.37.0 (Library for reading and writing a wide range of image, video, scientific, and volumetric data formats.)
+ * [importlib-metadata](https://pypi.org/project/importlib-metadata) 7.1.0 → 8.6.1 (Read metadata from Python packages)
+ * [ipympl](https://pypi.org/project/ipympl) 0.9.6 → 0.9.7 (Matplotlib Jupyter Extension)
+ * [ipython](https://pypi.org/project/ipython) 8.32.0 → 8.34.0 (IPython: Productive Interactive Computing)
+ * [ipywidgets](https://pypi.org/project/ipywidgets) 8.1.5 → 8.1.6 (Jupyter interactive widgets)
+ * [jupyter-client](https://pypi.org/project/jupyter-client) 8.6.2 → 8.6.3 (Jupyter protocol implementation and client libraries)
+ * [jupyter-events](https://pypi.org/project/jupyter-events) 0.10.0 → 0.12.0 (Jupyter Event System library)
+ * [jupyterlab](https://pypi.org/project/jupyterlab) 4.3.5 → 4.4.1 (JupyterLab computational environment)
+ * [jupyterlab-widgets](https://pypi.org/project/jupyterlab-widgets) 3.0.13 → 3.0.14 (Jupyter interactive widgets for JupyterLab)
+ * [keras](https://pypi.org/project/keras) 3.8.0 → 3.9.2 (Multi-backend Keras)
+ * [langchain](https://pypi.org/project/langchain) 0.3.18 → 0.3.23 (Building applications with LLMs through composability)
+ * [langchain-core](https://pypi.org/project/langchain-core) 0.3.34 → 0.3.51 (Building applications with LLMs through composability)
+ * [langchain-text-splitters](https://pypi.org/project/langchain-text-splitters) 0.3.6 → 0.3.8 (LangChain text splitting utilities)
+ * [langsmith](https://pypi.org/project/langsmith) 0.2.11 → 0.3.24 (Client library to connect to the LangSmith LLM Tracing and Evaluation Platform.)
+ * [markdown](https://pypi.org/project/markdown) 3.5.1 → 3.7 (Python implementation of John Gruber's Markdown.)
+ * [matplotlib](https://pypi.org/project/matplotlib) 3.10.0 → 3.10.1 (Python plotting package)
+ * [mypy](https://pypi.org/project/mypy) 1.14.0 → 1.15.0 (Optional static typing for Python)
+ * [mysql-connector-python](https://pypi.org/project/mysql-connector-python) 8.0.21 → 9.2.0 (A self-contained Python driver for communicating with MySQL servers, using an API that is compliant with the Python Database API Specification v)
+ * [narwhals](https://pypi.org/project/narwhals) 1.21.1 → 1.30.0 (Extremely lightweight compatibility layer between dataframe libraries)
+ * [notebook](https://pypi.org/project/notebook) 7.3.1 → 7.4.0 (Jupyter Notebook - A web-based notebook environment for interactive computing)
+ * [numba](https://pypi.org/project/numba) 0.61.0 → 0.61.2 (compiling Python code using LLVM)
+ * [numpy](https://pypi.org/project/numpy) 2.1.3 → 2.2.4 (Fundamental package for array computing in Python)
+ * [openai](https://pypi.org/project/openai) 1.61.1 → 1.72.0 (The official Python library for the openai API)
+ * [opencv-python](https://pypi.org/project/opencv-python) 4.10.0.84 → 4.11.0.86 (Wrapper package for OpenCV python bindings.)
+ * [optree](https://pypi.org/project/optree) 0.13.1 → 0.14.0 (Optimized PyTree Utilities.)
+ * [panel](https://pypi.org/project/panel) 1.6.0 → 1.6.2 (The powerful data exploration & web app framework for Python.)
+ * [param](https://pypi.org/project/param) 2.1.1 → 2.2.0 (Make your Python code clearer and more reliable by declaring Parameters.)
+ * [pip](https://pypi.org/project/pip) 24.3.1 → 25.0.1 (The PyPA recommended tool for installing Python packages.)
+ * [platformdirs](https://pypi.org/project/platformdirs) 4.2.2 → 4.3.6 (A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`.)
+ * [plotly](https://pypi.org/project/plotly) 5.24.1 → 6.0.1 (An open-source interactive data visualization library for Python)
+ * [polars](https://pypi.org/project/polars) 1.22.0 → 1.27.1 (Blazingly fast DataFrame library)
+ * [prometheus-client](https://pypi.org/project/prometheus-client) 0.18.0 → 0.21.1 (Python client for the Prometheus monitoring system.)
+ * [prompt-toolkit](https://pypi.org/project/prompt-toolkit) 3.0.48 → 3.0.50 (Library for building powerful interactive command lines in Python)
+ * [pyarrow](https://pypi.org/project/pyarrow) 19.0.0 → 19.0.1 (Python library for Apache Arrow)
+ * [pyasn1](https://pypi.org/project/pyasn1) 0.4.8 → 0.6.1 (Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208))
+ * [pyasn1-modules](https://pypi.org/project/pyasn1-modules) 0.2.8 → 0.4.1 (A collection of ASN.1-based protocols modules)
+ * [pyjwt](https://pypi.org/project/pyjwt) 2.8.0 → 2.10.1 (JSON Web Token implementation in Python)
+ * [pympler](https://pypi.org/project/pympler) 1.0.1 → 1.1 (A development tool to measure, monitor and analyze the memory behavior of Python objects.)
+ * [pyomo](https://pypi.org/project/pyomo) 6.8.2 → 6.9.1 (Pyomo: Python Optimization Modeling Objects)
+ * [pypandoc](https://pypi.org/project/pypandoc) 1.5 → 1.15 (Thin wrapper for pandoc.)
+ * [pytest](https://pypi.org/project/pytest) 8.2.2 → 8.3.4 (pytest: simple powerful testing with Python)
+ * [Python](http://www.python.org/) 3.13.2 → 3.13.3 (Python programming language with standard library)
+ * [pytz](https://pypi.org/project/pytz) 2024.1 → 2024.2 (World timezone definitions, modern and historical)
+ * [pyzmq](https://pypi.org/project/pyzmq) 26.2.0 → 26.2.1 (Python bindings for 0MQ)
+ * [qtawesome](https://pypi.org/project/qtawesome) 1.3.1 → 1.4.0 (FontAwesome icons in PyQt and PySide applications)
+ * [qtconsole](https://pypi.org/project/qtconsole) 5.5.2 → 5.6.1 (Jupyter Qt console)
+ * [quart](https://pypi.org/project/quart) 0.19.4 → 0.20.0 (A Python ASGI web framework with the same API as Flask)
+ * [rtree](https://pypi.org/project/rtree) 1.1.0 → 1.3.0 (R-Tree spatial index for Python GIS)
+ * [rx](https://pypi.org/project/rx) 3.1.1 → 3.2.0 (Reactive Extensions (Rx) for Python)
+ * [scikit-image](https://pypi.org/project/scikit-image) 0.25.0 → 0.25.2 (Image processing in Python)
+ * [scipy](https://pypi.org/project/scipy) 1.15.1 → 1.15.2 (Fundamental algorithms for scientific computing in Python)
+ * [send2trash](https://pypi.org/project/send2trash) 1.8.2 → 1.8.3 (Send file to trash natively under Mac OS X, Windows and Linux)
+ * [setuptools](https://pypi.org/project/setuptools) 75.6.0 → 75.8.2 (Easily download, build, install, upgrade, and uninstall Python packages)
+ * [simpy](https://pypi.org/project/simpy) 4.0.1 → 4.1.1 (Event discrete, process based simulation for Python.)
+ * [spyder](https://pypi.org/project/spyder) 5.5.6 → 6.0.5 (The Scientific Python Development Environment)
+ * [spyder-kernels](https://pypi.org/project/spyder-kernels) 2.5.2 → 3.0.3 (Jupyter kernels for Spyder's console)
+ * [sqlalchemy](https://pypi.org/project/sqlalchemy) 2.0.35 → 2.0.38 (Database Abstraction Library)
+ * [starlette](https://pypi.org/project/starlette) 0.41.3 → 0.45.3 (The little ASGI library that shines.)
+ * [streamlit](https://pypi.org/project/streamlit) 1.41.1 → 1.44.0 (A faster way to build and share data apps)
+ * [tomli-w](https://pypi.org/project/tomli-w) 1.1.0 → 1.2.0 (A lil' TOML writer)
+ * [trio](https://pypi.org/project/trio) 0.28.0 → 0.29.0 (A friendly Python library for async concurrency and I/O)
+ * [twine](https://pypi.org/project/twine) 6.0.1 → 6.1.0 (Collection of utilities for publishing packages on PyPI)
+ * [widgetsnbextension](https://pypi.org/project/widgetsnbextension) 4.0.13 → 4.0.14 (Jupyter interactive widgets for Jupyter Notebook)
+ * [winpython](https://pypi.org/project/winpython) 13.1.20250222 → 15.3.20250425 (WinPython distribution tools, including WPPM)
+ * [xarray](https://pypi.org/project/xarray) 2025.1.1 → 2025.3.0 (N-D labeled arrays and datasets in Python)
+ * [yt-dlp](https://pypi.org/project/yt-dlp) 2023.7.6 → 2025.2.19 (A feature-rich command-line audio/video downloader)
+
+Removed packages:
+
+ * [bcrypt](https://pypi.org/project/bcrypt) 4.0.1 (Modern password hashing for your software and your servers)
+ * [dask_expr](https://pypi.org/project/dask_expr) 1.1.21 (High Level Expressions for Dask )
+ * [mutagen](https://pypi.org/project/mutagen) 1.47.0 (read and write audio tags for many formats)
+ * [paramiko](https://pypi.org/project/paramiko) 2.8.0 (SSH2 protocol library)
+ * [pint](https://pypi.org/project/pint) 0.23 (Physical quantities module)
+ * [pkginfo](https://pypi.org/project/pkginfo) 1.11.2 (Query metadata from sdists / bdists / installed packages.)
+ * [pycryptodomex](https://pypi.org/project/pycryptodomex) 3.20.0 (Cryptographic library for Python)
+ * [streamz](https://pypi.org/project/streamz) 0.6.3 (Streams)
+ * [websockets](https://pypi.org/project/websockets) 14.2 (An implementation of the WebSocket Protocol (RFC 6455 & 7692))
+
+
+
+* * *
diff --git a/changelogs/md5_sha1.txt b/changelogs/md5_sha1.txt
index 330882ef..2ab82bcb 100644
--- a/changelogs/md5_sha1.txt
+++ b/changelogs/md5_sha1.txt
@@ -1,3 +1,40 @@
+### WinPython 2025-02 release (May 4th, 2025)
+
+MD5 | SHA-1 | SHA-256 | Binary | Size | blake2b-256
+---------------------------------|------------------------------------------|------------------------------------------------------------------|-----------------------------------|----------------------|-----------------------------------------------------------------
+b5a3814f26dade2f6ee9acf983427a8e | b3826baea1606868628128bab5527e3600342fbf | 517eff0673658da3f2da64a28afbd7733fb91807f7d074d3a9e9e6c0eb1dd523 | Winpython64-3.12.10.0dot.7z | 23 076 535 Bytes | e3e4b8b944e79cf20dea5e7691c24485a5b68bb70d34df6edfb181fd499b0335
+6f354778174e04fdb4c4c28c7a543f31 | 5d1bd5bd76dcb0e61df1a268e4ce47f56acbfe6f | b6d196d72ce443ccfbdb5a640f5645a7ade742092fddde65d73755c4eba89a1d | Winpython64-3.12.10.0dot.exe | 23 291 575 Bytes | 785f61ee3821d772bdbff037f86a4229d707c97d97f2508e8cdd03f81c1a8436
+431e37ef366ebe9ae30fa7fb162bb314 | 32965a55a8bc119b96875c542d9a08c6f4ed9b75 | bcb2a87ef210076ff4507a4a644bfb82daa0c2361e7945e5cb7de161450460f6 | Winpython64-3.12.10.0dot.zip | 38 334 544 Bytes | ab0b83f09299291a36298754a445429964f610f507b18e484f6bdf572880acbe
+6e7131129ff75dd4e8832f7be131dcc3 | 4d6c5b10d4b3044b9a70597fcd4fd34cd5e2b2a8 | 294c287c4a9918c730d26188e2dc34e97a92431c83515165f04c2ea8d33f0c1d | Winpython64-3.12.10.0slim.7z | 624 548 662 Bytes | f0b952a2fe29837783b69dcb4259369ee5c1d40a3220ad0b4dd82b1668322973
+3cefa92f927471aeef6c1fa3b7911166 | 1699db6b9c44b605c9f2031201bb58a46a260f0e | 3ea3368ca0e9182c03e8e0bc38b65c5398dd4f8aee7ccf5ab38d5a9226af6b9a | Winpython64-3.12.10.0slim.exe | 624 763 614 Bytes | 8584e33e01025ce04d0e429f2c08c7fe94576901aabf030341b21e0837ed5966
+95c7326579dbd4a16cb2f5b56a141673 | f28906c1e3e4ba073f0363a4e35326f9e8090ce1 | 13abddd4cc2702be56b672c868d0d1bc085e80748dc7d7e9315ab4080f157f3b | Winpython64-3.13.3.0dot.7z | 24 839 744 Bytes | 1cb42e1ea66116bc0e7804fb44bb519140d5a5acc9bb63c650ef38dc138ca0bb
+bccca9b3e79dfbc13d14837e3ba85c9b | 41c805812b778ccaf3781701264b23e6c9908069 | a6b1882b8eff8a44782bfeec7e5228826ebd38c4234e10ba38a52a85860c41d0 | Winpython64-3.13.3.0dot.exe | 25 054 784 Bytes | eea4a48f72d3ca7e784e86883ef2b46cd48a75fd68321c1088e9ed8c11ad47bd
+06a5eb8fa4f7447ad63b7e214b126fd7 | 80ab8340798a318c09ffe07a77a920d5d1eda2b7 | f7ef5a6cfe23b7f39f87c128594fc6c7f73f42f9516a0b828dac0da187af68ec | Winpython64-3.13.3.0dot.zip | 39 870 933 Bytes | a4f9a910f55c5efdbb843874384d5295ff3b3a45d27cab63f74d2f215f9d798c
+40e207597ddecd78f60e8474d8dc3c81 | 5e4df5e04424a754b33e4a63f4ae31d0a65eb0a5 | 0ee4eaa17ed86fbcb9e861989e08c85dcf13ca1ef067c52f4fc8b68dd7836c46 | Winpython64-3.13.3.0slim.7z | 629 049 097 Bytes | f275d41a374ff5f3b75decbe65cd52a54c1ac8157edeb62f377dfa2278201ccb
+312a8e7fa70b5b58e44f69c1066687a8 | 12e992d1e40fb04c0e7fe367a983dc27ef88b151 | 9abfd2a54ba314dfe573792a573ad31a43e63765f7b77c2002849086a1a47c5e | Winpython64-3.13.3.0slim.exe | 629 265 120 Bytes | 87fc9b086fae8a07b234fcced8b428cd0c3367a9ff068cd3c28b661813c94cab
+588e3a1a7ddc461f528270a302a3b667 | a77e443c86c1d21c9a177193e69847efa6346373 | 060046dc83030a639d50396f403a28556ebbd87495bb14045b21118e6cff4c4b | requirement_hash.WinPython64-3.12.10..0slim.txt | 78 133 Bytes | 54d3902407c7c935d83681796585e24d80478f68d22d62ff500d4072ab0385b0
+fb5edb31a3f1e0e7f43eb810f5dd4032 | c6c043e8ec9c7af50eb2d297a91c1b87d3bc7074 | 225500ba0b3aea779b24f7b17bece53250b24380390685bac5ae6c5804f68367 | requirement_hash.WinPython64-3.13.3.0slim.txt | 78 125 Bytes | 1b3d8ff70b049c368ae848d69331faf2ceb19ddc6821ec3549e5511ecac7f393
+
+
+### WinPython 2025-01 release (March 1st, 2025)
+
+ MD5 | SHA-1 | SHA-256 | Binary | Size | blake2b-256
+---------------------------------|------------------------------------------|------------------------------------------------------------------|-----------------------------------|--------------------|-----------------------------------------------------------------
+8aef7e46e862e543d38bed851d0d6505 | fe32d81a13bfd830b5c2820eb9f545ea2dc3302d | 2bcb5bda5d6d27ffce3cccadd772599d534edcbcbca7cb59124e015b3919db68 | Winpython64-3.12.9.0dot.zip | 38 280 444 Bytes | 9f2a468504c56bfb28fec03e47c6526b546098801f21e5137a58dd302838cc6d
+b6fdc51ec5aa7cc449e3e31ab4750899 | f623dc942a6e572a078a2cc71ddc0532d6fd7aef | bf240df0e6ba72499dbea42ba4638264bb777f4d59822df0033f421a342c5188 | Winpython64-3.12.9.0dot.7z | 23 093 610 Bytes | db09d389d7ac6a8e2cfb5369ad910ffcf60ee673894f0ad0a94386409f1d582c
+39dcdd15299ac9a0aa068290432b6c89 | 80c48b7a91446019c1444b85be1124e8b27b9393 | bf1be605dffa97207ab108d9d8dcab2f51c597fc31bebb5e6067811c93402fd3 | Winpython64-3.12.9.0dot.exe | 23 308 650 Bytes | b4f20a6d870c99628fed5fa070ef4bf9312fabc91be926267ec9b9919d1f2353
+e5c92eca86d5063d7c927b87ca7a979a | eabb5add549cda18e7405c8dbe64f163ab92aa05 | 13a08f3bd516558ebca224bb44cc61d763e679b821a1bf240a700a093e7d47fc | Winpython64-3.12.9.0slim.7z | 616 678 094 Bytes | ddcb6f9118e3e2522e920049cb44d82fdcd8e48bfe5f7a30faf1706742971951
+688a2be695eda8f59d0cc690326d1299 | d9e9ddaea543964d9e9743aec86ee7b342f5480f | 02936d96bb488d111136dce11b08afa189b51f57f59d8d0e7068bea2a5fa67c0 | Winpython64-3.12.9.0slim.exe | 616 892 419 Bytes | bcb6fdccc898a2d70d0f8ba7f80d9a056062fcc5d4cc78845dc979ee46e9292e
+6a8d945c058d9fb08b78235bbf8d7ae6 | bcbf848ed72de9b4595ee44faeec15a084408c06 | 0f984ca5dfc195a265a8b547be43891caed9a8770ba8a13b6f87b45990f12704 | Winpython64-3.13.2.0dot.zip | 39 737 933 Bytes | 10008fb4a9193332a1cf5a0d180e503d3860a708a3add9a021c1b23c72ac767a
+51617e557c70a78f70153b92c784ea69 | 217e21a9292ede8ddc50f4628a0a031c2320be3b | 069f4a9a32b713f27d5a8f8ffccf2658580eeea7df7120b414b3fd74e7fc099e | Winpython64-3.13.2.0dot.7z | 24 777 973 Bytes | b2e6ae219ea69c5f212534cd8a52e0c2bf0506b272b643be5884a52251da4125
+7f509cb8aba38aa748b35014ef7d8c1c | a37826beb8474d678e6dac8d263c3062055e1050 | ecba739bd41459656b632306f316da73980bae84e62b540f14c03affb8ac2d93 | Winpython64-3.13.2.0dot.exe | 24 993 013 Bytes | 4f51cba5d6533bbe59367f925649da08c008cf40aaa564a1ee9134799311b83e
+6486a208002d34492af762d33e51c058 | bd1af3dbd687ed1797ac61a85df74f25efb1578b | dcdcb0608d74333bfb987219150f418b0c9637328703a5c12786ad1e24d5485b | Winpython64-3.13.2.0slim.7z | 621 789 094 Bytes | 112a12e15435b200c22055407553879554e3487bed5118468ee2cd6a3c56fff2
+04b8e6e1dc61e2871b5cf522c76ab471 | 7d66dd128689ae80dbfdb589604572bdf204fc9b | 865c54d31aec95f3138b934a4c0a4ff440ac7a27d82b1a9667c61a80ec4d764f | Winpython64-3.13.2.0slim.exe | 622 004 549 Bytes | fd1ad38146a6323be31c7a35aa39c31dd26b6c3d9328da97b71c6a3dcea622f9
+99a59eda2bf37dfab76bcffcae9cd3a7 | 77df69ec8875a7733c60ce2f0d78ced356d7b4c9 | fc66c242a6fe975dd85c764bd1068ad944440684a2bdc8599c2e5a13b5ca29cd | Winpython64-3.14.0.0dota5b.zip | 40 495 265 Bytes | 8344a7e9a40d15d12fe6e3682b86a72ff512136d4cdc65ebca321cd3283c088e
+a0a66a0d00aeefcc185327999fd044c8 | 501888e481f95f824ca7e3160ea117f4f302385e | 92a9a6da1faef872ade0905cf01471831da54ff628b722a4e1d5b4d2a9338f8c | Winpython64-3.14.0.0dota5b.7z | 25 110 864 Bytes | 38275cae601dbbd83fba9591930c893e71b7ea7a8333b2acc0a5a2bde85001bb
+91d3e6ebb32677e6ed9674f5e91fc538 | 931baf8ea70e052e4d87d7dc89d8cdb9c3c277e2 | e4933634b52e0b4ae498ddd1302ecf2ccb8b3de95df8af5120f9f298c2b64d3d | Winpython64-3.14.0.0dota5b.exe | 25 325 904 Bytes | fe50cdcb5328813d783cf92b0b2bb16ef6330d7f45d6888fab1f0fcc208c1b16
+
+
### WinPython 2024-05 release (January 3rd, 2025)
MD5 | SHA-1 | SHA-256 | Binary | Size | blake2b-256
diff --git a/diff.py b/diff.py
deleted file mode 100644
index ec658aba..00000000
--- a/diff.py
+++ /dev/null
@@ -1,349 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Copyright © 2013 Pierre Raybaut
-# Licensed under the terms of the MIT License
-# (see winpython/__init__.py for details)
-
-"""
-WinPython diff script
-
-Created on Tue Jan 29 11:56:54 2013
-"""
-
-import os
-from pathlib import Path
-import re
-import shutil
-
-# Local imports
-from winpython import utils
-
-
-CHANGELOGS_DIR = str(Path(__file__).parent / "changelogs")
-assert Path(CHANGELOGS_DIR).is_dir()
-
-
-class Package(object):
- # SourceForge Wiki syntax:
- PATTERN = r"\[([a-zA-Z\-\:\/\.\_0-9]*)\]\(([^\]\ ]*)\) \| ([^\|]*) \| ([^\|]*)"
- # Google Code Wiki syntax:
- PATTERN_OLD = r"\[([a-zA-Z\-\:\/\.\_0-9]*) ([^\]\ ]*)\] \| ([^\|]*) \| ([^\|]*)"
-
- def __init__(self):
- self.name = None
- self.version = None
- self.description = None
- self.url = None
-
- def __str__(self):
- text = f"{self.name} {self.version}"
- text += f"\r\n{self.description}\r\nWebsite: {self.url}"
- return text
-
- def from_text(self, text):
- try:
- self.url, self.name, self.version, self.description = re.match(
- self.PATTERN_OLD, text
- ).groups()
- except AttributeError:
- self.name, self.url, self.version, self.description = re.match(
- self.PATTERN, text
- ).groups()
-
- def to_wiki(self):
- return f" * [{self.name}]({self.url}) {self.version} ({self.description})\r\n"
-
- def upgrade_wiki(self, other):
- # wheel replace '-' per '_' in package name
- assert (
- self.name.replace("-", "_").lower() == other.name.replace("-", "_").lower()
- )
- return f" * [{self.name}]({self.url}) {other.version} → {self.version} ({self.description})\r\n"
-
-
-class PackageIndex(object):
- WINPYTHON_PATTERN = r"\#\# WinPython\-*[0-9b-t]* ([0-9\.a-zA-Z]*)"
- TOOLS_LINE = "### Tools"
- PYTHON_PACKAGES_LINE = "### Python packages"
- HEADER_LINE1 = "Name | Version | Description"
- HEADER_LINE2 = "-----|---------|------------"
-
- def __init__(
- self,
- version,
- basedir=None,
- flavor="",
- architecture=64,
- ):
- self.version = version
- self.other_packages = {}
- self.python_packages = {}
- self.flavor = flavor
- self.basedir = basedir
- self.architecture = architecture
- self.from_file(basedir)
-
- def from_file(self, basedir):
- fname = str(
- Path(CHANGELOGS_DIR)
- / f"WinPython{self.flavor}-{self.architecture}bit-{self.version}.md"
- )
-
- try:
- with open(fname, "r", encoding = 'utf-8') as fdesc: # python3 doesn't like 'rb'
- text = fdesc.read()
- except:
- with open(fname, "r") as fdesc: # python3 doesn't like 'rb'
- text = fdesc.read()
- self.from_text(text)
-
- def from_text(self, text):
- version = re.match(self.WINPYTHON_PATTERN + self.flavor, text).groups()[0]
- assert version == self.version
- tools_flag = False
- python_flag = False
- for line in text.splitlines():
- if line:
- if line == self.TOOLS_LINE:
- tools_flag = True
- continue
- elif line == self.PYTHON_PACKAGES_LINE:
- tools_flag = False
- python_flag = True
- continue
- elif line in (
- self.HEADER_LINE1,
- self.HEADER_LINE2,
- "",
- " ",
- ):
- continue
- if tools_flag or python_flag:
- package = Package()
- package.from_text(line)
- if tools_flag:
- self.other_packages[package.name] = package
- else:
- self.python_packages[package.name] = package
-
-
-def diff_package_dicts(dict1_in, dict2_in):
- """Return difference between package dict1 and package dict2"""
- text = ""
- # wheel replace '-' per '_' in key
- dict1 = {}
- dict2 = {}
- for key in dict1_in:
- dict1[key.replace("-", "_").lower()] = dict1_in[key]
- for key in dict2_in:
- dict2[key.replace("-", "_").lower()] = dict2_in[key]
- set1, set2 = set(dict1.keys()), set(dict2.keys())
- # New packages
- new = sorted(set2 - set1)
- if new:
- text += "New packages:\r\n\r\n"
- for name in new:
- package = dict2[name]
- text += package.to_wiki()
- text += "\r\n"
- # Upgraded packages
- upgraded_list = []
- for name in sorted(set1 & set2):
- package1 = dict1[name]
- package2 = dict2[name]
- if package1.version != package2.version:
- upgraded_list.append(package2.upgrade_wiki(package1))
- if upgraded_list:
- text += "Upgraded packages:\r\n\r\n" + f"{''.join(upgraded_list)}" + "\r\n"
- # Removed packages
- removed = sorted(set1 - set2)
- if removed:
- text += "Removed packages:\r\n\r\n"
- for name in removed:
- package = dict1[name]
- text += package.to_wiki()
- text += "\r\n"
- return text
-
-
-def find_closer_version(version1, basedir=None, flavor="", architecture=64):
- """Find version which is the closest to `version`"""
- builddir = str(Path(basedir) / f"bu{flavor}")
- func = lambda name: re.match(
- r"WinPython%s-%sbit-([0-9\.]*)\.(txt|md)" % (flavor, architecture),
- name,
- )
- versions = [func(name).groups()[0] for name in os.listdir(builddir) if func(name)]
- # versions:['3.10.0.1', '3.10.10.0', '3.10.2.0'.... '3.10.8.1', '3.10.9.0']
- try:
- index = versions.index(version1)
- except ValueError:
- raise ValueError(f"Unknown version {version1}")
-
- from packaging import version
- version_below = '0.0.0.0'
- for v in versions:
- if version.parse(v) > version.parse(version_below) and version.parse(v)",
- "",
- ]
- )
- pi1 = PackageIndex(
- version1,
- basedir=basedir,
- flavor=flavor1,
- architecture=architecture,
- )
- pi2 = PackageIndex(
- version2,
- basedir=basedir,
- flavor=flavor,
- architecture=architecture,
- )
- tools_text = diff_package_dicts(pi1.other_packages, pi2.other_packages)
- if tools_text:
- text += PackageIndex.TOOLS_LINE + "\r\n\r\n" + tools_text
- py_text = diff_package_dicts(pi1.python_packages, pi2.python_packages)
- if py_text:
- text += PackageIndex.PYTHON_PACKAGES_LINE + "\r\n\r\n" + py_text
- text += "\r\n\r\n* * *\r\n"
- return text
-
-
-def _copy_all_changelogs(version, basedir, flavor="", architecture=64):
- basever = ".".join(version.split(".")[:2])
- for name in os.listdir(CHANGELOGS_DIR):
- if re.match(
- r"WinPython%s-%sbit-%s([0-9\.]*)\.(txt|md)"
- % (flavor, architecture, basever),
- name,
- ):
- shutil.copyfile(
- str(Path(CHANGELOGS_DIR) / name),
- str(Path(basedir) / f"bu{flavor}" / name),
- )
-
-
-def write_changelog(
- version2,
- version1=None,
- basedir=None,
- flavor="",
- release_level="",
- architecture=64,
-):
- """Write changelog between version1 and version2 of WinPython"""
- _copy_all_changelogs(
- version2,
- basedir,
- flavor=flavor,
- architecture=architecture,
- )
- print(
- "comparing_package_indexes",
- version2,
- basedir,
- flavor,
- architecture,
- )
- text = compare_package_indexes(
- version2,
- version1,
- basedir=basedir,
- flavor=flavor,
- architecture=architecture,
- )
- fname = str(
- Path(basedir)
- / f"bu{flavor}"
- / f"WinPython{flavor}-{architecture}bit-{version2}_History.md"
- )
-
- with open(fname, "w", encoding="utf-8-sig") as fdesc: # python 3 need
- fdesc.write(text)
- # Copy to winpython/changelogs
- shutil.copyfile(fname, str(Path(CHANGELOGS_DIR) / Path(fname).name))
-
-
-def test_parse_package_index_wiki(version, basedir=None, flavor="", architecture=64):
- """Parse the package index Wiki page"""
- pi = PackageIndex(
- version,
- basedir=basedir,
- flavor=flavor,
- architecture=architecture,
- )
- utils.print_box(f"WinPython {pi.version}:")
- utils.print_box("Tools:")
- for package in pi.other_packages.values():
- print(package)
- print("")
- utils.print_box("Python packages:")
- for package in pi.python_packages.values():
- print(package)
- print("")
-
-
-def test_compare(basedir, version2, version1, architecture=64):
- print(
- compare_package_indexes(
- basedir,
- version2,
- version1,
- architecture=architecture,
- )
- )
-
-
-if __name__ == "__main__":
- print(
- compare_package_indexes(
- version2="3.7.4.0",
- version1="3.7.2.0",
- basedir=r"C:\WinP\bd37",
- flavor="Zero",
- flavor1="Zero",
- architecture=32,
- )
- )
- write_changelog(
- version2="3.7.4.0",
- version1="3.7.2.0",
- basedir=r"C:\WinP\bd37",
- flavor="Ps2",
- architecture=64,
- )
- # test_parse_package_index_wiki('2.7.3.3')
- # print(compare_package_indexes('2.7.3.3', '2.7.3.1'))
- # write_changelog('2.7.4.1', '2.7.4.0')
- # write_changelog('3.3.0.0beta2', '3.3.0.0beta1')
diff --git a/dot_requirements.txt b/dot_requirements.txt
index 68a29ece..c5453f90 100644
--- a/dot_requirements.txt
+++ b/dot_requirements.txt
@@ -1,5 +1,9 @@
# the essential
sqlite_bro
-#idlex
+setuptools
wheel
+build
+##msvc_runtime
# end of requirements.txt
+
+
diff --git a/generate_a_winpython_distro.bat b/generate_a_winpython_distro.bat
index c2af1bcb..e9c73d9a 100644
--- a/generate_a_winpython_distro.bat
+++ b/generate_a_winpython_distro.bat
@@ -1,67 +1,18 @@
-rem to launch from a winpython package directory, where 'make.py' is
+rem generate_a_winpython_distro.bat: to be launched from a winpython directory, where 'make.py' is
@echo on
-rem *****************************
-rem 2020-07-05: install msvc_runtime before packages that may want to compile
-rem 2020-12-05 : add a constraints.txt file from a recent pip list
-rem 2021-03-20 : track successes packages combination are archived for future contraint update
-rem 2021-04-22 : path PyPy3 (as we don't try to copy PyPy3.exe to Python.exe)
-rem 2023-08-21a: add a pre_step with my_requirements_pre.txt + my_find_links_pre
-rem 2024-05-12a: use python -m pip instead of pip , and remove --upgrade %new_resolver%
-rem 2024-09-15a: compactify for lisiblity
-rem *****************************
-
-rem algorithm:
-rem 0.0 Initialize variables
-rem 1.0 Do 2021-04-22 : patch PyPy3 (as we don't try to copy PyPy3.exe to Python.exe)
-rem 2 a Pre-clear of previous build infrastructure
-rem 2.0 Create a new build
-rem 2.1 Create basic build infrastructure
-rem 2.2 check infrastructure is in place
-rem 2.3 add mandatory packages for build
-rem 2.4 add packages pre_requirements (if any)
-rem 2.5 add requirement packages
-rem 2.8 post-build (if specific workarounds)
-rem 2.9 archive success
-rem 3.0 Generate Changelog and binaries
-
-rem "my_release_level" is optionaly set per the calling program *********************************************
-rem set my_release_level=
-if "%my_release_level%"=="" set my_release_level=b1
-
-rem "my_create_installer" is optionaly set per the calling program
+REM Initialize variables
+if "%my_release_level%"=="" set my_release_level=b4
if "%my_create_installer%"=="" set my_create_installer=True
+rem Set archive directory and log file
+set my_archive_dir=%~dp0WinPython_build_logs
+if not exist %my_archive_dir% mkdir %my_archive_dir%
-rem this is pre-initialised per the program calling this .bat
-rem set my_original_path=%path%
-rem set my_root_dir_for_builds=D:\WinP
-
-rem set my_python_target=34
-rem set my_pyver=3.4
-rem set my_flavor=slim
-rem set my_release=84
-
-rem set my_find_link=C:\WinP\packages.srcreq
-
-rem set my_arch=64
-rem set my_preclear_build_directory=Yes
-
-rem set my_requirements_pre=C:\WinP\bd311\requirements_mkl_pre.txt
-rem set my_find_links_pre=C:\WinP\packages_mkl.srcreq
-
-rem set my_requirements=C:\Winpents=d:\my_req1.txt
-
-rem set my_source_dirs=D:\WinPython\bd34\packages.src D:\WinPython\bd34\packages.win32.Slim
-rem set my_toolsdirs=D:\WinPython\bd34\Tools.Slim
-rem set my_docsdirs=D:\WinPython\bd34\docs.Slim
-
-
-
-echo ----------------------------------------
-echo 0.0 (%date% %time%) Initialize variables
-echo ----------------------------------------
-
+set my_time=%time:~0,5%
+set my_time=%my_time::=_%
+set my_time=%my_time: =0%
+set my_archive_log=%my_archive_dir%\build_%my_pyver%._.%my_release%%my_flavor%_%my_release_level%_of_%date:/=-%at_%my_time%.txt
set my_basedir=%my_root_dir_for_builds%\bd%my_python_target%
@@ -73,267 +24,194 @@ if "%my_constraints%"=="" set my_constraints=C:\WinP\constraints.txt
rem 2021-04-22 : path PyPy3 (as we don't try to copy PyPy3.exe to Python.exe)
if "%target_python_exe%"=="" set target_python_exe=python.exe
-
-if %my_python_target%==310 (
- set my_python_target_release=31011
- set my_release=2
-)
-
-if %my_python_target%==311 (
- set my_python_target_release=3119
- set my_release=1
+rem Set Python target release based on my_python_target
+if %my_python_target%==311 set my_python_target_release=3119& set my_release=1
+if %my_python_target%==312 set my_python_target_release=31210& set my_release=1
+if %my_python_target%==313 set my_python_target_release=3133& set my_release=1
+if %my_python_target%==314 set my_python_target_release=3140& set my_release=0
+
+echo -------------------------------------- >>%my_archive_log%
+echo (%date% %time%) preparing winPython for %my_pyver% (%my_python_target%)release %my_release%%my_flavor% (%my_release_level%) *** %my_arch% bit ***>>%my_archive_log%
+echo -------------------------------------- >>%my_archive_log%
+
+rem Pre-clear previous build infrastructure
+if "%my_preclear_build_directory%"=="Yes" (
+ echo "(%date% %time%) Pre-clear previous build infrastructure">>%my_archive_log%
+ del -y %userprofile%\.jupyter\jupyter_notebook_config.py
+ cd /D %my_root_dir_for_builds%\bd%my_python_target%
+ set build_det=\%my_flavor%
+ if "%my_flavor%"=="" set build_det=
+ dir %build_det%
+ ren bu%my_flavor% bu%my_flavor%_old
+ start rmdir /S /Q bu%my_flavor%_old
+ rmdir /S /Q bu%my_flavor%
+ rmdir /S /Q dist
)
-if %my_python_target%==312 (
- set my_python_target_release=3128
- set my_release=0
-)
-
-if %my_python_target%==313 (
- set my_python_target_release=3131
- set my_release=0
-)
-
-
-rem set my_install_options=--no-index --pre
-
-set my_day=%date:/=-%
-set my_time=%time:~0,5%
-set my_time=%my_time::=_%
-set my_time=%my_time: =0%
-
-set my_archive_dir=%~dp0WinPython_build_logs
-if not exist %my_archive_dir% mkdir %my_archive_dir%
-
-set my_archive_log=%my_archive_dir%\build_%my_pyver%._.%my_release%%my_flavor%_%my_release_level%_of_%my_day%_at_%my_time%.txt
-
-
-echo ----------------------------------------
-echo preparing winPython for %my_pyver% (%my_python_target%)release %my_release%%my_flavor% (%my_release_level%) *** %my_arch% bit ***
-echo ----------------------------------------
-echo ---------------------------------------- >>%my_archive_log%
-echo (%date% %time%) preparing winPython for %my_pyver% (%my_python_target%)release %my_release%%my_flavor% (%my_release_level%) *** %my_arch% bit ***>>%my_archive_log%
-echo ---------------------------------------- >>%my_archive_log%
-
-
-if not "%my_preclear_build_directory%"=="Yes" goto no_preclear
-
-
-echo ----------------------------------------
-echo 1.0 (%date% %time%) Do a Pre-clear of previous build infrastructure
-echo ----------------------------------------
-echo ---------------------------------------- >>%my_archive_log%
-echo 1.0 (%date% %time%) Do a Pre-clear of previous build infrastructure>>%my_archive_log%
-echo ---------------------------------------- >>%my_archive_log%
-
-rem 2019-05-10 PATCH for build problem (asking permission to overwrite the file)
-del -y %userprofile%\.jupyter\jupyter_notebook_config.py
-
-cd /D %my_root_dir_for_builds%\bd%my_python_target%
-
-set build_det=\%my_flavor%
-if "%my_flavor%"=="" set build_det=
-
-dir %build_det%
-
-rem 2021-02-13 workaround to hard to remove json files
-echo ren bu%my_flavor% bu%my_flavor%_old
-ren bu%my_flavor% bu%my_flavor%_old
-
-rem pause
-start rmdir /S /Q bu%my_flavor%_old
-
-
-echo rmdir /S /Q bu%my_flavor%
-rem pause
-rmdir /S /Q bu%my_flavor%
-rmdir /S /Q bu%my_flavor%
-rmdir /S /Q bu%my_flavor%
-rmdir /S /Q bu%my_flavor%
-rmdir /S /Q bu%my_flavor%
-rmdir /S /Q dist
-
-echo %date% %time%
-echo %date% %time%>>%my_archive_log%
-
-:no_preclear
-
-
-echo ----------------------------------------
-echo 2.0 (%date% %time%) Create a new build
-echo ---------------------------------------- >>%my_archive_log%
-echo 2.0 (%date% %time%) Create a new build>>%my_archive_log%
-echo ---------------------------------------- >>%my_archive_log%
-
-
-echo cd /D %~dp0>>%my_archive_log%
+REM Create a new build
+echo -------------------------------------- >>%my_archive_log%
+echo "(%date% %time%) Create a new build">>%my_archive_log%
+echo -------------------------------------- >>%my_archive_log%
cd /D %~dp0
-
-echo set path=%my_original_path%>>%my_archive_log%
set path=%my_original_path%
-
-echo call %my_buildenv%\scripts\env.bat>>%my_archive_log%
call %my_buildenv%\scripts\env.bat
+@echo on
-echo ----------------------------------------
-echo 2.1 (%date% %time%) Create basic build infrastructure
-echo ----------------------------------------
-echo ---------------------------------------- >>%my_archive_log%
-echo 2.1 (%date% %time%) Create basic build infrastructure>>%my_archive_log%
-echo ---------------------------------------- >>%my_archive_log%
-
-rem at First step 2.1
-rem we don't use any %my_requirements%
-rem we don't create installer
-rem we use legacy python build cd /D %~dp0
-
-set my_buildenv_path=%path%
-
-echo python.exe -c "from make import *;make_all(%my_release%, '%my_release_level%', pyver='%my_pyver%', basedir=r'%my_basedir%', verbose=True, architecture=%my_arch%, flavor='%my_flavor%', install_options=r'%my_install_options%', find_links=r'%my_find_links%', source_dirs=r'%my_source_dirs%', toolsdirs=r'%my_toolsdirs%', docsdirs=r'%my_docsdirs%', create_installer='False', python_target_release='%my_python_target_release%')">>%my_archive_log%
-
-echo python.exe -c "from make import *;make_all(%my_release%, '%my_release_level%', pyver='%my_pyver%', basedir=r'%my_basedir%', verbose=True, architecture=%my_arch%, flavor='%my_flavor%', install_options=r'%my_install_options%', find_links=r'%my_find_links%', source_dirs=r'%my_source_dirs%', toolsdirs=r'%my_toolsdirs%', docsdirs=r'%my_docsdirs%', create_installer='False', python_target_release='%my_python_target_release%')"
-
-rem pause
-
+REM Create basic build infrastructure
+echo "(%date% %time%) Create basic build infrastructure">>%my_archive_log%
python.exe -c "from make import *;make_all(%my_release%, '%my_release_level%', pyver='%my_pyver%', basedir=r'%my_basedir%', verbose=True, architecture=%my_arch%, flavor='%my_flavor%', install_options=r'%my_install_options%', find_links=r'%my_find_links%', source_dirs=r'%my_source_dirs%', toolsdirs=r'%my_toolsdirs%', docsdirs=r'%my_docsdirs%', create_installer='False', python_target_release='%my_python_target_release%')">>%my_archive_log%
-
-echo ----------------------------------------
-echo 2.2 (%date% %time%) check infrastructure is in place
-echo ----------------------------------------
-echo ---------------------------------------- >>%my_archive_log%
-echo 2.2 (%date% %time%) check infrastructure is in place>>%my_archive_log%
-echo ---------------------------------------- >>%my_archive_log%
-
-@echo on
+REM Check infrastructure is in place
+echo "(%date% %time%) Check infrastructure">>%my_archive_log%
set my_WINPYDIRBASE=%my_root_dir_for_builds%\bd%my_python_target%\bu%my_flavor%\Wpy%my_arch%-%my_python_target_release%%my_release%%my_release_level%
-
set WINPYDIRBASE=%my_WINPYDIRBASE%
if not exist %my_WINPYDIRBASE%\scripts\env.bat (
+ @echo off
+ echo as %my_WINPYDIRBASE%\scripts\env.bat does not exist
echo please check and correct my_python_target_release=%my_python_target_release%
echo my_arch=%my_arch%
echo my_python_target_release=%my_python_target_release%
echo my_release=%my_release%
echo my_release_level=%my_release_level%
- echo in generate_a_winpython_distro.bat
- echo as %my_WINPYDIRBASE%\scripts\env.bat doesnt exist
pause
exit
-)
+)
-rem we use final environment to install requirements
-set path=%my_original_path%
+REM Add pre-requisite packages
+echo -------------------------------------- >>%my_archive_log%
+echo "(%date% %time%) Add pre-requisite packages">>%my_archive_log%
+echo -------------------------------------- >>%my_archive_log%
+set path=%my_original_path%
call %my_WINPYDIRBASE%\scripts\env.bat
-set
-
-echo ----------------------------------------
-echo 2.3 (%date% %time%) add mandatory packages for build 'msvc_runtime'.. still necessary ? 2024-12-22 dropped
-echo ----------------------------------------
-echo ---------------------------------------- >>%my_archive_log%
-echo 2.3 (%date% %time%) add mandatory packages for build 'msvc_runtime'.. still necessary ? 2024-12-22 dropped>>%my_archive_log%
-echo ---------------------------------------- >>%my_archive_log%
-
-rem echo python -m pip install msvc_runtime --pre --no-index --trusted-host=None --find-links=%my_find_links% --upgrade
-rem echo python -m pip install msvc_runtime --pre --no-index --trusted-host=None --find-links=%my_find_links% --upgrade>>%my_archive_log%
-rem python -m pip install msvc_runtime --pre --no-index --trusted-host=None --find-links=%my_find_links% --upgrade
+rem Install pre-requirements if any
+if not "Z%my_requirements_pre%Z"=="ZZ" (
+ if "%my_find_links_pre%"=="" set my_find_links_pre=%my_find_links%
+ python -m pip install -r %my_requirements_pre% -c %my_constraints% --pre --no-index --trusted-host=None --find-links=%my_find_links_pre% >> %my_archive_log%
+) else (
+ echo "No pre-requisite packages">>%my_archive_log%
+)
+REM Add requirement packages
+echo -------------------------------------- >>%my_archive_log%
+echo "(%date% %time%) Add requirement packages">>%my_archive_log%
+echo -------------------------------------- >>%my_archive_log%
+python -m pip install -r %my_requirements% -c %my_constraints% --pre --no-index --trusted-host=None --find-links=%my_find_links% >>%my_archive_log%
+python -c "from winpython import wppm;dist=wppm.Distribution(r'%WINPYDIR%');dist.patch_standard_packages('spyder', to_movable=True)"
+
+REM Add Wheelhouse (to replace per pip lock direct ? would allow paralellism)
+echo -------------------------------------- >>%my_archive_log%
+echo "(%date% %time%) Add lockfile wheels">>%my_archive_log%
+echo -------------------------------------- >>%my_archive_log%
+set path=%my_original_path%
+@echo on
+call %my_WINPYDIRBASE%\scripts\env.bat
+@echo on
+set WINPYVERLOCK=%WINPYVER2:.=_%
+set pylockinclude=%my_root_dir_for_builds%\bd%my_python_target%\bu%addlockfile%\pylock.%addlockfile%-%WINPYARCH%bit-%WINPYVERLOCK%.toml
+echo pylockinclude="%pylockinclude%"
+if not "Z%addlockfile%Z"=="ZZ" if exist "%pylockinclude%" (
+echo %my_WINPYDIRBASE%\python\scripts\wppm.exe "%pylockinclude%" -ws "%my_find_links%" -wd "%my_WINPYDIRBASE%\wheelhouse\included.wheels">>%my_archive_log%
+%my_WINPYDIRBASE%\python\scripts\wppm.exe "%pylockinclude%" -ws "%my_find_links%" -wd "%my_WINPYDIRBASE%\wheelhouse\included.wheels"
+)
-echo ----------------------------------------
-echo 2.4 (%date% %time%) add packages pre_requirements (if any)
-echo ----------------------------------------
-echo ---------------------------------------- >>%my_archive_log%
-echo 2.4 (%date% %time%) add packages pre_requirements (if any)
-echo ---------------------------------------- >>%my_archive_log%
+@echo on
+echo wheelhousereq=%wheelhousereq%
+set LOCKDIR=%WINPYDIRBASE%\..\
+set pip_lock_includedlocal=%LOCKDIR%pylock.%my_flavor%-%WINPYARCH%bit-%WINPYVERLOCK%_includedwheelslocal.toml
+set pip_lock_includedweb=%LOCKDIR%pylock.%my_flavor%-%WINPYARCH%bit-%WINPYVERLOCK%_includedwheels.toml
+set req_lock_includedlocal=%LOCKDIR%requirement.%my_flavor%-%WINPYARCH%bit-%WINPYVERLOCK%_includedwheelslocal.txt
+set req_lock_includedweb=%LOCKDIR%requirement.%my_flavor%-%WINPYARCH%bit-%WINPYVERLOCK%_includedwheels.txt
+
+if not "Z%wheelhousereq%Z"=="ZZ" if exist "%wheelhousereq%" (
+echo JOYYYwheelhousereq=%wheelhousereq%
+echo z%pip_lock_includedlocal%z=%pip_lock_includedlocal%
+rem no winpython in it naturally, with deps
+python.exe -m pip lock --no-index --trusted-host=None --find-links=%my_find_links% -c C:\WinP\constraints.txt -r "%wheelhousereq%" -o %pip_lock_includedlocal%
+rem generating also classic requirement with hash-256, from obtained pylock.toml
+python.exe -c "from winpython import wheelhouse as wh;wh.pylock_to_req(r'%pip_lock_includedlocal%', r'%req_lock_includedlocal%')"
+
+rem same with frozen web from local
+python.exe -m pip lock --no-deps --require-hashes -c C:\WinP\constraints.txt -r "%req_lock_includedlocal%" -o %pip_lock_includedweb%
+
+echo %my_WINPYDIRBASE%\python\scripts\wppm.exe "%pip_lock_includedweb%" -ws "%my_find_links%" -wd "%my_WINPYDIRBASE%\wheelhouse\included.wheels">>%my_archive_log%
+%my_WINPYDIRBASE%\python\scripts\wppm.exe "%pip_lock_includedweb%" -ws "%my_find_links%" -wd "%my_WINPYDIRBASE%\wheelhouse\included.wheels"
+)
-if not "Z%my_requirements_pre%Z"=="ZZ" (
+echo -------------------------------------- >>%my_archive_log%;
+echo "(%date% %time%) generate pylock.toml files and requirement.txt with hash files">>%my_archive_log%
+echo -------------------------------------- >>%my_archive_log%
-if "%my_find_links_pre%"=="" set my_find_links_pre=%my_find_links%
+set path=%my_original_path%
+call %my_WINPYDIRBASE%\scripts\env.bat
-echo python -m pip install -r %my_requirements_pre% -c %my_constraints% --pre --no-index --trusted-host=None --find-links=%my_find_links_pre%
-echo python -m pip install -r %my_requirements_pre% -c %my_constraints% --pre --no-index --trusted-host=None --find-links=%my_find_links_pre% >>%my_archive_log%
-echo if pip doesn't work, check the path of %my_WINPYDIRBASE%
+rem generate pip freeze requirements
+echo %date% %time%
+set LOCKDIR=%WINPYDIRBASE%\..\
-python -m pip install -r %my_requirements_pre% -c %my_constraints% --pre --no-index --trusted-host=None --find-links=%my_find_links_pre% >>%my_archive_log%
-) else (
-echo no packages pre_requirements
-echo no packages pre_requirements>>%my_archive_log%
-)
+set WINPYVERLOCK=%WINPYVER2:.=_%
+set req=%LOCKDIR%requirement.%my_flavor%-%WINPYARCH%bit-%WINPYVERLOCK%_raw.txt
+set wanted_req=%LOCKDIR%requirement.%my_flavor%-%WINPYARCH%bit-%WINPYVERLOCK%.txt
+set pip_lock_web=%LOCKDIR%pylock.%my_flavor%-%WINPYARCH%bit-%WINPYVERLOCK%.toml
+set pip_lock_local=%LOCKDIR%pylock.%my_flavor%-%WINPYARCH%bit-%WINPYVERLOCK%_local.toml
+set req_lock_web=%LOCKDIR%requirement.%my_flavor%-%WINPYARCH%bit-%WINPYVERLOCK%.txt
+set req_lock_local=%LOCKDIR%requirement.%my_flavor%-%WINPYARCH%bit-%WINPYVERLOCK%_local.txt
+set pip_lock_web=%LOCKDIR%pylock.%WINPYARCH%-%WINPYVERLOCK%%my_flavor%%my_release_level%.toml
+set pip_lock_local=%LOCKDIR%pylock.%WINPYARCH%-%WINPYVERLOCK%%my_flavor%%my_release_level%_local.toml
+set req_lock_web=%LOCKDIR%requirement.%WINPYARCH%-%WINPYVERLOCK%%my_flavor%%my_release_level%.txt
+set req_lock_local=%LOCKDIR%requirement.%WINPYARCH%-%WINPYVERLOCK%%my_flavor%_local.txt
-echo ----------------------------------------
-echo 2.5 (%date% %time%) add requirement packages
-echo ----------------------------------------
-echo ---------------------------------------- >>%my_archive_log%
-echo 2.5 (%date% %time%) add requirement packages_versions>>%my_archive_log%
-echo ---------------------------------------- >>%my_archive_log%
-echo python -m pip install -r %my_requirements% -c %my_constraints% --pre --no-index --trusted-host=None --find-links=%my_find_links%
-echo python -m pip install -r %my_requirements% -c %my_constraints% --pre --no-index --trusted-host=None --find-links=%my_find_links% >>%my_archive_log%
-echo if pip doesn't work, check the path of %my_WINPYDIRBASE%
+set my_archive_lockfile=%my_archive_dir%\pylock.%my_flavor%-%WINPYARCH%bit-%WINPYVERLOCK%_%date:/=-%at_%my_time%.toml
+set my_archive_lockfile_local=%my_archive_dir%\pylock.%my_flavor%-%WINPYARCH%bit-%WINPYVERLOCK%_%date:/=-%at_%my_time%.local.toml
+set my_changelog_lockfile=%~dp0changelogs\pylock.%my_flavor%-%WINPYARCH%bit-%WINPYVERLOCK%.toml
-python -m pip install -r %my_requirements% -c %my_constraints% --pre --no-index --trusted-host=None --find-links=%my_find_links% >>%my_archive_log%
+python.exe -m pip freeze>%req%
+findstr /v "winpython" %req% > %wanted_req%
-echo ----------------------------------------
-echo 2.8 (%date% %time%) post-build (if specific workarounds)
-echo ----------------------------------------
-echo ---------------------------------------- >>%my_archive_log%
-echo 2.8 (%date% %time%) post-build (if specific workarounds)>>%my_archive_log%
-echo ---------------------------------------- >>%my_archive_log%
+rem pip lock from pypi, from the frozen req
+python.exe -m pip lock --no-deps -c C:\WinP\constraints.txt -r "%wanted_req%" -o %pip_lock_web%
-@echo on
-call %my_basedir%\run_complement_newbuild.bat %my_WINPYDIRBASE%
+rem pip lock from local WheelHouse, from the frozen req
+python.exe -m pip lock --no-deps --no-index --trusted-host=None --find-links=C:\WinP\packages.srcreq -c C:\WinP\constraints.txt -r "%wanted_req%" -o %pip_lock_local%
+rem generating also classic requirement with hash-256, from obtained pylock.toml
+python.exe -c "from winpython import wheelhouse as wh;wh.pylock_to_req(r'%pip_lock_web%', r'%req_lock_web%')"
+python.exe -c "from winpython import wheelhouse as wh;wh.pylock_to_req(r'%pip_lock_local%', r'%req_lock_local%')"
-echo ----------------------------------------
-echo 2.9 (%date% %time%) archive success
-echo ----------------------------------------
-echo ---------------------------------------- >>%my_archive_log%
-echo 2.9 (%date% %time%) archive success >>%my_archive_log%
-echo ---------------------------------------- >>%my_archive_log%
+rem compare the two (result from pypi and local Wheelhouse must be equal)
+fc "%req_lock_web%" "%req_lock_local%"
-echo %target_python_exe% -m pip freeze>%my_archive_log%.packages_versions.txt>>%my_archive_log%
-%target_python_exe% -m pip freeze>%my_archive_log%.packages_versions.txt
+copy/Y %pip_lock_web% %my_archive_lockfile%
+copy/Y %pip_lock_web% %my_changelog_lockfile%
-echo ----------------------------------------
-echo 3.0 (%date% %time%) Generate Changelog and binaries
-echo ----------------------------------------
-echo ---------------------------------------- >>%my_archive_log%
-echo 3.0 (%date% %time%) Generate Changelog and binaries >>%my_archive_log%
-echo ---------------------------------------- >>%my_archive_log%
+REM Archive success
+echo -------------------------------------- >>%my_archive_log%
+echo "(%date% %time%) Archive success">>%my_archive_log%
+echo -------------------------------------- >>%my_archive_log%
+set path=%my_original_path%
+call %my_WINPYDIRBASE%\scripts\env.bat
-rem build final changelog and binaries, using create_installer='%my_create_installer%', remove_existing=False , remove : requirements, toolsdirs and docdirs
+%target_python_exe% -m pip freeze > %my_archive_log%.packages_versions.txt
+REM Generate changelog and binaries
+echo "(%date% %time%) Generate changelog and binaries">>%my_archive_log%
set path=%my_original_path%
-echo cd /D %~dp0>>%my_archive_log%
cd /D %~dp0
-
-echo call %my_buildenv%\scripts\env.bat>>%my_archive_log%
call %my_buildenv%\scripts\env.bat
-set
-echo python.exe -c "from make import *;make_all(%my_release%, '%my_release_level%', pyver='%my_pyver%', basedir=r'%my_basedir%', verbose=True, architecture=%my_arch%, flavor='%my_flavor%', install_options=r'%my_install_options%', find_links=r'%my_find_links%', source_dirs=r'%my_source_dirs%', create_installer='%my_create_installer%', remove_existing=False, python_target_release='%my_python_target_release%')">>%my_archive_log%
+python.exe -c "from make import *;make_all(%my_release%, '%my_release_level%', pyver='%my_pyver%', basedir=r'%my_basedir%', verbose=True, architecture=%my_arch%, flavor='%my_flavor%', install_options=r'%my_install_options%', find_links=r'%my_find_links%', source_dirs=r'%my_source_dirs%', create_installer='%my_create_installer%', rebuild=False, python_target_release='%my_python_target_release%')" >> %my_archive_log%
-echo python.exe -c "from make import *;make_all(%my_release%, '%my_release_level%', pyver='%my_pyver%', basedir=r'%my_basedir%', verbose=True, architecture=%my_arch%, flavor='%my_flavor%', install_options=r'%my_install_options%', find_links=r'%my_find_links%', source_dirs=r'%my_source_dirs%', create_installer='%my_create_installer%', remove_existing=False, python_target_release='%my_python_target_release%')"
-python.exe -c "from make import *;make_all(%my_release%, '%my_release_level%', pyver='%my_pyver%', basedir=r'%my_basedir%', verbose=True, architecture=%my_arch%, flavor='%my_flavor%', install_options=r'%my_install_options%', find_links=r'%my_find_links%', source_dirs=r'%my_source_dirs%', create_installer='%my_create_installer%', remove_existing=False, python_target_release='%my_python_target_release%')">>%my_archive_log%
-
-
-echo ----------------------------------------
-echo (%date% %time%) END OF creation
-echo ----------------------------------------
-echo ---------------------------------------- >>%my_archive_log%
-echo (%date% %time%) END OF creation>>%my_archive_log%
-echo ---------------------------------------- >>%my_archive_log%
-
-rem show logs
+echo -------------------------------------- >>%my_archive_log%
+echo "(%date% %time%) END OF CREATION">>%my_archive_log%
+echo -------------------------------------- >>%my_archive_log%
start notepad.exe %my_archive_log%
-
start notepad.exe %my_archive_log%.packages_versions.txt
-set path=%my_original_path%
-rem pause
+set path=%my_original_path%
\ No newline at end of file
diff --git a/generate_winpython_distros311_mkl.bat b/generate_winpython_distros311_mkl.bat
deleted file mode 100644
index 9f28bf24..00000000
--- a/generate_winpython_distros311_mkl.bat
+++ /dev/null
@@ -1,44 +0,0 @@
-rem 20230821 add a pre_step with my_requirements_pre.txt + my_find_links_pre
-rem this replace running manually from spyder the make.py
-rem to launch from a winpython module 'make' directory
-
-set my_original_path=%path%
-
-set my_root_dir_for_builds=C:\WinP
-set my_python_target=311
-set my_pyver=3.11
-
-set my_flavor=mkl
-
-set my_release=0
-
-set my_release_level=
-
-rem set my_create_installer=False
-set my_create_installer=nsis.zip
-set my_create_installer=7zip
-rem set my_create_installer=False
-
-set my_arch=64
-set my_preclear_build_directory=Yes
-
-set tmp_reqdir=%my_root_dir_for_builds%\bd%my_python_target%
-
-rem 20230821 add a requirement_pre.txt +
-set my_requirements_pre=C:\WinP\bd311\requirements_mkl_pre.txt
-set my_find_links_pre=C:\WinP\packages_mkl.srcreq
-
-rem just mkl = 204 Mo total
-
-set my_requirements=C:\WinP\bd311\requirements_mkl.txt
-set my_find_links=C:\WinP\packages.srcreq
-
-set my_source_dirs=C:\WinP\bd311\packages.win-amd64
-set my_toolsdirs=C:\WinP\bdTools\tools64
-set my_docsdirs=C:\WinP\bdDocs\docs
-set my_install_options=--no-index --pre --trusted-host=None
-
-call %~dp0\generate_a_winpython_distro.bat
-
-
-pause
\ No newline at end of file
diff --git a/generate_winpython_distros311_qt5.bat b/generate_winpython_distros311_qt5.bat
deleted file mode 100644
index b5640e7f..00000000
--- a/generate_winpython_distros311_qt5.bat
+++ /dev/null
@@ -1,37 +0,0 @@
-rem this replace running manually from spyder the make.py
-rem to launch from a winpython module 'make' directory
-
-set my_original_path=%path%
-
-set my_root_dir_for_builds=C:\WinP
-set my_python_target=311
-set my_pyver=3.11
-
-set my_flavor=
-
-set my_release=0
-
-set my_release_level=
-
-rem set my_create_installer=False
-set my_create_installer=nsis.zip
-set my_create_installer=7zip
-
-set my_arch=64
-set my_preclear_build_directory=Yes
-
-set tmp_reqdir=%my_root_dir_for_builds%\bd%my_python_target%
-
-set my_requirements=C:\WinP\bd311\Qt5_requirements64.txt
-
-set my_find_links=C:\WinP\packages.srcreq
-
-set my_source_dirs=C:\WinP\bd311\packages.win-amd64
-set my_toolsdirs=C:\WinP\bdTools\tools64
-set my_docsdirs=C:\WinP\bdDocs\docs
-set my_install_options=--no-index --pre --trusted-host=None
-
-call %~dp0\generate_a_winpython_distro.bat
-
-
-pause
\ No newline at end of file
diff --git a/generate_winpython_distros311_dot.bat b/generate_winpython_distros313_dot.bat
similarity index 58%
rename from generate_winpython_distros311_dot.bat
rename to generate_winpython_distros313_dot.bat
index 1fdd2ff8..b0ed9351 100644
--- a/generate_winpython_distros311_dot.bat
+++ b/generate_winpython_distros313_dot.bat
@@ -4,29 +4,26 @@ rem to launch from a winpython module 'make' directory
set my_original_path=%path%
set my_root_dir_for_builds=C:\Winp
-set my_python_target=311
-set my_pyver=3.11
-
+set my_python_target=313
+set my_pyver=3.13
set my_flavor=dot
+set my_arch=64
-set my_release=0
-
+rem settings delegated to generate_a_winpython_distro.bat
+set my_release=
set my_release_level=
-rem set my_create_installer=False
-set my_create_installer=nsis.zip
-set my_create_installer=7zip
+rem list of installers to create separated per dot: False=none, .zip=zip, .7z=.7z, 7zip=auto-extractible 7z
+set my_create_installer=7zip.7z.zip
-set my_arch=64
set my_preclear_build_directory=Yes
set tmp_reqdir=%my_root_dir_for_builds%\bd%my_python_target%
-set my_requirements=C:\Winp\bd311\dot_requirements.txt
+set my_requirements=C:\Winp\bd313\dot_requirements.txt
+set my_source_dirs=C:\Winp\bd313\packages.win-amd64
set my_find_links=C:\Winp\packages.srcreq
-
-set my_source_dirs=C:\Winp\bd311\packages.win-amd64
set my_toolsdirs=C:\Winp\bdTools\Tools.dot
set my_docsdirs=C:\WinP\bdDocs\docs.dot
@@ -35,12 +32,4 @@ set my_install_options=--no-index --pre --trusted-host=None
call %~dp0\generate_a_winpython_distro.bat
-set my_arch=32
-set my_preclear_build_directory=No
-
-set my_source_dirs=C:\Winp\bd311\packages.win32
-
-rem call %~dp0\generate_a_winpython_distro.bat
-
-
pause
\ No newline at end of file
diff --git a/generate_winpython_distros312_dot.bat b/generate_winpython_distros313_slim.bat
similarity index 55%
rename from generate_winpython_distros312_dot.bat
rename to generate_winpython_distros313_slim.bat
index b69e3090..7b7a1ffc 100644
--- a/generate_winpython_distros312_dot.bat
+++ b/generate_winpython_distros313_slim.bat
@@ -4,34 +4,32 @@ rem to launch from a winpython module 'make' directory
set my_original_path=%path%
set my_root_dir_for_builds=C:\Winp
-set my_python_target=312
-set my_pyver=3.12
-
-set my_flavor=dot
+set my_python_target=313
+set my_pyver=3.13
+set my_flavor=slim
+set my_arch=64
+rem settings delegated to generate_a_winpython_distro.bat
set my_release=
-
set my_release_level=
-rem set my_create_installer=False
-set my_create_installer=nsis.zip
-set my_create_installer=7zip
-
-rem 2024-07-14: ask both the 7zip auto executable and the .7z simple archive
+rem list of installers to create separated per dot: False=none, .zip=zip, .7z=.7z, 7zip=auto-extractible 7z
+rem set my_create_installer=7zip.7z.zip
set my_create_installer=7zip.7z
-
-set my_arch=64
set my_preclear_build_directory=Yes
set tmp_reqdir=%my_root_dir_for_builds%\bd%my_python_target%
-set my_requirements=C:\Winp\bd312\dot_requirements.txt
+set my_requirements=C:\Winp\bd313\requirements64_slim.txt
+set my_source_dirs=C:\Winp\bd313\packages.win-amd64
set my_find_links=C:\Winp\packages.srcreq
-
-set my_source_dirs=C:\Winp\bd312\packages.win-amd64
set my_toolsdirs=C:\Winp\bdTools\Tools.dot
+
+REM 2024-07-13:put back pandoc (so from 598Mo to 518Mo?)
+set my_toolsdirs=C:\WinP\bdTools\tools64_pandoc_alone
+
set my_docsdirs=C:\WinP\bdDocs\docs.dot
set my_install_options=--no-index --pre --trusted-host=None
@@ -39,12 +37,4 @@ set my_install_options=--no-index --pre --trusted-host=None
call %~dp0\generate_a_winpython_distro.bat
-set my_arch=32
-set my_preclear_build_directory=No
-
-set my_source_dirs=C:\Winp\bd312\packages.win32
-
-rem call %~dp0\generate_a_winpython_distro.bat
-
-
pause
\ No newline at end of file
diff --git a/generate_winpython_distros313_wheel.bat b/generate_winpython_distros313_wheel.bat
new file mode 100644
index 00000000..02edeb99
--- /dev/null
+++ b/generate_winpython_distros313_wheel.bat
@@ -0,0 +1,40 @@
+rem this replace running manually from spyder the make.py
+rem to launch from a winpython module 'make' directory
+
+set my_original_path=%path%
+
+set my_root_dir_for_builds=C:\Winp
+set my_python_target=313
+set my_pyver=3.13
+set my_flavor=whl
+set my_arch=64
+
+rem settings delegated to generate_a_winpython_distro.bat
+set my_release=
+set my_release_level=
+
+rem list of installers to create separated per dot: False=none, .zip=zip, .7z=.7z, 7zip=auto-extractible 7z
+set my_create_installer=7zip-mx5.7z-mx7.zip
+set my_create_installer=.7z-mx7
+
+set my_preclear_build_directory=Yes
+
+set tmp_reqdir=%my_root_dir_for_builds%\bd%my_python_target%
+
+set my_requirements=C:\Winp\bd313\dot_requirements.txt
+set my_source_dirs=C:\Winp\bd313\packages.win-amd64
+
+set my_find_links=C:\Winp\packages.srcreq
+set my_toolsdirs=C:\Winp\bdTools\Tools.dot
+set my_docsdirs=C:\WinP\bdDocs\docs.dot
+
+set my_install_options=--no-index --pre --trusted-host=None
+
+rem set addlockfile=dot
+
+set wheelhousereq=C:\Winp\bd313\requirements64_whl.txt
+
+
+call %~dp0\generate_a_winpython_distro.bat
+
+pause
diff --git a/hash.py b/hash.py
deleted file mode 100644
index 525ab1f8..00000000
--- a/hash.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
-Created on Tue Jun 23 21:30:06 2015
-
-@author: famille
-"""
-
-import io
-import os
-import sys
-import hashlib
-
-
-def give_hash(file_in, with_this):
- with io.open(file_in, 'rb') as f:
- return with_this(f.read()).hexdigest()
-
-def give_hashblake(file_in, with_this):
- with io.open(file_in, 'rb') as f:
- return with_this(f.read(),digest_size=32).hexdigest()
-
-
-if __name__ == '__main__':
- if len(sys.argv) < 2:
- print(
- "Usage: "
- + sys.argv[0]
- + " github-user [github-project]"
- )
- exit(1)
- file = sys.argv[1]
-
- header = (
- " MD5"
- + " " * (32 - 4)
- + " | SHA-1"
- + " " * (40 - 5)
- + " | SHA-256"
- + " " * (64 - 7)
- + " | Binary"
- + " " * (33 - 5)
- + "| Size"
- + " " * (20 - 6)
- #+ " | SHA3-256"
- #+ " " * (64 - 8)
- + " | blake2b-256"
- + " " * (64 - 11)
- )
- line = "|".join(
- ["-" * len(i) for i in header.split("|")]
- )
-
- print(header)
- print(line)
-
- print(""+
- f"{give_hash(file, hashlib.md5)} | " +
- f"{give_hash(file, hashlib.sha1)} | " +
- f"{give_hash(file, hashlib.sha256)} | " +
- f"{os.path.basename(file):33} |"+
- f"{os.path.getsize(file):13,}".replace(",", " ") + ' Bytes | ' +
- # f" | {give_hash(file, hashlib.sha3_256)}"
- f"{give_hashblake(file, hashlib.blake2b)}")
-
-
-
diff --git a/hash_launch.bat b/hash_launch.bat
index 08105e73..623765d7 100644
--- a/hash_launch.bat
+++ b/hash_launch.bat
@@ -1,8 +1,10 @@
-call C:\WPy64-3890\scripts\env.bat
+call C:\WinPdev\WPy64-310111\scripts\env.bat
cd %~dp0
rem echo %date% %time%>>gdc_counting.txt
-python hash.py %1 >>hash_counting_%date:/=_%.txt
+python -c "import sys;from winpython import hash; hash.print_hashes(sys.argv[1:])" %* >>hash_counting_%date:/=_%.txt
+rem python hash.py %* >>hash_counting_%date:/=_%.txt
start notepad.exe hash_counting_%date:/=_%.txt
+
\ No newline at end of file
diff --git a/make.py b/make.py
index 40640f42..ec75c078 100644
--- a/make.py
+++ b/make.py
@@ -1,271 +1,112 @@
# -*- coding: utf-8 -*-
#
+# WinPython build script
# Copyright © 2012 Pierre Raybaut
-# Copyright © 2014-2024+ The Winpython development team https://github.com/winpython/
+# Copyright © 2014-2025+ The Winpython development team https://github.com/winpython/
# Licensed under the terms of the MIT License
# (see winpython/__init__.py for details)
-"""
-WinPython build script
-Created on Sun Aug 12 11:17:50 2012
-"""
-
import os
import re
import shutil
import subprocess
import sys
from pathlib import Path
+from winpython import wppm, utils, diff
-from winpython import wppm, utils
-# Local imports
-import diff
-
-CHANGELOGS_DIR = Path(__file__).parent / "changelogs"
-PORTABLE_DIR = Path(__file__).parent / "portable"
-
-assert CHANGELOGS_DIR.is_dir(), f"Changelogs directory not found: {CHANGELOGS_DIR}"
-assert PORTABLE_DIR.is_dir(), f"Portable directory not found: {PORTABLE_DIR}"
+# Define constant paths for clarity
+CHANGELOGS_DIRECTORY = Path(__file__).parent / "changelogs"
+PORTABLE_DIRECTORY = Path(__file__).parent / "portable"
+NODEJS_RELATIVE_PATH = "n" # Relative path within WinPython dir
+# Ensure necessary directories exist at the start
+assert CHANGELOGS_DIRECTORY.is_dir(), f"Changelogs directory not found: {CHANGELOGS_DIRECTORY}"
+assert PORTABLE_DIRECTORY.is_dir(), f"Portable directory not found: {PORTABLE_DIRECTORY}"
def find_7zip_executable() -> str:
- """
- Locates the 7-Zip executable (7z.exe) in common installation directories.
-
- Raises:
- RuntimeError: If 7-Zip executable is not found.
-
- Returns:
- str: Path to the 7-Zip executable.
- """
- program_files_dirs = [
- Path(r"C:\Program Files"),
- Path(r"C:\Program Files (x86)"),
- Path(sys.prefix).parent.parent / "7-Zip",
- ]
- for base_dir in program_files_dirs:
- for subdir in [".", "App"]:
- exe_path = base_dir / subdir / "7-Zip" / "7z.exe"
- if exe_path.is_file():
- return str(exe_path)
+ """Locates the 7-Zip executable (7z.exe)."""
+ possible_program_files = [r"C:\Program Files", r"C:\Program Files (x86)", Path(sys.prefix).parent / "t"]
+ for base_dir in possible_program_files:
+ if (executable_path := Path(base_dir) / "7-Zip" / "7z.exe").is_file():
+ return str(executable_path)
raise RuntimeError("7ZIP is not installed on this computer.")
+def copy_items(source_directories: list[Path], target_directory: Path, verbose: bool = False):
+ """Copies items from source directories to the target directory."""
+ target_directory.mkdir(parents=True, exist_ok=True)
+ for source_dir in source_directories:
+ if not source_dir.is_dir():
+ print(f"Warning: Source directory not found: {source_dir}")
+ continue
+ for source_item in source_dir.iterdir():
+ target_item = target_directory / source_item.name
+ copy_function = shutil.copytree if source_item.is_dir() else shutil.copy2
+ try:
+ copy_function(source_item, target_item)
+ if verbose:
+ print(f"Copied: {source_item} -> {target_item}")
+ except Exception as e:
+ print(f"Error copying {source_item} to {target_item}: {e}")
-def replace_lines_in_file(filepath: Path, replacements: list[tuple[str, str]]):
- """
- Replaces lines in a file that start with a given prefix.
-
- Args:
- filepath: Path to the file to modify.
- replacements: A list of tuples, where each tuple contains:
- - The prefix of the line to replace (str).
- - The new text for the line (str).
- """
- lines: list[str] = []
- with open(filepath, "r") as f:
- lines = f.readlines()
-
- updated_lines = list(lines) # Create a mutable copy
-
- for index, line in enumerate(lines):
- for prefix, new_text in replacements:
- start_prefix = prefix
- if prefix not in ("Icon", "OutFile") and not prefix.startswith("!"):
- start_prefix = "set " + prefix
- if line.startswith(start_prefix + "="):
- updated_lines[index] = f"{start_prefix}={new_text}\n"
-
- with open(filepath, "w") as f:
- f.writelines(updated_lines)
- print(f"Updated 7-zip script: {filepath}")
-
-
-def build_installer_7zip(
- script_template_path: Path, output_script_path: Path, replacements: list[tuple[str, str]]
-):
- """
- Creates a 7-Zip installer script by copying a template and applying text replacements.
-
- Args:
- script_template_path: Path to the template 7-Zip script (.bat file).
- output_script_path: Path to save the generated 7-Zip script.
- replacements: A list of tuples for text replacements (prefix, new_text).
- """
- sevenzip_exe = find_7zip_executable()
- shutil.copy(script_template_path, output_script_path)
-
- # Standard replacements for all 7zip scripts
- data = [
- ("PORTABLE_DIR", str(PORTABLE_DIR)),
- ("SEVENZIP_EXE", sevenzip_exe),
- ] + replacements
-
- replace_lines_in_file(output_script_path, data)
-
- try:
- # Execute the generated 7-Zip script
- 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
- # with stdout=sys.stdout, we would not see 7zip compressing
- ) # Use subprocess.run for better error handling
- except subprocess.CalledProcessError as e:
- print(f"Error executing 7-Zip script: {e}", file=sys.stderr)
-
+def parse_list_argument(argument_value: str | list[str], separator=" ") -> list[str]:
+ """Parse a separated list argument into a list of strings."""
+ if not argument_value:
+ return []
+ return argument_value.split(separator) if isinstance(argument_value, str) else list(argument_value)
class WinPythonDistributionBuilder:
- """
- Builds a WinPython distribution.
- """
-
- JULIA_PATH_REL = r"\t\Julia\bin" # Relative path within WinPython dir
- NODEJS_PATH_REL = r"\n" # Relative path within WinPython dir
+ """Builds a WinPython distribution."""
- def __init__(
- self,
- build_number: int,
- release_level: str,
- target_dir: Path,
- wheels_dir: Path,
- tools_dirs: list[Path] = None,
- docs_dirs: list[Path] = None,
- verbose: bool = False,
- base_dir: Path = None,
- install_options: list[str] = None,
- flavor: str = "",
- ):
+ def __init__(self, build_number: int, release_level: str, target_directory: Path, wheels_directory: Path,
+ tools_directories: list[Path] = None, documentation_directories: list[Path] = None, verbose: bool = False,
+ base_directory: Path = None, install_options: list[str] = None, flavor: str = ""):
"""
Initializes the WinPythonDistributionBuilder.
-
Args:
build_number: The build number (integer).
release_level: The release level (e.g., "beta", "").
- target_dir: The base directory where WinPython will be created.
- wheels_dir: Directory containing wheel files for packages.
- tools_dirs: List of directories containing development tools to include.
- docs_dirs: List of directories containing documentation to include.
+ target_directory: The base directory where WinPython will be created.
+ wheels_directory: Directory containing wheel files for packages.
+ tools_directories: List of directories containing development tools to include.
+ documentation_directories: List of directories containing documentation to include.
verbose: Enable verbose output.
- base_dir: Base directory for building (optional, for relative paths).
+ base_directory: Base directory for building (optional, for relative paths).
install_options: Additional pip install options.
flavor: WinPython flavor (e.g., "Barebone").
"""
self.build_number = build_number
self.release_level = release_level
- self.target_dir = Path(target_dir) # Ensure Path object
- self.wheels_dir = Path(wheels_dir) # Ensure Path object
- self.tools_dirs = tools_dirs or []
- self.docs_dirs = docs_dirs or []
+ self.target_directory = Path(target_directory)
+ self.wheels_directory = Path(wheels_directory)
+ self.tools_directories = tools_directories or []
+ self.documentation_directories = documentation_directories or []
self.verbose = verbose
- self.winpy_dir: Path | None = None # Will be set during build
- self.distribution: wppm.Distribution | None = None # Will be set during build
- self.base_dir = base_dir
+ self.winpython_directory: Path | None = None
+ self.distribution: wppm.Distribution | None = None
+ self.base_directory = base_directory
self.install_options = install_options or []
self.flavor = flavor
self.python_zip_file: Path = self._get_python_zip_file()
- self.python_name = self.python_zip_file.stem # Filename without extension
- self.python_dir_name = "python" # Standardized Python directory name
+ self.python_name = self.python_zip_file.stem
+ self.python_directory_name = "python"
def _get_python_zip_file(self) -> Path:
- """
- Finds the Python zip file in the wheels directory.
-
- Returns:
- Path: Path to the Python zip file.
- Raises:
- RuntimeError: if no python zip file is found
- """
- patterns = [
- r"(pypy3|python-)([0-9]|[a-zA-Z]|.)*.zip", # PyPy pattern
- r"python-([0-9\.rcba]*)((\.|\-)amd64)?\.(zip|zip)", # Standard Python pattern
- ]
- for pattern in patterns:
- for filename in os.listdir(self.wheels_dir):
- if re.match(pattern, filename):
- return self.wheels_dir / filename
- raise RuntimeError(f"Could not find Python zip package in {self.wheels_dir}")
+ """Finds the Python .zip file in the wheels directory."""
+ for source_item in self.wheels_directory.iterdir():
+ if re.match(r"(pypy3|python-)([0-9]|[a-zA-Z]|.)*.zip", source_item.name):
+ return source_item
+ raise RuntimeError(f"Could not find Python zip package in {self.wheels_directory}")
@property
def package_index_markdown(self) -> str:
- """
- Generates a Markdown formatted package index page.
-
- Returns:
- str: Markdown content for the package index.
- """
- installed_tools_md = self._get_installed_tools_markdown()
- installed_packages_md = self._get_installed_packages_markdown()
- python_description = "Python programming language with standard library"
-
- return f"""## WinPython {self.winpyver2 + self.flavor}
-
-The following packages are included in WinPython-{self.architecture_bits}bit v{self.winpyver2 + self.flavor} {self.release_level}.
-
-
-
-### Tools
-
-Name | Version | Description
------|---------|------------
-{installed_tools_md}
-
-### Python packages
-
-Name | Version | Description
------|---------|------------
-[Python](http://www.python.org/) | {self.python_full_version} | {python_description}
-{installed_packages_md}
-
-
-"""
- def _get_installed_tools_markdown(self) -> str:
- """Generates Markdown for installed tools section in package index."""
- installed_tools = []
-
- def get_tool_path(rel_path):
- path = self.winpy_dir / rel_path if self.winpy_dir else None
- return path if path and (path.is_file() or path.is_dir()) else None
-
- julia_path = get_tool_path(self.JULIA_PATH_REL)
- if julia_path:
- julia_version = utils.get_julia_version(str(julia_path))
- installed_tools.append(("Julia", julia_version))
-
- nodejs_path = get_tool_path(self.NODEJS_PATH_REL)
- if nodejs_path:
- node_version = utils.get_nodejs_version(str(nodejs_path))
- installed_tools.append(("Nodejs", node_version))
- npm_version = utils.get_npmjs_version(str(nodejs_path))
- installed_tools.append(("npmjs", npm_version))
-
- pandoc_exe = get_tool_path(r"\t\pandoc.exe")
- if pandoc_exe:
- pandoc_version = utils.get_pandoc_version(str(pandoc_exe.parent))
- installed_tools.append(("Pandoc", pandoc_version))
-
- vscode_exe = get_tool_path(r"\t\VSCode\Code.exe")
- if vscode_exe:
- vscode_version = utils.getFileProperties(str(vscode_exe))["FileVersion"]
- installed_tools.append(("VSCode", vscode_version))
-
- tool_lines = []
- for name, version in installed_tools:
- metadata = utils.get_package_metadata("tools.ini", name)
- url, description = metadata["url"], metadata["description"]
- tool_lines.append(f"[{name}]({url}) | {version} | {description}")
- return "\n".join(tool_lines)
-
- def _get_installed_packages_markdown(self) -> str:
- """Generates Markdown for installed packages section in package index."""
- if self.distribution is None:
- return "" # Distribution not initialized yet.
- self.installed_packages = self.distribution.get_installed_packages(update=True)
- package_lines = [
- f"[{pkg.name}]({pkg.url}) | {pkg.version} | {pkg.description}"
- for pkg in sorted(self.installed_packages, key=lambda p: p.name.lower())
- ]
- return "\n".join(package_lines)
-
+ """Generates a Markdown formatted package index page."""
+ return self.distribution.generate_package_index_markdown(
+ self.python_executable_directory,
+ self.winpyver2,
+ self.flavor,
+ self.architecture_bits,
+ self.release_level
+ )
@property
def winpython_version_name(self) -> str:
@@ -274,147 +115,39 @@ def winpython_version_name(self) -> str:
@property
def python_full_version(self) -> str:
- """
- Retrieves the Python full version string from the distribution.
- Will be set after _extract_python is called and distribution is initialized.
- """
- if self.distribution is None:
- return "0.0.0" # Placeholder before initialization
- return utils.get_python_long_version(self.distribution.target)
-
+ """Retrieves the Python full version string from the distribution."""
+ return utils.get_python_long_version(self.distribution.target) if self.distribution else "0.0.0"
@property
- def python_executable_dir(self) -> str:
+ def python_executable_directory(self) -> str:
"""Returns the directory containing the Python executable."""
- python_path_dir = self.winpy_dir / self.python_dir_name if self.winpy_dir else None
- if python_path_dir and python_path_dir.is_dir():
- return str(python_path_dir)
- else:
- python_path_exe = self.winpy_dir / self.python_name if self.winpy_dir else None # Fallback for older structure
- return str(python_path_exe) if python_path_exe 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 # Default to 64 if distribution is not initialized yet
-
- @property
- def pre_path_entries(self) -> list[str]:
- """Returns a list of PATH entries to prepend to the environment."""
- return [
- r"Lib\site-packages\PyQt5",
- "", # Python root directory
- "DLLs",
- "Scripts",
- r"..\t",
- r".." + self.JULIA_PATH_REL,
- r".." + self.NODEJS_PATH_REL,
- ]
-
- @property
- def post_path_entries(self) -> list[str]:
- """Returns a list of PATH entries to append to the environment."""
- return []
+ return self.distribution.architecture if self.distribution else 64
- @property
- def tools_directories(self) -> list[Path]:
- """Returns the list of tools directories to include."""
- return self.tools_dirs
-
- @property
- def docs_directories(self) -> list[Path]:
- """Returns the list of documentation directories to include."""
- default_docs_dir = Path(__file__).resolve().parent / "docs"
- if default_docs_dir.is_dir():
- return [default_docs_dir] + self.docs_dirs
- return self.docs_dirs
-
- def create_batch_script(self, name: str, contents: str, replacements: list[tuple[str, str]] = None):
- """
- Creates a batch script in the WinPython scripts directory.
-
- Args:
- name: The name of the batch script file.
- contents: The contents of the batch script.
- replacements: A list of tuples for text replacements in the content.
- """
- script_dir = self.winpy_dir / "scripts" if self.winpy_dir else None
- if not script_dir:
- print("Warning: WinPython directory not set, cannot create batch script.")
- return
- script_dir.mkdir(parents=True, exist_ok=True)
- final_contents = contents
- if replacements:
- for old_text, new_text in replacements:
- final_contents = final_contents.replace(old_text, new_text)
- script_path = script_dir / name
- with open(script_path, "w") as f:
- f.write(final_contents)
- print(f"Created batch script: {script_path}")
-
- def create_python_launcher_batch(
- self,
- name: str,
- script_name: str,
- working_dir: str = None,
- options: str = None,
- command: str = None,
- ):
- """
- Creates a batch file to launch a Python script within the WinPython environment.
-
- Args:
- name: The name of the batch file.
- script_name: The name of the Python script to execute.
- working_dir: Optional working directory for the script.
- options: Optional command-line options for the script.
- command: Optional command to execute python, defaults to python.exe or pythonw.exe
- """
- options_str = f" {options}" if options else ""
- if command is None:
- command = '"%WINPYDIR%\\pythonw.exe"' if script_name.endswith(".pyw") else '"%WINPYDIR%\\python.exe"'
- change_dir_cmd = f"cd /D {working_dir}\n" if working_dir else ""
- script_name_str = f" {script_name}" if script_name else ""
- batch_content = f"""@echo off
-call "%~dp0env_for_icons.bat"
-{change_dir_cmd}{command}{script_name_str}{options_str} %*"""
- self.create_batch_script(name, batch_content)
-
- def create_installer_7zip(self, installer_type: str = ".exe"):
- """
- Creates a WinPython installer using 7-Zip.
-
- Args:
- installer_type: Type of installer to create (".exe", ".7z", ".zip").
- """
+ def create_installer_7zip(self, installer_type: str = "exe", compression= "mx5"):
+ """Creates a WinPython installer using 7-Zip: "exe", "7z", "zip")"""
self._print_action(f"Creating WinPython installer ({installer_type})")
- template_name = "installer_7zip.bat"
- output_name = "installer_7zip-tmp.bat" # temp file to avoid overwriting template
- if installer_type not in [".exe", ".7z", ".zip"]:
- print(f"Warning: Unsupported installer type '{installer_type}'. Defaulting to .exe")
- installer_type = ".exe"
-
- replacements = [
- ("DISTDIR", str(self.winpy_dir)),
- ("ARCH", str(self.architecture_bits)),
- ("VERSION", f"{self.python_full_version}.{self.build_number}{self.flavor}"),
- (
- "VERSION_INSTALL",
- f'{self.python_full_version.replace(".", "")}{self.build_number}',
- ),
- ("RELEASELEVEL", self.release_level),
- ("INSTALLER_OPTION", installer_type), # Pass installer type as option to bat script
- ]
-
- build_installer_7zip(
- PORTABLE_DIR / template_name,
- PORTABLE_DIR / output_name,
- replacements
- )
- self._print_action_done()
-
+ if installer_type not in ["exe", "7z", "zip"]:
+ return
+ DISTDIR = self.winpython_directory
+ filename_stem = f"Winpython{self.architecture_bits}-{self.python_full_version}.{self.build_number}{self.flavor}{self.release_level}"
+ fullfilename = DISTDIR.parent / (filename_stem + "." + installer_type)
+ sfx_option = "-sfx7z.sfx" if installer_type == "exe" else ""
+ zip_option = "-tzip" if installer_type == "zip" else ""
+ compress_level = "mx5" if compression == "" else compression
+ command = f'"{find_7zip_executable()}" {zip_option} -{compress_level} a "{fullfilename}" "{DISTDIR}" {sfx_option}'
+ print(f'Executing 7-Zip script: "{command}"')
+ try:
+ subprocess.run(command, 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)
def _print_action(self, text: str):
"""Prints an action message with progress indicator."""
@@ -423,795 +156,175 @@ def _print_action(self, text: str):
else:
print(f"{text}... ", end="", flush=True)
- def _print_action_done(self):
- """Prints "OK" to indicate action completion."""
- if not self.verbose:
- print("OK")
-
def _extract_python_archive(self):
"""Extracts the Python zip archive to create the base Python environment."""
self._print_action("Extracting Python archive")
- utils.extract_archive(
- str(self.python_zip_file),
- targetdir=str(self.winpy_dir), # Extract directly to winpy_dir
- )
- self._print_action_done()
+ utils.extract_archive(self.python_zip_file, self.winpython_directory)
# Relocate to /python subfolder if needed (for newer structure) #2024-12-22 to /python
- python_target_dir = self.winpy_dir / self.python_dir_name
- if self.python_dir_name != self.python_name and not python_target_dir.is_dir():
- os.rename(self.winpy_dir / self.python_name, python_target_dir)
+ expected_python_directory = self.winpython_directory / self.python_directory_name
+ if self.python_directory_name != self.python_name and not expected_python_directory.is_dir():
+ os.rename(self.winpython_directory / self.python_name, expected_python_directory)
+
+ def _copy_essential_files(self):
+ """Copies pre-made objects"""
+ self._print_action("Copying default scripts")
+ copy_items([PORTABLE_DIRECTORY / "scripts"], self.winpython_directory / "scripts", self.verbose)
+
+ self._print_action("Copying launchers")
+ copy_items([PORTABLE_DIRECTORY / "launchers_final"], self.winpython_directory, self.verbose)
+ docs_target_directory = self.winpython_directory / "notebooks" / "docs"
+ self._print_action(f"Copying documentation to {docs_target_directory}")
+ copy_items(self.documentation_directories, docs_target_directory, self.verbose)
- def _copy_tools(self):
- """Copies development tools to the WinPython 't' directory."""
- tools_target_dir = self.winpy_dir / "t"
- self._print_action(f"Copying tools to {tools_target_dir}")
- tools_target_dir.mkdir(parents=True, exist_ok=True)
- for source_dir in self.tools_directories:
- if not source_dir.is_dir():
- print(f"Warning: Tools directory not found: {source_dir}")
- continue
- for item_name in os.listdir(source_dir):
- source_item = source_dir / item_name
- target_item = tools_target_dir / item_name
- copy_func = shutil.copytree if source_item.is_dir() else shutil.copy2
- try:
- copy_func(source_item, target_item)
- if self.verbose:
- print(f" Copied: {source_item} -> {target_item}")
- except Exception as e:
- print(f"Error copying {source_item} to {target_item}: {e}")
+ tools_target_directory = self.winpython_directory / "t"
+ self._print_action(f"Copying tools to {tools_target_directory}")
+ copy_items(self.tools_directories, tools_target_directory, self.verbose)
- # Special handling for Node.js to move it up one level
- nodejs_current_dir = tools_target_dir / "n"
- nodejs_target_dir = self.winpy_dir / self.NODEJS_PATH_REL
- if nodejs_current_dir != nodejs_target_dir and nodejs_current_dir.is_dir():
+ if (nodejs_current_directory := tools_target_directory / "n").is_dir():
+ self._print_action(f"Moving tools from {nodejs_current_directory} to {tools_target_directory.parent / NODEJS_RELATIVE_PATH}")
try:
- shutil.move(nodejs_current_dir, nodejs_target_dir)
+ shutil.move(nodejs_current_directory, tools_target_directory.parent / NODEJS_RELATIVE_PATH)
except Exception as e:
print(f"Error moving Node.js directory: {e}")
- self._print_action_done()
-
-
- def _copy_documentation(self):
- """Copies documentation files to the WinPython 'docs' directory."""
- docs_target_dir = self.winpy_dir / "notebooks" / "docs"
- self._print_action(f"Copying documentation to {docs_target_dir}")
- docs_target_dir.mkdir(parents=True, exist_ok=True)
- for source_dir in self.docs_directories:
- if not source_dir.is_dir():
- print(f"Warning: Documentation directory not found: {source_dir}")
- continue
- for item_name in os.listdir(source_dir):
- source_item = source_dir / item_name
- target_item = docs_target_dir / item_name
- copy_func = shutil.copytree if source_item.is_dir() else shutil.copy2
- try:
- copy_func(source_item, target_item)
- if self.verbose:
- print(f" Copied: {source_item} -> {target_item}")
- except Exception as e:
- print(f"Error copying {source_item} to {target_item}: {e}")
- self._print_action_done()
-
-
- def _create_launchers(self):
- """Copies pre-made launchers to the WinPython directory."""
- self._print_action("Creating launchers")
- launchers_source_dir = PORTABLE_DIR / "launchers_final"
- for item in launchers_source_dir.rglob('*.exe'):
- shutil.copy2(item, self.winpy_dir)
- if self.verbose:
- print(f" Copied launcher: {item.name} -> {self.winpy_dir}")
- for item in launchers_source_dir.rglob('licence*.*'):
- shutil.copy2(item, self.winpy_dir)
- self._print_action_done()
-
-
def _create_initial_batch_scripts(self):
"""Creates initial batch scripts, including environment setup."""
self._print_action("Creating initial batch scripts")
-
- path_entries_str = ";".join([rf"%WINPYDIR%\{pth}" for pth in self.pre_path_entries])
- full_path_env_var = f"{path_entries_str};%PATH%;" + ";".join([rf"%WINPYDIR%\{pth}" for pth in self.post_path_entries])
-
- path_entries_ps_str = ";".join([rf"$env:WINPYDIR\\{pth}" for pth in self.pre_path_entries])
- full_path_ps_env_var = f"{path_entries_ps_str};$env:path;" + ";".join([rf"$env:WINPYDIR\\{pth}" for pth in self.post_path_entries])
-
# Replacements for batch scripts (PyPy compatibility)
- exe_name = self.distribution.short_exe if self.distribution else "python.exe" # default to python.exe if distribution is not yet set
- batch_replacements = [
- (r"DIR%\\python.exe", rf"DIR%\\{exe_name}"),
- (r"DIR%\\PYTHON.EXE", rf"DIR%\\{exe_name}"),
- ]
- if self.distribution and (Path(self.distribution.target) / r"lib-python\3\idlelib").is_dir():
- batch_replacements.append((r"\Lib\idlelib", r"\lib-python\3\idlelib"))
-
-
- env_bat_content = f"""@echo off
-set WINPYDIRBASE=%~dp0..
-
-rem get a normalized path
-set WINPYDIRBASETMP=%~dp0..
-pushd %WINPYDIRBASETMP%
-set WINPYDIRBASE=%__CD__%
-if "%WINPYDIRBASE:~-1%"=="\\" set WINPYDIRBASE=%WINPYDIRBASE:~0,-1%
-set WINPYDIRBASETMP=
-popd
-
-set WINPYDIR=%WINPYDIRBASE%\\{self.python_dir_name}
-rem 2019-08-25 pyjulia needs absolutely a variable PYTHON=%WINPYDIR%\\python.exe
-set PYTHON=%WINPYDIR%\\python.exe
-set PYTHONPATHz=%WINPYDIR%;%WINPYDIR%\\Lib;%WINPYDIR%\\DLLs
-set WINPYVER={self.winpython_version_name}
-
-rem 2023-02-12 utf-8 on console to avoid pip crash
-rem see https://github.com/pypa/pip/issues/11798#issuecomment-1427069681
-set PYTHONIOENCODING=utf-8
-rem set PYTHONUTF8=1 creates issues in "movable" patching
-
-set HOME=%WINPYDIRBASE%\\settings
-rem see https://github.com/winpython/winpython/issues/839
-rem set USERPROFILE=%HOME%
-set JUPYTER_DATA_DIR=%HOME%
-set JUPYTER_CONFIG_DIR=%WINPYDIR%\\etc\\jupyter
-set JUPYTER_CONFIG_PATH=%WINPYDIR%\\etc\\jupyter
-set FINDDIR=%WINDIR%\\system32
-echo ";%PATH%;" | %FINDDIR%\\find.exe /C /I ";%WINPYDIR%\\;" >nul
-if %ERRORLEVEL% NEQ 0 (
- set "PATH={full_path_env_var}"
- cd .
-)
-
-rem force default pyqt5 kit for Spyder if PyQt5 module is there
-if exist "%WINPYDIR%\\Lib\\site-packages\\PyQt5\\__init__.py" set QT_API=pyqt5
-"""
- self.create_batch_script("env.bat", env_bat_content, replacements=batch_replacements)
-
-
- ps1_content = r"""### WinPython_PS_Prompt.ps1 ###
-$0 = $myInvocation.MyCommand.Definition
-$dp0 = [System.IO.Path]::GetDirectoryName($0)
-# $env:PYTHONUTF8 = 1 would create issues in "movable" patching
-$env:WINPYDIRBASE = "$dp0\.."
-# get a normalize path
-# http://stackoverflow.com/questions/1645843/resolve-absolute-path-from-relative-path-and-or-file-name
-$env:WINPYDIRBASE = [System.IO.Path]::GetFullPath( $env:WINPYDIRBASE )
-
-# avoid double_init (will only resize screen)
-if (-not ($env:WINPYDIR -eq [System.IO.Path]::GetFullPath( $env:WINPYDIRBASE+""" + '"\\' + self.python_dir_name + '"' + r""")) ) {
-$env:WINPYDIR = $env:WINPYDIRBASE+""" + '"\\' + self.python_dir_name + '"' + r"""
-# 2019-08-25 pyjulia needs absolutely a variable PYTHON=%WINPYDIR%python.exe
-$env:PYTHON = "%WINPYDIR%\python.exe"
-$env:PYTHONPATHz = "%WINPYDIR%;%WINPYDIR%\Lib;%WINPYDIR%\DLLs"
-
-$env:WINPYVER = '""" + self.winpython_version_name + r"""'
-# rem 2023-02-12 try utf-8 on console
-# rem see https://github.com/pypa/pip/issues/11798#issuecomment-1427069681
-$env:PYTHONIOENCODING = "utf-8"
-
-$env:HOME = "$env:WINPYDIRBASE\settings"
-
-# rem read https://github.com/winpython/winpython/issues/839
-# $env:USERPROFILE = "$env:HOME"
-
-$env:WINPYDIRBASE = ""
-$env:JUPYTER_DATA_DIR = "$env:HOME"
-
-if (-not $env:PATH.ToLower().Contains(";"+ $env:WINPYDIR.ToLower()+ ";")) {
- $env:PATH = """ + '"' + full_path_ps_env_var + '"' + r""" }
-
-#rem force default pyqt5 kit for Spyder if PyQt5 module is there
-if (Test-Path "$env:WINPYDIR\Lib\site-packages\PyQt5\__init__.py") { $env:QT_API = "pyqt5" }
-
-# PyQt5 qt.conf creation and winpython.ini creation done via Winpythonini.py (called per env_for_icons.bat for now)
-# Start-Process -FilePath $env:PYTHON -ArgumentList ($env:WINPYDIRBASE + '\scripts\WinPythonIni.py')
-
-
-### Set-WindowSize
-
-Function Set-WindowSize {
-Param([int]$x=$host.ui.rawui.windowsize.width,
- [int]$y=$host.ui.rawui.windowsize.heigth,
- [int]$buffer=$host.UI.RawUI.BufferSize.heigth)
- $buffersize = new-object System.Management.Automation.Host.Size($x,$buffer)
- $host.UI.RawUI.BufferSize = $buffersize
- $size = New-Object System.Management.Automation.Host.Size($x,$y)
- $host.ui.rawui.WindowSize = $size
-}
-# Windows10 yelling at us with 150 40 6000
-# Set-WindowSize 195 40 6000
-
-### Colorize to distinguish
-$host.ui.RawUI.BackgroundColor = "Black"
-$host.ui.RawUI.ForegroundColor = "White"
-}
-"""
- self.create_batch_script("WinPython_PS_Prompt.ps1", ps1_content, replacements=batch_replacements)
-
- cmd_ps_bat_content = r"""@echo off
-call "%~dp0env_for_icons.bat"
-Powershell.exe -Command "& {Start-Process PowerShell.exe -ArgumentList '-ExecutionPolicy RemoteSigned -noexit -File ""%~dp0WinPython_PS_Prompt.ps1""'}"
-"""
- self.create_batch_script("cmd_ps.bat", cmd_ps_bat_content, replacements=batch_replacements)
-
-
- env_for_icons_bat_content = r"""@echo off
-call "%~dp0env.bat"
-
-rem default is as before: Winpython ..\Notebooks
-set WINPYWORKDIR=%WINPYDIRBASE%\Notebooks
-set WINPYWORKDIR1=%WINPYWORKDIR%
-
-rem if we have a file or directory in %1 parameter, we use that directory to define WINPYWORKDIR1
-if not "%~1"=="" (
- if exist "%~1" (
- if exist "%~1\" (
- rem echo it is a directory %~1
- set WINPYWORKDIR1=%~1
- ) else (
- rem echo it is a file %~1, so we take the directory %~dp1
- set WINPYWORKDIR1=%~dp1
- )
- )
-) else (
-rem if it is launched from another directory than icon origin , we keep it that one echo %__CD__%
-if not "%__CD__%"=="%~dp0" if not "%__CD__%scripts\"=="%~dp0" set WINPYWORKDIR1="%__CD__%"
-)
-rem remove potential doublequote
-set WINPYWORKDIR1=%WINPYWORKDIR1:"=%
-rem remove some potential last \
-if "%WINPYWORKDIR1:~-1%"=="\" set WINPYWORKDIR1=%WINPYWORKDIR1:~0,-1%
-
-rem you can use winpython.ini to change defaults
-FOR /F "delims=" %%i IN ('""%WINPYDIR%\python.exe" "%~dp0WinpythonIni.py""') DO set winpythontoexec=%%i
-%winpythontoexec%set winpythontoexec=
-
-
-rem Preventive Working Directories creation if needed
-if not "%WINPYWORKDIR%"=="" if not exist "%WINPYWORKDIR%" mkdir "%WINPYWORKDIR%"
-if not "%WINPYWORKDIR1%"=="" if not exist "%WINPYWORKDIR1%" mkdir "%WINPYWORKDIR1%"
-
-rem Change of directory only if we are in a launcher directory
-if "%__CD__%scripts\"=="%~dp0" cd/D %WINPYWORKDIR1%
-if "%__CD__%"=="%~dp0" cd/D %WINPYWORKDIR1%
-
-if not exist "%HOME%\.spyder-py%WINPYVER:~0,1%" mkdir "%HOME%\.spyder-py%WINPYVER:~0,1%"
-if not exist "%HOME%\.spyder-py%WINPYVER:~0,1%\workingdir" echo %HOME%\Notebooks>"%HOME%\.spyder-py%WINPYVER:~0,1%\workingdir"
-"""
- self.create_batch_script("env_for_icons.bat", env_for_icons_bat_content, replacements=batch_replacements)
-
-
- winpython_ini_py_content = r"""
-# Prepares a dynamic list of variables settings from a .ini file
-import os
-import subprocess
-from pathlib import Path
-
-winpython_inidefault=r'''
-[debug]
-state = disabled
-[inactive_environment_per_user]
-## > changing this segment to [active_environment_per_user] makes this segment of lines active or not
-HOME = %HOMEDRIVE%%HOMEPATH%\Documents\WinPython%WINPYVER%\settings
-USERPROFILE = %HOME%
-JUPYTER_DATA_DIR = %HOME%
-WINPYWORKDIR = %HOMEDRIVE%%HOMEPATH%\Documents\WinPython%WINPYVER%\Notebooks
-[inactive_environment_common]
-USERPROFILE = %HOME%
-[environment]
-## > Uncomment lines to override environment variables
-#JUPYTERLAB_SETTINGS_DIR = %HOME%\.jupyter\lab
-#JUPYTERLAB_WORKSPACES_DIR = %HOME%\.jupyter\lab\workspaces
-#R_HOME=%WINPYDIRBASE%\t\R
-#R_HOMEbin=%R_HOME%\bin\x64
-#JULIA_HOME=%WINPYDIRBASE%\t\Julia\bin\
-#JULIA_EXE=julia.exe
-#JULIA=%JULIA_HOME%%JULIA_EXE%
-#JULIA_PKGDIR=%WINPYDIRBASE%\settings\.julia
-#QT_PLUGIN_PATH=%WINPYDIR%\Lib\site-packages\pyqt5_tools\Qt\plugins
-'''
-
-def get_file(file_name):
- if file_name.startswith("..\\"):
- file_name = os.path.join(os.path.dirname(os.path.dirname(__file__)), file_name[3:])
- elif file_name.startswith(".\\"):
- file_name = os.path.join(os.path.dirname(__file__), file_name[2:])
- try:
- with open(file_name, 'r') as file:
- return file.read()
- except FileNotFoundError:
- if file_name[-3:] == 'ini':
- os.makedirs(Path(file_name).parent, exist_ok=True)
- with open(file_name, 'w') as file:
- file.write(winpython_inidefault)
- return winpython_inidefault
-
-def translate(line, env):
- parts = line.split('%')
- for i in range(1, len(parts), 2):
- if parts[i] in env:
- parts[i] = env[parts[i]]
- return ''.join(parts)
-
-def main():
- import sys
- args = sys.argv[1:]
- file_name = args[0] if args else "..\\settings\\winpython.ini"
-
- my_lines = get_file(file_name).splitlines()
- segment = "environment"
- txt = ""
- env = os.environ.copy() # later_version: env = os.environ
-
- # default directories (from .bat)
- os.makedirs(Path(env['WINPYDIRBASE']) / 'settings' / 'Appdata' / 'Roaming', exist_ok=True)
-
- # default qt.conf for Qt directories
- qt_conf='''echo [Paths]
- echo Prefix = .
- echo Binaries = .
- '''
-
- pathlist = [Path(env['WINPYDIR']) / 'Lib' / 'site-packages' / i for i in ('PyQt5', 'PyQt6', 'Pyside6')]
- for p in pathlist:
- if p.is_dir():
- if not (p / 'qt.conf').is_file():
- with open(p / 'qt.conf', 'w') as file:
- file.write(qt_conf)
-
- for l in my_lines:
- if l.startswith("["):
- segment = l[1:].split("]")[0]
- elif not l.startswith("#") and "=" in l:
- data = l.split("=", 1)
- if segment == "debug" and data[0].strip() == "state":
- data[0] = "WINPYDEBUG"
- if segment in ["environment", "debug", "active_environment_per_user", "active_environment_common"]:
- txt += f"set {data[0].strip()}={translate(data[1].strip(), env)}&& "
- env[data[0].strip()] = translate(data[1].strip(), env)
- if segment == "debug" and data[0].strip() == "state":
- txt += f"set WINPYDEBUG={data[1].strip()}&&"
-
- print(txt)
-
- # set potential directory
- for i in ('HOME', 'WINPYWORKDIR'):
- if i in env:
- os.makedirs(Path(env[i]), exist_ok=True)
- # later_version:
- # p = subprocess.Popen(["start", "cmd", "/k", "set"], shell = True)
- # p.wait() # I can wait until finished (although it too finishes after start finishes)
-
-if __name__ == "__main__":
- main()
- """
- self.create_batch_script("WinPythonIni.py", winpython_ini_py_content)
-
- self._print_action_done()
-
-
- def _create_standard_batch_scripts(self):
- """Creates standard WinPython batch scripts for various actions."""
- self._print_action("Creating standard batch scripts")
-
- exe_name = self.distribution.short_exe if self.distribution else "python.exe"
- batch_replacements = [
- (r"DIR%\\python.exe", rf"DIR%\\{exe_name}"),
- (r"DIR%\\PYTHON.EXE", rf"DIR%\\{exe_name}"),
- ]
- if self.distribution and (Path(self.distribution.target) / r"lib-python\3\idlelib").is_dir():
- batch_replacements.append((r"\Lib\idlelib", r"\lib-python\3\idlelib"))
-
-
- self.create_batch_script("readme.txt", """These batch files are required to run WinPython icons.
-These files should help the user writing his/her own
-The environment variables are set-up in 'env.bat' and 'env_for_icons.bat'.""",
- )
-
- self.create_batch_script(
- "make_winpython_movable.bat",
- r"""@echo off
-call "%~dp0env.bat"
-echo patch pip and current launchers for move
-
-"%WINPYDIR%\python.exe" -c "from winpython import wppm;dist=wppm.Distribution(r'%WINPYDIR%');dist.patch_standard_packages('pip', to_movable=True)"
-pause""",
- replacements=batch_replacements
- )
-
- self.create_batch_script(
- "make_winpython_fix.bat",
- r"""@echo off
-call "%~dp0env.bat"
-echo patch pip and current launchers for non-move
-
-"%WINPYDIR%\python.exe" -c "from winpython import wppm;dist=wppm.Distribution(r'%WINPYDIR%');dist.patch_standard_packages('pip', to_movable=False)"
-pause""",
- replacements=batch_replacements
- )
-
- for ini_patch_script in [
- ("make_working_directory_be_not_winpython.bat", "[active_environment", "[inactive_environment", "[inactive_environment_per_user]", "[active_environment_per_user]"),
- ("make_working_directory_be_winpython.bat", "[active_environment", "[inactive_environment"),
- ("make_working_directory_and_userprofile_be_winpython.bat", "[active_environment", "[inactive_environment", "[inactive_environment_common]", "[active_environment_common]")
- ]:
- name, patch1_start, patch1_end, *patch2 = ini_patch_script
- content = f"""call "%~dp0env_for_icons.bat"
-"%PYTHON%" -c "from winpython.utils import patch_sourcefile;patch_sourcefile(r'%~dp0..\\settings\winpython.ini', '{patch1_start}', '{patch1_end}' )"
-"""
- if patch2:
- content += f""""%PYTHON%" -c "from winpython.utils import patch_sourcefile;patch_sourcefile(r'%~dp0..\\settings\winpython.ini', '{patch2[0]}', '{patch2[1]}' )" """
- self.create_batch_script(name, content)
-
-
- self.create_batch_script("cmd.bat", r"""@echo off
-call "%~dp0env_for_icons.bat" %*
-cmd.exe /k""", replacements=batch_replacements)
-
- self.create_batch_script("WinPython_Terminal.bat", r"""@echo off
-Powershell.exe -Command "& {Start-Process PowerShell.exe -ArgumentList '-ExecutionPolicy RemoteSigned -noexit -File ""%~dp0WinPython_PS_Prompt.ps1""'}"
-exit""", replacements=batch_replacements)
-
- self.create_batch_script("python.bat", r"""@echo off
-call "%~dp0env_for_icons.bat" %*
-"%WINPYDIR%\python.exe" %*""", replacements=batch_replacements)
-
- self.create_batch_script(
- "winpython.bat",
- r"""@echo off
-call "%~dp0env_for_icons.bat" %*
-rem backward compatibility for non-ptpython users
-if exist "%WINPYDIR%\scripts\ptpython.exe" (
- "%WINPYDIR%\scripts\ptpython.exe" %*
-) else (
- "%WINPYDIR%\python.exe" %*
-)""",
- replacements=batch_replacements
- )
-
- self.create_batch_script(
- "winidle.bat",
- r"""@echo off
-call "%~dp0env_for_icons.bat" %*
-"%WINPYDIR%\python.exe" "%WINPYDIR%\Lib\idlelib\idle.pyw" %*""",
- replacements=batch_replacements
- )
-
- self.create_batch_script(
- "winspyder.bat",
- r"""@echo off
-call "%~dp0env_for_icons.bat" %*
-"%WINPYDIR%\scripts\spyder.exe" %* -w "%WINPYWORKDIR1%" """,
- )
-
- self.create_batch_script(
- "spyder_reset.bat",
- r"""@echo off
-call "%~dp0env_for_icons.bat"
-"%WINPYDIR%\scripts\spyder.exe" --reset %*""",
- )
-
- for jupyter_script in [
- ("winipython_notebook.bat", "jupyter-notebook.exe"),
- ("winjupyter_lab.bat", "jupyter-lab.exe"),
- ("winqtconsole.bat", "jupyter-qtconsole.exe"),
- ]:
- name, exe = jupyter_script
- self.create_batch_script(name, f"""@echo off
-call "%~dp0env_for_icons.bat" %*
-"%WINPYDIR%\\scripts\\{exe}" %*""")
-
-
- self.create_python_launcher_batch(
- "register_python.bat",
- r'"%WINPYDIR%\Lib\site-packages\winpython\register_python.py"',
- working_dir=r'"%WINPYDIR%\Scripts"',
- )
-
- self.create_python_launcher_batch(
- "unregister_python.bat",
- r'"%WINPYDIR%\Lib\site-packages\winpython\unregister_python.py"',
- working_dir=r'"%WINPYDIR%\Scripts"',
- )
-
- for register_all_script in [
- ("register_python_for_all.bat", "register_python.bat"),
- ("unregister_python_for_all.bat", "unregister_python.bat"),
- ]:
- name, base_script = register_all_script
- self.create_batch_script(name, f"""@echo off
-call "%~dp0env.bat"
-call "%~dp0{base_script}" --all""")
-
-
- self.create_batch_script("wpcp.bat", r"""@echo off
-call "%~dp0env_for_icons.bat" %*
-cmd.exe /k "echo wppm & wppm" """, replacements=batch_replacements)
-
- self.create_batch_script(
- "upgrade_pip.bat",
- r"""@echo off
-call "%~dp0env.bat"
-echo this will upgrade pip with latest version, then patch it for WinPython portability ok ?
-pause
-"%WINPYDIR%\python.exe" -m pip install --upgrade pip
-"%WINPYDIR%\python.exe" -c "from winpython import wppm;dist=wppm.Distribution(r'%WINPYDIR%');dist.patch_standard_packages('pip', to_movable=True)
-pause""",
- replacements=batch_replacements
- )
-
- self.create_batch_script("activate.bat", r"""@echo off
-call "%~dp0env.bat" %*""", replacements=batch_replacements)
-
-
- vscode_bat_content = r"""@echo off
-call "%~dp0env_for_icons.bat"
-if exist "%WINPYDIR%\..\t\vscode\code.exe" (
- "%WINPYDIR%\..\t\vscode\code.exe" %*
-) else (
-if exist "%LOCALAPPDATA%\Programs\Microsoft VS Code\code.exe" (
- "%LOCALAPPDATA%\Programs\Microsoft VS Code\code.exe" %*
-) else (
- "code.exe" %*
-))"""
- self.create_batch_script("winvscode.bat", vscode_bat_content)
-
- self._print_action_done()
-
-
- def build(self, remove_existing: bool = True, requirements=None, winpy_dirname: str = None):
- """Make WinPython distribution in target directory from the installers
- located in wheels_dir
-
- remove_existing=True: (default) install all from scratch
- remove_existing=False: for complementary purposes (create installers)
- requirements=file(s) of requirements (separated by space if several)"""
- python_zip_filename = self.python_zip_file.name
- print(f"Building WinPython with Python archive: {python_zip_filename}")
-
+ executable_name = self.distribution.short_exe if self.distribution else "python.exe" # default to python.exe if distribution is not yet set
+ init_variables = [('WINPYthon_exe', executable_name), ('WINPYthon_subdirectory_name', self.python_directory_name), ('WINPYVER', self.winpython_version_name)]
+ init_variables += [('WINPYVER2', f"{self.python_full_version}.{self.build_number}"), ('WINPYFLAVOR', self.flavor), ('WINPYARCH', self.architecture_bits)]
+ with open(self.winpython_directory / "scripts" / "env.ini", "w") as f:
+ f.writelines([f'{a}={b}\n' for a, b in init_variables])
+
+ def build(self, rebuild: bool = True, requirements_files_list=None, winpy_dirname: str = None):
+ """Make or finalise WinPython distribution in the target directory"""
+ print(f"Building WinPython with Python archive: {self.python_zip_file.name}")
if winpy_dirname is None:
- raise RuntimeError("WinPython base directory to create is undefined")
- else:
- self.winpy_dir = self.target_dir / winpy_dirname # Create/re-create the WinPython base directory
- self._print_action(f"Creating WinPython {self.winpy_dir} base directory")
- if self.winpy_dir.is_dir() and remove_existing:
- try:
- shutil.rmtree(self.winpy_dir, onexc=utils.onerror)
- except TypeError: # before 3.12
- shutil.rmtree(self.winpy_dir, onerror=utils.onerror)
- os.makedirs(self.winpy_dir, exist_ok=True)
- if remove_existing:
+ raise RuntimeError("WinPython base directory to create is undefined")
+ self.winpython_directory = self.target_directory / winpy_dirname
+
+ if rebuild:
+ self._print_action(f"Creating WinPython {self.winpython_directory} base directory")
+ if self.winpython_directory.is_dir():
+ shutil.rmtree(self.winpython_directory)
+ os.makedirs(self.winpython_directory, exist_ok=True)
# preventive re-Creation of settings directory
- # (necessary if user is starting an application with a batch)
- (self.winpy_dir / "settings" / "AppData" / "Roaming").mkdir(parents=True, exist_ok=True) # Ensure settings dir exists
+ (self.winpython_directory / "settings" / "AppData" / "Roaming").mkdir(parents=True, exist_ok=True)
self._extract_python_archive()
- self._print_action_done()
- self.distribution = wppm.Distribution(
- self.python_executable_dir,
- verbose=self.verbose,
- indent=True,
- )
+ self.distribution = wppm.Distribution(self.python_executable_directory, verbose=self.verbose)
- if remove_existing:
+ if rebuild:
+ self._copy_essential_files()
self._create_initial_batch_scripts()
- self._create_standard_batch_scripts()
- self._create_launchers()
- utils.python_execmodule("ensurepip", self.distribution.target) # Ensure pip is installed for PyPy
+ utils.python_execmodule("ensurepip", self.distribution.target)
self.distribution.patch_standard_packages("pip")
- # Upgrade essential packages
essential_packages = ["pip", "setuptools", "wheel", "winpython"]
for package_name in essential_packages:
actions = ["install", "--upgrade", "--pre", package_name] + self.install_options
- print(f"Piping: {' '.join(actions)}")
self._print_action(f"Piping: {' '.join(actions)}")
self.distribution.do_pip_action(actions)
self.distribution.patch_standard_packages(package_name)
- self._copy_tools()
- self._copy_documentation()
-
- if requirements:
- if not list(requirements) == requirements:
- requirements = requirements.split()
- for req in requirements:
- actions = ["install", "-r", req]
- if self.install_options is not None:
- actions += self.install_options
- print(f"piping {' '.join(actions)}")
- self._print_action(f"piping {' '.join(actions)}")
- self.distribution.do_pip_action(actions)
-
+ if requirements_files_list:
+ for req in requirements_files_list:
+ actions = ["install", "-r", req] + (self.install_options or [])
+ self._print_action(f"Piping: {' '.join(actions)}")
+ self.distribution.do_pip_action(actions)
self.distribution.patch_standard_packages()
- self._print_action("Cleaning up distribution")
- self.distribution.clean_up()
- self._print_action_done()
- # Writing package index
self._print_action("Writing package index")
- # winpyver2 = the version without build part but with self.distribution.architecture
self.winpyver2 = f"{self.python_full_version}.{self.build_number}"
- fname = str(
- self.winpy_dir.parent
- / (
- f"WinPython{self.flavor}-"
- + f"{self.distribution.architecture}bit-"
- + f"{self.winpyver2}.md"
- )
- )
- open(fname, "w", encoding='utf-8').write(self.package_index_markdown)
- # Copy to winpython/changelogs
+ output_markdown_filename = str(self.winpython_directory.parent / f"WinPython{self.flavor}-{self.distribution.architecture}bit-{self.winpyver2}.md")
+ with open(output_markdown_filename, "w", encoding='utf-8') as f:
+ f.write(self.package_index_markdown)
- shutil.copyfile(
- fname,
- str(Path(CHANGELOGS_DIR) / Path(fname).name),
- )
- self._print_action_done()
-
- # Writing changelog
self._print_action("Writing changelog")
- diff.write_changelog(
- self.winpyver2,
- basedir=self.base_dir,
- flavor=self.flavor,
- release_level=self.release_level,
- architecture=self.distribution.architecture,
- )
- self._print_action_done()
-
+ shutil.copyfile(output_markdown_filename, str(Path(CHANGELOGS_DIRECTORY) / Path(output_markdown_filename).name))
+ diff.write_changelog(self.winpyver2, None, CHANGELOGS_DIRECTORY, self.flavor, self.distribution.architecture, basedir=self.winpython_directory.parent)
-def rebuild_winpython_package(source_dir: Path, target_dir: Path, architecture: int = 64, verbose: bool = False):
+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_dir):
- if filename.startswith("winpython-") and filename.endswith((".exe", ".whl", ".gz")):
- os.remove(Path(target_dir) / filename)
-
- utils.buildflit_wininst(
- str(source_dir),
- copy_to=str(target_dir),
- verbose=verbose,
- )
-
-
-def _parse_list_argument(arg_value: str | list[str]) -> list[str]:
- """Parses a string or list argument into a list of strings."""
- if arg_value is None:
- return []
- if isinstance(arg_value, str):
- return arg_value.split()
- return list(arg_value) # Ensure it's a list if already a list-like object
-
-
-def make_all(
- build_number: int,
- release_level: str,
- pyver: str,
- architecture: int,
- basedir: Path,
- verbose: bool = False,
- remove_existing: bool = True,
- create_installer: str = "True",
- install_options=["--no-index"],
- flavor: str = "",
- requirements: str | list[Path] = None,
- find_links: str | list[Path] = None,
- source_dirs: Path = None,
- toolsdirs: str | list[Path] = None,
- docsdirs: str | list[Path] = None,
- python_target_release: str = None, # e.g. "37101" for 3.7.10
+ 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=True)
+
+def make_all(build_number: int, release_level: str, pyver: str, architecture: int, basedir: Path,
+ verbose: bool = False, rebuild: bool = True, create_installer: str = "True", install_options=["--no-index"],
+ flavor: str = "", requirements: str | list[Path] = None, find_links: str | list[Path] = None,
+ source_dirs: Path = None, toolsdirs: str | list[Path] = None, docsdirs: str | list[Path] = None,
+ python_target_release: str = None, # e.g. "37101" for 3.7.10
):
- """Make WinPython distribution, for a given base directory and
- architecture:
- `build_number`: build number [int]
- `release_level`: release level (e.g. 'beta1', '') [str]
- `pyver`: python version ('3.4' or 3.5')
- `architecture`: [int] (32 or 64)
- `basedir`: where will be created tmp_wheel and Winpython build
- r'D:\Winpython\basedir34'.
- `requirements`: the package list for pip r'D:\requirements.txt',
- `install_options`: pip options r'--no-index --pre --trusted-host=None',
- `find_links`: package directories r'D:\Winpython\packages.srcreq',
- `source_dirs`: the python.zip + rebuilt winpython wheel package directory,
- `toolsdirs`: r'D:\WinPython\basedir34\t.Slim',
- `docsdirs`: r'D:\WinPython\basedir34\docs.Slim'"""
-
+ """
+ Make a WinPython distribution for a given set of parameters:
+ Args:
+ build_number: build number [int]
+ release_level: release level (e.g. 'beta1', '') [str]
+ pyver: python version ('3.4' or 3.5')
+ architecture: [int] (32 or 64)
+ basedir: where to create the build (r'D:\Winpython\basedir34')
+ verbose: Enable verbose output (bool).
+ rebuild: Whether to rebuild the distribution (bool).
+ create_installer: Type of installer to create (str).
+ install_options: pip options (r'--no-index --pre --trusted-host=None')
+ flavor: WinPython flavor (str).
+ requirements: package lists for pip (r'D:\requirements.txt')
+ find_links: package directories (r'D:\Winpython\packages.srcreq')
+ source_dirs: the python.zip + rebuilt winpython wheel package directory
+ toolsdirs: Directory with development tools r'D:\WinPython\basedir34\t.Slim'
+ docsdirs: Directory with documentation r'D:\WinPython\basedir34\docs.Slim'
+ python_target_release: Target Python release (str).
+ """
assert basedir is not None, "The *basedir* directory must be specified"
assert architecture in (32, 64)
- utils.print_box(
- f"Making WinPython {architecture}bits"
- + f" at {Path(basedir) / ('bu' + flavor)}"
- )
-
- # Create Build director, where Winpython will be constructed
- builddir = str(Path(basedir) / ("bu" + flavor))
- os.makedirs(Path(builddir), exist_ok=True)
- # use source_dirs as the directory to re-build Winpython wheel
- wheels_dir = source_dirs
- # Rebuild WinPython package
- winpython_source_dir = Path(__file__).resolve().parent
- rebuild_winpython_package(
- source_dir=winpython_source_dir,
- target_dir=wheels_dir,
- architecture=architecture,
- verbose=verbose,
- )
+ tools_dirs_list = parse_list_argument(toolsdirs, ",")
+ docs_dirs_list = parse_list_argument(docsdirs, ",")
+ install_options_list = parse_list_argument(install_options, " ")
+ 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 = Path(basedir) / ("bu" + flavor)
+
+ if rebuild:
+ utils.print_box(f"Making WinPython {architecture}bits at {Path(basedir) / ('bu' + flavor)}")
+ 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, Path(source_dirs), architecture, verbose)
- # Parse list arguments
- tools_dirs_list = _parse_list_argument(toolsdirs)
- docs_dirs_list = _parse_list_argument(docsdirs)
- install_options_list = _parse_list_argument(install_options)
- find_links_dirs_list = _parse_list_argument(find_links)
- requirements_files_list = [Path(f) for f in _parse_list_argument(requirements) if f] # ensure Path objects
-
- find_links_options = [f"--find-links={link}" for link in find_links_dirs_list + [wheels_dir]]
builder = WinPythonDistributionBuilder(
- build_number,
- release_level,
- builddir,
- wheels_dir=wheels_dir,
- tools_dirs=[Path(d) for d in tools_dirs_list],
- docs_dirs=[Path(d) for d in docs_dirs_list],
- verbose=verbose,
- base_dir=basedir,
+ build_number, release_level, build_directory, wheels_directory=source_dirs,
+ tools_directories=[Path(d) for d in tools_dirs_list],
+ documentation_directories=[Path(d) for d in docs_dirs_list],
+ verbose=verbose, base_directory=basedir,
install_options=install_options_list + find_links_options,
- flavor=flavor,
+ flavor=flavor
)
- # define a pre-defined winpydir, instead of having to guess
-
- # extract the python subversion to get WPy64-3671b1
- my_x = "".join(builder.python_name.replace(".amd64", "").split(".")[-2:-1])
- while not my_x.isdigit() and len(my_x) > 0:
- my_x = my_x[:-1]
+ # define the directory where to create the distro
+ python_minor_version_str = "".join(builder.python_name.replace(".amd64", "").split(".")[-2:-1])
+ while not python_minor_version_str.isdigit() and len(python_minor_version_str) > 0:
+ python_minor_version_str = python_minor_version_str[:-1]
# simplify for PyPy
- if not python_target_release == None:
- winpy_dirname = (
- "WPy"
- + f"{architecture}"
- + "-"
- + python_target_release
- + ""
- + f"{build_number}"
- ) + release_level
- # + flavor
+ if python_target_release is not None:
+ winpython_dirname = f"WPy{architecture}-{python_target_release}{build_number}{release_level}"
else:
- winpy_dirname = (
- "WPy"
- + f"{architecture}"
- + "-"
- + pyver.replace(".", "")
- + ""
- + my_x
- + ""
- + f"{build_number}"
- ) + release_level
- # + flavor
-
- builder.build(
- remove_existing=remove_existing,
- requirements=requirements_files_list,
- winpy_dirname=winpy_dirname,
- )
- if str(create_installer).lower() != "false":
- if ".zip" in str(create_installer).lower():
- builder.create_installer_7zip(".zip")
- if ".7z" in str(create_installer).lower():
- builder.create_installer_7zip(".7z")
- if "7zip" in str(create_installer).lower():
- builder.create_installer_7zip(".exe")
+ winpython_dirname = f"WPy{architecture}-{pyver.replace('.', '')}{python_minor_version_str}{build_number}{release_level}"
- return builder
+ builder.build(rebuild=rebuild, requirements_files_list=requirements_files_list, winpy_dirname=winpython_dirname)
+ for commmand in create_installer.lower().replace("7zip",".exe").split('.'):
+ installer_type, compression = (commmand + "-").split("-")[:2]
+ builder.create_installer_7zip(installer_type, compression)
if __name__ == "__main__":
- # DO create only one version at a time
- # You may have to manually delete previous build\winpython-.. directory
-
+ # DO create only one Winpython distribution at a time
make_all(
- 1,
+ build_number=1,
release_level="build3",
pyver="3.4",
basedir=r"D:\Winpython\basedir34",
@@ -1224,4 +337,4 @@ def make_all(
source_dirs=r"D:\WinPython\basedir34\packages.win-amd64",
toolsdirs=r"D:\WinPython\basedir34\t.Slim",
docsdirs=r"D:\WinPython\basedir34\docs.Slim",
- )
\ No newline at end of file
+ )
diff --git a/portable/build_my_launchers.bat b/portable/build_my_launchers.bat
index 04c4671e..579a96e6 100644
--- a/portable/build_my_launchers.bat
+++ b/portable/build_my_launchers.bat
@@ -7,21 +7,26 @@ set VCVARS_PATH="C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\
rem pick the right ones and rename them in launchers_final
set do_launcher=%~dp0launchers_src\build_one_launcher.bat
+set do_launcher_original=%~dp0launchers_src_original\build_one_launcher.bat
::WINDOWS launchers
-call %do_launcher% "powershell.ico" "cmd_ps.bat" "WinPython Powershell Prompt" WINDOWS
+rem call %do_launcher% "python.ico" "winidle.bat" "IDLE (Python GUI)" WINDOWS proposed
+echo displace this pause if you want to re-build more
pause
-call %do_launcher% "python.ico" "winidle.bat" "IDLE (Python GUI)" WINDOWS
-call %do_launcher% "spyder.ico" "winspyder.bat" "Spyder" WINDOWS
-call %do_launcher% "spyder_reset.ico" "spyder_reset.bat" "Spyder reset" WINDOWS
-call %do_launcher% "code.ico" "winvscode.bat" "VS Code" WINDOWS
+rem exit
+
+
+call %do_launcher% "powershell.ico" "cmd_ps.bat" "WinPython Powershell Prompt" WINDOWS proposed
+call %do_launcher% "spyder.ico" "winspyder.bat" "Spyder" WINDOWS proposed
+call %do_launcher% "spyder_reset.ico" "spyder_reset.bat" "Spyder reset" WINDOWS proposed
+call %do_launcher% "code.ico" "winvscode.bat" "VS Code" WINDOWS proposed
:: CONSOLE launchers
-call %do_launcher% "cmd.ico" "cmd.bat" "WinPython Command Prompt" CONSOLE
-call %do_launcher% "python.ico" "winpython.bat" "WinPython Interpreter" CONSOLE
-call %do_launcher% "jupyter.ico" "winipython_notebook.bat" "Jupyter Notebook" CONSOLE
-call %do_launcher% "jupyter.ico" "winjupyter_lab.bat" "Jupyter Lab" CONSOLE
-call %do_launcher% "winpython.ico" "wpcp.bat" "WinPython Control Panel" CONSOLE
+call %do_launcher% "cmd.ico" "cmd.bat" "WinPython Command Prompt" CONSOLE proposed
+call %do_launcher% "python.ico" "winpython.bat" "WinPython Interpreter" CONSOLE proposed
+call %do_launcher% "jupyter.ico" "winipython_notebook.bat" "Jupyter Notebook" CONSOLE proposed
+call %do_launcher% "jupyter.ico" "winjupyter_lab.bat" "Jupyter Lab" CONSOLE proposed
+call %do_launcher% "winpython.ico" "wpcp.bat" "WinPython Control Panel" CONSOLE proposed
pause
diff --git a/portable/installer_7zip.bat b/portable/installer_7zip.bat
deleted file mode 100644
index 0b308f2a..00000000
--- a/portable/installer_7zip.bat
+++ /dev/null
@@ -1,78 +0,0 @@
-rem Copyright @ 2018 WinPython team
-rem Licensed under the terms of the MIT License
-rem (see winpython/__init__.py for details)
-
-rem This is to do a 7-zip installer
-
-rem ================================================================
-rem These lines are automatically replaced when creating installer:
-rem (see winpython/make.py)
-set SEVENZIP_EXE=C:\Program Files (x86)\7-Zip\7z
-set DISTDIR=C:\WinP\bd36\buPs2\winp64-3.6.x.0
-set ARCH=64
-set VERSION=3.6.7.0Ps2
-
-rem 2018-04-04 need to minimize path length of installation further: remove flavor in install path
-
-set VERSION_INSTALL=3670
-
-set RELEASELEVEL=beta3
-set PORTABLE_DIR=C:\WinPython-64bit-3.4.3.7Qt5\winpython_github20181029\portable
-set INSTALLER_OPTION=.exe
-
-rem ================================================================
-rem these lines are static definitions
-set ID=Winpython
-set ID_INSTALL=WPy
-set FILE_DESCRIPTION=%ID% Installer
-set COMPANY=%ID%
-set BRANDING=%ID%, the portable Python Distribution for Scientists
-set COPYRIGHT=Copyright © 2018+ WinPython Team
-set MyAppPublisher=WinPython team
-set MyAppURL=https://winpython.github.io/
-
-rem OutputBaseFilename "{#ID}{#ARCH}-{#VERSION}{#RELEASELEVEL}"
-
-rem ================================================================ [Setup]
-rem OutFile "${DISTDIR}\..\${ID}${ARCH}-${VERSION}${RELEASELEVEL}.exe"
-set MyBinaryOutputDir=%DISTDIR%\..
-set OutputBaseFilename=%ID%%ARCH%-%VERSION%%RELEASELEVEL%
-
-rem 7-zip uncompress the directory compressed %DISTDIR% (no option to change it in gui)
-
-rem ================================================================
-rem 2019-03-16 copy license at source (due to 7zip limitations)
-
-REM 2025-01-05 done in make.py
-rem copy/Y %PORTABLE_DIR%\license.txt %DISTDIR%\license.txt
-
-rem ================================================================
-
-echo %time%
-
-rem compression + include auto_extract in GUI mode
-if "%INSTALLER_OPTION%"==".exe" (
- "%SEVENZIP_EXE%" -mx5 a "%MyBinaryOutputDir%\%OutputBaseFilename%.exe" %DISTDIR% -sfx7z.sfx
- echo autoextract using command line options
- echo "%MyBinaryOutputDir%\%OutputBaseFilename%.exe" -y -o%MyBinaryOutputDir%\zz > NUL
- )
-
-if "%INSTALLER_OPTION%"==".7z" (
- "%SEVENZIP_EXE%" -mx5 a "%MyBinaryOutputDir%\%OutputBaseFilename%.7z" %DISTDIR%
- echo no autoextract
- )
-if "%INSTALLER_OPTION%"==".zip" (
- "%SEVENZIP_EXE%" -tzip -mx5 a "%MyBinaryOutputDir%\%OutputBaseFilename%.zip" %DISTDIR%
- echo no autoextract
- )
-
-
-
-rem -mx1 = speed fastest
-rem -mx3 = speed fast
-rem -mx5 = speed normal
-rem -mx7 = compress maximum
-rem -mx9 = compress ultra
-
-rem -t7z = [by default] 7 zip compression , the only choice with auto-extract
-rem -tzip = Zip compatible compression.
diff --git a/portable/launchers_final/IDLE (Python GUI).exe b/portable/launchers_final/IDLE (Python GUI).exe
index c1e0c9dc..65523199 100644
Binary files a/portable/launchers_final/IDLE (Python GUI).exe and b/portable/launchers_final/IDLE (Python GUI).exe differ
diff --git a/portable/launchers_final/Jupyter Lab.exe b/portable/launchers_final/Jupyter Lab.exe
index 98bb8bde..93003fcb 100644
Binary files a/portable/launchers_final/Jupyter Lab.exe and b/portable/launchers_final/Jupyter Lab.exe differ
diff --git a/portable/launchers_final/Jupyter Notebook.exe b/portable/launchers_final/Jupyter Notebook.exe
index 5d59af59..28fdbea3 100644
Binary files a/portable/launchers_final/Jupyter Notebook.exe and b/portable/launchers_final/Jupyter Notebook.exe differ
diff --git a/portable/launchers_final/Spyder.exe b/portable/launchers_final/Spyder.exe
index 43874aa7..93b1a050 100644
Binary files a/portable/launchers_final/Spyder.exe and b/portable/launchers_final/Spyder.exe differ
diff --git a/portable/launchers_final/WinPython Control Panel.exe b/portable/launchers_final/WinPython Control Panel.exe
index 5795bf9c..72a57a67 100644
Binary files a/portable/launchers_final/WinPython Control Panel.exe and b/portable/launchers_final/WinPython Control Panel.exe differ
diff --git a/portable/launchers_final_original/IDLE (Python GUI).exe b/portable/launchers_final_original/IDLE (Python GUI).exe
new file mode 100644
index 00000000..c1e0c9dc
Binary files /dev/null and b/portable/launchers_final_original/IDLE (Python GUI).exe differ
diff --git a/portable/launchers_final_original/Jupyter Lab.exe b/portable/launchers_final_original/Jupyter Lab.exe
new file mode 100644
index 00000000..98bb8bde
Binary files /dev/null and b/portable/launchers_final_original/Jupyter Lab.exe differ
diff --git a/portable/launchers_final_original/Jupyter Notebook.exe b/portable/launchers_final_original/Jupyter Notebook.exe
new file mode 100644
index 00000000..5d59af59
Binary files /dev/null and b/portable/launchers_final_original/Jupyter Notebook.exe differ
diff --git a/portable/launchers_final_original/Spyder reset.exe b/portable/launchers_final_original/Spyder reset.exe
new file mode 100644
index 00000000..21250f98
Binary files /dev/null and b/portable/launchers_final_original/Spyder reset.exe differ
diff --git a/portable/launchers_final_original/Spyder.exe b/portable/launchers_final_original/Spyder.exe
new file mode 100644
index 00000000..43874aa7
Binary files /dev/null and b/portable/launchers_final_original/Spyder.exe differ
diff --git a/portable/launchers_final_original/VS Code.exe b/portable/launchers_final_original/VS Code.exe
new file mode 100644
index 00000000..225decb4
Binary files /dev/null and b/portable/launchers_final_original/VS Code.exe differ
diff --git a/portable/launchers_final_original/WinPython Command Prompt.exe b/portable/launchers_final_original/WinPython Command Prompt.exe
new file mode 100644
index 00000000..e4e824c5
Binary files /dev/null and b/portable/launchers_final_original/WinPython Command Prompt.exe differ
diff --git a/portable/launchers_final_original/WinPython Control Panel.exe b/portable/launchers_final_original/WinPython Control Panel.exe
new file mode 100644
index 00000000..5795bf9c
Binary files /dev/null and b/portable/launchers_final_original/WinPython Control Panel.exe differ
diff --git a/portable/launchers_final_original/WinPython Interpreter.exe b/portable/launchers_final_original/WinPython Interpreter.exe
new file mode 100644
index 00000000..dfa43135
Binary files /dev/null and b/portable/launchers_final_original/WinPython Interpreter.exe differ
diff --git a/portable/launchers_final_original/WinPython Powershell Prompt.exe b/portable/launchers_final_original/WinPython Powershell Prompt.exe
new file mode 100644
index 00000000..d4512f32
Binary files /dev/null and b/portable/launchers_final_original/WinPython Powershell Prompt.exe differ
diff --git a/portable/launchers_final_proposed/IDLE (Python GUI).exe b/portable/launchers_final_proposed/IDLE (Python GUI).exe
new file mode 100644
index 00000000..65523199
Binary files /dev/null and b/portable/launchers_final_proposed/IDLE (Python GUI).exe differ
diff --git a/portable/launchers_final_proposed/IDLE (Python GUI)_2025-05-09_not_ok.exe b/portable/launchers_final_proposed/IDLE (Python GUI)_2025-05-09_not_ok.exe
new file mode 100644
index 00000000..01eed2ce
Binary files /dev/null and b/portable/launchers_final_proposed/IDLE (Python GUI)_2025-05-09_not_ok.exe differ
diff --git a/portable/launchers_final_proposed/IDLE (Python GUI)_20250401.exe b/portable/launchers_final_proposed/IDLE (Python GUI)_20250401.exe
new file mode 100644
index 00000000..c1e0c9dc
Binary files /dev/null and b/portable/launchers_final_proposed/IDLE (Python GUI)_20250401.exe differ
diff --git a/portable/launchers_final_proposed/Jupyter Lab.exe b/portable/launchers_final_proposed/Jupyter Lab.exe
new file mode 100644
index 00000000..93003fcb
Binary files /dev/null and b/portable/launchers_final_proposed/Jupyter Lab.exe differ
diff --git a/portable/launchers_final_proposed/Jupyter Notebook.exe b/portable/launchers_final_proposed/Jupyter Notebook.exe
new file mode 100644
index 00000000..28fdbea3
Binary files /dev/null and b/portable/launchers_final_proposed/Jupyter Notebook.exe differ
diff --git a/portable/launchers_final_proposed/Spyder reset.exe b/portable/launchers_final_proposed/Spyder reset.exe
new file mode 100644
index 00000000..0baf4ab3
Binary files /dev/null and b/portable/launchers_final_proposed/Spyder reset.exe differ
diff --git a/portable/launchers_final_proposed/Spyder.exe b/portable/launchers_final_proposed/Spyder.exe
new file mode 100644
index 00000000..93b1a050
Binary files /dev/null and b/portable/launchers_final_proposed/Spyder.exe differ
diff --git a/portable/launchers_final_proposed/Spyder_2025-05-08_no_drag_and_drop.exe b/portable/launchers_final_proposed/Spyder_2025-05-08_no_drag_and_drop.exe
new file mode 100644
index 00000000..f3729201
Binary files /dev/null and b/portable/launchers_final_proposed/Spyder_2025-05-08_no_drag_and_drop.exe differ
diff --git a/portable/launchers_final_proposed/VS Code.exe b/portable/launchers_final_proposed/VS Code.exe
new file mode 100644
index 00000000..731f5f52
Binary files /dev/null and b/portable/launchers_final_proposed/VS Code.exe differ
diff --git a/portable/launchers_final_proposed/WinPython Command Prompt.exe b/portable/launchers_final_proposed/WinPython Command Prompt.exe
new file mode 100644
index 00000000..6f1b6bd6
Binary files /dev/null and b/portable/launchers_final_proposed/WinPython Command Prompt.exe differ
diff --git a/portable/launchers_final_proposed/WinPython Control Panel.exe b/portable/launchers_final_proposed/WinPython Control Panel.exe
new file mode 100644
index 00000000..72a57a67
Binary files /dev/null and b/portable/launchers_final_proposed/WinPython Control Panel.exe differ
diff --git a/portable/launchers_final_proposed/WinPython Control Panel_2025-05-09.exe b/portable/launchers_final_proposed/WinPython Control Panel_2025-05-09.exe
new file mode 100644
index 00000000..664ff576
Binary files /dev/null and b/portable/launchers_final_proposed/WinPython Control Panel_2025-05-09.exe differ
diff --git a/portable/launchers_final_proposed/WinPython Interpreter.exe b/portable/launchers_final_proposed/WinPython Interpreter.exe
new file mode 100644
index 00000000..e0cdbe77
Binary files /dev/null and b/portable/launchers_final_proposed/WinPython Interpreter.exe differ
diff --git a/portable/launchers_final_proposed/WinPython Powershell Prompt.exe b/portable/launchers_final_proposed/WinPython Powershell Prompt.exe
new file mode 100644
index 00000000..c6bda2eb
Binary files /dev/null and b/portable/launchers_final_proposed/WinPython Powershell Prompt.exe differ
diff --git a/portable/launchers_final_proposed/license.txt b/portable/launchers_final_proposed/license.txt
new file mode 100644
index 00000000..da461f3b
--- /dev/null
+++ b/portable/launchers_final_proposed/license.txt
@@ -0,0 +1,37 @@
+Note
+----
+
+WinPython components are distributed as they were received from
+their copyright holder, under their own copyright and/or license,
+and without any linking with each other.
+
+WinPython software collection (i.e. the collection of software,
+libraries and documents) is licensed under the terms of the
+following license agreement.
+
+
+WinPython License Agreement (MIT License)
+-----------------------------------------
+
+Copyright (c) 2012 Pierre Raybaut, 2016+ WinPython team
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff --git a/portable/launchers_src/launcher_template_CONSOLE.cpp b/portable/launchers_src/launcher_template_CONSOLE.cpp
index 93614b9e..1008d7f0 100644
--- a/portable/launchers_src/launcher_template_CONSOLE.cpp
+++ b/portable/launchers_src/launcher_template_CONSOLE.cpp
@@ -19,6 +19,26 @@ int main() {
std::wstring exeDir = exePath;
exeDir = exeDir.substr(0, exeDir.find_last_of(L"\\/"));
+ // Get command line string and extract arguments
+ LPWSTR commandLine = GetCommandLineW();
+ std::wstring args;
+ // If executable path is double quoted, skip the entire quoted section
+ if (commandLine[0] == L'"') {
+ LPWSTR closingQuote = wcschr(commandLine + 1, L'"');
+ if (closingQuote) {
+ args = closingQuote + 1;
+ }
+ // For non-quoted path, skip to character after first space if it exists
+ } else {
+ LPWSTR spacePos = wcschr(commandLine, L' ');
+ if (spacePos) {
+ args = spacePos + 1;
+ }
+ }
+ // Strip leading whitespace
+ size_t args_start = args.find_first_not_of(L' ');
+ args = (args_start != std::wstring::npos) ? args.substr(args_start) : L"";
+
// Define the path to the "scripts" directory
std::wstring scriptsDir = exeDir + L"\\scripts";
@@ -37,8 +57,13 @@ int main() {
return 1;
}
- // Define the command to run
- std::wstring target = L"cmd.exe /c \"" LAUNCH_TARGET L"\"";
+ // Define the command to run and append arguments if present
+ std::wstring target;
+ if (!args.empty()) {
+ target = L"cmd.exe /c \"\"" LAUNCH_TARGET L"\" " + args + L"\"";
+ } else {
+ target = L"cmd.exe /c \"" LAUNCH_TARGET L"\"";
+ }
// Configure the process startup info
STARTUPINFO si = { sizeof(si) };
diff --git a/portable/launchers_src/launcher_template_WINDOWS.cpp b/portable/launchers_src/launcher_template_WINDOWS.cpp
index 9c878be6..6b10a89a 100644
--- a/portable/launchers_src/launcher_template_WINDOWS.cpp
+++ b/portable/launchers_src/launcher_template_WINDOWS.cpp
@@ -19,6 +19,26 @@ int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, LPSTR /
std::wstring exeDir = exePath;
exeDir = exeDir.substr(0, exeDir.find_last_of(L"\\/"));
+ // Get command line string and extract arguments
+ LPWSTR commandLine = GetCommandLineW();
+ std::wstring args;
+ // If executable path is double quoted, skip the entire quoted section
+ if (commandLine[0] == L'"') {
+ LPWSTR closingQuote = wcschr(commandLine + 1, L'"');
+ if (closingQuote) {
+ args = closingQuote + 1;
+ }
+ // For non-quoted path, skip to character after first space if it exists
+ } else {
+ LPWSTR spacePos = wcschr(commandLine, L' ');
+ if (spacePos) {
+ args = spacePos + 1;
+ }
+ }
+ // Strip leading whitespace
+ size_t args_start = args.find_first_not_of(L" ");
+ args = (args_start != std::wstring::npos) ? args.substr(args_start) : L"";
+
// Define the path to the "scripts" directory
std::wstring scriptsDir = exeDir + L"\\scripts";
@@ -37,8 +57,13 @@ int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, LPSTR /
return 1;
}
- // Define the command to run
- std::wstring target = L"cmd.exe /c \"" LAUNCH_TARGET L"\"";
+ // Define the command to run and append arguments if present
+ std::wstring target;
+ if (!args.empty()) {
+ target = L"cmd.exe /c \"\"" LAUNCH_TARGET L"\" " + args + L"\"";
+ } else {
+ target = L"cmd.exe /c \"" LAUNCH_TARGET L"\"";
+ }
// Configure the process startup info
STARTUPINFO si = { sizeof(si) };
diff --git a/portable/launchers_src_original/LICENSE b/portable/launchers_src_original/LICENSE
new file mode 100644
index 00000000..b3fb976c
--- /dev/null
+++ b/portable/launchers_src_original/LICENSE
@@ -0,0 +1,63 @@
+DataLab-WinPython license terms
+===============================
+
+DataLab-WinPython is a Python distribution for Windows:
+- Based on WinPython, a portable distribution of Python for Windows (see section I. below).
+- Including DataLab, an open-source platform for signal and image processing (see section II. below).
+
+I. - WinPython License Agreement (MIT License)
+----------------------------------------------
+
+Copyright (c) 2012 Pierre Raybaut, 2016+ WinPython team
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+II. - DataLab License Agreement (BSD 3-Clause License)
+------------------------------------------------------
+
+Copyright (c) 2023, DataLab Platform Developers.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+3. Neither the name of the copyright holder nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/portable/launchers_src_original/build_one_launcher.bat b/portable/launchers_src_original/build_one_launcher.bat
new file mode 100644
index 00000000..233f68de
--- /dev/null
+++ b/portable/launchers_src_original/build_one_launcher.bat
@@ -0,0 +1,107 @@
+@echo on
+set icon_name=%1
+set LAUNCH_TARGET=%2
+set launcher_name=%3
+set subsystem=%4
+
+set icon_name=%icon_name:"=%
+set LAUNCH_TARGET=%LAUNCH_TARGET:"=%
+set launcher_name=%launcher_name:"=%
+set subsystem=%subsystem:"=%
+
+set ROOT_PATH=%~dp0..\
+set SCRIPT_PATH=%~dp0
+set TEMPO_PATH=%ROOT_PATH%launchers_temp
+set OUTPUT_DIR=%ROOT_PATH%launchers_final
+
+set "ICON_FILE=%ROOT_PATH%icons\%icon_name%"
+set LAUNCHER_EXE=%OUTPUT_DIR%\%launcher_name%.exe
+
+
+:: Paths to template WINDOWS or CONSOLE
+set SOURCE_FILE=%SCRIPT_PATH%launcher_template_%subsystem%.cpp
+echo SOURCE_FILE=%SOURCE_FILE%
+
+set "RESOURCE_FILE=%TEMPO_PATH%\%icon_name%.rc"
+set "RESOURCE_OBJ=%TEMPO_PATH%\%icon_name%.res"
+
+
+:: create pDirectory if needed
+if not exist "%OUTPUT_DIR%" mkdir "%OUTPUT_DIR%"
+if not exist "%TEMPO_PATH%" mkdir "%TEMPO_PATH%"
+
+cd/d %TEMPO_PATH%
+
+:: Check if MSVC environment is already initialized
+if not defined VSINSTALLDIR (
+ echo Initializing MSVC environment...
+ call %VCVARS_PATH%
+ if errorlevel 1 (
+ echo [ERROR] Failed to initialize MSVC environment.
+ exit /b 1
+ )
+)
+
+@echo on
+
+:: Walk through .bat files in the current directory
+ echo Processing %icon_name%..
+ :: Stonebig: Remove previous .exe file
+ echo launcher_exe_action del /q "%LAUNCHER_EXE%"
+ if exist "%LAUNCHER_EXE%" (
+ move "%LAUNCHER_EXE%" "%LAUNCHER_EXE%.old.exe"
+ del /q "%LAUNCHER_EXE%.old.exe"
+ )
+ :: Stonebig: Remove intermediate .res and.rc file
+ if exist "%RESOURCE_OBJ%" (
+ move "%RESOURCE_OBJ%" "%RESOURCE_OBJ%.old.exe"
+ del /q "%RESOURCE_OBJ%.old.exe"
+ )
+ if exist "%RESOURCE_FILE%" (
+ move "%RESOURCE_FILE%" "%RESOURCE_FILE%.old.exe"
+ del /q "%RESOURCE_FILE%.old.exe"
+ )
+ :: Remove intermediate .obj file
+ del /q "launcher_template_%subsystem%.obj"
+
+ :: Check if the icon exists
+ if exist "%ICON_FILE%" (
+ echo Icon found: "%ICON_FILE%"
+ ) else (
+ echo No icon found for "%ICON_FILE%" stoping
+ pause
+ exit
+ )
+
+
+ :: Create resource file
+ echo Creating resource file...
+ > "%RESOURCE_FILE%" echo IDI_ICON1 ICON "%ICON_FILE%"
+ :: Compile resource
+ echo Compiling resource...
+ rc /fo "%RESOURCE_OBJ%" "%RESOURCE_FILE%"
+
+ :: Compile the launcher executable
+ echo Compiling launcher executable...
+ cl /EHsc /O2 /DUNICODE /W4 "%SOURCE_FILE%" "%RESOURCE_OBJ%" ^
+ /Fe"%LAUNCHER_EXE%%" ^
+ /DLAUNCH_TARGET=\"%LAUNCH_TARGET%\" ^
+ User32.lib ^
+ /link /SUBSYSTEM:%subsystem%
+
+
+ if errorlevel 1 (
+ echo [ERROR] Failed to build launcher for %LAUNCH_TARGET%
+ exit /b 1
+ )
+
+ if exist "%LAUNCHER_EXE%" (
+ echo [SUCCESS] Launcher created: "%LAUNCHER_EXE%""
+ ) else (
+ echo [ERROR] Failed to build launcher "%LAUNCHER_EXE%" from "%icon_name%" to call "%LAUNCH_TARGET%"
+ exit /b 1
+ )
+
+echo All launchers processed.
+rem exit /b 0
+
diff --git a/portable/launchers_src_original/launcher_template_CONSOLE.cpp b/portable/launchers_src_original/launcher_template_CONSOLE.cpp
new file mode 100644
index 00000000..93614b9e
--- /dev/null
+++ b/portable/launchers_src_original/launcher_template_CONSOLE.cpp
@@ -0,0 +1,75 @@
+/*
+DataLab-WinPython launcher script
+---------------------------------
+
+Licensed under the terms of the BSD 3-Clause
+(see ./LICENSE for details)
+
+*/
+
+#include
+#include
+
+int main() {
+ // Get the path to the current executable
+ wchar_t exePath[MAX_PATH];
+ GetModuleFileNameW(NULL, exePath, MAX_PATH);
+
+ // Determine the directory of the executable
+ std::wstring exeDir = exePath;
+ exeDir = exeDir.substr(0, exeDir.find_last_of(L"\\/"));
+
+ // Define the path to the "scripts" directory
+ std::wstring scriptsDir = exeDir + L"\\scripts";
+
+ // Check if the "scripts" directory exists
+ DWORD attributes = GetFileAttributesW(scriptsDir.c_str());
+ if (attributes == INVALID_FILE_ATTRIBUTES || !(attributes & FILE_ATTRIBUTE_DIRECTORY)) {
+ MessageBoxW(NULL, L"The 'scripts' directory does not exist. Please ensure it is in the same folder as the launcher.",
+ L"Launcher Error", MB_ICONERROR);
+ return 1;
+ }
+
+ // Set the working directory to the "scripts" folder
+ if (!SetCurrentDirectoryW(scriptsDir.c_str())) {
+ MessageBoxW(NULL, L"Failed to set the working directory to 'scripts'.",
+ L"Launcher Error", MB_ICONERROR);
+ return 1;
+ }
+
+ // Define the command to run
+ std::wstring target = L"cmd.exe /c \"" LAUNCH_TARGET L"\"";
+
+ // Configure the process startup info
+ STARTUPINFO si = { sizeof(si) };
+ si.dwFlags = STARTF_USESHOWWINDOW; // Prevent the window from appearing
+ si.wShowWindow = SW_HIDE; // Hide the command window
+
+ PROCESS_INFORMATION pi = {};
+
+ // Start the process without CREATE_NO_WINDOW flag to show the command window
+ if (!CreateProcessW(
+ NULL, // Application name (NULL because we pass the command in the command line)
+ &target[0], // Command line
+ NULL, // Process security attributes
+ NULL, // Thread security attributes
+ FALSE, // Inherit handles
+ 0, // No special flags
+ NULL, // Environment block (NULL to inherit parent)
+ NULL, // Current directory (NULL to use the parent process's current directory)
+ &si, // Startup info
+ &pi // Process information
+ )) {
+ MessageBoxW(NULL, L"Failed to launch the script.", L"Launcher Error", MB_ICONERROR);
+ return 1;
+ }
+
+ // Wait for the script to finish
+ WaitForSingleObject(pi.hProcess, INFINITE);
+
+ // Cleanup
+ CloseHandle(pi.hProcess);
+ CloseHandle(pi.hThread);
+
+ return 0;
+}
diff --git a/portable/launchers_src_original/launcher_template_WINDOWS.cpp b/portable/launchers_src_original/launcher_template_WINDOWS.cpp
new file mode 100644
index 00000000..9c878be6
--- /dev/null
+++ b/portable/launchers_src_original/launcher_template_WINDOWS.cpp
@@ -0,0 +1,75 @@
+/*
+DataLab-WinPython launcher script
+---------------------------------
+
+Licensed under the terms of the BSD 3-Clause
+(see ./LICENSE for details)
+
+*/
+
+#include
+#include
+
+int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, LPSTR /*lpCmdLine*/, int /*nShowCmd*/) {
+ // Get the path to the current executable
+ wchar_t exePath[MAX_PATH];
+ GetModuleFileNameW(NULL, exePath, MAX_PATH);
+
+ // Determine the directory of the executable
+ std::wstring exeDir = exePath;
+ exeDir = exeDir.substr(0, exeDir.find_last_of(L"\\/"));
+
+ // Define the path to the "scripts" directory
+ std::wstring scriptsDir = exeDir + L"\\scripts";
+
+ // Check if the "scripts" directory exists
+ DWORD attributes = GetFileAttributesW(scriptsDir.c_str());
+ if (attributes == INVALID_FILE_ATTRIBUTES || !(attributes & FILE_ATTRIBUTE_DIRECTORY)) {
+ MessageBoxW(NULL, L"The 'scripts' directory does not exist. Please ensure it is in the same folder as the launcher.",
+ L"Launcher Error", MB_ICONERROR);
+ return 1;
+ }
+
+ // Set the working directory to the "scripts" folder
+ if (!SetCurrentDirectoryW(scriptsDir.c_str())) {
+ MessageBoxW(NULL, L"Failed to set the working directory to 'scripts'.",
+ L"Launcher Error", MB_ICONERROR);
+ return 1;
+ }
+
+ // Define the command to run
+ std::wstring target = L"cmd.exe /c \"" LAUNCH_TARGET L"\"";
+
+ // Configure the process startup info
+ STARTUPINFO si = { sizeof(si) };
+ si.dwFlags = STARTF_USESHOWWINDOW; // Prevent the window from appearing
+ si.wShowWindow = SW_HIDE; // Hide the command window
+
+ PROCESS_INFORMATION pi = {};
+
+ // Start the process with CREATE_NO_WINDOW flag
+ if (!CreateProcessW(
+ NULL, // Application name (NULL because we pass the command in the command line)
+ &target[0], // Command line
+ NULL, // Process security attributes
+ NULL, // Thread security attributes
+ FALSE, // Inherit handles
+ CREATE_NO_WINDOW, // Flags to prevent creating a window
+ NULL, // Environment block (NULL to inherit parent)
+ NULL, // Current directory (NULL to use the parent process's current directory)
+ &si, // Startup info
+ &pi // Process information
+ )) {
+ MessageBoxW(NULL, L"Failed to launch the script.", L"Launcher Error", MB_ICONERROR);
+ return 1;
+ }
+
+ // Wait for the script to finish
+ WaitForSingleObject(pi.hProcess, INFINITE);
+
+ // Cleanup
+ CloseHandle(pi.hProcess);
+ CloseHandle(pi.hThread);
+
+ return 0;
+}
diff --git a/portable/scripts/WinPythonIni.py b/portable/scripts/WinPythonIni.py
new file mode 100644
index 00000000..7bc11bb9
--- /dev/null
+++ b/portable/scripts/WinPythonIni.py
@@ -0,0 +1,104 @@
+
+# Prepares a dynamic list of variables settings from a .ini file
+import os
+import subprocess
+from pathlib import Path
+
+winpython_inidefault=r'''
+[debug]
+state = disabled
+[inactive_environment_per_user]
+## > changing this segment to [active_environment_per_user] makes this segment of lines active or not
+HOME = %HOMEDRIVE%%HOMEPATH%\Documents\WinPython%WINPYVER%\settings
+USERPROFILE = %HOME%
+JUPYTER_DATA_DIR = %HOME%
+WINPYWORKDIR = %HOMEDRIVE%%HOMEPATH%\Documents\WinPython%WINPYVER%\Notebooks
+[inactive_environment_common]
+USERPROFILE = %HOME%
+[environment]
+## > Uncomment lines to override environment variables
+#JUPYTERLAB_SETTINGS_DIR = %HOME%\.jupyter\lab
+#JUPYTERLAB_WORKSPACES_DIR = %HOME%\.jupyter\lab\workspaces
+#R_HOME=%WINPYDIRBASE%\t\R
+#R_HOMEbin=%R_HOME%\bin\x64
+#JULIA_HOME=%WINPYDIRBASE%\t\Julia\bin\
+#JULIA_EXE=julia.exe
+#JULIA=%JULIA_HOME%%JULIA_EXE%
+#JULIA_PKGDIR=%WINPYDIRBASE%\settings\.julia
+#QT_PLUGIN_PATH=%WINPYDIR%\Lib\site-packages\pyqt5_tools\Qt\plugins
+'''
+
+def get_file(file_name):
+ if file_name.startswith("..\\"):
+ file_name = os.path.join(os.path.dirname(os.path.dirname(__file__)), file_name[3:])
+ elif file_name.startswith(".\\"):
+ file_name = os.path.join(os.path.dirname(__file__), file_name[2:])
+ try:
+ with open(file_name, 'r') as file:
+ return file.read()
+ except FileNotFoundError:
+ if file_name[-3:] == 'ini':
+ os.makedirs(Path(file_name).parent, exist_ok=True)
+ with open(file_name, 'w') as file:
+ file.write(winpython_inidefault)
+ return winpython_inidefault
+
+def translate(line, env):
+ parts = line.split('%')
+ for i in range(1, len(parts), 2):
+ if parts[i] in env:
+ parts[i] = env[parts[i]]
+ return ''.join(parts)
+
+def main():
+ import sys
+ args = sys.argv[1:]
+ file_name = args[0] if args else "..\\settings\\winpython.ini"
+
+ my_lines = get_file(file_name).splitlines()
+ segment = "environment"
+ txt = ""
+ env = os.environ.copy() # later_version: env = os.environ
+
+ # default directories (from .bat)
+ os.makedirs(Path(env['WINPYDIRBASE']) / 'settings' / 'Appdata' / 'Roaming', exist_ok=True)
+
+ # default qt.conf for Qt directories
+ qt_conf='''echo [Paths]
+ echo Prefix = .
+ echo Binaries = .
+ '''
+
+ pathlist = [Path(env['WINPYDIR']) / 'Lib' / 'site-packages' / i for i in ('PyQt5', 'PyQt6', 'Pyside6')]
+ for p in pathlist:
+ if p.is_dir():
+ if not (p / 'qt.conf').is_file():
+ with open(p / 'qt.conf', 'w') as file:
+ file.write(qt_conf)
+
+ for l in my_lines:
+ if l.startswith("["):
+ segment = l[1:].split("]")[0]
+ elif not l.startswith("#") and "=" in l:
+ data = l.split("=", 1)
+ if segment == "debug" and data[0].strip() == "state":
+ data[0] = "WINPYDEBUG"
+ if segment in ["environment", "debug", "active_environment_per_user", "active_environment_common"]:
+ txt += f"set {data[0].strip()}={translate(data[1].strip(), env)}&& "
+ env[data[0].strip()] = translate(data[1].strip(), env)
+ if segment == "debug" and data[0].strip() == "state":
+ txt += f"set WINPYDEBUG={data[1].strip()}&&"
+
+ print(txt)
+
+ # set potential directory
+ for i in ('HOME', 'WINPYWORKDIR'):
+ if i in env:
+ os.makedirs(Path(env[i]), exist_ok=True)
+ # later_version:
+ # p = subprocess.Popen(["start", "cmd", "/k", "set"], shell = True)
+ # p.wait() # I can wait until finished (although it too finishes after start finishes)
+
+if __name__ == "__main__":
+ main()
+
\ No newline at end of file
diff --git a/portable/scripts/WinPython_PS_Prompt.ps1 b/portable/scripts/WinPython_PS_Prompt.ps1
new file mode 100644
index 00000000..ecd2d6aa
--- /dev/null
+++ b/portable/scripts/WinPython_PS_Prompt.ps1
@@ -0,0 +1,70 @@
+### WinPython_PS_Prompt.ps1 ###
+$0 = $myInvocation.MyCommand.Definition
+$dp0 = [System.IO.Path]::GetDirectoryName($0)
+
+# default if env.cfg fails
+$env:WINPYthon_subdirectory_name = "python"
+$env:WINPYthon_exe = "python.exe"
+# Define the path to the config file
+Get-Content (${PSScriptRoot} +"\env.ini") | ForEach-Object {
+ $parts = $_ -split '=', 2
+ if ($parts.Count -eq 2) {
+ Set-Variable -Name ($parts[0]).Trim() -Value $parts[1].Trim() -Scope Global
+ }
+}
+
+# $env:PYTHONUTF8 = 1 would create issues in "movable" patching
+$env:WINPYDIRBASE = "$dp0\.."
+# get a normalize path
+# http://stackoverflow.com/questions/1645843/resolve-absolute-path-from-relative-path-and-or-file-name
+$env:WINPYDIRBASE = [System.IO.Path]::GetFullPath( $env:WINPYDIRBASE )
+
+# avoid double_init (will only resize screen)
+if (-not ($env:WINPYDIR -eq [System.IO.Path]::GetFullPath( $env:WINPYDIRBASE+"\{self.python_dir_name}")) ) {
+$env:WINPYDIR = $env:WINPYDIRBASE+ "\" +$env:WINPYthon_subdirectory_name
+# 2019-08-25 pyjulia needs absolutely a variable PYTHON=%WINPYDIR%python.exe
+$env:PYTHON = $env:WINPYthon_exe
+$env:PYTHONPATHz = "%WINPYDIR%;%WINPYDIR%\Lib;%WINPYDIR%\DLLs"
+
+$env:WINPYVER = $env:WINPYVER
+# rem 2023-02-12 try utf-8 on console
+# rem see https://github.com/pypa/pip/issues/11798#issuecomment-1427069681
+$env:PYTHONIOENCODING = "utf-8"
+
+$env:HOME = "$env:WINPYDIRBASE\settings"
+
+# rem read https://github.com/winpython/winpython/issues/839
+# $env:USERPROFILE = "$env:HOME"
+
+$env:WINPYDIRBASE = ""
+$env:JUPYTER_DATA_DIR = "$env:HOME"
+
+if (-not $env:PATH.ToLower().Contains(";"+ $env:WINPYDIR.ToLower()+ ";")) {
+ $env:PATH = "$env:WINPYDIR\\Lib\site-packages\PyQt5;$env:WINPYDIR\\;$env:WINPYDIR\\DLLs;$env:WINPYDIR\\Scripts;$env:WINPYDIR\\..\t;$env:WINPYDIR\\..\n;$env:path" }
+
+
+#rem force default pyqt5 kit for Spyder if PyQt5 module is there
+if (Test-Path "$env:WINPYDIR\Lib\site-packages\PyQt5\__init__.py") { $env:QT_API = "pyqt5" }
+
+# PyQt5 qt.conf creation and winpython.ini creation done via Winpythonini.py (called per env_for_icons.bat for now)
+# Start-Process -FilePath $env:PYTHON -ArgumentList ($env:WINPYDIRBASE + '\scripts\WinPythonIni.py')
+
+
+### Set-WindowSize
+
+Function Set-WindowSize {
+Param([int]$x=$host.ui.rawui.windowsize.width,
+ [int]$y=$host.ui.rawui.windowsize.heigth,
+ [int]$buffer=$host.UI.RawUI.BufferSize.heigth)
+ $buffersize = new-object System.Management.Automation.Host.Size($x,$buffer)
+ $host.UI.RawUI.BufferSize = $buffersize
+ $size = New-Object System.Management.Automation.Host.Size($x,$y)
+ $host.ui.rawui.WindowSize = $size
+}
+# Windows10 yelling at us with 150 40 6000
+# Set-WindowSize 195 40 6000
+
+### Colorize to distinguish
+$host.ui.RawUI.BackgroundColor = "Black"
+$host.ui.RawUI.ForegroundColor = "White"
+}
diff --git a/portable/scripts/activate.bat b/portable/scripts/activate.bat
new file mode 100644
index 00000000..e52886af
--- /dev/null
+++ b/portable/scripts/activate.bat
@@ -0,0 +1,2 @@
+@echo off
+call "%~dp0env.bat" %*
\ No newline at end of file
diff --git a/portable/scripts/cmd.bat b/portable/scripts/cmd.bat
new file mode 100644
index 00000000..fc76541f
--- /dev/null
+++ b/portable/scripts/cmd.bat
@@ -0,0 +1,3 @@
+@echo off
+call "%~dp0env_for_icons.bat" %*
+cmd.exe /k
\ No newline at end of file
diff --git a/portable/scripts/cmd_ps.bat b/portable/scripts/cmd_ps.bat
new file mode 100644
index 00000000..c6fa79a4
--- /dev/null
+++ b/portable/scripts/cmd_ps.bat
@@ -0,0 +1,3 @@
+@echo off
+call "%~dp0env_for_icons.bat"
+Powershell.exe -Command "& {Start-Process PowerShell.exe -ArgumentList '-ExecutionPolicy RemoteSigned -noexit -File ""%~dp0WinPython_PS_Prompt.ps1""'}"
diff --git a/portable/scripts/env.bat b/portable/scripts/env.bat
new file mode 100644
index 00000000..316f6587
--- /dev/null
+++ b/portable/scripts/env.bat
@@ -0,0 +1,52 @@
+@echo off
+
+rem default if init fails
+set WINPYthon_subdirectory_name=python
+set WINPYthon_exe=python.exe
+rem read init variables
+FOR /F "usebackq tokens=1,2 delims==" %%G IN ("%~dp0env.ini") DO (set %%G=%%H)
+
+set WINPYDIRBASE=%~dp0..
+
+rem get a normalized path
+set WINPYDIRBASETMP=%~dp0..
+pushd %WINPYDIRBASETMP%
+set WINPYDIRBASE=%__CD__%
+if "%WINPYDIRBASE:~-1%"=="\" set WINPYDIRBASE=%WINPYDIRBASE:~0,-1%
+set WINPYDIRBASETMP=
+popd
+
+set WINPYDIR=%WINPYDIRBASE%\%WINpython_subdirectory_name%
+rem 2019-08-25 pyjulia needs absolutely a variable PYTHON=%WINPYDIR%\python.exe
+set PYTHON=%WINPYDIR%\%WINpython_exe%
+set PYTHONPATHz=%WINPYDIR%;%WINPYDIR%\Lib;%WINPYDIR%\DLLs
+set WINPYVER=%WINPYVER%
+
+rem 2023-02-12 utf-8 on console to avoid pip crash
+rem see https://github.com/pypa/pip/issues/11798#issuecomment-1427069681
+set PYTHONIOENCODING=utf-8
+rem set PYTHONUTF8=1 creates issues in "movable" patching
+
+set HOME=%WINPYDIRBASE%\settings
+rem see https://github.com/winpython/winpython/issues/839
+rem set USERPROFILE=%HOME%
+set JUPYTER_DATA_DIR=%HOME%
+set JUPYTER_CONFIG_DIR=%WINPYDIR%\etc\jupyter
+set JUPYTER_CONFIG_PATH=%WINPYDIR%\etc\jupyter
+set FINDDIR=%WINDIR%\system32
+
+rem Remove all double quotes
+set PATH_CLEANED=%PATH:"=%
+echo ";%PATH_CLEANED%;" | %FINDDIR%\find.exe /C /I ";%WINPYDIR%\;" >nul
+if %ERRORLEVEL% NEQ 0 (
+ set "PATH=%WINPYDIR%\Lib\site-packages\PyQt5;%WINPYDIR%\;%WINPYDIR%\DLLs;%WINPYDIR%\Scripts;%WINPYDIR%\..\t;%WINPYDIR%\..\n;%PATH%"
+ cd .
+)
+set PATH_CLEANED=
+
+rem force default pyqt5 kit for Spyder if PyQt5 module is there
+if exist "%WINPYDIR%\Lib\site-packages\PyQt5\__init__.py" set QT_API=pyqt5
+
+rem modern Pandoc wheel need this
+if exist "%WINPYDIRBASE%\t\pandoc.exe" set PYPANDOC_PANDOC=%WINPYDIRBASE%\t\pandoc.exe
+
diff --git a/portable/scripts/env_for_icons.bat b/portable/scripts/env_for_icons.bat
new file mode 100644
index 00000000..a6ac886f
--- /dev/null
+++ b/portable/scripts/env_for_icons.bat
@@ -0,0 +1,42 @@
+@echo off
+call "%~dp0env.bat"
+
+rem default is as before: Winpython ..\Notebooks
+set WINPYWORKDIR=%WINPYDIRBASE%\Notebooks
+set WINPYWORKDIR1=%WINPYWORKDIR%
+
+rem if we have a file or directory in %1 parameter, we use that directory to define WINPYWORKDIR1
+if not "%~1"=="" (
+ if exist "%~1" (
+ if exist "%~1\" (
+ rem echo it is a directory %~1
+ set WINPYWORKDIR1=%~1
+ ) else (
+ rem echo it is a file %~1, so we take the directory %~dp1
+ set WINPYWORKDIR1=%~dp1
+ )
+ )
+) else (
+rem if it is launched from another directory than icon origin , we keep it that one echo %__CD__%
+if not "%__CD__%"=="%~dp0" if not "%__CD__%scripts\"=="%~dp0" set WINPYWORKDIR1="%__CD__%"
+)
+rem remove potential doublequote
+set WINPYWORKDIR1=%WINPYWORKDIR1:"=%
+rem remove some potential last \
+if "%WINPYWORKDIR1:~-1%"=="\" set WINPYWORKDIR1=%WINPYWORKDIR1:~0,-1%
+
+rem you can use winpython.ini to change defaults
+FOR /F "delims=" %%i IN ('""%WINPYDIR%\python.exe" "%~dp0WinpythonIni.py""') DO set winpythontoexec=%%i
+%winpythontoexec%set winpythontoexec=
+
+
+rem Preventive Working Directories creation if needed
+if not "%WINPYWORKDIR%"=="" if not exist "%WINPYWORKDIR%" mkdir "%WINPYWORKDIR%"
+if not "%WINPYWORKDIR1%"=="" if not exist "%WINPYWORKDIR1%" mkdir "%WINPYWORKDIR1%"
+
+rem Change of directory only if we are in a launcher directory
+if "%__CD__%scripts\"=="%~dp0" cd/D %WINPYWORKDIR1%
+if "%__CD__%"=="%~dp0" cd/D %WINPYWORKDIR1%
+
+if not exist "%HOME%\.spyder-py%WINPYVER:~0,1%" mkdir "%HOME%\.spyder-py%WINPYVER:~0,1%"
+if not exist "%HOME%\.spyder-py%WINPYVER:~0,1%\workingdir" echo %HOME%\Notebooks>"%HOME%\.spyder-py%WINPYVER:~0,1%\workingdir"
diff --git a/portable/scripts/make_working_directory_and_userprofile_be_winpython.bat b/portable/scripts/make_working_directory_and_userprofile_be_winpython.bat
new file mode 100644
index 00000000..2806dc14
--- /dev/null
+++ b/portable/scripts/make_working_directory_and_userprofile_be_winpython.bat
@@ -0,0 +1,3 @@
+call "%~dp0env_for_icons.bat"
+"%PYTHON%" -c "from winpython.utils import patch_sourcefile;patch_sourcefile(r'%~dp0..\settings\winpython.ini', '[active_environment', '[inactive_environment' )"
+"%PYTHON%" -c "from winpython.utils import patch_sourcefile;patch_sourcefile(r'%~dp0..\settings\winpython.ini', '[inactive_environment_common]', '[active_environment_common]' )"
\ No newline at end of file
diff --git a/portable/scripts/make_working_directory_be_not_winpython.bat b/portable/scripts/make_working_directory_be_not_winpython.bat
new file mode 100644
index 00000000..759de71d
--- /dev/null
+++ b/portable/scripts/make_working_directory_be_not_winpython.bat
@@ -0,0 +1,3 @@
+call "%~dp0env_for_icons.bat"
+"%PYTHON%" -c "from winpython.utils import patch_sourcefile;patch_sourcefile(r'%~dp0..\settings\winpython.ini', '[active_environment', '[inactive_environment' )"
+"%PYTHON%" -c "from winpython.utils import patch_sourcefile;patch_sourcefile(r'%~dp0..\settings\winpython.ini', '[inactive_environment_per_user]', '[active_environment_per_user]' )"
\ No newline at end of file
diff --git a/portable/scripts/make_working_directory_be_winpython.bat b/portable/scripts/make_working_directory_be_winpython.bat
new file mode 100644
index 00000000..bcdd3c45
--- /dev/null
+++ b/portable/scripts/make_working_directory_be_winpython.bat
@@ -0,0 +1,2 @@
+call "%~dp0env_for_icons.bat"
+"%PYTHON%" -c "from winpython.utils import patch_sourcefile;patch_sourcefile(r'%~dp0..\settings\winpython.ini', '[active_environment', '[inactive_environment' )"
diff --git a/portable/scripts/python.bat b/portable/scripts/python.bat
new file mode 100644
index 00000000..1e8fea0b
--- /dev/null
+++ b/portable/scripts/python.bat
@@ -0,0 +1,3 @@
+@echo off
+call "%~dp0env_for_icons.bat" %*
+"%WINPYDIR%\python.exe" %*
\ No newline at end of file
diff --git a/portable/scripts/readme.txt b/portable/scripts/readme.txt
new file mode 100644
index 00000000..11592357
--- /dev/null
+++ b/portable/scripts/readme.txt
@@ -0,0 +1,3 @@
+These batch files are required to run WinPython icons.
+These files should help the user writing his/her own
+The environment variables are set-up in 'env.bat' and 'env_for_icons.bat'.
\ No newline at end of file
diff --git a/portable/scripts/spyder_reset.bat b/portable/scripts/spyder_reset.bat
new file mode 100644
index 00000000..89cb78c8
--- /dev/null
+++ b/portable/scripts/spyder_reset.bat
@@ -0,0 +1,3 @@
+@echo off
+call "%~dp0env_for_icons.bat"
+"%WINPYDIR%\scripts\spyder.exe" --reset %*
\ No newline at end of file
diff --git a/portable/scripts/upgrade_pip.bat b/portable/scripts/upgrade_pip.bat
new file mode 100644
index 00000000..da212592
--- /dev/null
+++ b/portable/scripts/upgrade_pip.bat
@@ -0,0 +1,7 @@
+@echo off
+call "%~dp0env.bat"
+echo this will upgrade pip with latest version, then patch it for WinPython portability ok ?
+pause
+"%WINPYDIR%\python.exe" -m pip install --upgrade pip
+"%WINPYDIR%\python.exe" -c "from winpython import wppm;dist=wppm.Distribution(r'%WINPYDIR%');dist.patch_standard_packages('pip', to_movable=True)
+pause
\ No newline at end of file
diff --git a/portable/scripts/winidle.bat b/portable/scripts/winidle.bat
new file mode 100644
index 00000000..79a6a01a
--- /dev/null
+++ b/portable/scripts/winidle.bat
@@ -0,0 +1,3 @@
+@echo off
+call "%~dp0env_for_icons.bat" %*
+"%WINPYDIR%\python.exe" "%WINPYDIR%\Lib\idlelib\idle.pyw" %*
\ No newline at end of file
diff --git a/portable/scripts/winipython_notebook.bat b/portable/scripts/winipython_notebook.bat
new file mode 100644
index 00000000..7ee541d9
--- /dev/null
+++ b/portable/scripts/winipython_notebook.bat
@@ -0,0 +1,3 @@
+@echo off
+call "%~dp0env_for_icons.bat" %*
+"%WINPYDIR%\scripts\jupyter-notebook.exe" %*
\ No newline at end of file
diff --git a/portable/scripts/winjupyter_lab.bat b/portable/scripts/winjupyter_lab.bat
new file mode 100644
index 00000000..845d1f0b
--- /dev/null
+++ b/portable/scripts/winjupyter_lab.bat
@@ -0,0 +1,3 @@
+@echo off
+call "%~dp0env_for_icons.bat" %*
+"%WINPYDIR%\scripts\jupyter-lab.exe" %*
\ No newline at end of file
diff --git a/portable/scripts/winpython.bat b/portable/scripts/winpython.bat
new file mode 100644
index 00000000..9f98d397
--- /dev/null
+++ b/portable/scripts/winpython.bat
@@ -0,0 +1,8 @@
+@echo off
+call "%~dp0env_for_icons.bat" %*
+rem backward compatibility for non-ptpython users
+if exist "%WINPYDIR%\scripts\ptpython.exe" (
+ "%WINPYDIR%\scripts\ptpython.exe" %*
+) else (
+ "%WINPYDIR%\python.exe" %*
+)
\ No newline at end of file
diff --git a/portable/scripts/winspyder.bat b/portable/scripts/winspyder.bat
new file mode 100644
index 00000000..1a843ca0
--- /dev/null
+++ b/portable/scripts/winspyder.bat
@@ -0,0 +1,5 @@
+@echo off
+call "%~dp0env_for_icons.bat" %*
+rem "%WINPYDIR%\scripts\spyder.exe" %* -w "%WINPYWORKDIR1%"
+"%WINPYDIR%\scripts\spyder.exe" %*
+
diff --git a/portable/scripts/winvscode.bat b/portable/scripts/winvscode.bat
new file mode 100644
index 00000000..d9697b89
--- /dev/null
+++ b/portable/scripts/winvscode.bat
@@ -0,0 +1,10 @@
+@echo off
+call "%~dp0env_for_icons.bat"
+if exist "%WINPYDIR%\..\t\vscode\code.exe" (
+ "%WINPYDIR%\..\t\vscode\code.exe" %*
+) else (
+if exist "%LOCALAPPDATA%\Programs\Microsoft VS Code\code.exe" (
+ "%LOCALAPPDATA%\Programs\Microsoft VS Code\code.exe" %*
+) else (
+ code %*
+))
\ No newline at end of file
diff --git a/portable/scripts/wpcp.bat b/portable/scripts/wpcp.bat
new file mode 100644
index 00000000..5edb982c
--- /dev/null
+++ b/portable/scripts/wpcp.bat
@@ -0,0 +1,3 @@
+@echo off
+call "%~dp0env_for_icons.bat" %*
+cmd.exe /k "echo wppm & wppm %*"
\ No newline at end of file
diff --git a/requirements64_slim.txt b/requirements64_slim.txt
new file mode 100644
index 00000000..9c0872cd
--- /dev/null
+++ b/requirements64_slim.txt
@@ -0,0 +1,510 @@
+# 313
+# ortool 290MO UNCOMPRESSED
+# re-add pandoc … 618Mo?
+# 698 Mo after remoal of moviepy/imageio-ffmpeg
+# 714 Mo after removal of maturin and WASM Klein
+# 725Mo before removal of: maturin 7 Mo, WASM KLEIN example
+#2024-09-22: swifter removed
+
+#2024-12-28 add pydantic_ai
+
+# the essential
+wheel
+pywin32
+build
+
+
+# compilers
+cython
+pycparser
+cffi
+
+# numeric stones
+numpy
+
+scipy
+sympy
+Pillow
+matplotlib
+
+pandas
+
+# sql - data
+
+pyodbc
+
+
+SQLAlchemy
+sqlparse
+sqlite_bro
+baresql
+mysql_connector_python
+pg8000
+ipython_sql
+
+XlsxWriter
+
+pymongo
+redis
+
+# high numeric
+#numexpr 2024-12-25: not worth it
+
+#h5py 2024-12-25: not worth it
+
+cytoolz
+#netCDF4 2024-12-25: not worth it
+xarray
+
+#Pulp 2024-12-25: not worth it
+
+scikit_learn
+scikit_image
+
+
+
+# gui
+jupyter
+ipython
+
+spyder
+
+# seaborn wants patsy and statsmodels for linear modeling
+seaborn
+patsy
+statsmodels
+
+holoviews
+mpld3
+
+# web
+beautifulsoup4
+
+lxml
+html5lib
+requests
+
+
+simplejson
+
+flask
+
+# dev complements
+
+pytest
+jedi
+pep8
+pyflakes
+
+pylint
+
+numpydoc
+
+twine
+
+# other
+networkx
+nltk
+
+# PyAudio 2024-12-25: not worth it, no visibility of source
+sounddevice
+
+pyserial
+
+#pdf
+
+reportlab
+
+
+# Pierre Raybaut Stack (PyQt5 only for now)
+plotpy
+PythonQwt
+guidata
+
+# for dask
+
+lmfit
+
+# Qt
+
+pyqtgraph
+
+
+# yet other
+julia
+
+# remember me why
+certifi
+click
+
+
+
+sphinx_rtd_theme
+Sphinx
+greenlet
+rx
+
+# wheelhouse-uploader apache-libcloud (is heavy)
+
+Markdown
+
+prompt-toolkit
+ptpython
+
+geopy
+
+wordcloud
+
+
+
+pycodestyle
+
+altair
+nbconvert
+pypandoc
+
+
+
+
+fuzzywuzzy
+#scikit_fuzzy
+imageio
+
+#xlwings 2024-12-25 not worth it
+
+# parallelize (and replace celery)
+joblib
+#dask[complete] contains irrelevant pyarrow-hotfix
+dask[array,dataframe,distributed,diagnostics]
+
+# dask 'bag' and 'delayed'
+cloudpickle
+toolz
+partd
+
+brotli
+
+
+pybind11
+
+#SLIM_2024 pygame
+plotnine
+
+mpl_scatter_density
+
+
+
+
+#SLIM_2024 moviepy
+
+
+streamz
+
+
+# Tensorflow_world
+###edward
+###Keras
+###keras_vis
+###Tensorflow_cpu
+###tensorflow_probability
+
+##keras-tuner
+
+# pytorch eco-system
+#Torch
+#torchvision
+#torchaudio
+#botorch
+#lightning
+#kornia
+#transformers[torch]
+#accelerate
+#fidle (tensorboard-2.15.1 wants still protobuf<4.24 , problem with ortools)
+## waiting for torch:
+##fastai
+##spacy
+
+# if we drop torch: jaxlib ml-dtypes numpy scipy jax opt-einsum
+#jax[cpu]
+
+terminado
+
+# pywinpty added due link removed from terminado for PyPy3
+pywinpty
+
+Send2Trash
+
+vega_datasets
+
+regex
+
+#loky
+
+hvplot
+
+#clrmagic 2024-12-25 not Worth it
+#pythonnet 2024-12-25 not Worth it
+
+cvxopt
+
+numba
+##pyarrow
+
+
+cvxpy
+mypy
+
+datashader
+
+mlxtend
+
+##jupyterlab_rise
+
+simpy
+
+
+trio
+
+imbalanced-learn
+
+tzlocal
+astropy
+
+panel
+
+hypothesis
+geopandas
+
+mercantile
+
+#rasterio 2024-12-25 not jangmin and maxsecure
+
+quantecon
+
+kiwisolver
+
+# automate notebooks 2019-04-26
+papermill
+
+autopep8
+black
+
+## winrt not yet
+
+
+# python_language_server no more
+python_lsp_server
+pexpect
+
+
+#swagger flask (still no asyncio choice)
+#flask_accepts
+#flaskerize
+# flask_RESTplus ... shall be now flask-restx
+quart
+datasette
+hypercorn
+
+#complementing asgi stack
+#2023-03-19 no more with sqlalchemy2.0
+##databases[sqlite]
+
+## ibis-framework no big life
+
+folium
+plotly
+
+
+umap-learn
+#SLIM_2024 virtualenv
+pympler
+## pipdeptree replaced par wppm
+
+##nlopt
+
+#2025-02-15 flask-sqlalchemy
+#2025-02-15 flask-session
+#2025-02-15 flask-Mail
+python-dotenv
+httpie
+asgiref
+
+#SLIM_2024 importlib_metadata
+
+
+##jupyterlab things
+jupyterlab
+widgetsnbextension
+
+##jupyterlab_launcher
+jupyter_bokeh
+#2023-05-21 too fragile: dask_labextension
+#SLIM_2024 pydeck
+
+## jupyterlab3 only
+jupyterlab-widgets
+
+## 2020-09-27 jupyterlab2 only
+ipympl
+ipyleaflet
+
+ipycanvas
+
+#SLIM_2024 wasmer
+#SLIM_2024 wasmer_compiler_cranelift
+#SLIM_2024 wasmer_compiler_singlepass
+
+fastapi
+
+
+datasette_graphql
+sqlite_utils
+aiosqlite
+
+
+## onnxruntime
+
+##sklearn-contrib-lightning
+openpyxl
+zstandard
+
+
+pynndescent
+
+
+flit
+## 2023-10-15 (too constraining) poetry
+## so moves to hatch
+## buth hatch wants now uv.. a bit too much
+hatchling
+
+#ecos 2024-12-25
+
+##csvs_to_sqlite
+datasette_graphql
+sqlite_utils
+
+maturin
+
+orjson
+
+
+#2023-08-22 fuzz replacements
+rapidfuzz
+
+## waiting pyarrow on 3.11 oct 23th
+streamlit
+
+## 2024-09-08 until plotly at least updates its lumnio thing https://github.com/plotly/plotly.py/pull/4685
+# dash
+alembic
+
+
+#webapps example needs
+Django
+#channels
+
+
+## badly formed uvicorn[standard]
+uvicorn
+python-multipart
+deap
+
+polars
+
+##timseries bis
+
+
+# for SSRS
+requests_ntlm
+missingno
+
+##xgboost
+# lightgbm ?
+duckdb
+
+
+# for flask
+waitress
+
+#2023-10-08 soon:jupyterlab-lsp
+
+array-api-compat
+
+
+mpmath
+
+openai
+
+
+#azure
+azure-identity
+azure-cosmos
+azure-core
+
+## build
+
+# write & read QRcode
+python-barcode
+qrcode
+opencv-python
+
+#llm follow-up
+# llm
+#risk llm_gpt4all
+# llm_llama_cpp
+# llm_markov
+# llm-python
+huggingface_hub
+
+
+#course of langchain https://learn.deeplearning.ai/langchain-chat-with-your-data
+pypdf
+yt_dlp
+pydub
+
+
+# new friends of panel (load psygnal, a qt-like signaling)
+anywidget
+
+keras
+
+
+
+# pyomo becomes a frequent wrapper nowodays
+
+langchain
+pyomo
+#NUMPY2_WAIT highspy
+#pymoo 2024-12-25 not well maintained
+
+clarabel
+#SLIM_2024 ortools
+
+#waiting cvxpy
+scs
+optuna
+
+
+#pyarrow complement
+adbc_driver_manager
+#adbc_driver_sqlite
+#backport optional importlib_resources
+
+#cartopy 2024-12-26 use geopandas more popular (that include gdal via pyogrio)
+
+#2024-12-26 agent ai things
+pydantic_ai
+#skrub replaces dirty_cat, seems needing torch
+termcolor
+tiktoken
+
+# from Microsoft own distro
+thefuzz
+tabulate
+squarify
+PyWavelets
+prince
+faker
+
+pyusb
diff --git a/requirements_mkl.txt b/requirements_mkl.txt
deleted file mode 100644
index a2a94317..00000000
--- a/requirements_mkl.txt
+++ /dev/null
@@ -1,370 +0,0 @@
-# the essential
-wheel
-pywin32
-
-# compilers
-cython
-pycparser
-cffi
-numba
-maturin
-
-# done in pre-step
-## numpy
-## scipy
-## numexpr
-## mkl_service
-
-# pytorch eco-system
-#Torch
-#torchvision
-#torchaudio
-#botorch
-#fastai
-#dask_ml
-
-#LLM huggingface
-#openai
-#transformers[torch]
-#accelerate
-
-
-# complementary tools
-mypy
-black
-pep8
-twine
-pytest
-coverage
-hypothesis
-pybind11
-flit
-poetry
-virtualenv
-pympler
-
-sqlite_bro
-baresql
-idlex
-
-# scientific
-matplotlib
-sympy
-
-scikit_learn
-scikit_image
-
-SQLAlchemy
-alembic
-
-#statistic
-statsmodels
-pmdarima
-pymc
-
-# to become skrub
-dirty_cat
-
-pandas
-# pandas-datareader
-xarray
-
-#pdf
-pdfrw
-reportlab
-
-#git
-gitdb
-gitpython
-
-# Jupyter
-jupyter
-# jupyterlab, ipython
-papermill
-ipython_sql
-ipympl
-ipyleaflet
-ipycanvas
-#not popular jupyterlab_rise
-
-jedi
-
-# gui
-seaborn
-altair
-plotnine
-plotly
-bokeh
-datashader
-holoviews
-mpld3
-networkx
-bqplot
-imageio
-imageio_ffmpeg
-hvplot
-wordcloud
-panel
-
-
-# gui geographic
-geopandas
-geopy
-pydeck
-# geoviews has no success
-gdal
-
-#solvers
-pycosat
-ecos
-qpsolvers
-cvxpy
-pulp
-
-# Qt5
-
-# QT
-spyder
-pyzo
-pyqtgraph
-qtconsole
-guiqwt
-PythonQwt
-guidata
-formlayout
-folium
-
-# web
-Flask
-Django
-python_dotenv
-uvicorn
-beautifulsoup4
-regex
-lxml
-html5lib
-requests
-datasette
-yarl
-xmltodict
-pystache
-pysocks
-pyjwt
-mako
-
-# parallelize (and replace celery)
-joblib
-dask[complete]
-dask_image
-cloudpickle
-fastparquet
-
-# write & read QRcode
-python-barcode
-qrcode
-opencv-python
-
-# ports
-pyodbc
-pyserial
-# pywinusb to replace per puysb+libusb-package ?
-pywinusb
-
-#rust packages
-duckdb
-polars
-
-# excel
-xlsxwriter
-openpyxl
-
-# connect to other langages
-julia
-pythonnet
-clrmagic
-
-ptpython
-
-# async
-trio
-trio-asyncio
-
-# large lange models
-llm
-llm_gpt4all
-llm_llama_cpp
-llm_markov
-huggingface_hub
-
-imbalanced-learn
-
-
-fastapi
-
-
-# needs recent wheel for altai5
-#great_expectations
-
-datasette_graphql
-sqlite_utils
-db.py
-aiosqlite
-
-
-# compression
-zstandard
-
-#2023-08-22 fuzz replacements
-rapidfuzz
-
-# dashboards
-streamlit
-dash
-
-#popular 2023-08-23
-greenlet
-Markdown
-docopt
-PyOpenGL
-Sphinx
-sphinx_rtd_theme
-rx
-bottleneck
-pystache
-pypandoc
-scikit-optimize
-fuzzywuzzy
-loky
-astropy
-snuggs
-rasterio
-flask-session
-python-multipart
-filterpy
-requests_ntlm
-
-swifter
-emcee
-zarr
-pyflux
-snakeviz
-nbdime
-simplegeneric
-ipydatagrid
-
-simpy
-supersmoother
-mpl_scatter_density
-ppci
-nltk
-simplejson
-sounddevice
-pygame
-moviepy
-altair-transform
-altair_data_server
-pygad
-xgboost
-xlwings
-cvxopt
-mpmath
-#azure
-azure-identity
-azure-cosmos
-azure-core
-sspyrs
-
-# sql - data
-adodbapi
-
-
-sqlparse
-
-mysql_connector_python
-pg8000
-
-pymongo
-redis
-
-#hdf files
-h5py
-tables
-netCDF4
-# not_popular python-hdf4
-
-cytoolz
-
-blosc
-
-brewer2mpl
-
-PyAudio
-
-lmfit
-
-# less popular cartographic
-mercantile
-pyepsg
-
-#preparing parquet
-python_snappy
-brotli
-
-feather_format
-
-jupyter_sphinx
-
-streamz
-
-vega_datasets
-
-
-gmpy2
-
-mlxtend
-
-quantecon
-
-quart
-
-hypercorn
-
-umap-learn
-flask-sqlalchemy
-
-nlopt
-
-httpie
-flask-Mail
-
-lz4
-
-jupyter_bokeh
-
-pydeck
-
-wasmer
-wasmer_compiler_cranelift
-wasmer_compiler_singlepass
-
-nbval
-
-## onnxruntime
-
-pynndescent
-
-quadprog
-
-orjson
-
-jupyter_packaging
-
-deap
-
-tbats
-
-missingno
-
-# for flask
-waitress
-
diff --git a/winpython/__init__.py b/winpython/__init__.py
index cca25d39..468eed57 100644
--- a/winpython/__init__.py
+++ b/winpython/__init__.py
@@ -4,7 +4,7 @@
-----------------------------------------
Copyright (c) 2012-2013 Pierre Raybaut
-Copyright (c) 2014-2024+ The Winpython development team https://github.com/winpython/
+Copyright (c) 2014-2025+ The Winpython development team https://github.com/winpython/
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
@@ -28,6 +28,6 @@
OTHER DEALINGS IN THE SOFTWARE.
"""
-__version__ = '13.1.20250222'
+__version__ = '16.4.20250603'
__license__ = __doc__
__project_url__ = 'http://winpython.github.io/'
diff --git a/winpython/associate.py b/winpython/associate.py
index 8868ea7a..894d8bda 100644
--- a/winpython/associate.py
+++ b/winpython/associate.py
@@ -1,430 +1,300 @@
# -*- coding: utf-8 -*-
#
+# associate.py = Register a Python distribution
# Copyright © 2012 Pierre Raybaut
# Licensed under the terms of the MIT License
# (see winpython/__init__.py for details)
-"""
-Register a Python distribution
-
-Created on Tue Aug 21 21:46:30 2012
-"""
-
import sys
import os
from pathlib import Path
-import platform
-import importlib
+import importlib.util
+import winreg
+from . import utils
+from argparse import ArgumentParser
-# import subprocess
+def get_special_folder_path(path_name):
+ """Return special folder path."""
+ from win32com.shell import shell, shellcon
+ try:
+ csidl = getattr(shellcon, path_name)
+ return shell.SHGetSpecialFolderPath(0, csidl, False)
+ except OSError:
+ print(f"{path_name} is an unknown path ID")
+def get_winpython_start_menu_folder(current=True):
+ """Return WinPython Start menu shortcuts folder."""
+ folder = get_special_folder_path("CSIDL_PROGRAMS")
+ if not current:
+ try:
+ folder = get_special_folder_path("CSIDL_COMMON_PROGRAMS")
+ except OSError:
+ pass
+ return str(Path(folder) / 'WinPython')
-# Local imports
-import winreg
-from winpython import utils
-
-KEY_C = r"Software\Classes\%s"
-KEY_C0 = KEY_C % r"Python.%sFile\shell"
-KEY_C1 = KEY_C % r"Python.%sFile\shell\%s"
-KEY_C2 = KEY_C1 + r"\command"
-KEY_DROP0 = KEY_C % r"Python.%sFile\shellex"
-KEY_DROP1 = KEY_C % r"Python.%sFile\shellex\DropHandler"
-KEY_I = KEY_C % r"Python.%sFile\DefaultIcon"
-KEY_D = KEY_C % r"Python.%sFile"
-EWI = "Edit with IDLE"
-EWS = "Edit with Spyder"
-
-KEY_S = r"Software\Python"
-KEY_S0 = KEY_S + r"\WinPython" # was PythonCore before PEP-0514
-KEY_S1 = KEY_S0 + r"\%s"
-
-def _remove_start_menu_folder(target, current=True):
- "remove menu Folder for target WinPython"
- import importlib.util
- win32com_exists = importlib.util.find_spec('win32com') is not None
-
- # we return nothing if no win32com package
- if win32com_exists:
- utils.remove_winpython_start_menu_folder(current=current)
-
-def _get_shortcut_data(target, current=True):
- "get windows menu access, if win32com exists otherwise nothing"
- import importlib.util
- win32com_exists = importlib.util.find_spec('win32com') is not None
-
- # we return nothing if no win32com package
- if not win32com_exists:
+def remove_winpython_start_menu_folder(current=True):
+ """Remove WinPython Start menu folder -- remove it if it already exists"""
+ path = get_winpython_start_menu_folder(current=current)
+ if Path(path).is_dir():
+ try:
+ shutil.rmtree(path, onexc=onerror)
+ except WindowsError:
+ print(f"Directory {path} could not be removed", file=sys.stderr)
+
+def create_winpython_start_menu_folder(current=True):
+ """Create WinPython Start menu folder."""
+ path = get_winpython_start_menu_folder(current=current)
+ if Path(path).is_dir():
+ try:
+ shutil.rmtree(path, onexc=onerror)
+ except WindowsError:
+ print(f"Directory {path} could not be removed", file=sys.stderr)
+ Path(path).mkdir(parents=True, exist_ok=True)
+ return path
+
+def create_shortcut(path, description, filename, arguments="", workdir="", iconpath="", iconindex=0, verbose=True):
+ """Create Windows shortcut (.lnk file)."""
+ import pythoncom
+ from win32com.shell import shell
+ ilink = pythoncom.CoCreateInstance(shell.CLSID_ShellLink, None, pythoncom.CLSCTX_INPROC_SERVER, shell.IID_IShellLink)
+ ilink.SetPath(path)
+ ilink.SetDescription(description)
+ if arguments:
+ ilink.SetArguments(arguments)
+ if workdir:
+ ilink.SetWorkingDirectory(workdir)
+ if iconpath or iconindex:
+ ilink.SetIconLocation(iconpath, iconindex)
+ # now save it.
+ ipf = ilink.QueryInterface(pythoncom.IID_IPersistFile)
+ if not filename.endswith('.lnk'):
+ filename += '.lnk'
+ if verbose:
+ print(f'create menu *{filename}*')
+ try:
+ ipf.Save(filename, 0)
+ except:
+ print("a fail !")
+
+# --- Helper functions for Registry ---
+
+def _set_reg_value(root, key_path, name, value, reg_type=winreg.REG_SZ, verbose=False):
+ """Helper to create key and set a registry value using CreateKeyEx."""
+ rootkey_name = "HKEY_CURRENT_USER" if root == winreg.HKEY_CURRENT_USER else "HKEY_LOCAL_MACHINE"
+ if verbose:
+ print(f"{rootkey_name}\\{key_path}\\{name if name else ''}:{value}")
+ try:
+ # Use CreateKeyEx with context manager for automatic closing
+ with winreg.CreateKeyEx(root, key_path, 0, winreg.KEY_WRITE) as key:
+ winreg.SetValueEx(key, name, 0, reg_type, value)
+ except OSError as e:
+ print(f"Error creating/setting registry value {rootkey_name}\\{key_path}\\{name}: {e}", file=sys.stderr)
+
+def _delete_reg_key(root, key_path, verbose=False):
+ """Helper to delete a registry key, ignoring if not found."""
+ rootkey_name = "HKEY_CURRENT_USER" if root == winreg.HKEY_CURRENT_USER else "HKEY_LOCAL_MACHINE"
+ if verbose:
+ print(f"{rootkey_name}\\{key_path}")
+ try:
+ # DeleteKey can only delete keys with no subkeys.
+ # For keys with (still) subkeys, use DeleteKeyEx on the parent key if available
+ winreg.DeleteKey(root, key_path)
+ except FileNotFoundError:
+ if verbose:
+ print(f"Registry key not found (skipping deletion): {rootkey_name}\\{key_path}")
+ except OSError as e: # Catch other potential errors like key not empty
+ print(f"Error deleting registry key {rootkey_name}\\{key_path}: {e}", file=sys.stderr)
+
+
+# --- Helper functions for Start Menu Shortcuts ---
+
+def _has_pywin32():
+ """Check if pywin32 (pythoncom) is installed."""
+ return importlib.util.find_spec('pythoncom') is not None
+
+def _remove_start_menu_folder(target, current=True, has_pywin32=False):
+ "remove menu Folder for target WinPython if pywin32 exists"
+ if has_pywin32:
+ remove_winpython_start_menu_folder(current=current)
+ else:
+ print("Skipping start menu removal as pywin32 package is not installed.")
+
+def _get_shortcut_data(target, current=True, has_pywin32=False):
+ "get windows menu access data if pywin32 exists, otherwise empty list"
+ if not has_pywin32:
return []
- wpgroup = utils.create_winpython_start_menu_folder(current=current)
+
wpdir = str(Path(target).parent)
data = []
for name in os.listdir(wpdir):
bname, ext = Path(name).stem, Path(name).suffix
- if ext == ".exe":
+ if ext.lower() == ".exe":
+ # Path for the shortcut file in the start menu folder
+ shortcut_name = str(Path(create_winpython_start_menu_folder(current=current)) / bname) + '.lnk'
data.append(
(
- str(Path(wpdir) / name),
- bname,
- str(Path(wpgroup) / bname),
+ str(Path(wpdir) / name), # Target executable path
+ bname, # Description/Name
+ shortcut_name, # Shortcut file path
)
)
return data
+# --- PythonCore entries (PEP-0514 and WinPython specific) ---
+
+
+def register_in_registery(target, current=True, reg_type=winreg.REG_SZ, verbose=True) -> tuple[list[any], ...]:
+ """Register in Windows (like regedit)"""
-def register(target, current=True, verbose=True):
- """Register a Python distribution in Windows registry"""
+ # --- Constants ---
+ DROP_HANDLER_CLSID = "{60254CA5-953B-11CF-8C96-00AA00B8708C}"
+
+ # --- CONFIG ---
+ target_path = Path(target).resolve()
+ python_exe = str(target_path / "python.exe")
+ pythonw_exe = str(target_path / "pythonw.exe")
+ spyder_exe = str(target_path.parent / "Spyder.exe")
+ icon_py = str(target_path / "DLLs" / "py.ico")
+ icon_pyc = str(target_path / "DLLs" / "pyc.ico")
+ idle_path = str(target_path / "Lib" / "idlelib" / "idle.pyw")
+ doc_path = str(target_path / "Doc" / "html" / "index.html")
+ python_infos = utils.get_python_infos(target) # ('3.11', 64)
+ short_version = python_infos[0] # e.g., '3.11'
+ version = utils.get_python_long_version(target) # e.g., '3.11.5'
+ arch = f'{python_infos[1]}bit' # e.g., '64bit'
+ display = f"Python {version} ({arch})"
+
+ permanent_entries = [] # key_path, name, value
+ dynamic_entries = [] # key_path, name, value
+ core_entries = [] # key_path, name, value
+ lost_entries = [] # intermediate keys to remove later
+ # --- File associations ---
+ ext_map = {".py": "Python.File", ".pyw": "Python.NoConFile", ".pyc": "Python.CompiledFile"}
+ ext_label = {".py": "Python File", ".pyw": "Python File (no console)", ".pyc": "Compiled Python File"}
+ for ext, ftype in ext_map.items():
+ permanent_entries.append((f"Software\\Classes\\{ext}", None, ftype))
+ if ext in (".py", ".pyw"):
+ permanent_entries.append((f"Software\\Classes\\{ext}", "Content Type", "text/plain"))
+
+ # --- Descriptions, Icons, DropHandlers ---
+ for ext, ftype in ext_map.items():
+ dynamic_entries.append((f"Software\\Classes\\{ftype}", None, ext_label[ext]))
+ dynamic_entries.append((f"Software\\Classes\\{ftype}\\DefaultIcon", None, icon_py if "Compiled" not in ftype else icon_pyc))
+ dynamic_entries.append((f"Software\\Classes\\{ftype}\\shellex\\DropHandler", None, DROP_HANDLER_CLSID))
+ lost_entries.append((f"Software\\Classes\\{ftype}\\shellex", None, None))
+
+ # --- Shell commands ---
+ for ext, ftype in ext_map.items():
+ dynamic_entries.append((f"Software\\Classes\\{ftype}\\shell\\open\\command", None, f'''"{pythonw_exe if ftype=='Python.NoConFile' else python_exe}" "%1" %*'''))
+ lost_entries.append((f"Software\\Classes\\{ftype}\\shell\\open", None, None))
+ lost_entries.append((f"Software\\Classes\\{ftype}\\shell", None, None))
+
+ dynamic_entries.append((rf"Software\Classes\Python.File\shell\Edit with IDLE\command", None, f'"{pythonw_exe}" "{idle_path}" -n -e "%1"'))
+ dynamic_entries.append((rf"Software\Classes\Python.NoConFile\shell\Edit with IDLE\command", None, f'"{pythonw_exe}" "{idle_path}" -n -e "%1"'))
+ lost_entries.append((rf"Software\Classes\Python.File\shell\Edit with IDLE", None, None))
+ lost_entries.append((rf"Software\Classes\Python.NoConFile\shell\Edit with IDLE", None, None))
+
+ if Path(spyder_exe).exists():
+ dynamic_entries.append((rf"Software\Classes\Python.File\shell\Edit with Spyder\command", None, f'"{spyder_exe}" "%1" -w "%w"'))
+ dynamic_entries.append((rf"Software\Classes\Python.NoConFile\shell\Edit with Spyder\command", None, f'"{spyder_exe}" "%1" -w "%w"'))
+ lost_entries.append((rf"Software\Classes\Python.File\shell\Edit with Spyder", None, None))
+ lost_entries.append((rf"Software\Classes\Python.NoConFile\shell\Edit with Spyder", None, None))
+
+ # --- WinPython Core registry entries (PEP 514 style) ---
+ base = f"Software\\Python\\WinPython\\{short_version}"
+ core_entries.append((base, "DisplayName", display))
+ core_entries.append((base, "SupportUrl", "https://winpython.github.io"))
+ core_entries.append((base, "SysVersion", short_version))
+ core_entries.append((base, "SysArchitecture", arch))
+ core_entries.append((base, "Version", version))
+
+ core_entries.append((f"{base}\\InstallPath", None, str(target)))
+ core_entries.append((f"{base}\\InstallPath", "ExecutablePath", python_exe))
+ core_entries.append((f"{base}\\InstallPath", "WindowedExecutablePath", pythonw_exe))
+ core_entries.append((f"{base}\\InstallPath\\InstallGroup", None, f"Python {short_version}"))
+
+ core_entries.append((f"{base}\\Modules", None, ""))
+ core_entries.append((f"{base}\\PythonPath", None, f"{target}\\Lib;{target}\\DLLs"))
+ core_entries.append((f"{base}\\Help\\Main Python Documentation", None, doc_path))
+ lost_entries.append((f"{base}\\Help", None, None))
+ lost_entries.append((f"Software\\Python\\WinPython", None, None))
+
+ return permanent_entries, dynamic_entries, core_entries, lost_entries
+
+# --- Main Register/Unregister Functions ---
+
+def register(target, current=True, reg_type=winreg.REG_SZ, verbose=True):
+ """Register a Python distribution in Windows registry and create Start Menu shortcuts"""
root = winreg.HKEY_CURRENT_USER if current else winreg.HKEY_LOCAL_MACHINE
+ has_pywin32 = _has_pywin32()
- # Creating Registry entries
if verbose:
print(f'Creating WinPython registry entries for {target}')
- # Extensions
- winreg.SetValueEx(
- winreg.CreateKey(root, KEY_C % ".py"),
- "",
- 0,
- winreg.REG_SZ,
- "Python.File",
- )
- winreg.SetValueEx(
- winreg.CreateKey(root, KEY_C % ".pyw"),
- "",
- 0,
- winreg.REG_SZ,
- "Python.NoConFile",
- )
- winreg.SetValueEx(
- winreg.CreateKey(root, KEY_C % ".pyc"),
- "",
- 0,
- winreg.REG_SZ,
- "Python.CompiledFile",
- )
- winreg.SetValueEx(
- winreg.CreateKey(root, KEY_C % ".pyo"),
- "",
- 0,
- winreg.REG_SZ,
- "Python.CompiledFile",
- )
-
- # MIME types
- winreg.SetValueEx(
- winreg.CreateKey(root, KEY_C % ".py"),
- "Content Type",
- 0,
- winreg.REG_SZ,
- "text/plain",
- )
- winreg.SetValueEx(
- winreg.CreateKey(root, KEY_C % ".pyw"),
- "Content Type",
- 0,
- winreg.REG_SZ,
- "text/plain",
- )
-
- # Verbs
- python = str((Path(target) / "python.exe").resolve())
- pythonw = str((Path(target) / "pythonw.exe").resolve())
- spyder = str((Path(target).parent / "Spyder.exe").resolve())
-
- if not Path(spyder).is_file():
- spyder = f'{pythonw}" "{target}\Scripts\spyder'
- winreg.SetValueEx(
- winreg.CreateKey(root, KEY_C2 % ("", "open")),
- "",
- 0,
- winreg.REG_SZ,
- '"%s" "%%1" %%*' % python,
- )
- winreg.SetValueEx(
- winreg.CreateKey(root, KEY_C2 % ("NoCon", "open")),
- "",
- 0,
- winreg.REG_SZ,
- '"%s" "%%1" %%*' % pythonw,
- )
- winreg.SetValueEx(
- winreg.CreateKey(root, KEY_C2 % ("Compiled", "open")),
- "",
- 0,
- winreg.REG_SZ,
- '"%s" "%%1" %%*' % python,
- )
- winreg.SetValueEx(
- winreg.CreateKey(root, KEY_C2 % ("", EWI)),
- "",
- 0,
- winreg.REG_SZ,
- '"%s" "%s\Lib\idlelib\idle.pyw" -n -e "%%1"' % (pythonw, target),
- )
- winreg.SetValueEx(
- winreg.CreateKey(root, KEY_C2 % ("NoCon", EWI)),
- "",
- 0,
- winreg.REG_SZ,
- '"%s" "%s\Lib\idlelib\idle.pyw" -n -e "%%1"' % (pythonw, target),
- )
- winreg.SetValueEx(
- winreg.CreateKey(root, KEY_C2 % ("", EWS)),
- "",
- 0,
- winreg.REG_SZ,
- '"%s" "%%1"' % spyder,
- )
- winreg.SetValueEx(
- winreg.CreateKey(root, KEY_C2 % ("NoCon", EWS)),
- "",
- 0,
- winreg.REG_SZ,
- '"%s" "%%1"' % spyder,
- )
-
- # Drop support
- handler = "{60254CA5-953B-11CF-8C96-00AA00B8708C}"
- for ftype in ("", "NoCon", "Compiled"):
- winreg.SetValueEx(
- winreg.CreateKey(root, KEY_DROP1 % ftype),
- "",
- 0,
- winreg.REG_SZ,
- handler,
- )
- # Icons
- dlls = str(Path(target) / "DLLs")
- winreg.SetValueEx(
- winreg.CreateKey(root, KEY_I % ""),
- "",
- 0,
- winreg.REG_SZ,
- r"%s\py.ico" % dlls,
- )
- winreg.SetValueEx(
- winreg.CreateKey(root, KEY_I % "NoCon"),
- "",
- 0,
- winreg.REG_SZ,
- r"%s\py.ico" % dlls,
- )
- winreg.SetValueEx(
- winreg.CreateKey(root, KEY_I % "Compiled"),
- "",
- 0,
- winreg.REG_SZ,
- r"%s\pyc.ico" % dlls,
- )
-
- # Descriptions
- winreg.SetValueEx(
- winreg.CreateKey(root, KEY_D % ""),
- "",
- 0,
- winreg.REG_SZ,
- "Python File",
- )
- winreg.SetValueEx(
- winreg.CreateKey(root, KEY_D % "NoCon"),
- "",
- 0,
- winreg.REG_SZ,
- "Python File (no console)",
- )
- winreg.SetValueEx(
- winreg.CreateKey(root, KEY_D % "Compiled"),
- "",
- 0,
- winreg.REG_SZ,
- "Compiled Python File",
- )
-
- # PythonCore entries
- python_infos = utils.get_python_infos(target) # ('3.11', 64)
- short_version = python_infos[0] # 3.11 from ('3.11', 64)
- long_version = utils.get_python_long_version(target) # 3.11.5
- key_core = (KEY_S1 % short_version) + r"\%s" # Winpython\3.11
-
- # PEP-0514 additions, with standard Python practice
- SupportUrl="https://winpython.github.io"
- SysArchitecture = platform.architecture()[0] # '64bit'
- SysVersion = '.'.join(platform.python_version_tuple()[:2]) # '3.11'
- Version = platform.python_version() # '3.11.5'
-
- # But keep consistent with past possibilities until more alignement
- SysArchitecture = f'{python_infos[1]}bit' # '64bit'
- SysVersion = short_version
- Version = long_version
-
- DisplayName = f'Python {Version} ({SysArchitecture})'
- key_short = (KEY_S1 % short_version) # WinPython\3.11
- key_keys={'DisplayName':DisplayName,
- 'SupportUrl':SupportUrl,
- 'SysVersion':SysVersion,
- 'SysArchitecture':SysArchitecture,
- 'Version':Version}
-
- regkey = winreg.CreateKey(root, key_short)
- # see https://www.programcreek.com/python/example/106949/winreg.CreateKey
- # winreg.SetValueEx(key, '', reg.REG_SZ, '')
- for k, v in key_keys.items():
- winreg.SetValueEx(
- regkey,
- k,
- 0,
- winreg.REG_SZ,
- v,
- )
- winreg.CloseKey(regkey)
-
- # pep-0514 additions at InstallPathLevel
- ExecutablePath = python
- WindowedExecutablePath = pythonw
-
- key_short = key_core % "InstallPath" # WinPython\3.11\InstallPath
- key_keys={'ExecutablePath':ExecutablePath,
- 'WindowedExecutablePath':WindowedExecutablePath}
-
- regkey = winreg.CreateKey(root, key_core % "InstallPath")
- winreg.SetValueEx(
- regkey,
- "",
- 0,
- winreg.REG_SZ,
- target + '\\',
- )
- for k, v in key_keys.items():
- winreg.SetValueEx(
- regkey,
- k,
- 0,
- winreg.REG_SZ,
- v,
- )
- winreg.CloseKey(regkey)
-
-
-
- winreg.SetValueEx(
- winreg.CreateKey(root, key_core % r"InstallPath\InstallGroup"),
- "",
- 0,
- winreg.REG_SZ,
- "Python %s" % short_version,
- )
- winreg.SetValueEx(
- winreg.CreateKey(root, key_core % "Modules"),
- "",
- 0,
- winreg.REG_SZ,
- "",
- )
- winreg.SetValueEx(
- winreg.CreateKey(root, key_core % "PythonPath"),
- "",
- 0,
- winreg.REG_SZ,
- r"%s\Lib;%s\DLLs" % (target, target),
- )
- winreg.SetValueEx(
- winreg.CreateKey(
- root,
- key_core % r"Help\Main Python Documentation",
- ),
- "",
- 0,
- winreg.REG_SZ,
- r"%s\Doc\python%s.chm" % (target, long_version),
- )
-
- # Create start menu entries for all WinPython launchers
- spec = importlib.util.find_spec('pythoncom')
- if verbose and spec is None:
- print(f"Can't create WinPython menu as pywin32 package is not installed")
- if verbose and spec is not None:
- print(f'Creating WinPython menu for all icons in {target}')
- for path, desc, fname in _get_shortcut_data(target, current=current):
- utils.create_shortcut(path, desc, fname, verbose=verbose)
+ permanent_entries, dynamic_entries, core_entries, lost_entries = register_in_registery(target)
+ # Set registry entries for given target
+ for key_path, name, value in permanent_entries + dynamic_entries + core_entries:
+ _set_reg_value(root, key_path, name, value, verbose=verbose)
+
+ # Create start menu entries
+ if has_pywin32:
+ if verbose:
+ print(f'Creating WinPython menu for all icons in {target.parent}')
+ for path, desc, fname in _get_shortcut_data(target, current=current, has_pywin32=True):
+ try:
+ create_shortcut(path, desc, fname, verbose=verbose)
+ except Exception as e:
+ print(f"Error creating shortcut for {desc} at {fname}: {e}", file=sys.stderr)
+ else:
+ print("Skipping start menu shortcut creation as pywin32 package is needed.")
def unregister(target, current=True, verbose=True):
- """Unregister a Python distribution in Windows registry"""
- # Removing Registry entries
- if verbose:
- print(f'Removing WinPython registry entries for {target}')
+ """Unregister a Python distribution from Windows registry and remove Start Menu shortcuts"""
root = winreg.HKEY_CURRENT_USER if current else winreg.HKEY_LOCAL_MACHINE
- short_version = utils.get_python_infos(target)[0]
- key_core = (KEY_S1 % short_version) + r"\%s"
- for key in (
- # Drop support
- KEY_DROP1 % "",
- KEY_DROP1 % "NoCon",
- KEY_DROP1 % "Compiled",
- KEY_DROP0 % "",
- KEY_DROP0 % "NoCon",
- KEY_DROP0 % "Compiled",
- # Icons
- KEY_I % "NoCon",
- KEY_I % "Compiled",
- KEY_I % "",
- # Edit with IDLE
- KEY_C2 % ("", EWI),
- KEY_C2 % ("NoCon", EWI),
- KEY_C1 % ("", EWI),
- KEY_C1 % ("NoCon", EWI),
- # Edit with Spyder
- KEY_C2 % ("", EWS),
- KEY_C2 % ("NoCon", EWS),
- KEY_C1 % ("", EWS),
- KEY_C1 % ("NoCon", EWS),
- # Verbs
- KEY_C2 % ("", "open"),
- KEY_C2 % ("NoCon", "open"),
- KEY_C2 % ("Compiled", "open"),
- KEY_C1 % ("", "open"),
- KEY_C1 % ("NoCon", "open"),
- KEY_C1 % ("Compiled", "open"),
- KEY_C0 % "",
- KEY_C0 % "NoCon",
- KEY_C0 % "Compiled",
- # Descriptions
- KEY_D % "NoCon",
- KEY_D % "Compiled",
- KEY_D % "",
- # PythonCore
- key_core % r"InstallPath\InstallGroup",
- key_core % "InstallPath",
- key_core % "Modules",
- key_core % "PythonPath",
- key_core % r"Help\Main Python Documentation",
- key_core % "Help",
- KEY_S1 % short_version,
- KEY_S0,
- KEY_S,
- ):
- try:
- if verbose:
- print(key)
- winreg.DeleteKey(root, key)
- except WindowsError:
- rootkey = "HKEY_CURRENT_USER" if current else "HKEY_LOCAL_MACHINE"
- if verbose:
- print(
- r"Unable to remove %s\%s" % (rootkey, key),
- file=sys.stderr,
- )
- # remove menu shortcuts
- spec = importlib.util.find_spec('pythoncom')
- if verbose and spec is None:
- print(f"Can't remove WinPython menu as pywin32 package is not installed")
- if verbose and spec is not None:
- print(f'Removing WinPython menu for all icons in {target}')
- _remove_start_menu_folder(target, current=current)
-
- #for path, desc, fname in _get_shortcut_data(target, current=current):
- # if Path(fname).exists():
- # os.remove(fname)
+ has_pywin32 = _has_pywin32()
+
+ if verbose:
+ print(f'Removing WinPython registry entries for {target}')
+
+ permanent_entries, dynamic_entries, core_entries , lost_entries = register_in_registery(target)
+
+ # List of keys to attempt to delete, ordered from most specific to general
+ keys_to_delete = sorted(list(set(key_path for key_path , name, value in (dynamic_entries + core_entries + lost_entries))), key=len, reverse=True)
+
+ rootkey_name = "HKEY_CURRENT_USER" if root == winreg.HKEY_CURRENT_USER else "HKEY_LOCAL_MACHINE"
+ for key_path in keys_to_delete:
+ _delete_reg_key(root, key_path, verbose=verbose)
+
+ # Remove start menu shortcuts
+ if has_pywin32:
+ if verbose:
+ print(f'Removing WinPython menu for all icons in {target.parent}')
+ _remove_start_menu_folder(target, current=current, has_pywin32=True)
+ # The original code had commented out code to delete .lnk files individually.
+ else:
+ print("Skipping start menu removal as pywin32 package is needed.")
if __name__ == "__main__":
- register(sys.prefix)
- unregister(sys.prefix)
\ No newline at end of file
+ # Ensure we are running from the target WinPython environment
+ parser = ArgumentParser(description="Register or Un-register Python file extensions, icons "\
+ "and Windows explorer context menu to this "\
+ "Python distribution.")
+ parser.add_argument('--unregister', action="store_true",
+ help='register to all users, requiring administrative '\
+ 'privileges (default: register to current user only)')
+ parser.add_argument('--all', action="store_true",
+ help='action is to all users, requiring administrative '\
+ 'privileges (default: to current user only)')
+ args = parser.parse_args()
+ expected_target = Path(sys.prefix)
+ command = "unregister" if args.unregister else "register"
+ users = "all" if args.all else "user"
+ print(f"Attempting to {command} the Python environment for {users} at: {expected_target}")
+
+ target_dir = sys.prefix # Or get from arguments
+ is_current_user = True # Or get from arguments
+ if command == "register":
+ register(expected_target, current=not args.all)
+ else:
+ unregister(expected_target, current=not args.all)
diff --git a/winpython/data/tools.ini b/winpython/data/tools.ini
deleted file mode 100644
index 0f27fc8f..00000000
--- a/winpython/data/tools.ini
+++ /dev/null
@@ -1,47 +0,0 @@
-[gettext]
-description=GNU gettext Win32 porting - the GNU translation tool (useful tools for pygettext, a standard library module)
-url=https://sourceforge.net/projects/gettext
-
-[julia]
-description=The Julia Langage
-url=https://julialang.org/
-
-[mingw32]
-description=C/C++ and Fortran compilers (Mingwpy static toolchain version)
-url=https://github.com/numpy/numpy/wiki/Mingw-static-toolchain
-
-[pandoc]
-description=a universal document converter
-url=https://pandoc.org/
-
-[r]
-description=The R Project for Statistical Computing
-url=https://www.r-project.org
-
-[scite]
-description=SCIntilla based Text Editor - Multilanguage, powerful and light-weight text editor
-url=http://www.scintilla.org/SciTE.html
-
-[tortoisehg]
-description=Set of graphical tools and a shell extension for the Mercurial distributed revision control system
-url=https://tortoisehg.bitbucket.io/
-
-[winmerge]
-description=Open Source differencing and merging tool for Windows
-url=http://winmerge.org
-
-[nodejs]
-description=a JavaScript runtime built on Chrome's V8 JavaScript engine
-url=https://nodejs.org
-
-[npmjs]
-description=a package manager for JavaScript
-url=https://www.npmjs.com/
-
-[yarnpkg]
-description=a package manager for JavaScriptFast, reliable, and secure dependency management
-url=https://yarnpkg.com/lang/en/
-
-[ffmpeg]
-description=a collection of libraries and tools to process multimedia content such as audio, video, subtitles and related metadata
-url=https://ffmpeg.org
diff --git a/winpython/diff.py b/winpython/diff.py
new file mode 100644
index 00000000..a8e52e1d
--- /dev/null
+++ b/winpython/diff.py
@@ -0,0 +1,147 @@
+# -*- coding: utf-8 -*-
+#
+# WinPython diff.py script
+# Copyright © 2013 Pierre Raybaut
+# Copyright © 2014-2025+ The Winpython development team https://github.com/winpython/
+# Licensed under the terms of the MIT License
+# (see winpython/__init__.py for details)
+
+import os
+from pathlib import Path
+import re
+import shutil
+from packaging import version
+from . import utils
+
+CHANGELOGS_DIR = Path(__file__).parent.parent / "changelogs"
+assert CHANGELOGS_DIR.is_dir()
+
+class Package:
+ PATTERNS = [
+ r"\[([\w\-\:\/\.\_]+)\]\(([^)]+)\) \| ([^\|]*) \| ([^\|]*)", # SourceForge
+ r"\[([\w\-\:\/\.\_]+) ([^\]\ ]+)\] \| ([^\|]*) \| ([^\|]*)" # Google Code
+ ]
+
+ def __init__(self, text=None):
+ self.name = self.url = self.version = self.description = None
+ if text:
+ self.from_text(text)
+
+ def from_text(self, text):
+ for pattern in self.PATTERNS:
+ match = re.match(pattern, text)
+ if match:
+ self.name, self.url, self.version, self.description = match.groups()
+ return
+ raise ValueError(f"Unrecognized package line format: {text}")
+
+ def to_wiki(self):
+ return f" * [{self.name}]({self.url}) {self.version} ({self.description})\n"
+
+ def upgrade_wiki(self, other):
+ return f" * [{self.name}]({self.url}) {other.version} → {self.version} ({self.description})\n"
+
+class PackageIndex:
+ HEADERS = {"tools": "### Tools", "python": "### Python packages", "wheelhouse": "### WheelHouse packages"}
+ BLANKS = ["Name | Version | Description", "-----|---------|------------", "", "", " "]
+
+ def __init__(self, version, searchdir=None, flavor="", architecture=64):
+ self.version = version
+ self.flavor = flavor
+ self.searchdir = searchdir
+ self.architecture = architecture
+ self.packages = {"tools": {}, "python": {}, "wheelhouse": {}}
+ self._load_index()
+
+ def _load_index(self):
+ filename = self.searchdir / f"WinPython{self.flavor}-{self.architecture}bit-{self.version}.md"
+ if not filename.exists():
+ raise FileNotFoundError(f"Changelog not found: {filename}")
+
+ with open(filename, "r", encoding=utils.guess_encoding(filename)[0]) as f:
+ self._parse_index(f.read())
+
+ def _parse_index(self, text):
+ current = None
+ for line in text.splitlines():
+ if line in self.HEADERS.values():
+ current = [k for k, v in self.HEADERS.items() if v == line][0]
+ continue
+ if line.strip() in self.BLANKS:
+ continue
+ if current:
+ pkg = Package(line)
+ self.packages[current][pkg.name] = pkg
+
+def compare_packages(old, new):
+ """Return difference between package old and package new"""
+
+ # wheel replace '-' per '_' in key
+ def normalize(d): return {k.replace("-", "_").lower(): v for k, v in d.items()}
+ old, new = normalize(old), normalize(new)
+ output = ""
+
+ added = [new[k].to_wiki() for k in new if k not in old]
+ upgraded = [new[k].upgrade_wiki(old[k]) for k in new if k in old and new[k].version != old[k].version]
+ removed = [old[k].to_wiki() for k in old if k not in new]
+
+ if added:
+ output += "New packages:\n\n" + "".join(added) + "\n\n"
+ if upgraded:
+ output += "Upgraded packages:\n\n" + "".join(upgraded) + "\n\n"
+ if removed:
+ output += "Removed packages:\n\n" + "".join(removed) + "\n\n"
+ return output
+
+def find_previous_version(target_version, searchdir=None, flavor="", architecture=64):
+ """Find version which is the closest to `version`"""
+ search_dir = Path(searchdir) if searchdir else CHANGELOGS_DIR
+ pattern = re.compile(rf"WinPython{flavor}-{architecture}bit-([0-9\.]+)\.(txt|md)")
+ versions = [pattern.match(f).group(1) for f in os.listdir(search_dir) if pattern.match(f)]
+ versions = [v for v in versions if version.parse(v) < version.parse(target_version)]
+ return max(versions, key=version.parse, default=target_version)
+
+def compare_package_indexes(version2, version1=None, searchdir=None, flavor="", flavor1=None, architecture=64):
+ version1 = version1 or find_previous_version(version2, searchdir, flavor, architecture)
+ flavor1 = flavor1 or flavor
+
+ pi1 = PackageIndex(version1, searchdir, flavor1, architecture)
+ pi2 = PackageIndex(version2, searchdir, flavor, architecture)
+
+ text = (
+ f"## History of changes for WinPython-{architecture}bit {version2 + flavor}\r\n\r\n"
+ f"The following changes were made to WinPython-{architecture}bit distribution since version {version1 + flavor1}.\n\n\n"
+ "\n\n"
+ )
+
+ for key in PackageIndex.HEADERS:
+ diff = compare_packages(pi1.packages[key], pi2.packages[key])
+ if diff:
+ text += f"\n{PackageIndex.HEADERS[key]}\n\n{diff}"
+
+ return text + "\n \n\n* * *\n"
+
+def copy_changelogs(version, searchdir, flavor="", architecture=64, basedir=None):
+ basever = ".".join(version.split(".")[:2])
+ pattern = re.compile(rf"WinPython{flavor}-{architecture}bit-{basever}[0-9\.]*\.(txt|md)")
+ dest = Path(basedir)
+ for fname in os.listdir(searchdir):
+ if pattern.match(fname):
+ shutil.copyfile(searchdir / fname, dest / fname)
+
+def write_changelog(version2, version1=None, searchdir=None, flavor="", architecture=64, basedir=None):
+ """Write changelog between version1 and version2 of WinPython"""
+ if basedir:
+ copy_changelogs(version2, searchdir, flavor, architecture, basedir)
+ print("comparing_package_indexes", version2, searchdir, flavor, architecture)
+ changelog = compare_package_indexes(version2, version1, searchdir, flavor, architecture=architecture)
+ output_file = searchdir / f"WinPython{flavor}-{architecture}bit-{version2}_History.md"
+ with open(output_file, "w", encoding="utf-8") as f:
+ f.write(changelog)
+ # Copy to winpython/changelogs back to basedir
+ if basedir:
+ shutil.copyfile(output_file, basedir / output_file.name)
+
+if __name__ == "__main__":
+ print(compare_package_indexes("3.7.4.0", "3.7.2.0", r"C:\WinP\bd37\budot", "Zero", architecture=32))
+ write_changelog("3.7.4.0", "3.7.2.0", r"C:\WinP\bd37\budot", "Ps2", architecture=64)
diff --git a/winpython/hash.py b/winpython/hash.py
new file mode 100644
index 00000000..e0bdd46a
--- /dev/null
+++ b/winpython/hash.py
@@ -0,0 +1,46 @@
+# -*- coding: utf-8 -*-
+"""
+hash.py: compute hash of given files into a markdown output
+"""
+# Copyright © 2014-2025+ The Winpython development team https://github.com/winpython/
+# Licensed under the terms of the MIT License
+# (see winpython/__init__.py for details)
+
+from pathlib import Path
+import sys
+import hashlib
+
+def compute_hash(file_path, hash_function, digest_size=None):
+ """Compute the hash of a file using the specified hash function."""
+ try:
+ with open(file_path, 'rb') as file:
+ if digest_size:
+ return hash_function(file.read(), digest_size=digest_size).hexdigest()
+ return hash_function(file.read()).hexdigest()
+ except IOError as e:
+ print(f"Error reading file {file_path}: {e}")
+ return None
+
+def print_hashes(files):
+ """Print the hashes of the given files."""
+ header = f"{'MD5':<32} | {'SHA-1':<40} | {'SHA-256':<64} | {'Binary':<33} | {'Size':<20} | {'blake2b-256':<64}"
+ line = "|".join(["-" * len(part) for part in header.split("|")])
+
+ print(header)
+ print(line)
+
+ for file in sorted(files):
+ md5 = compute_hash(file, hashlib.md5)
+ sha1 = compute_hash(file, hashlib.sha1)
+ sha256 = compute_hash(file, hashlib.sha256)
+ name = Path(file).name.ljust(33)
+ size = f"{Path(file).stat().st_size:,} Bytes".replace(",", " ").rjust(20)
+ blake2b = compute_hash(file, hashlib.blake2b, digest_size=32)
+ print(f"{md5} | {sha1} | {sha256} | {name} | {size} | {blake2b}")
+
+if __name__ == '__main__':
+ if len(sys.argv) < 2:
+ print("Usage: hash.py files_to_compute_hash")
+ sys.exit(1)
+ files = [file for file in sys.argv[1:] if file[-3:].lower() != ".py"]
+ print_hashes(files)
diff --git a/winpython/packagemetadata.py b/winpython/packagemetadata.py
new file mode 100644
index 00000000..a51e8331
--- /dev/null
+++ b/winpython/packagemetadata.py
@@ -0,0 +1,92 @@
+# -*- coding: utf-8 -*-
+"""
+packagemetadata.py - get metadata from designated place
+"""
+import os
+import re
+import tarfile
+import zipfile
+import sys
+from pathlib import Path
+from typing import Dict, List, Optional, Tuple
+from . import utils
+import importlib.metadata
+import email
+from packaging.utils import canonicalize_name
+# --- Abstract metadata accessor ---
+
+class PackageMetadata:
+ """A minimal abstraction for package metadata."""
+ def __init__(self, name, version, requires, summary, description, metadata):
+ self.name = name
+ self.version = version
+ self.requires = requires # List[str] of dependencies
+ self.summary = summary
+ self.description = description
+ self.metadata = metadata
+
+def get_installed_metadata(path = None) -> List[PackageMetadata]:
+ # Use importlib.metadata or pkg_resources
+ pkgs = []
+ distro = importlib.metadata.distributions(path = path) if path else importlib.metadata.distributions()
+ for dist in distro:
+ name = canonicalize_name(dist.metadata['Name'])
+ version = dist.version
+ summary = dist.metadata.get("Summary", ""),
+ description = dist.metadata.get("Description", ""),
+ requires = dist.requires or []
+ metadata = dist.metadata
+ pkgs.append(PackageMetadata(name, version, requires, summary, description, metadata))
+ return pkgs
+
+def get_directory_metadata(directory: str) -> List[PackageMetadata]:
+ # For each .whl/.tar.gz file in directory, extract metadata
+ pkgs = []
+ for fname in os.listdir(directory):
+ if fname.endswith('.whl'):
+ # Extract METADATA from wheel
+ meta = extract_metadata_from_wheel(os.path.join(directory, fname))
+ pkgs.append(meta)
+ elif fname.endswith('.tar.gz'):
+ # Extract PKG-INFO from sdist
+ meta = extract_metadata_from_sdist(os.path.join(directory, fname))
+ pkgs.append(meta)
+ return pkgs
+
+def extract_metadata_from_wheel(path: str) -> PackageMetadata:
+ with zipfile.ZipFile(path) as zf:
+ for name in zf.namelist():
+ if name.endswith(r'.dist-info/METADATA') and name.split("/")[1] == "METADATA":
+ with zf.open(name) as f:
+ # Parse metadata (simple parsing for Name, Version, Requires-Dist)
+ return parse_metadata_file(f.read().decode())
+ raise ValueError(f"No METADATA found in {path}")
+
+def extract_metadata_from_sdist(path: str) -> PackageMetadata:
+ with tarfile.open(path, "r:gz") as tf:
+ for member in tf.getmembers():
+ if member.name.endswith('PKG-INFO'):
+ f = tf.extractfile(member)
+ return parse_metadata_file(f.read().decode())
+ raise ValueError(f"No PKG-INFO found in {path}")
+
+def parse_metadata_file(txt: str) -> PackageMetadata:
+ meta = email.message_from_string(txt)
+ name = canonicalize_name(meta.get('Name', ''))
+ version = meta.get('Version', '')
+ summary = meta.get('Summary', '')
+ description = meta.get('Description', '')
+ requires = meta.get_all('Requires-Dist') or []
+ return PackageMetadata(name, version, requires, summary, description, dict(meta.items()))
+
+def main():
+ if len(sys.argv) > 1:
+ # Directory mode
+ directory = sys.argv[1]
+ pkgs = get_directory_metadata(directory)
+ else:
+ # Installed packages mode
+ pkgs = get_installed_metadata()
+
+if __name__ == "__main__":
+ main()
\ No newline at end of file
diff --git a/winpython/piptree.py b/winpython/piptree.py
index b47e165f..e46bd465 100644
--- a/winpython/piptree.py
+++ b/winpython/piptree.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
"""
-This script provides functionality to inspect and display package dependencies
-in a Python environment, including both downward and upward dependencies.
+Enhanced script to inspect and display Python package dependencies,
+supporting both downward and upward dependency trees.
Requires Python 3.8+ due to importlib.metadata.
"""
@@ -10,54 +10,27 @@
import re
import platform
import os
+import logging
+from functools import lru_cache
from collections import OrderedDict
from typing import Dict, List, Optional, Tuple, Union
from pip._vendor.packaging.markers import Marker
from importlib.metadata import Distribution, distributions
from pathlib import Path
+from . import utils
+from . import packagemetadata as pm
-def normalize(name: str) -> str:
- """
- Normalize package name according to PEP 503.
-
- This function converts a package name to its canonical form by replacing
- any sequence of dashes, underscores, or dots with a single dash and
- converting the result to lowercase.
-
- :param name: The package name to normalize
- :return: The normalized package name
- """
- return re.sub(r"[-_.]+", "-", name).lower()
-
-def sum_up(text: str, max_length: int = 144, stop_at: str = ". ") -> str:
- """
- Summarize text to fit within max_length characters, ending at the last complete sentence if possible.
-
- This function attempts to create a summary of the given text that fits within
- the specified maximum length. It tries to end the summary at a complete sentence
- if possible.
-
- :param text: The text to summarize
- :param max_length: Maximum length for summary
- :param stop_at: String to stop summarization at
- :return: Summarized text
- """
- summary = (text + os.linesep).splitlines()[0]
- if len(summary) > max_length and len(stop_at) > 1:
- summary = (summary + stop_at).split(stop_at)[0]
- if len(summary) > max_length:
- summary = summary[:max_length]
- return summary
+logging.basicConfig(level=logging.INFO)
+logger = logging.getLogger(__name__)
-class PipData:
- """
- Wrapper around Distribution.discover() or Distribution.distributions() to manage package metadata.
+class PipDataError(Exception):
+ """Custom exception for PipData related errors."""
+ pass
- This class provides methods to inspect and display package dependencies
- in a Python environment, including both downward and upward dependencies.
- """
+class PipData:
+ """Manages package metadata and dependency relationships in a Python environment."""
- def __init__(self, target: Optional[str] = None):
+ def __init__(self, target: Optional[str] = None, wheelhouse = None):
"""
Initialize the PipData instance.
@@ -66,25 +39,21 @@ def __init__(self, target: Optional[str] = None):
self.distro: Dict[str, Dict] = {}
self.raw: Dict[str, Dict] = {}
self.environment = self._get_environment()
-
- search_path = target or sys.executable
- packages = self._get_packages(search_path)
-
- for package in packages:
- self._process_package(package)
-
- # On a second pass, complement dependencies in reverse mode with 'wanted-per':
- self._populate_reverse_dependencies()
+ try:
+ packages = self._get_packages(target or sys.executable, wheelhouse)
+ self._process_packages(packages)
+ self._populate_reverse_dependencies()
+ except Exception as e:
+ raise PipDataError(f"Failed to initialize package data: {str(e)}") from e
+
+ @staticmethod
+ @lru_cache(maxsize=None)
+ def normalize(name: str) -> str:
+ """Normalize package name per PEP 503."""
+ return re.sub(r"[-_.]+", "-", name).lower()
def _get_environment(self) -> Dict[str, str]:
- """
- Collect environment details for dependency evaluation.
-
- This method gathers information about the system and Python environment,
- which is used to evaluate package dependencies.
-
- :return: Dictionary containing system and Python environment information
- """
+ """Collect system and Python environment details."""
return {
"implementation_name": sys.implementation.name,
"implementation_version": f"{sys.implementation.version.major}.{sys.implementation.version.minor}.{sys.implementation.version.micro}",
@@ -99,61 +68,40 @@ def _get_environment(self) -> Dict[str, str]:
"sys_platform": sys.platform,
}
- def _get_packages(self, search_path: str) -> List[Distribution]:
- """
- Get the list of packages based on the search path.
-
- This method retrieves the list of installed packages in the specified
- search path. If the search path is the current executable, it uses
- Distribution.discover(). Otherwise, it uses distributions() with the
- specified path.
-
- :param search_path: Path to search for packages
- :return: List of Distribution objects
- """
+ def _get_packages(self, search_path: str, wheelhouse) -> List[Distribution]:
+ """Retrieve installed packages from the specified path."""
+ if wheelhouse:
+ return pm.get_directory_metadata(wheelhouse)
if sys.executable == search_path:
- return Distribution.discover()
+ return pm.get_installed_metadata() #Distribution.discover()
else:
- return distributions(path=[str(Path(search_path).parent / 'lib' / 'site-packages')])
-
- def _process_package(self, package: Distribution) -> None:
- """
- Process package metadata and store it in the distro dictionary.
-
- This method extracts metadata from a Distribution object and stores it
- in the distro dictionary. It also initializes the reverse dependencies
- and provided extras for the package.
+ return pm.get_installed_metadata(path=[str(Path(search_path).parent / 'lib' / 'site-packages')]) #distributions(path=[str(Path(search_path).parent / 'lib' / 'site-packages')])
- :param package: The Distribution object to process
- """
- meta = package.metadata
- name = meta['Name']
- version = package.version
- key = normalize(name)
- self.raw[key] = meta
-
- self.distro[key] = {
- "name": name,
- "version": version,
- "summary": meta.get("Summary", ""),
- "requires_dist": self._get_requires(package),
- "reverse_dependencies": [],
- "description": meta.get("Description", ""),
- "provides": self._get_provides(package),
- "provided": {'': None} # Placeholder for extras provided by this package
- }
+ def _process_packages(self, packages: List[Distribution]) -> None:
+ """Process packages metadata and store them in the distro dictionary."""
+ for package in packages:
+ try:
+ meta = package.metadata
+ name = meta.get('Name')
+ if not name:
+ continue
+ key = self.normalize(name)
+ self.raw[key] = meta
+ self.distro[key] = {
+ "name": name,
+ "version": package.version,
+ "summary": meta.get("Summary", ""),
+ "requires_dist": self._get_requires(package),
+ "reverse_dependencies": [],
+ "description": meta.get("Description", ""),
+ "provides": self._get_provides(package),
+ "provided": {'': None} # Placeholder for extras provided by this package
+ }
+ except Exception as e:
+ logger.warning(f"Failed to process package {name}: {str(e)}", exc_info=True)
def _get_requires(self, package: Distribution) -> List[Dict[str, str]]:
- """
- Extract and normalize requirements for a package.
-
- This method parses the requirements of a package and normalizes them
- into a list of dictionaries. Each dictionary contains the required
- package key, version, extra, and marker (if any).
-
- :param package: The Distribution object to extract requirements from
- :return: List of dictionaries containing normalized requirements
- """
+ """Extract and normalize requirements for a package."""
requires = []
replacements = str.maketrans({" ": " ", "[": "", "]": "", "'": "", '"': ""})
further_replacements = [
@@ -166,8 +114,8 @@ def _get_requires(self, package: Distribution) -> List[Dict[str, str]]:
if package.requires:
for req in package.requires:
req_nameextra, req_marker = (req + ";").split(";")[:2]
- req_nameextra = normalize(re.split(r" |;|==|!|>|<", req_nameextra + ";")[0])
- req_key = normalize((req_nameextra + "[").split("[")[0])
+ req_nameextra = self.normalize(re.split(r" |;|==|!|>|<|~=", req_nameextra + ";")[0])
+ req_key = self.normalize((req_nameextra + "[").split("[")[0])
req_key_extra = req_nameextra[len(req_key) + 1:].split("]")[0]
req_version = req[len(req_nameextra):].translate(replacements)
@@ -185,16 +133,7 @@ def _get_requires(self, package: Distribution) -> List[Dict[str, str]]:
return requires
def _get_provides(self, package: Distribution) -> Dict[str, None]:
- """
- Get the list of extras provided by this package.
-
- This method extracts the extras provided by a package from its requirements.
- It returns a dictionary where the keys are the provided extras and the values
- are None.
-
- :param package: The Distribution object to extract provided extras from
- :return: Dictionary containing provided extras
- """
+ """Extract provided extras from package requirements."""
provides = {'': None}
if package.requires:
for req in package.requires:
@@ -205,83 +144,62 @@ def _get_provides(self, package: Distribution) -> Dict[str, None]:
return provides
def _populate_reverse_dependencies(self) -> None:
- """
- Add reverse dependencies to each package.
-
- This method populates the reverse dependencies for each package in the
- distro dictionary. It iterates over the requirements of each package
- and adds the package as a reverse dependency to the required packages.
- """
- for package in self.distro:
- for requirement in self.distro[package]["requires_dist"]:
- if requirement["req_key"] in self.distro:
- want_add = {
- "req_key": package,
- "req_version": requirement["req_version"],
- "req_extra": requirement["req_extra"],
- }
- if "req_marker" in requirement:
- want_add["req_marker"] = requirement["req_marker"]
- if 'extra == ' in requirement["req_marker"]:
+ """Populate reverse dependencies."""
+ for pkg_key, pkg_data in self.distro.items():
+ for req in pkg_data["requires_dist"]:
+ target_key = req["req_key"]
+ if target_key in self.distro:
+ rev_dep = {"req_key": pkg_key, "req_version": req["req_version"], "req_extra": req["req_extra"]}
+ if "req_marker" in req:
+ rev_dep["req_marker"] = req["req_marker"]
+ if 'extra == ' in req["req_marker"]:
remove_list = {ord("'"): None, ord('"'): None}
- self.distro[requirement["req_key"]]["provided"][requirement["req_marker"].split('extra == ')[1].translate(remove_list)] = None
- self.distro[requirement["req_key"]]["reverse_dependencies"].append(want_add)
+ self.distro[target_key]["provided"][req["req_marker"].split('extra == ')[1].translate(remove_list)] = None
+ self.distro[target_key]["reverse_dependencies"].append(rev_dep)
def _get_dependency_tree(self, package_name: str, extra: str = "", version_req: str = "", depth: int = 20, path: Optional[List[str]] = None, verbose: bool = False, upward: bool = False) -> List[List[str]]:
- """
- Recursive function to build dependency tree.
-
- This method builds a dependency tree for the specified package. It can
- build the tree for downward dependencies (default) or upward dependencies
- (if upward is True). The tree is built recursively up to the specified
- depth.
-
- :param package_name: The name of the package to build the tree for
- :param extra: The extra to include in the dependency tree
- :param version_req: The version requirement for the package
- :param depth: The maximum depth of the dependency tree
- :param path: The current path in the dependency tree (used for cycle detection)
- :param verbose: Whether to include verbose output in the tree
- :param upward: Whether to build the tree for upward dependencies
- :return: List of lists containing the dependency tree
- """
+ """Recursive function to build dependency tree."""
path = path or []
extras = extra.split(",")
- package_key = normalize(package_name)
+ pkg_key = self.normalize(package_name)
ret_all = []
- if package_key + "[" + extra + "]" in path:
- print("cycle!", "->".join(path + [package_key + "[" + extra + "]"]))
- return [] # Return empty list to avoid further recursion
+ full_name = f"{package_name}[{extra}]" if extra else package_name
+ if full_name in path:
+ logger.warning(f"Cycle detected: {' -> '.join(path + [full_name])}")
+ return []
- package_data = self.distro.get(package_key)
- if package_data and len(path) <= depth:
+ pkg_data = self.distro[pkg_key]
+ if pkg_data and len(path) <= depth:
for extra in extras:
environment = {"extra": extra, **self.environment}
- summary = f' {package_data["summary"]}' if verbose else ''
+ summary = f' {pkg_data["summary"]}' if verbose else ''
base_name = f'{package_name}[{extra}]' if extra else package_name
- ret = [f'{base_name}=={package_data["version"]} {version_req}{summary}']
+ ret = [f'{base_name}=={pkg_data["version"]} {version_req}{summary}']
- dependencies = package_data["requires_dist"] if not upward else package_data["reverse_dependencies"]
+ dependencies = pkg_data["requires_dist"] if not upward else pkg_data["reverse_dependencies"]
for dependency in dependencies:
if dependency["req_key"] in self.distro:
next_path = path + [base_name]
if upward:
up_req = (dependency.get("req_marker", "").split('extra == ')+[""])[1].strip("'\"")
- # avoids circular links on dask[array]
if dependency["req_key"] in self.distro and dependency["req_key"]+"["+up_req+"]" not in path:
# upward dependancy taken if:
# - if extra "" demanded, and no marker from upward package: like pandas[] ==> numpy
# - or the extra is in the upward package, like pandas[test] ==> pytest, for 'test' extra
# - or an extra "array" is demanded, and indeed in the req_extra list: array,dataframe,diagnostics,distributer
- if (not dependency.get("req_marker") and extra ==""
- ) or ("req_marker" in dependency and extra==up_req and dependency["req_key"]!=package_key and Marker(dependency["req_marker"]).evaluate(environment=environment)
- ) or ("req_marker" in dependency and extra!="" and extra+',' in dependency["req_extra"]+',' and Marker(dependency["req_marker"]).evaluate(environment=environment|{"extra": up_req})
- ):
+ if (not dependency.get("req_marker") and extra == "") or \
+ ("req_marker" in dependency and extra == up_req and \
+ dependency["req_key"] != pkg_key and \
+ Marker(dependency["req_marker"]).evaluate(environment=environment)) or \
+ ("req_marker" in dependency and extra != "" and \
+ extra + ',' in dependency["req_extra"] + ',' and \
+ Marker(dependency["req_marker"]).evaluate(environment=environment | {"extra": up_req})):
+ # IA risk error: # dask[array] go upwards as dask[dataframe], so {"extra": up_req} , not {"extra": extra}
ret += self._get_dependency_tree(
dependency["req_key"],
- up_req, # dask[array] going upwards continues as dask[dataframe]
+ up_req,
f"[requires: {package_name}"
+ (f"[{dependency['req_extra']}]" if dependency["req_extra"] != "" else "")
+ f'{dependency["req_version"]}]',
@@ -305,23 +223,9 @@ def _get_dependency_tree(self, package_name: str, extra: str = "", version_req:
return ret_all
def down(self, pp: str = "", extra: str = "", depth: int = 20, indent: int = 5, version_req: str = "", verbose: bool = False) -> str:
- """
- Print the downward requirements for the package or all packages.
-
- This method prints the downward dependencies for the specified package
- or all packages if pp is ".". It uses the _get_dependency_tree method
- to build the dependency tree and formats the output as a JSON string.
-
- :param pp: The package name or "." to print dependencies for all packages
- :param extra: The extra to include in the dependency tree
- :param depth: The maximum depth of the dependency tree
- :param indent: The indentation level for the JSON output
- :param version_req: The version requirement for the package
- :param verbose: Whether to include verbose output in the tree
- :return: JSON string containing the downward dependencies
- """
+ """Generate downward dependency tree as formatted string."""
if pp == ".":
- results = [self.down(one_pp, extra, depth, indent, version_req, verbose=verbose) for one_pp in sorted(self.distro)]
+ results = [self.down(p, extra, depth, indent, version_req, verbose=verbose) for p in sorted(self.distro)]
return '\n'.join(filter(None, results))
if extra == ".":
@@ -329,39 +233,25 @@ def down(self, pp: str = "", extra: str = "", depth: int = 20, indent: int = 5,
results = [self.down(pp, one_extra, depth, indent, version_req, verbose=verbose)
for one_extra in sorted(self.distro[pp]["provides"])]
return '\n'.join(filter(None, results))
- return "" # Handle cases where extra is "." and package_name is not found.
+ return ""
if pp not in self.distro:
- return "" # Handle cases where package_name is not found.
+ return ""
rawtext = json.dumps(self._get_dependency_tree(pp, extra, version_req, depth, verbose=verbose), indent=indent)
lines = [l for l in rawtext.split("\n") if len(l.strip()) > 2]
return "\n".join(lines).replace('"', "")
def up(self, pp: str, extra: str = "", depth: int = 20, indent: int = 5, version_req: str = "", verbose: bool = False) -> str:
- """
- Print the upward needs for the package.
-
- This method prints the upward dependencies for the specified package.
- It uses the _get_dependency_tree method to build the dependency tree
- and formats the output as a JSON string.
-
- :param pp: The package name
- :param extra: The extra to include in the dependency tree
- :param depth: The maximum depth of the dependency tree
- :param indent: The indentation level for the JSON output
- :param version_req: The version requirement for the package
- :param verbose: Whether to include verbose output in the tree
- :return: JSON string containing the upward dependencies
- """
+ """Generate upward dependency tree as formatted string."""
if pp == ".":
- results = [self.up(one_pp, extra, depth, indent, version_req, verbose) for one_pp in sorted(self.distro)]
+ results = [self.up(p, extra, depth, indent, version_req, verbose) for p in sorted(self.distro)]
return '\n'.join(filter(None, results))
if extra == ".":
if pp in self.distro:
extras = set(self.distro[pp]["provided"]).union(set(self.distro[pp]["provides"]))
- results = [self.up(pp, one_extra, depth, indent, version_req, verbose=verbose) for one_extra in sorted(extras)]
+ results = [self.up(pp, e, depth, indent, version_req, verbose=verbose) for e in sorted(extras)]
return '\n'.join(filter(None, results))
return ""
@@ -373,42 +263,24 @@ def up(self, pp: str, extra: str = "", depth: int = 20, indent: int = 5, version
return "\n".join(filter(None, lines)).replace('"', "")
def description(self, pp: str) -> None:
- """
- Return description of the package.
-
- This method prints the description of the specified package.
-
- :param pp: The package name
- """
+ """Return package description or None if not found."""
if pp in self.distro:
return print("\n".join(self.distro[pp]["description"].split(r"\n")))
def summary(self, pp: str) -> str:
- """
- Return summary of the package.
-
- This method returns the summary of the specified package.
-
- :param pp: The package name
- :return: The summary of the package
- """
+ """Return package summary or empty string if not found."""
if pp in self.distro:
return self.distro[pp]["summary"]
return ""
def pip_list(self, full: bool = False, max_length: int = 144) -> List[Tuple[str, Union[str, Tuple[str, str]]]]:
- """
- List installed packages similar to pip list.
-
- This method lists the installed packages in a format similar to the
- output of the `pip list` command. If full is True, it includes the
- package version and summary.
+ """List installed packages with optional details.
:param full: Whether to include the package version and summary
:param max_length: The maximum length for the summary
:return: List of tuples containing package information
"""
+ pkgs = sorted(self.distro.items())
if full:
- return [(p, self.distro[p]["version"], sum_up(self.distro[p]["summary"], max_length)) for p in sorted(self.distro)]
- else:
- return [(p, sum_up(self.distro[p]["version"], max_length)) for p in sorted(self.distro)]
+ return [(p, d["version"], utils.sum_up(d["summary"], max_length)) for p, d in pkgs]
+ return [(p, d["version"]) for p, d in pkgs]
diff --git a/winpython/register_python.py b/winpython/register_python.py
deleted file mode 100644
index fc24c96b..00000000
--- a/winpython/register_python.py
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/env python
-import sys
-from winpython import associate, utils
-from argparse import ArgumentParser
-
-parser = ArgumentParser(description="Register Python file extensions, icons "\
- "and Windows explorer context menu to a target "\
- "Python distribution.")
-try:
- str_type = unicode
-except NameError:
- str_type = str
-parser.add_argument('--target', metavar='path', type=str,
- default=sys.prefix,
- help='path to the target Python distribution')
-parser.add_argument('--all', dest='all', action='store_const',
- const=True, default=False,
- help='register to all users, requiring administrative '\
- 'privileges (default: register to current user only)')
-args = parser.parse_args()
-
-print(args.target)
-if utils.is_python_distribution(args.target):
- associate.register(args.target, current=not args.all)
-else:
- raise WindowsError(f"Invalid Python distribution {args.target}")
diff --git a/winpython/unregister_python.py b/winpython/unregister_python.py
deleted file mode 100644
index f0bcefda..00000000
--- a/winpython/unregister_python.py
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/env python
-import sys
-from winpython import associate, utils
-from argparse import ArgumentParser
-
-parser = ArgumentParser(description="unRegister Python file extensions, icons "\
- "and Windows explorer context menu to a target "\
- "Python distribution.")
-try:
- str_type = unicode
-except NameError:
- str_type = str
-parser.add_argument('--target', metavar='path', type=str,
- default=sys.prefix,
- help='path to the target Python distribution')
-parser.add_argument('--all', dest='all', action='store_const',
- const=True, default=False,
- help='unregister to all users, requiring administrative '\
- 'privileges (default: register to current user only)')
-args = parser.parse_args()
-
-print(args.target)
-if utils.is_python_distribution(args.target):
- associate.unregister(args.target, current=not args.all)
-else:
- raise WindowsError(f"Invalid Python distribution {args.target}")
diff --git a/winpython/utils.py b/winpython/utils.py
index 9c651c9b..2d549f20 100644
--- a/winpython/utils.py
+++ b/winpython/utils.py
@@ -1,345 +1,133 @@
# -*- coding: utf-8 -*-
#
+# WinPython utilities
# Copyright © 2012 Pierre Raybaut
+# Copyright © 2014-2025+ The Winpython development team https://github.com/winpython/
# Licensed under the terms of the MIT License
# (see winpython/__init__.py for details)
-"""
-WinPython utilities
-
-Created on Tue Aug 14 14:08:40 2012
-"""
-
import os
import sys
import stat
import shutil
import locale
-import tempfile
import subprocess
-import configparser as cp
from pathlib import Path
import re
import tarfile
import zipfile
-import atexit
-import io
-import winreg
+
+# SOURCE_PATTERN defines what an acceptable source package name is
+SOURCE_PATTERN = r'([a-zA-Z0-9\-\_\.]*)-([0-9\.\_]*[a-z]*[\-]?[0-9]*)(\.zip|\.tar\.gz|\-(py[2-7]*|py[2-7]*\.py[2-7]*)\-none\-any\.whl)'
+
+# WHEELBIN_PATTERN defines what an acceptable binary wheel package is
+WHEELBIN_PATTERN = r'([a-zA-Z0-9\-\_\.]*)-([0-9\.\_]*[a-z0-9\+]*[0-9]?)-cp([0-9]*)\-[0-9|c|o|n|e|p|m]*\-(win32|win\_amd64)\.whl'
def get_python_executable(path=None):
"""Return the path to the Python executable."""
- python_path = sys.executable if path is None else path
- base_dir = Path(python_path).parent if not Path(python_path).is_dir() else Path(python_path)
+ python_path = Path(path) if path else Path(sys.executable)
+ base_dir = python_path if python_path.is_dir() else python_path.parent
python_exe = base_dir / 'python.exe'
pypy_exe = base_dir / 'pypy3.exe' # For PyPy
return str(python_exe if python_exe.is_file() else pypy_exe)
def get_site_packages_path(path=None):
"""Return the path to the Python site-packages directory."""
- python_path = sys.executable if path is None else path
- base_dir = Path(python_path).parent if not Path(python_path).is_dir() else Path(python_path)
+ python_path = Path(path) if path else Path(sys.executable)
+ base_dir = python_path if python_path.is_dir() else python_path.parent
site_packages = base_dir / 'Lib' / 'site-packages'
pypy_site_packages = base_dir / 'site-packages' # For PyPy
return str(pypy_site_packages if pypy_site_packages.is_dir() else site_packages)
-def onerror(function, path, excinfo):
- """Error handler for `shutil.rmtree`.
-
- If the error is due to an access error (read-only file), it
- attempts to add write permission and then retries.
- If the error is for another reason, it re-raises the error.
+def get_installed_tools(path=None)-> str:
+ """Generates Markdown for installed tools section in package index."""
+ tool_lines = []
+ python_exe = Path(get_python_executable(path))
+ version = exec_shell_cmd(f'powershell (Get-Item {python_exe}).VersionInfo.FileVersion', python_exe.parent).splitlines()[0]
+ tool_lines.append(("Python" ,f"http://www.python.org/", version, "Python programming language with standard library"))
+ if (node_exe := python_exe.parent.parent / "n" / "node.exe").exists():
+ version = exec_shell_cmd(f'powershell (Get-Item {node_exe}).VersionInfo.FileVersion', node_exe.parent).splitlines()[0]
+ tool_lines.append("Nodejs", "https://nodejs.org", version, "a JavaScript runtime built on Chrome's V8 JavaScript engine")
+
+ if (pandoc_exe := python_exe.parent.parent / "t" / "pandoc.exe").exists():
+ version = exec_shell_cmd("pandoc -v", pandoc_exe.parent).splitlines()[0].split(" ")[-1]
+ tool_lines.append("Pandoc", "https://pandoc.org", version, "an universal document converter")
+
+ if (vscode_exe := python_exe.parent.parent / "t" / "VSCode" / "Code.exe").exists():
+ version = exec_shell_cmd(f'powershell (Get-Item {vscode_exe}).VersionInfo.FileVersion', vscode_exe.parent).splitlines()[0]
+ tool_lines.append("VSCode","https://code.visualstudio.com", version, "a source-code editor developed by Microsoft")
+ return tool_lines
- Usage: `shutil.rmtree(path, onexc=onerror)"""
+def onerror(function, path, excinfo):
+ """Error handler for `shutil.rmtree`."""
if not os.access(path, os.W_OK):
- # Is the error an access error?
os.chmod(path, stat.S_IWUSR)
function(path)
else:
raise
-
-def getFileProperties(fname):
- """
- Read all properties of the given file return them as a dictionary.
- """
- # from https://stackoverflow.com/questions/580924/how-to-access-a-files-properties-on-windows
- import win32api
- propNames = ('Comments', 'InternalName', 'ProductName',
- 'CompanyName', 'LegalCopyright', 'ProductVersion',
- 'FileDescription', 'LegalTrademarks', 'PrivateBuild',
- 'FileVersion', 'OriginalFilename', 'SpecialBuild')
-
- props = {'FixedFileInfo': None, 'StringFileInfo': None, 'FileVersion': None}
-
- try:
- # backslash as parm returns dictionary of numeric info corresponding to VS_FIXEDFILEINFO struc
- fixedInfo = win32api.GetFileVersionInfo(fname, '\\')
- props['FixedFileInfo'] = fixedInfo
- props['FileVersion'] = "%d.%d.%d.%d" % (fixedInfo['FileVersionMS'] / 65536,
- fixedInfo['FileVersionMS'] % 65536, fixedInfo['FileVersionLS'] / 65536,
- fixedInfo['FileVersionLS'] % 65536)
-
- # \VarFileInfo\Translation returns list of available (language, codepage)
- # pairs that can be used to retreive string info. We are using only the first pair.
- lang, codepage = win32api.GetFileVersionInfo(fname, '\\VarFileInfo\\Translation')[0]
-
- # any other must be of the form \StringfileInfo\%04X%04X\parm_name, middle
- # two are language/codepage pair returned from above
-
- strInfo = {}
- for propName in propNames:
- strInfoPath = u'\\StringFileInfo\\%04X%04X\\%s' % (lang, codepage, propName)
- ## print str_info
- strInfo[propName] = win32api.GetFileVersionInfo(fname, strInfoPath)
-
- props['StringFileInfo'] = strInfo
- except:
- pass
-
- return props
-
-
-def get_special_folder_path(path_name):
- """Return special folder path"""
- from win32com.shell import shell, shellcon
-
- for maybe in """
- CSIDL_COMMON_STARTMENU CSIDL_STARTMENU CSIDL_COMMON_APPDATA
- CSIDL_LOCAL_APPDATA CSIDL_APPDATA CSIDL_COMMON_DESKTOPDIRECTORY
- CSIDL_DESKTOPDIRECTORY CSIDL_COMMON_STARTUP CSIDL_STARTUP
- CSIDL_COMMON_PROGRAMS CSIDL_PROGRAMS CSIDL_PROGRAM_FILES_COMMON
- CSIDL_PROGRAM_FILES CSIDL_FONTS""".split():
- if maybe == path_name:
- csidl = getattr(shellcon, maybe)
- return shell.SHGetSpecialFolderPath(
- 0, csidl, False
- )
- raise ValueError(
- f"{path_name} is an unknown path ID"
- )
-
-
-def get_winpython_start_menu_folder(current=True):
- """Return WinPython Start menu shortcuts folder"""
- if current:
- # non-admin install - always goes in this user's start menu.
- folder = get_special_folder_path("CSIDL_PROGRAMS")
- else:
- try:
- folder = get_special_folder_path(
- "CSIDL_COMMON_PROGRAMS"
- )
- except OSError:
- # No CSIDL_COMMON_PROGRAMS on this platform
- folder = get_special_folder_path(
- "CSIDL_PROGRAMS"
- )
- return str(Path(folder) / 'WinPython')
-
-def remove_winpython_start_menu_folder(current=True):
- """Remove WinPython Start menu folder -- remove it if it already exists"""
- path = get_winpython_start_menu_folder(current=current)
- if Path(path).is_dir():
- try:
- shutil.rmtree(path, onexc=onerror)
- except WindowsError:
- print(
- f"Directory {path} could not be removed",
- file=sys.stderr,
- )
-
-def create_winpython_start_menu_folder(current=True):
- """Create WinPython Start menu folder -- remove it if it already exists"""
- path = get_winpython_start_menu_folder(current=current)
- if Path(path).is_dir():
- try:
- shutil.rmtree(path, onexc=onerror)
- except WindowsError:
- print(
- f"Directory {path} could not be removed",
- file=sys.stderr,
- )
- # create, or re-create !
- Path(path).mkdir(parents=True, exist_ok=True)
- return path
-
-
-def create_shortcut(
- path,
- description,
- filename,
- arguments="",
- workdir="",
- iconpath="",
- iconindex=0,
- verbose=True,
-):
- """Create Windows shortcut (.lnk file)"""
- import pythoncom
- from win32com.shell import shell
-
- ilink = pythoncom.CoCreateInstance(
- shell.CLSID_ShellLink,
- None,
- pythoncom.CLSCTX_INPROC_SERVER,
- shell.IID_IShellLink,
- )
- ilink.SetPath(path)
- ilink.SetDescription(description)
- if arguments:
- ilink.SetArguments(arguments)
- if workdir:
- ilink.SetWorkingDirectory(workdir)
- if iconpath or iconindex:
- ilink.SetIconLocation(iconpath, iconindex)
- # now save it.
- ipf = ilink.QueryInterface(pythoncom.IID_IPersistFile)
- if not filename.endswith('.lnk'):
- filename += '.lnk'
- if verbose:
- print(f'create menu *{filename}*')
- try:
- ipf.Save(filename, 0)
- except:
- print ("a fail !")
- pass
-
+def sum_up(text: str, max_length: int = 144, stop_at: str = ". ") -> str:
+ """Summarize text to fit within max_length, ending at last complete sentence."""
+ summary = (text + os.linesep).splitlines()[0].strip()
+ if len(summary) <= max_length:
+ return summary
+ if stop_at and stop_at in summary[:max_length]:
+ return summary[:summary.rfind(stop_at, 0, max_length)] + stop_at.strip()
+ return summary[:max_length].strip()
def print_box(text):
"""Print text in a box"""
line0 = "+" + ("-" * (len(text) + 2)) + "+"
line1 = "| " + text + " |"
- print(
- ("\n\n" + "\n".join([line0, line1, line0]) + "\n")
- )
-
+ print("\n\n" + "\n".join([line0, line1, line0]) + "\n")
def is_python_distribution(path):
- """Return True if path is a Python distribution"""
- # XXX: This test could be improved but it seems to be sufficient
+ """Return True if path is a Python distribution."""
has_exec = Path(get_python_executable(path)).is_file()
- has_site = Path(get_site_packages_path(path)).is_dir()
+ has_site = Path(get_site_packages_path(path)).is_dir()
return has_exec and has_site
-
def decode_fs_string(string):
- """Convert string from file system charset to unicode"""
- charset = sys.getfilesystemencoding()
- if charset is None:
- charset = locale.getpreferredencoding()
+ """Convert string from file system charset to unicode."""
+ charset = sys.getfilesystemencoding() or locale.getpreferredencoding()
return string.decode(charset)
-
def exec_shell_cmd(args, path):
- """Execute shell command (*args* is a list of arguments) in *path*"""
- # print " ".join(args)
- process = subprocess.Popen(
- args,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- cwd=path,
- shell=True
- )
+ """Execute shell command (*args* is a list of arguments) in *path*."""
+ process = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=path, shell=True)
return decode_fs_string(process.stdout.read())
def exec_run_cmd(args, path=None):
- """run a single command (*args* is a list of arguments) in optional *path*"""
- # only applicable to Python-3.5+
- # python-3.7+ allows to replace "stdout and stderr ", per "capture_output=True"
- if path:
- process = subprocess.run(args,
- capture_output=True,
- cwd=path, text=True)
- #return decode_fs_string(process.stdout)
- return process.stdout
- else:
- process = subprocess.run(args,
- capture_output=True,
- cwd=path, text=True)
- #return decode_fs_string(process.stdout)
- return process.stdout
-
-
-def get_r_version(path):
- """Return version of the R installed in *path*"""
- return exec_shell_cmd(r"dir ..\README.R*", path).splitlines()[-3].split("-")[-1]
-
-
-def get_julia_version(path):
- """Return version of the Julia installed in *path*"""
- return exec_shell_cmd("julia.exe -v", path).splitlines()[0].split(" ")[-1]
-
-
-def get_nodejs_version(path):
- """Return version of the Nodejs installed in *path*"""
- return exec_shell_cmd("node -v", path).splitlines()[0]
-
-
-def get_npmjs_version(path):
- """Return version of the Nodejs installed in *path*"""
- return exec_shell_cmd("npm -v", path).splitlines()[0]
-
-
-def get_pandoc_version(path):
- """Return version of the Pandoc executable in *path*"""
- return exec_shell_cmd("pandoc -v", path).splitlines()[0].split(" ")[-1]
-
+ """Run a single command (*args* is a list of arguments) in optional *path*."""
+ process = subprocess.run(args, capture_output=True, cwd=path, text=True)
+ return process.stdout
def python_query(cmd, path):
- """Execute Python command using the Python interpreter located in *path*"""
+ """Execute Python command using the Python interpreter located in *path*."""
the_exe = get_python_executable(path)
- # debug2021-09-12
- # print(f'"{the_exe}" -c "{cmd}"', ' * ', path)
-
return exec_shell_cmd(f'"{the_exe}" -c "{cmd}"', path).splitlines()[0]
-
def python_execmodule(cmd, path):
- """Execute Python command using the Python interpreter located in *path*"""
+ """Execute Python command using the Python interpreter located in *path*."""
the_exe = get_python_executable(path)
exec_shell_cmd(f'{the_exe} -m {cmd}', path)
-
def get_python_infos(path):
- """Return (version, architecture) for the Python distribution located in
- *path*. The version number is limited to MAJOR.MINOR, the architecture is
- an integer: 32 or 64"""
+ """Return (version, architecture) for the Python distribution located in *path*."""
is_64 = python_query("import sys; print(sys.maxsize > 2**32)", path)
arch = {"True": 64, "False": 32}.get(is_64, None)
- ver = python_query(
- "import sys;print(f'{sys.version_info.major}.{sys.version_info.minor}')",
- path,
- )
- if re.match(r"([0-9]*)\.([0-9]*)", ver) is None:
- ver = None
+ ver = python_query("import sys;print(f'{sys.version_info.major}.{sys.version_info.minor}')", path)
return ver, arch
-
def get_python_long_version(path):
- """Return long version (X.Y.Z) for the Python distribution located in
- *path*"""
- ver = python_query(
- "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}')",
- path,
- )
- if re.match(r"([0-9]*)\.([0-9]*)\.([0-9]*)", ver) is None:
- ver = None
- return ver
-
+ """Return long version (X.Y.Z) for the Python distribution located in *path*."""
+ ver = python_query("import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}')", path)
+ return ver if re.match(r"([0-9]*)\.([0-9]*)\.([0-9]*)", ver) else None
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"""
-
- import re
- import sys
- import os
-
- target_dir = targetdir # movable option
- if to_movable == False:
- target_dir = os.path.abspath(os.path.dirname(fname))
- target_dir = os.path.abspath(os.path.join(target_dir, r"..")) + "\\"
+ """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+
@@ -347,8 +135,6 @@ def patch_shebang_line(fname, pad=b" ", to_movable=True, targetdir=""):
with open(fname, "rb") as fh:
initial_content = fh.read()
- fh.close
- fh = None
content = shebang_line.split(initial_content, maxsplit=1)
if len(content) != 3:
return
@@ -360,437 +146,168 @@ def patch_shebang_line(fname, pad=b" ", to_movable=True, targetdir=""):
try:
with open(fname, "wb") as fo:
fo.write(final_content)
- fo.close
- fo = None
print("patched", fname)
except Exception:
print("failed to patch", fname)
-
def patch_shebang_line_py(fname, to_movable=True, targetdir=""):
- """Changes shebang line in '.py' file to relative or absolue path"""
"""Changes shebang line in '.py' file to relative or absolue path"""
import fileinput
- import re
- import sys
-
- 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) is not None:
+ if re.match(r'^#\!.*python\.exe$', line) or re.match(r'^#\!.*pypy3\.exe$', line):
print(exec_path)
- elif re.match(r'^#\!.*pypy3\.exe$', line) is not None:# PyPy !
- print(exec_path)
else:
print(line, end='')
-
def guess_encoding(csv_file):
"""guess the encoding of the given file"""
- # UTF_8_BOM = "\xEF\xBB\xBF"
- # Python behavior on UTF-16 not great on write, so we drop it
- with io.open(csv_file, "rb") as f:
+ 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 io.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 patch_sourcefile(fname, in_text, out_text, silent_mode=False):
- """Replace a string in a source file"""
- import io
-
- if Path(fname).is_file() and not in_text == out_text:
- the_encoding = guess_encoding(fname)[0]
- with io.open(fname, 'r', encoding=the_encoding) as fh:
- content = fh.read()
- new_content = content.replace(in_text, out_text)
- if not new_content == content:
- if not silent_mode:
- print(
- "patching ",
- fname,
- "from",
- in_text,
- "to",
- out_text,
- )
- with io.open(fname, 'wt', encoding=the_encoding) as fh:
- fh.write(new_content)
-
-
-def patch_sourcelines(
- fname,
- in_line_start,
- out_line,
- endline="\n",
- silent_mode=False,
-):
- """Replace the middle of lines between in_line_start and endline"""
- import io
-
- if Path(fname).is_file():
- the_encoding = guess_encoding(fname)[0]
- with io.open(fname, "r", encoding=the_encoding) as fh:
- contents = fh.readlines()
- content = "".join(contents)
- for l in range(len(contents)):
- if contents[l].startswith(in_line_start):
- begining, middle = (
- in_line_start,
- contents[l][len(in_line_start) :],
- )
- ending = ""
- if middle.find(endline) > 0:
- ending = endline + endline.join(middle.split(endline)[1:])
- middle = middle.split(endline)[0]
- middle = out_line
- new_line = begining + middle + ending
- if not new_line == contents[l]:
- if not silent_mode:
- print(
- "patching ",
- fname,
- " from\n",
- contents[l],
- "\nto\n",
- new_line,
- )
- contents[l] = new_line
- new_content = "".join(contents)
- if not new_content == content:
- # if not silent_mode:
- # print("patching ", fname, "from", content, "to", new_content)
-
- with io.open(fname, "wt", encoding=the_encoding) as fh:
- try:
- fh.write(new_content)
- except:
- print(
- "impossible to patch",
- fname,
- "from",
- content,
- "to",
- new_content,
- )
-
-
-def _create_temp_dir():
- """Create a temporary directory and remove it at exit"""
- tmpdir = tempfile.mkdtemp(prefix='wppm_')
- atexit.register(
- lambda path: shutil.rmtree(path, onexc=onerror),
- tmpdir,
- )
- return tmpdir
+def replace_in_file(filepath: Path, replacements: list[tuple[str, str]], filedest: Path = None, verbose=False):
+ """
+ Replaces strings in a file
+ Args:
+ filepath: Path to the file to modify.
+ replacements: A list of tuples of ('old string 'new string')
+ filedest: optional output file, otherwise will be filepath
+ """
+ the_encoding = guess_encoding(filepath)[0]
+ with open(filepath, "r", encoding=the_encoding) as f:
+ content = f.read()
+ new_content = content
+ for old_text, new_text in replacements:
+ new_content = new_content.replace(old_text, new_text)
+ outfile = filedest if filedest else filepath
+ if new_content != content or str(outfile) != str(filepath):
+ with open(outfile, "w", encoding=the_encoding) as f:
+ f.write(new_content)
+ if verbose:
+ print(f"patched from {Path(filepath).name} into {outfile} !")
+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 in_text != out_text:
+ replace_in_file(Path(fname), [(in_text, out_text)])
def extract_archive(fname, targetdir=None, verbose=False):
- """Extract .zip, .exe (considered to be a zip archive) or .tar.gz archive
- to a temporary directory (if targetdir is None).
+ """Extract .zip, .exe or .tar.gz archive to a temporary directory.
Return the temporary directory path"""
- if targetdir is None:
- targetdir = _create_temp_dir()
- else:
- try:
- Path(targetdir).mkdir(parents=True, exist_ok=True)
- except:
- pass
+ targetdir = targetdir or create_temp_dir()
+ Path(targetdir).mkdir(parents=True, exist_ok=True)
if Path(fname).suffix in ('.zip', '.exe'):
obj = zipfile.ZipFile(fname, mode="r")
elif fname.endswith('.tar.gz'):
obj = tarfile.open(fname, mode='r:gz')
else:
- raise RuntimeError(
- f"Unsupported archive filename {fname}"
- )
+ raise RuntimeError(f"Unsupported archive filename {fname}")
obj.extractall(path=targetdir)
return targetdir
-# SOURCE_PATTERN defines what an acceptable source package name is
-# As of 2014-09-08 :
-# - the wheel package format is accepte in source directory
-# - the tricky regexp is tuned also to support the odd jolib naming :
-# . joblib-0.8.3_r1-py2.py3-none-any.whl,
-# . joblib-0.8.3-r1.tar.gz
-
-SOURCE_PATTERN = r'([a-zA-Z0-9\-\_\.]*)-([0-9\.\_]*[a-z]*[\-]?[0-9]*)(\.zip|\.tar\.gz|\-(py[2-7]*|py[2-7]*\.py[2-7]*)\-none\-any\.whl)'
-
-# WHEELBIN_PATTERN defines what an acceptable binary wheel package is
-# "cp([0-9]*)" to replace per cp(34) for python3.4
-# "win32|win\_amd64" to replace per "win\_amd64" for 64bit
-WHEELBIN_PATTERN = r'([a-zA-Z0-9\-\_\.]*)-([0-9\.\_]*[a-z0-9\+]*[0-9]?)-cp([0-9]*)\-[0-9|c|o|n|e|p|m]*\-(win32|win\_amd64)\.whl'
-
-
def get_source_package_infos(fname):
- """Return a tuple (name, version) of the Python source package"""
- if fname[-4:] == '.whl':
+ """Return a tuple (name, version) of the Python source package."""
+ if fname.endswith('.whl'):
return Path(fname).name.split("-")[:2]
match = re.match(SOURCE_PATTERN, Path(fname).name)
- if match is not None:
- return match.groups()[:2]
-
-
-def buildflit_wininst(
- root,
- python_exe=None,
- copy_to=None,
- verbose=False,
-):
- """Build Wheel from Python package located in *root*
- with flit"""
- if python_exe is None:
- python_exe = sys.executable
- assert Path(python_exe).is_file()
- cmd = [python_exe, '-m' ,'flit', 'build']
-
- # root = a tmp dir in windows\tmp,
+ return match.groups()[:2] if match else None
+
+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']
if verbose:
subprocess.call(cmd, cwd=root)
else:
- p = subprocess.Popen(
- cmd,
- cwd=root,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- )
- p.communicate()
- p.stdout.close()
- p.stderr.close()
- distdir = str(Path(root) / 'dist')
- if not Path(distdir).is_dir():
+ subprocess.Popen(cmd, cwd=root, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
+ distdir = Path(root) / 'dist'
+ if not distdir.is_dir():
raise RuntimeError(
- "Build failed: see package README file for further"
- " details regarding installation requirements.\n\n"
- "For more concrete debugging infos, please try to build "
- "the package from the command line:\n"
+ "Build failed: see package README file for further details regarding installation requirements.\n\n"
+ "For more concrete debugging infos, please try to build the package from the command line:\n"
"1. Open a WinPython command prompt\n"
"2. Change working directory to the appropriate folder\n"
- "3. Type `python -m filt build`"
+ "3. Type `python -m flit build`"
)
-
for distname in os.listdir(distdir):
- # for wheels (winpython here)
- match = re.match(SOURCE_PATTERN, distname)
- if match is not None:
+ if re.match(SOURCE_PATTERN, distname) or re.match(WHEELBIN_PATTERN, distname):
break
- match = re.match(WHEELBIN_PATTERN, distname)
- if match is not None:
- break
- else:
- raise RuntimeError(
- f"Build failed: not a pure Python package? {distdir}"
- )
- src_fname = str(Path(distdir) / distname)
- if copy_to is None:
- return src_fname
else:
- dst_fname = str(Path(copy_to) / distname)
+ raise RuntimeError(f"Build failed: not a pure Python package? {distdir}")
+
+ src_fname = distdir / distname
+ if copy_to:
+ dst_fname = Path(copy_to) / distname
shutil.move(src_fname, dst_fname)
if verbose:
- print(
- (
- f"Move: {src_fname} --> {dst_fname}"
- )
- )
- # remove tempo dir 'root' no more needed
- #try:
- # shutil.rmtree(root, onexc=onerror)
- #except TypeError: # before 3.12
- # shutil.rmtree(root, onerror=onerror)
- return dst_fname
-
-
-def direct_pip_install(
- fname,
- python_exe=None,
- verbose=False,
- install_options=None,
-):
- """Direct install via python -m pip !"""
- copy_to = str(Path(fname).parent)
-
- if python_exe is None:
- python_exe = sys.executable
- assert Path(python_exe).is_file()
- myroot = str(Path(python_exe).parent)
-
- cmd = [python_exe, "-m", "pip", "install"]
- if install_options:
- cmd += install_options # typically ['--no-deps']
- print("python -m pip install_options", install_options)
- cmd += [fname]
-
- if verbose:
- subprocess.call(cmd, cwd=myroot)
- else:
- p = subprocess.Popen(
- cmd,
- cwd=myroot,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- )
- stdout, stderr = p.communicate()
- the_log = f"{stdout}" + f"\n {stderr}"
+ print(f"Move: {src_fname} --> {dst_fname}")
+def direct_pip_install(fname, python_exe=None, verbose=False, install_options=None):
+ """Direct install via python -m pip !"""
+ python_exe = python_exe or sys.executable
+ myroot = Path(python_exe).parent
+ 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()
+ the_log = f"{stdout}\n {stderr}"
if " not find " in the_log or " not found " in the_log:
- print(f"Failed to Install: \n {fname} \n")
- print(f"msg: {the_log}")
+ print(f"Failed to Install: \n {fname} \n msg: {the_log}")
raise RuntimeError
- p.stdout.close()
- p.stderr.close()
- src_fname = fname
- if copy_to is None:
- return src_fname
+ process.stdout.close()
+ process.stderr.close()
else:
- if verbose:
- print(f"Installed {src_fname}")
- return src_fname
-
-
-def do_script(
- this_script,
- python_exe=None,
- copy_to=None,
- verbose=False,
- install_options=None,
-):
- """Execute a script (get-pip typically)"""
- if python_exe is None:
- python_exe = sys.executable
- myroot = os.path.dirname(python_exe)
+ subprocess.call(cmd, cwd=myroot)
+ print(f"Installed {fname} via {' '.join(cmd)}")
+ return fname
+def do_script(this_script, python_exe=None, copy_to=None, verbose=False, install_options=None):
+ """Execute a script (get-pip typically)."""
+ python_exe = python_exe or sys.executable
+ myroot = Path(python_exe).parent
# cmd = [python_exe, myroot + r'\Scripts\pip-script.py', 'install']
- cmd = [python_exe]
- if install_options:
- cmd += install_options # typically ['--no-deps']
- print('script install_options', install_options)
- if this_script:
- cmd += [this_script]
- # print('build_wheel', myroot, cmd)
+ cmd = [python_exe] + (install_options or []) + ([this_script] if this_script else [])
print("Executing ", cmd)
-
- if verbose:
- subprocess.call(cmd, cwd=myroot)
+ if not verbose:
+ subprocess.Popen(cmd, cwd=myroot, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
else:
- p = subprocess.Popen(
- cmd,
- cwd=myroot,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- )
- p.communicate()
- p.stdout.close()
- p.stderr.close()
- if verbose:
- print("Executed " , cmd)
+ subprocess.call(cmd, cwd=myroot)
+ print("Executed ", cmd)
return 'ok'
def columns_width(list_of_lists):
- """return the maximum string length of each column of a list of list"""
- if not isinstance(list_of_lists, list):
- return [0]
-
- # Transpose the list of lists using zip
- transposed_lists = list(zip(*list_of_lists))
- # Calculate the maximum width for each column
- column_widths = [max(len(str(item)) for item in sublist) for sublist in transposed_lists]
- return column_widths
+ """Return the maximum string length of each column of a list of lists."""
+ if not isinstance(list_of_lists, list):
+ return [0]
+ return [max(len(str(item)) for item in sublist) for sublist in zip(*list_of_lists)]
def formatted_list(list_of_list, full=False, max_width=70):
- """format a list_of_list to fix length columns"""
- columns_size = columns_width(list_of_list)
- nb_columns = len(columns_size)
-
- # normalize each columns to columns_size[col] width, in the limit of max_width
-
- zz = [
- list(
- line[col].ljust(columns_size[col])[:max_width] for col in range(nb_columns)
- )
- for line in list_of_list
- ]
- return zz
+ """Format a list_of_list to fixed length columns."""
+ columns_size = columns_width(list_of_list)
+ columns = range(len(columns_size))
+ return [list(line[col].ljust(columns_size[col])[:max_width] for col in columns) for line in list_of_list]
def normalize(this):
- """apply https://peps.python.org/pep-0503/#normalized-names"""
+ """Apply PEP 503 normalization to the string."""
return re.sub(r"[-_.]+", "-", this).lower()
-def get_package_metadata(database, name, update=False, suggested_summary=None):
- """Extract infos (description, url) from the local database"""
- # for package.ini safety belt
- # Note: we could use the PyPI database but this has been written on
- # machine which is not connected to the internet
- # we store only normalized names now (PEP 503)
- DATA_PATH = str(Path(sys.modules['winpython'].__file__).parent /'data')
- db = cp.ConfigParser()
- filepath = Path(database) if Path(database).is_absolute() else Path(DATA_PATH) / database
- try:
- db.read_file(open(str(filepath), encoding = 'utf-8'))
- except:
- db.read_file(open(str(filepath)))
- my_metadata = dict(
- description="",
- url="https://pypi.org/project/" + name,
- )
- for key in my_metadata:
- # wheel replace '-' per '_' in key
- for name2 in (name, normalize(name)):
- try:
- my_metadata[key] = db.get(name2, key)
- break
- except (cp.NoSectionError, cp.NoOptionError):
- pass
- db_desc = my_metadata.get("description")
-
- if my_metadata.get("description") == "" and suggested_summary:
- # nothing in package.ini, we look in our installed packages
- try:
- my_metadata["description"] = (
- suggested_summary + "\n"
- ).splitlines()[0]
- except:
- pass
-
- if update == True and db_desc == "" and my_metadata["description"] != "":
- # we add new findings in our packgages.ini list, if it's required
- try:
- db[normalize(name)] = {}
- db[normalize(name)]["description"] = my_metadata["description"]
- with open(str(Path(DATA_PATH) / database), "w", encoding='UTF-8') as configfile:
- db.write(configfile)
- except:
- pass
- return my_metadata
-
-
if __name__ == '__main__':
-
print_box("Test")
dname = sys.prefix
print((dname + ':', '\n', get_python_infos(dname)))
- # dname = r'E:\winpython\sandbox\python-2.7.3'
- # print dname+':', '\n', get_python_infos(dname)
tmpdir = r'D:\Tests\winpython_tests'
- Path(tmpdir).mkdir(parents=True, exist_ok=True)
- print(
- (
- extract_archive(
- str(Path(r'D:\WinP\bd37') / 'packages.win-amd64' /
- 'python-3.7.3.amd64.zip'),
- tmpdir,
- )
- )
- )
+ Path(tmpdir).mkdir(parents=True, exist_ok=True)
+ print(extract_archive(str(Path(r'D:\WinP\bd37') / 'packages.win-amd64' / 'python-3.7.3.amd64.zip'), tmpdir))
diff --git a/winpython/wheelhouse.py b/winpython/wheelhouse.py
new file mode 100644
index 00000000..f500dc31
--- /dev/null
+++ b/winpython/wheelhouse.py
@@ -0,0 +1,215 @@
+#!/usr/bin/env python3
+"""
+WheelHouse.py - manage WinPython local WheelHouse.
+"""
+import os
+import re
+import tarfile
+import zipfile
+import sys
+from pathlib import Path
+from collections import defaultdict
+import shutil
+import subprocess
+from typing import Dict, List, Optional, Tuple
+from . import packagemetadata as pm
+from . import utils
+
+from packaging.utils import canonicalize_name, parse_wheel_filename, parse_sdist_filename
+
+# Use tomllib if available (Python 3.11+), otherwise fall back to tomli
+try:
+ import tomllib # Python 3.11+
+except ImportError:
+ try:
+ import tomli as tomllib # For older Python versions
+ except ImportError:
+ print("Please install tomli for Python < 3.11: pip install tomli")
+ sys.exit(1)
+
+def parse_pylock_toml(path: Path) -> Dict[str, Dict[str, str | List[str]]]:
+ """Parse a pylock.toml file and extract package information."""
+ with open(path, "rb") as f:
+ data = tomllib.load(f)
+
+ # This dictionary maps package names to (version, [hashes])
+ package_hashes = defaultdict(lambda: {"version": "", "hashes": []})
+
+ for entry in data.get("packages", []):
+ name = entry["name"]
+ version = entry["version"]
+ all_hashes = []
+
+ # Handle wheels
+ for wheel in entry.get("wheels", []):
+ sha256 = wheel.get("hashes", {}).get("sha256")
+ if sha256:
+ all_hashes.append(sha256)
+
+ # Handle sdist (if present)
+ sdist = entry.get("sdist")
+ if sdist and "hashes" in sdist:
+ sha256 = sdist["hashes"].get("sha256")
+ if sha256:
+ all_hashes.append(sha256)
+
+ package_hashes[name]["version"] = version
+ package_hashes[name]["hashes"].extend(all_hashes)
+
+ return package_hashes
+
+def write_requirements_txt(package_hashes: Dict[str, Dict[str, str | List[str]]], output_path: Path) -> None:
+ """Write package requirements to a requirements.txt file."""
+ with open(output_path, "w") as f:
+ for name, data in sorted(package_hashes.items()):
+ version = data["version"]
+ hashes = data["hashes"]
+
+ if hashes:
+ f.write(f"{name}=={version} \\\n")
+ for i, h in enumerate(hashes):
+ end = " \\\n" if i < len(hashes) - 1 else "\n"
+ f.write(f" --hash=sha256:{h}{end}")
+ else:
+ f.write(f"{name}=={version}\n")
+
+ print(f"✅ requirements.txt written to {output_path}")
+
+def pylock_to_req(path: Path, output_path: Optional[Path] = None) -> None:
+ """Convert a pylock.toml file to requirements.txt."""
+ pkgs = parse_pylock_toml(path)
+ if not output_path:
+ output_path = path.parent / (path.stem.replace('pylock', 'requirement_with_hash') + '.txt')
+ write_requirements_txt(pkgs, output_path)
+
+def run_pip_command(command: List[str], check: bool = True, capture_output=True) -> Tuple[bool, Optional[str]]:
+ """Run a pip command and return the result."""
+ print('\n', ' '.join(command),'\n')
+ try:
+ result = subprocess.run(
+ command,
+ capture_output=capture_output,
+ text=True,
+ check=check
+ )
+ return (result.returncode == 0), (result.stderr or result.stdout)
+ except subprocess.CalledProcessError as e:
+ return False, e.stderr
+ except FileNotFoundError:
+ return False, "pip or Python not found."
+ except Exception as e:
+ return False, f"Unexpected error: {e}"
+
+def get_wheels(requirements: Path, wheeldrain: Path, wheelorigin: Optional[Path] = None
+ , only_check: bool = True,post_install: bool = False) -> bool:
+ """Download or check Python wheels based on requirements."""
+ added = []
+ if wheelorigin:
+ added = ['--no-index', '--trusted-host=None', f'--find-links={wheelorigin}']
+ pre_checks = [sys.executable, "-m", "pip", "install", "--dry-run", "--no-deps", "--require-hashes", "-r", str(requirements)] + added
+ instruction = [sys.executable, "-m", "pip", "download", "--no-deps", "--require-hashes", "-r", str(requirements), "--dest", str(wheeldrain)] + added
+ if wheeldrain:
+ added = ['--no-index', '--trusted-host=None', f'--find-links={wheeldrain}']
+ post_install_cmd = [sys.executable, "-m", "pip", "install", "--no-deps", "--require-hashes", "-r", str(requirements)] + added
+
+ # Run pip dry-run, only if a move of wheels
+ if wheelorigin and wheelorigin != wheeldrain:
+ success, output = run_pip_command(pre_checks, check=False)
+ if not success:
+ print("❌ Dry-run failed. Here's the output:\n")
+ print(output or "")
+ return False
+
+ print("✅ Requirements can be installed successfully (dry-run passed).\n")
+
+ # All ok
+ if only_check and not post_install:
+ return True
+
+ # Want to install
+ if not only_check and post_install:
+ success, output = run_pip_command(post_install_cmd, check=False, capture_output=False)
+ if not success:
+ print("❌ Installation failed. Here's the output:\n")
+ print(output or "")
+ return False
+ return True
+
+ # Otherwise download also, but not install direct
+ success, output = run_pip_command(instruction)
+ if not success:
+ print("❌ Download failed. Here's the output:\n")
+ print(output or "")
+ return False
+
+ return True
+
+def get_pylock_wheels(wheelhouse: Path, lockfile: Path, wheelorigin: Optional[Path] = None, wheeldrain: Optional[Path] = None) -> None:
+ """Get wheels asked pylock file."""
+ filename = Path(lockfile).name
+ wheelhouse.mkdir(parents=True, exist_ok=True)
+ trusted_wheelhouse = wheelhouse / "included.wheels"
+ trusted_wheelhouse.mkdir(parents=True, exist_ok=True)
+
+ filename_lock = wheelhouse / filename
+ filename_req = wheelhouse / (Path(lockfile).stem.replace('pylock', 'requirement') + '.txt')
+
+ pylock_to_req(Path(lockfile), filename_req)
+
+ if not str(Path(lockfile)) == str(filename_lock):
+ shutil.copy2(lockfile, filename_lock)
+
+ # We create a destination for wheels that is specific, so we can check all is there
+ destination_wheelhouse = Path(wheeldrain) if wheeldrain else wheelhouse / Path(lockfile).name.replace('.toml', '.wheels')
+ destination_wheelhouse.mkdir(parents=True, exist_ok=True)
+ # there can be an override
+
+
+ in_trusted = False
+
+ if wheelorigin is None:
+ # Try from trusted WheelHouse
+ print(f"\n\n*** Checking if we can install from our Local WheelHouse: ***\n {trusted_wheelhouse}\n\n")
+ in_trusted = get_wheels(filename_req, destination_wheelhouse, wheelorigin=trusted_wheelhouse, only_check=True)
+ if in_trusted:
+ print(f"\n\n*** We can install from Local WheelHouse: ***\n {trusted_wheelhouse}\n\n")
+ in_installed = get_wheels(filename_req, trusted_wheelhouse, wheelorigin=trusted_wheelhouse, only_check=False, post_install=True)
+
+ if not in_trusted:
+ post_install = True if wheelorigin and Path(wheelorigin).is_dir and Path(wheelorigin).samefile(destination_wheelhouse) else False
+ if post_install:
+ print(f"\n\n*** Installing from Local WheelHouse: ***\n {destination_wheelhouse}\n\n")
+ else:
+ print(f"\n\n*** Re-Checking if we can install from: {'pypi.org' if not wheelorigin or wheelorigin == '' else wheelorigin}\n\n")
+
+ in_pylock = get_wheels(filename_req, destination_wheelhouse, wheelorigin=wheelorigin, only_check=False, post_install=post_install)
+ if in_pylock:
+ if not post_install:
+ print(f"\n\n*** You can now install from this dedicated WheelHouse: ***\n {destination_wheelhouse}")
+ print(f"\n via:\n wppm {filename_lock} -wh {destination_wheelhouse}\n")
+ else:
+ print(f"\n\n*** We can't install {filename} ! ***\n\n")
+
+def list_packages_with_metadata(directory: str) -> List[Tuple[str, str, str]]:
+ "get metadata from a Wheelhouse directory"
+ packages = pm.get_directory_metadata(directory)
+ results = [ (p.name, p.version, p.summary) for p in packages]
+ return results
+
+def main() -> None:
+ """Main entry point for the script."""
+ if len(sys.argv) != 2:
+ print("Usage: python pylock_to_requirements.py pylock.toml")
+ sys.exit(1)
+
+ path = Path(sys.argv[1])
+ if not path.exists():
+ print(f"❌ File not found: {path}")
+ sys.exit(1)
+
+ pkgs = parse_pylock_toml(path)
+ dest = path.parent / (path.stem.replace('pylock', 'requirement_with_hash') + '.txt')
+ write_requirements_txt(pkgs, dest)
+
+if __name__ == "__main__":
+ main()
diff --git a/winpython/wppm.py b/winpython/wppm.py
index 03f44dcc..01ed2c83 100644
--- a/winpython/wppm.py
+++ b/winpython/wppm.py
@@ -1,261 +1,168 @@
# -*- coding: utf-8 -*-
#
+# WinPython Package Manager
# Copyright © 2012 Pierre Raybaut
+# Copyright © 2014-2025+ The Winpython development team https://github.com/winpython/
# Licensed under the terms of the MIT License
# (see winpython/__init__.py for details)
-"""
-WinPython Package Manager
-
-Created on Fri Aug 03 14:32:26 2012
-"""
-
import os
-from pathlib import Path
-import shutil
import re
import sys
+import shutil
import subprocess
import json
+from pathlib import Path
from argparse import ArgumentParser, RawTextHelpFormatter
-
-# Local imports
-from winpython import utils, piptree
-
-
+from . import utils, piptree, associate
+from . import wheelhouse as wh
+from operator import itemgetter
# Workaround for installing PyVISA on Windows from source:
os.environ["HOME"] = os.environ["USERPROFILE"]
-class BasePackage:
- def __init__(self, fname):
+class Package:
+ """Standardize a Package from filename or pip list."""
+ def __init__(self, fname: str, suggested_summary: str = None):
self.fname = fname
- self.name = None
- self.version = None
- self.description = ""
- self.url = None
+ self.description = (utils.sum_up(suggested_summary) if suggested_summary else "").strip()
+ self.name, self.version = fname, '?.?.?'
+ if fname.lower().endswith((".zip", ".tar.gz", ".whl")):
+ bname = Path(self.fname).name # e.g., "sqlite_bro-1.0.0..."
+ infos = utils.get_source_package_infos(bname) # get name, version
+ if infos:
+ self.name, self.version = utils.normalize(infos[0]), infos[1]
+ self.url = f"https://pypi.org/project/{self.name}"
+ self.files = []
def __str__(self):
return f"{self.name} {self.version}\r\n{self.description}\r\nWebsite: {self.url}"
-class Package(BasePackage):
- def __init__(self, fname, update=False, suggested_summary=None):
- BasePackage.__init__(self, fname)
- self.files = []
- self.extract_infos()
- if suggested_summary:
- setattr(self, 'description',
- piptree.sum_up(suggested_summary ))
- bname = fname.split("-")[0]
- setattr(self,'url',"https://pypi.org/project/" + bname)
-
- def extract_infos(self):
- "Extract package (name, version) from filename (installer basename)"
- bname = Path(self.fname).name
- if bname.endswith((".zip", ".tar.gz", ".whl")):
- # distutils sdist
- infos = utils.get_source_package_infos(bname)
- if infos is not None:
- self.name, self.version = infos
- return
- raise NotImplementedError(f"Not supported package type {bname}")
-
-
class Distribution:
- def __init__(self, target=None, verbose=False, indent=False):
- # if no target path given, take the current python interpreter one
- self.target = target or os.path.dirname(sys.executable)
+ """Handles operations on a WinPython distribution."""
+ def __init__(self, target: str = None, verbose: bool = False):
+ self.target = target or str(Path(sys.executable).parent) # Default target more explicit
self.verbose = verbose
- self.indent = indent
self.pip = None
- self.to_be_removed = [] # list of directories to be removed later
- self.version, self.architecture = utils.get_python_infos(target)
- # name of the exe (python.exe or pypy3.exe)
- self.short_exe = Path(utils.get_python_executable(self.target)).name
-
- def clean_up(self):
- """Remove directories which couldn't be removed when building"""
- for path in self.to_be_removed:
- try:
- shutil.rmtree(path, onexc=utils.onerror)
- except WindowsError:
- print(f"Directory {path} could not be removed", file=sys.stderr)
-
- def remove_directory(self, path):
- """Try to remove directory -- on WindowsError, remove it later"""
- try:
- shutil.rmtree(path)
- except WindowsError:
- self.to_be_removed.append(path)
-
- def copy_files(
- self,
- package,
- targetdir,
- srcdir,
- dstdir,
- create_bat_files=False,
- ):
- """Add copy task"""
- srcdir = str(Path(targetdir) / srcdir)
- if not Path(srcdir).is_dir():
- return
- offset = len(srcdir) + len(os.pathsep)
- for dirpath, dirnames, filenames in os.walk(srcdir):
- for dname in dirnames:
- t_dname = str(Path(dirpath) / dname)[offset:]
- src = str(Path(srcdir) / t_dname)
- dst = str(Path(dstdir) / t_dname)
- if self.verbose:
- print(f"mkdir: {dst}")
- full_dst = str(Path(self.target) / dst)
- if not Path(full_dst).exists():
- os.mkdir(full_dst)
- package.files.append(dst)
- for fname in filenames:
- t_fname = str(Path(dirpath) / fname)[offset:]
- src = str(Path(srcdir) / t_fname)
- dst = fname if dirpath.endswith("_system32") else str(Path(dstdir) / t_fname)
- if self.verbose:
- print(f"file: {dst}")
- full_dst = str(Path(self.target) / dst)
- shutil.move(src, full_dst)
- package.files.append(dst)
- name, ext = Path(dst).stem, Path(dst).suffix
- if create_bat_files and ext in ("", ".py"):
- dst = name + ".bat"
- if self.verbose:
- print(f"file: {dst}")
- full_dst = str(Path(self.target) / dst)
- fd = open(full_dst, "w")
- fd.write(f"""@echo off\npython "%~dpn0{ext}" %*""")
- fd.close()
- package.files.append(dst)
+ self.to_be_removed = []
+ self.version, self.architecture = utils.get_python_infos(self.target)
+ self.python_exe = utils.get_python_executable(self.target)
+ self.short_exe = Path(self.python_exe).name
+ self.wheelhouse = Path(self.target).parent / "wheelhouse"
def create_file(self, package, name, dstdir, contents):
"""Generate data file -- path is relative to distribution root dir"""
- dst = str(Path(dstdir) / name)
+ dst = Path(dstdir) / name
if self.verbose:
print(f"create: {dst}")
- full_dst = str(Path(self.target) / dst)
+ full_dst = Path(self.target) / dst
with open(full_dst, "w") as fd:
fd.write(contents)
- package.files.append(dst)
-
- def get_installed_packages(self, update=False):
- """Return installed packages"""
+ package.files.append(str(dst))
- # Include package installed via pip (not via WPPM)
- wppm = []
+ def get_installed_packages(self, update: bool = False) -> list[Package]:
+ """Return installed packages."""
if str(Path(sys.executable).parent) == self.target:
self.pip = piptree.PipData()
else:
self.pip = piptree.PipData(utils.get_python_executable(self.target))
- pip_list = self.pip.pip_list()
-
- # create pip package list
- wppm = [
- Package(
- f"{i[0].replace('-', '_').lower()}-{i[1]}-py3-none-any.whl",
- update=update,
- suggested_summary=self.pip.summary(i[0]) if self.pip else None
- )
- for i in pip_list
- ]
- return sorted(wppm, key=lambda tup: tup.name.lower())
+ pip_list = self.pip.pip_list(full=True)
+ return [Package(f"{i[0].replace('-', '_').lower()}-{i[1]}-py3-none-any.whl", suggested_summary=i[2]) for i in pip_list]
+
+ def render_markdown_for_list(self, title, items):
+ """Generates a Markdown section; name, url, version, summary"""
+ md = f"### {title}\n\n"
+ md += "Name | Version | Description\n"
+ md += "-----|---------|------------\n"
+ for name, url, version, summary in sorted(items, key=lambda p: (p[0].lower(), p[2])):
+ md += f"[{name}]({url}) | {version} | {summary} \n"
+ md += "\n"
+ return md
+
+ def generate_package_index_markdown(self, python_executable_directory: str|None = None, winpyver2: str|None = None,
+ flavor: str|None = None, architecture_bits: int|None = None, release_level: str|None = None) -> str:
+ """Generates a Markdown formatted package index page."""
+ my_ver , my_arch = utils.get_python_infos(python_executable_directory or self.target)
+ # suppose we suite ourself (method will vary over time)
+ my_winpyver2 = winpyver2 or os.getenv("WINPYVER2","")
+ my_winpyver2 = my_winpyver2 if my_winpyver2 != "" else my_ver
+ my_flavor = flavor or os.getenv("WINPYFLAVOR", "")
+ my_release_level = release_level or os.getenv("WINPYVER", "").replace(my_winpyver2+my_flavor, "")
+
+ tools_list = utils.get_installed_tools(utils.get_python_executable(python_executable_directory))
+ package_list = [(pkg.name, pkg.url, pkg.version, pkg.description) for pkg in self.get_installed_packages()]
+ wheelhouse_list = []
+ wheeldir = self.wheelhouse / 'included.wheels'
+ if wheeldir.is_dir():
+ wheelhouse_list = [(name, f"https://pypi.org/project/{name}", version, summary)
+ for name, version, summary in wh.list_packages_with_metadata(str(wheeldir)) ]
+
+ return f"""## WinPython {my_winpyver2 + my_flavor}
+
+The following packages are included in WinPython-{my_arch}bit v{my_winpyver2 + my_flavor} {my_release_level}.
+
+
+
+{self.render_markdown_for_list("Tools", tools_list)}
+{self.render_markdown_for_list("Python packages", package_list)}
+{self.render_markdown_for_list("WheelHouse packages", wheelhouse_list)}
+
+"""
- def find_package(self, name):
- """Find installed package"""
+ def find_package(self, name: str) -> Package | None:
+ """Find installed package by name."""
for pack in self.get_installed_packages():
if utils.normalize(pack.name) == utils.normalize(name):
return pack
- def patch_all_shebang(
- self,
- to_movable=True,
- max_exe_size=999999,
- targetdir="",
- ):
- """make all python launchers relatives"""
- import glob
-
- for ffname in glob.glob(r"%s\Scripts\*.exe" % self.target):
- size = os.path.getsize(ffname)
- if size <= max_exe_size:
- utils.patch_shebang_line(
- ffname,
- to_movable=to_movable,
- targetdir=targetdir,
- )
- for ffname in glob.glob(r"%s\Scripts\*.py" % self.target):
- utils.patch_shebang_line_py(
- ffname,
- to_movable=to_movable,
- targetdir=targetdir,
- )
-
- def install(self, package, install_options=None):
- """Install package in distribution"""
- # wheel addition
- if package.fname.endswith((".whl", ".tar.gz", ".zip")):
+ def patch_all_shebang(self, to_movable: bool = True, max_exe_size: int = 999999, targetdir: str = ""):
+ """Make all python launchers relative."""
+ for ffname in Path(self.target).glob("Scripts/*.exe"):
+ if ffname.stat().st_size <= max_exe_size:
+ utils.patch_shebang_line(ffname, to_movable=to_movable, targetdir=targetdir)
+ for ffname in Path(self.target).glob("Scripts/*.py"):
+ utils.patch_shebang_line_py(ffname, to_movable=to_movable, targetdir=targetdir)
+
+ def install(self, package: Package, install_options: list[str] = None):
+ """Install package in distribution."""
+ if package.fname.endswith((".whl", ".tar.gz", ".zip")) or (
+ ' ' not in package.fname and ';' not in package.fname and len(package.fname) >1): # Check extension with tuple
self.install_bdist_direct(package, install_options=install_options)
self.handle_specific_packages(package)
# minimal post-install actions
self.patch_standard_packages(package.name)
- def do_pip_action(self, actions=None, install_options=None):
- """Do pip action in a distribution"""
+ def do_pip_action(self, actions: list[str] = None, install_options: list[str] = None):
+ """Execute pip action in the distribution."""
my_list = install_options or []
my_actions = actions or []
executing = str(Path(self.target).parent / "scripts" / "env.bat")
if Path(executing).is_file():
- complement = [
- r"&&",
- "cd",
- "/D",
- self.target,
- r"&&",
- utils.get_python_executable(self.target),
- # Before PyPy: osp.join(self.target, 'python.exe')
- ]
- complement += ["-m", "pip"]
+ complement = [r"&&", "cd", "/D", self.target, r"&&", utils.get_python_executable(self.target), "-m", "pip"]
else:
executing = utils.get_python_executable(self.target)
- # Before PyPy: osp.join(self.target, 'python.exe')
complement = ["-m", "pip"]
try:
- fname = utils.do_script(
- this_script=None,
- python_exe=executing,
- verbose=self.verbose,
- install_options=complement + my_actions + my_list,
- )
- except RuntimeError:
+ fname = utils.do_script(this_script=None, python_exe=executing, verbose=self.verbose, install_options=complement + my_actions + my_list)
+ except RuntimeError as e:
if not self.verbose:
print("Failed!")
raise
+ else:
+ print(f"Pip action failed with error: {e}") # Print error if verbose
def patch_standard_packages(self, package_name="", to_movable=True):
"""patch Winpython packages in need"""
import filecmp
- # Adpating to PyPy
- if "pypy3" in Path(utils.get_python_executable(self.target)).name:
- site_package_place = "\\site-packages\\"
- else:
- site_package_place = "\\Lib\\site-packages\\"
# 'pywin32' minimal post-install (pywin32_postinstall.py do too much)
- if package_name.lower() == "pywin32" or package_name == "":
- origin = self.target + site_package_place + "pywin32_system32"
-
- destin = self.target
- if Path(origin).is_dir():
+ 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 = (
- str(Path(origin) / name),
- str(Path(destin) / name),
- )
- if not Path(there).exists() or not filecmp.cmp(here, there):
+ 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) !!!!
# rational: https://github.com/pypa/pip/issues/2328
@@ -263,96 +170,36 @@ def patch_standard_packages(self, package_name="", to_movable=True):
# ensure pip will create movable launchers
# sheb_mov1 = classic way up to WinPython 2016-01
# sheb_mov2 = tried way, but doesn't work for pip (at least)
+ the_place = Path(self.target) / "lib" / "site-packages" / "pip" / "_vendor" / "distlib" / "scripts.py"
sheb_fix = " executable = get_executable()"
sheb_mov1 = " executable = os.path.join(os.path.basename(get_executable()))"
- sheb_mov2 = (
- " executable = os.path.join('..',os.path.basename(get_executable()))"
- )
-
- # Adpating to PyPy
- the_place = site_package_place + r"pip\_vendor\distlib\scripts.py"
- print(the_place)
+ sheb_mov2 = " executable = os.path.join('..',os.path.basename(get_executable()))"
if to_movable:
- utils.patch_sourcefile(self.target + the_place, sheb_fix, sheb_mov1)
- utils.patch_sourcefile(self.target + the_place, sheb_mov2, sheb_mov1)
+ utils.patch_sourcefile(the_place, sheb_fix, sheb_mov1)
+ utils.patch_sourcefile(the_place, sheb_mov2, sheb_mov1)
else:
- utils.patch_sourcefile(self.target + the_place, sheb_mov1, sheb_fix)
- utils.patch_sourcefile(self.target + the_place, sheb_mov2, sheb_fix)
+ utils.patch_sourcefile(the_place, sheb_mov1, sheb_fix)
+ utils.patch_sourcefile(the_place, sheb_mov2, sheb_fix)
# 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(
- self.target + (site_package_place + r"spyderlib\config\main.py"),
+ Path(self.target) / "lib" / "site-packages" / "spyder" / "config" / "main.py",
"'check_updates_on_startup': True,",
"'check_updates_on_startup': False,",
)
- utils.patch_sourcefile(
- self.target + (site_package_place + r"spyder\config\main.py"),
- "'check_updates_on_startup': True,",
- "'check_updates_on_startup': False,",
- )
- # workaround bad installers
- if package_name.lower() == "numba":
- self.create_pybat(["numba"])
- else:
- self.create_pybat(package_name.lower())
-
- def create_pybat(
- self,
- names="",
- contents=r"""@echo off
-..\python "%~dpn0" %*""",
- ):
- """Create launcher batch script when missing"""
-
- scriptpy = str(Path(self.target) / "Scripts") # std Scripts of python
-
- # PyPy has no initial Scipts directory
- if not Path(scriptpy).is_dir():
- os.mkdir(scriptpy)
- if not list(names) == names:
- my_list = [f for f in os.listdir(scriptpy) if "." not in f and f.startswith(names)]
- else:
- my_list = names
- for name in my_list:
- if Path(scriptpy).is_dir() and (Path(scriptpy) / name).is_file():
- if (
- not (Path(scriptpy) / (name + ".exe")).is_file()
- and not (Path(scriptpy) / (name + ".bat")).is_file()
- ):
- with open(Path(scriptpy) / (name + ".bat"), "w") as fd:
- fd.write(contents)
- fd.close()
+
def handle_specific_packages(self, package):
"""Packages requiring additional configuration"""
- if package.name.lower() in (
- "pyqt4",
- "pyqt5",
- "pyside2",
- ):
+ if package.name.lower() in ("pyqt4", "pyqt5", "pyside2"):
# Qt configuration file (where to find Qt)
name = "qt.conf"
- contents = """[Paths]
-Prefix = .
-Binaries = ."""
- self.create_file(
- package,
- name,
- str(Path("Lib") / "site-packages" / package.name),
- contents,
- )
- self.create_file(
- package,
- name,
- ".",
- contents.replace(
- ".",
- f"./Lib/site-packages/{package.name}",
- ),
- )
+ contents = """[Paths]\nPrefix = .\nBinaries = ."""
+ self.create_file(package, name, str(Path("Lib") / "site-packages" / package.name), contents)
+ self.create_file(package, name, ".", contents.replace(".", f"./Lib/site-packages/{package.name}"))
# pyuic script
if package.name.lower() == "pyqt5":
# see http://code.activestate.com/lists/python-list/666469/
@@ -365,34 +212,20 @@ 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, action):
- """Print package-related action text (e.g. 'Installing')
- indicating progress"""
- text = " ".join([action, package.name, package.version])
+ 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}"
if self.verbose:
utils.print_box(text)
else:
- if self.indent:
- text = (" " * 4) + text
- print(text + "...", end=" ")
+ print(f" {text}...", end=" ")
def _print_done(self):
"""Print OK at the end of a process"""
@@ -402,7 +235,7 @@ def _print_done(self):
def uninstall(self, package):
"""Uninstall package from distribution"""
self._print(package, "Uninstalling")
- if not package.name == "pip":
+ if package.name != "pip":
# trick to get true target (if not current)
this_exec = utils.get_python_executable(self.target) # PyPy !
subprocess.call([this_exec, "-m", "pip", "uninstall", package.name, "-y"], cwd=self.target)
@@ -425,232 +258,140 @@ def install_bdist_direct(self, package, install_options=None):
package = Package(fname)
self._print_done()
- def install_script(self, script, install_options=None):
- try:
- fname = utils.do_script(
- script,
- python_exe=utils.get_python_executable(self.target), # PyPy3 !
- verbose=self.verbose,
- install_options=install_options,
- )
- except RuntimeError:
- if not self.verbose:
- print("Failed!")
- raise
-
-
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))
+ registerWinPythonHelp = f"Register WinPython: associate file extensions, icons and context menu with this WinPython"
+ unregisterWinPythonHelp = f"Unregister WinPython: de-associate file extensions, icons and context menu from this WinPython"
+ parser = ArgumentParser(
+ description="WinPython Package Manager: handle a WinPython Distribution and its packages",
+ formatter_class=RawTextHelpFormatter,
+ )
+ parser.add_argument("fname", metavar="package or lockfile", nargs="?", default="", type=str, help="optional package name or package wheel")
+ parser.add_argument("-v", "--verbose", action="store_true", help="show more details on packages and actions")
+ parser.add_argument( "--register", dest="registerWinPython", action="store_true", help=registerWinPythonHelp)
+ # parser.add_argument( "--register_forall", action="store_true", help="Register distribution for all users")
+ parser.add_argument("--unregister", dest="unregisterWinPython", action="store_true", help=unregisterWinPythonHelp)
+ # parser.add_argument( "--unregister_forall", action="store_true", help="un-Register distribution for all users")
+ parser.add_argument("--fix", action="store_true", help="make WinPython fix")
+ parser.add_argument("--movable", action="store_true", help="make WinPython movable")
+ parser.add_argument("-ws", dest="wheelsource", default=None, type=str, help="wheels location, '.' = WheelHouse): wppm pylock.toml -ws source_of_wheels, wppm -ls -ws .")
+ parser.add_argument("-wd", dest="wheeldrain" , default=None, type=str, help="wheels destination: wppm pylock.toml -wd destination_of_wheels")
+ parser.add_argument("-ls", "--list", action="store_true", help="list installed packages matching [optional] expression: wppm -ls, wppm -ls pand")
+ parser.add_argument("-lsa", dest="all", action="store_true",help=f"list details of packages matching [optional] expression: wppm -lsa pandas -l1")
+ parser.add_argument("-md", dest="markdown", action="store_true",help=f"markdown summary if the installation")
+ parser.add_argument("-p",dest="pipdown",action="store_true",help="show Package dependencies of the given package[option], [.]=all: wppm -p pandas[.]")
+ parser.add_argument("-r", dest="pipup", action="store_true", help=f"show Reverse wppmdependancies of the given package[option]: wppm -r pytest[test]")
+ parser.add_argument("-l", dest="levels", type=int, default=2, help="show 'LEVELS' levels of dependencies (with -p, -r), default is 2: wppm -p pandas -l1")
+ parser.add_argument("-t", dest="target", default=sys.prefix, help=f'path to target Python distribution (default: "{sys.prefix}")')
+ parser.add_argument("-i", "--install", action="store_true", help="install a given package wheel or pylock file (use pip for more features)")
+ parser.add_argument("-u", "--uninstall", action="store_true", help="uninstall package (use pip for more features)")
+
+
+ args = parser.parse_args()
+ targetpython = None
+ if args.target and args.target != sys.prefix:
+ targetpython = args.target if args.target.lower().endswith('.exe') else str(Path(args.target) / 'python.exe')
+ if args.wheelsource == ".": # play in default WheelHouse
+ if utils.is_python_distribution(args.target):
+ dist = Distribution(args.target)
+ args.wheelsource = dist.wheelhouse / 'included.wheels'
+ if args.install and args.uninstall:
+ raise RuntimeError("Incompatible arguments: --install and --uninstall")
+ if args.registerWinPython and args.unregisterWinPython:
+ raise RuntimeError("Incompatible arguments: --install and --uninstall")
+ if args.pipdown:
+ pip = piptree.PipData(targetpython, args.wheelsource)
+ pack, extra, *other = (args.fname + "[").replace("]", "[").split("[")
+ print(pip.down(pack, extra, args.levels, verbose=args.verbose))
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)
- print(pack.description)
- # dist.install(pack)
- # dist.uninstall(pack)
- else:
- registerWinPythonHelp = f"Register distribution: associate file extensions, icons and context menu with this WinPython"
- unregisterWinPythonHelp = f"Unregister distribution: de-associate file extensions, icons and context menu from this WinPython"
- parser = ArgumentParser(
- description="WinPython Package Manager: handle a WinPython Distribution and its packages",
- formatter_class=RawTextHelpFormatter,
- )
- parser.add_argument(
- "fname",
- metavar="package",
- nargs="?",
- default="",
- type=str,
- help="optional package name or package wheel",
- )
- parser.add_argument(
- "--register",
- dest="registerWinPython",
- action="store_const",
- const=True,
- default=False,
- help=registerWinPythonHelp,
- )
- parser.add_argument(
- "--unregister",
- dest="unregisterWinPython",
- action="store_const",
- const=True,
- default=False,
- help=unregisterWinPythonHelp,
- )
- parser.add_argument(
- "-v",
- "--verbose",
- dest="verbose",
- action="store_const",
- const=True,
- default=False,
- help="show more details on packages and actions",
- )
- parser.add_argument(
- "-ls",
- "--list",
- dest="list",
- action="store_const",
- const=True,
- default=False,
- help=f"list packages matching the given [optionnal] package expression: wppm -ls, wppm -ls pand",
- )
- parser.add_argument(
- "-p",
- dest="pipdown",
- action="store_const",
- const=True,
- default=False,
- help=f"show Package dependancies of the given package[option]: wppm -p pandas[test]",
- )
- parser.add_argument(
- "-r",
- dest="pipup",
- action="store_const",
- const=True,
- default=False,
- help=f"show Reverse dependancies of the given package[option]: wppm -r pytest[test]",
- )
- parser.add_argument(
- "-l",
- dest="levels",
- type=int,
- default=2,
- help=f"show 'LEVELS' levels of dependancies of the package, default is 2: wppm -p pandas -l1",
- )
- parser.add_argument(
- "-lsa",
- dest="all",
- action="store_const",
- const=True,
- default=False,
- help=f"list details of package names matching given regular expression: wppm -lsa pandas -l1",
- )
- parser.add_argument(
- "-t",
- dest="target",
- default=sys.prefix,
- help=f'path to target Python distribution (default: "{sys.prefix}")',
- )
- parser.add_argument(
- "-i",
- "--install",
- dest="install",
- action="store_const",
- const=True,
- default=False,
- help="install a given package wheel (use pip for more features)",
- )
- parser.add_argument(
- "-u",
- "--uninstall",
- dest="uninstall",
- action="store_const",
- const=True,
- default=False,
- help="uninstall package (use pip for more features)",
- )
- args = parser.parse_args()
- targetpython = None
- if args.target and not args.target==sys.prefix:
- targetpython = args.target if args.target[-4:] == '.exe' else str(Path(args.target) / 'python.exe')
- # print(targetpython.resolve() to check)
- if args.install and args.uninstall:
- raise RuntimeError("Incompatible arguments: --install and --uninstall")
- if args.registerWinPython and args.unregisterWinPython:
- raise RuntimeError("Incompatible arguments: --install and --uninstall")
- if args.pipdown:
- pip = piptree.PipData(targetpython)
- pack, extra, *other = (args.fname + "[").replace("]", "[").split("[")
- print(pip.down(pack, extra, args.levels, verbose=args.verbose))
+ elif args.pipup:
+ pip = piptree.PipData(targetpython, args.wheelsource)
+ pack, extra, *other = (args.fname + "[").replace("]", "[").split("[")
+ print(pip.up(pack, extra, args.levels, verbose=args.verbose))
+ sys.exit()
+ elif args.list:
+ pip = piptree.PipData(targetpython, args.wheelsource)
+ todo = [l for l in pip.pip_list(full=True) if bool(re.search(args.fname, l[0]))]
+ titles = [['Package', 'Version', 'Summary'], ['_' * max(x, 6) for x in utils.columns_width(todo)]]
+ listed = utils.formatted_list(titles + todo, max_width=70)
+ for p in listed:
+ print(*p)
+ sys.exit()
+ elif args.all:
+ pip = piptree.PipData(targetpython, args.wheelsource)
+ todo = [l for l in pip.pip_list(full=True) if bool(re.search(args.fname, l[0]))]
+ for l in todo:
+ # print(pip.distro[l[0]])
+ title = f"** Package: {l[0]} **"
+ print("\n" + "*" * len(title), f"\n{title}", "\n" + "*" * len(title))
+ for key, value in pip.raw[l[0]].items():
+ rawtext = json.dumps(value, indent=2, ensure_ascii=False)
+ lines = [l for l in rawtext.split(r"\n") if len(l.strip()) > 2]
+ if key.lower() != 'description' or args.verbose:
+ print(f"{key}: ", "\n".join(lines).replace('"', ""))
+ sys.exit()
+ if args.registerWinPython:
+ print(registerWinPythonHelp)
+ if utils.is_python_distribution(args.target):
+ dist = Distribution(args.target)
+ else:
+ raise OSError(f"Invalid Python distribution {args.target}")
+ print(f"registering {args.target}")
+ print("continue ? Y/N")
+ theAnswer = input()
+ if theAnswer == "Y":
+ associate.register(dist.target, verbose=args.verbose)
sys.exit()
- elif args.pipup:
- pip = piptree.PipData(targetpython)
- pack, extra, *other = (args.fname + "[").replace("]", "[").split("[")
- print(pip.up(pack, extra, args.levels, verbose=args.verbose))
+ if args.unregisterWinPython:
+ print(unregisterWinPythonHelp)
+ if utils.is_python_distribution(args.target):
+ dist = Distribution(args.target)
+ else:
+ raise OSError(f"Invalid Python distribution {args.target}")
+ print(f"unregistering {args.target}")
+ print("continue ? Y/N")
+ theAnswer = input()
+ if theAnswer == "Y":
+ associate.unregister(dist.target, verbose=args.verbose)
sys.exit()
- elif args.list:
- pip = piptree.PipData(targetpython)
- todo = [l for l in pip.pip_list(full=True) if bool(re.search(args.fname, l[0])) ]
- titles = [['Package', 'Version', 'Summary'],['_' * max(x, 6) for x in utils.columns_width(todo)]]
- listed = utils.formatted_list(titles + todo, max_width=70)
- for p in listed:
- print(*p)
+ if utils.is_python_distribution(args.target):
+ dist = Distribution(args.target, verbose=True)
+ cmd_fix = rf"from winpython import wppm;dist=wppm.Distribution(r'{dist.target}');dist.patch_standard_packages('pip', to_movable=False)"
+ cmd_mov = rf"from winpython import wppm;dist=wppm.Distribution(r'{dist.target}');dist.patch_standard_packages('pip', to_movable=True)"
+ if args.fix:
+ # dist.patch_standard_packages('pip', to_movable=False) # would fail on wppm.exe
+ p = subprocess.Popen(["start", "cmd", "/k",dist.python_exe, "-c" , cmd_fix], shell = True, cwd=dist.target)
sys.exit()
- elif args.all:
- pip = piptree.PipData(targetpython)
- todo = [l for l in pip.pip_list(full=True) if bool(re.search(args.fname, l[0])) ]
- for l in todo:
- # print(pip.distro[l[0]])
- title = f"** Package: {l[0]} **"
- print("\n"+"*"*len(title), f"\n{title}", "\n"+"*"*len(title) )
- for key, value in pip.raw[l[0]].items():
- rawtext=json.dumps(value, indent=2, ensure_ascii=False)
- lines = [l for l in rawtext.split(r"\n") if len(l.strip()) > 2]
- if key.lower() != 'description' or args.verbose==True:
- print(f"{key}: ", "\n".join(lines).replace('"', ""))
- sys.exit()
- if args.registerWinPython:
- print(registerWinPythonHelp)
- if utils.is_python_distribution(args.target):
- dist = Distribution(args.target)
- else:
- raise WindowsError(f"Invalid Python distribution {args.target}")
- print(f"registering {args.target}")
- print("continue ? Y/N")
- theAnswer = input()
- if theAnswer == "Y":
- from winpython import associate
-
- associate.register(dist.target, verbose=args.verbose)
- sys.exit()
- if args.unregisterWinPython:
- print(unregisterWinPythonHelp)
- if utils.is_python_distribution(args.target):
- dist = Distribution(args.target)
- else:
- raise WindowsError(f"Invalid Python distribution {args.target}")
- print(f"unregistering {args.target}")
- print("continue ? Y/N")
- theAnswer = input()
- if theAnswer == "Y":
- from winpython import associate
-
- associate.unregister(dist.target, verbose=args.verbose)
- sys.exit()
- elif not args.install and not args.uninstall:
- args.install = True
- if not Path(args.fname).is_file() and args.install:
- if args.fname == "":
+ if args.movable:
+ p = subprocess.Popen(["start", "cmd", "/k",dist.python_exe, "-c" , cmd_mov], shell = True, cwd=dist.target)
+ sys.exit()
+ if args.markdown:
+ print(dist.generate_package_index_markdown())
+ sys.exit()
+ if not args.install and not args.uninstall and args.fname.endswith(".toml"):
+ args.install = True # for Drag & Drop of .toml (and not wheel)
+ if args.fname == "" or (not args.install and not args.uninstall):
parser.print_help()
sys.exit()
- else:
- raise IOError(f"File not found: {args.fname}")
- if utils.is_python_distribution(args.target):
- dist = Distribution(args.target, verbose=True)
+ else:
try:
+ filename = Path(args.fname).name
+ install_from_wheelhouse = ["--no-index", "--trusted-host=None", f"--find-links={dist.wheelhouse / 'included.wheels'}"]
+ if filename.split('.')[0] == "pylock" and filename.split('.')[-1] == 'toml':
+ print(' a lock file !', args.fname, dist.target)
+ wh.get_pylock_wheels(dist.wheelhouse, Path(args.fname), args.wheelsource, args.wheeldrain)
+ sys.exit()
if args.uninstall:
package = dist.find_package(args.fname)
dist.uninstall(package)
- else:
+ elif args.install:
package = Package(args.fname)
if args.install:
- dist.install(package)
+ dist.install(package, install_options=install_from_wheelhouse)
except NotImplementedError:
raise RuntimeError("Package is not (yet) supported by WPPM")
- else:
- raise WindowsError(f"Invalid Python distribution {args.target}")
+ else:
+ raise OSError(f"Invalid Python distribution {args.target}")
if __name__ == "__main__":