depzip 0.1__py3-none-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- depzip/__init__.py +93 -0
- depzip/import312.exe +0 -0
- depzip/import313.exe +0 -0
- depzip-0.1.dist-info/METADATA +68 -0
- depzip-0.1.dist-info/RECORD +9 -0
- depzip-0.1.dist-info/WHEEL +5 -0
- depzip-0.1.dist-info/licenses/LICENSE +20 -0
- depzip-0.1.dist-info/top_level.txt +2 -0
- pyside6-uic/__main__.py +11 -0
depzip/__init__.py
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
3
|
+
from importlib import import_module
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def bundle(applications=[], modules=[], includes=[], excludes=[], output="bundle.zip"):
|
|
7
|
+
|
|
8
|
+
def contains(string, substrings):
|
|
9
|
+
string = string.casefold()
|
|
10
|
+
return any(s.casefold() in string for s in substrings)
|
|
11
|
+
|
|
12
|
+
base = os.path.dirname(sys.executable)
|
|
13
|
+
|
|
14
|
+
# Import modules to discover their dependencies
|
|
15
|
+
|
|
16
|
+
for m in modules:
|
|
17
|
+
import_module(m)
|
|
18
|
+
|
|
19
|
+
dependencies = {
|
|
20
|
+
n: m
|
|
21
|
+
for n, m in sys.modules.items()
|
|
22
|
+
if n not in ("__main__", __name__) and getattr(m, "__file__", None)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
# Collect files to bundle
|
|
26
|
+
|
|
27
|
+
bundle = {m.__file__ for m in dependencies.values()}
|
|
28
|
+
|
|
29
|
+
# Find and collect license files for bundled modules
|
|
30
|
+
|
|
31
|
+
from importlib.metadata import distribution, packages_distributions
|
|
32
|
+
|
|
33
|
+
packages = {n.split(".", 1)[0] for n in dependencies.keys()}
|
|
34
|
+
mapping = packages_distributions()
|
|
35
|
+
licenses = {"Python": {os.path.join(base, "LICENSE.txt")}}
|
|
36
|
+
|
|
37
|
+
for p in packages:
|
|
38
|
+
for d in mapping.get(p, []):
|
|
39
|
+
path = distribution(d)._path
|
|
40
|
+
licenses.setdefault(d, set()).update(
|
|
41
|
+
os.path.join(root, f)
|
|
42
|
+
for root, _, files in os.walk(path)
|
|
43
|
+
for f in files
|
|
44
|
+
if contains(f, ("license", "copying"))
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
# Collect DLLs to bundle
|
|
48
|
+
|
|
49
|
+
from dllist import dllist
|
|
50
|
+
|
|
51
|
+
bundle.update(
|
|
52
|
+
dll
|
|
53
|
+
for dll in dllist()
|
|
54
|
+
if os.path.commonpath([dll, base]) == base
|
|
55
|
+
and not contains(os.path.basename(dll), ("vcruntime", "msvcp"))
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
# Include additional files and directories
|
|
59
|
+
|
|
60
|
+
for path in includes:
|
|
61
|
+
path = path if os.path.exists(path) else os.path.join(base, path)
|
|
62
|
+
if os.path.isdir(path):
|
|
63
|
+
for root, dirs, files in os.walk(path):
|
|
64
|
+
dirs[:] = [d for d in dirs if d != "__pycache__"]
|
|
65
|
+
bundle.update(os.path.join(root, f) for f in files)
|
|
66
|
+
elif os.path.isfile(path):
|
|
67
|
+
bundle.add(path)
|
|
68
|
+
|
|
69
|
+
# Exclude specified files
|
|
70
|
+
|
|
71
|
+
bundle = {f for f in bundle if not contains(f, excludes)}
|
|
72
|
+
|
|
73
|
+
# Create the output zip file
|
|
74
|
+
|
|
75
|
+
from zipfile import ZipFile, ZIP_DEFLATED
|
|
76
|
+
|
|
77
|
+
v = sys.version_info[:2]
|
|
78
|
+
exe = os.path.join(__path__[0], f"import{v[0]}{v[1]}.exe")
|
|
79
|
+
|
|
80
|
+
with ZipFile(output, "w", ZIP_DEFLATED) as zf:
|
|
81
|
+
for a in applications:
|
|
82
|
+
if os.path.isfile(exe):
|
|
83
|
+
zf.write(exe, f"{a}.exe")
|
|
84
|
+
|
|
85
|
+
for d, files in licenses.items():
|
|
86
|
+
for f in sorted(files):
|
|
87
|
+
name = os.path.join("Licenses", d, os.path.basename(f))
|
|
88
|
+
zf.write(f, name)
|
|
89
|
+
|
|
90
|
+
for f in sorted(bundle):
|
|
91
|
+
if os.path.isfile(f):
|
|
92
|
+
name = os.path.relpath(f, base) if os.path.isabs(f) else f
|
|
93
|
+
zf.write(f, name)
|
depzip/import312.exe
ADDED
|
Binary file
|
depzip/import313.exe
ADDED
|
Binary file
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: depzip
|
|
3
|
+
Version: 0.1
|
|
4
|
+
Summary: A small library for zipping Python application dependencies
|
|
5
|
+
Author: Pavel Demin
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/pavel-demin/depzip
|
|
8
|
+
Requires-Python: <3.14,>=3.12
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Requires-Dist: dllist
|
|
12
|
+
Dynamic: license-file
|
|
13
|
+
|
|
14
|
+
This library can be used for zipping Python application dependencies.
|
|
15
|
+
|
|
16
|
+
This library uses the [dllist](https://github.com/wardbrian/dllist) library to discover required DLLs for dependencies.
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
This library can be installed using `pip`:
|
|
21
|
+
```
|
|
22
|
+
python -m pip install depzip
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Usage
|
|
26
|
+
|
|
27
|
+
Here is a Python script showing how to use `depzip` to copy the dependencies of a Python application using `matplotlib`, `numpy`, and `PySide6` into a file called `bundle.zip`:
|
|
28
|
+
```
|
|
29
|
+
import depzip
|
|
30
|
+
|
|
31
|
+
depzip.bundle(
|
|
32
|
+
applications=[
|
|
33
|
+
"pyside6-uic",
|
|
34
|
+
],
|
|
35
|
+
modules=[
|
|
36
|
+
"matplotlib.backends.backend_qtagg",
|
|
37
|
+
"matplotlib.figure",
|
|
38
|
+
"matplotlib.style",
|
|
39
|
+
"matplotlib",
|
|
40
|
+
"numpy",
|
|
41
|
+
"PySide6.QtCore",
|
|
42
|
+
"PySide6.QtGui",
|
|
43
|
+
"PySide6.QtNetwork",
|
|
44
|
+
"PySide6.QtUiTools",
|
|
45
|
+
"PySide6.QtWidgets",
|
|
46
|
+
],
|
|
47
|
+
includes=[
|
|
48
|
+
"Lib\\site-packages\\matplotlib\\mpl-data",
|
|
49
|
+
"Lib\\site-packages\\pyside6-uic",
|
|
50
|
+
"Lib\\site-packages\\PySide6\\plugins\\platforms\\qwindows.dll",
|
|
51
|
+
"Lib\\site-packages\\PySide6\\plugins\\styles\\qmodernwindowsstyle.dll",
|
|
52
|
+
"Lib\\site-packages\\PySide6\\uic.exe",
|
|
53
|
+
],
|
|
54
|
+
excludes=[
|
|
55
|
+
"python.exe",
|
|
56
|
+
"pythonw.exe",
|
|
57
|
+
],
|
|
58
|
+
output="bundle.zip",
|
|
59
|
+
)
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
The source code of this script can be found in [examples/bundle.py](https://github.com/pavel-demin/depzip/tree/main/examples/bundle.py).
|
|
63
|
+
|
|
64
|
+
The provided executable file `import.exe` can be used to run a Python application. It starts Python and imports a module with the same name as the executable file. For example, to run a Python file named `app.py`, the executable file `import.exe` should be renamed to `app.exe`.
|
|
65
|
+
|
|
66
|
+
The `applications` parameter is a list of application names that is used to automatically copy `import.exe` to executable files with names in this list.
|
|
67
|
+
|
|
68
|
+
The source code of the executable file `import.exe` can be found in [examples/import.c](https://github.com/pavel-demin/depzip/tree/main/examples/import.c).
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
depzip/__init__.py,sha256=8JNMnzwHCoZsFxWY9tbZTipL5UT7HJCj0iuc3V9tn2A,2788
|
|
2
|
+
depzip/import312.exe,sha256=t1fnVZ7URowlMFAGqbOQi3ilEUVheQN-D4yCQoRKb2g,16384
|
|
3
|
+
depzip/import313.exe,sha256=k0_nwiLTu7tmsH4Xxr2Lels6h82dUP-npMN5xg4t29k,16384
|
|
4
|
+
depzip-0.1.dist-info/licenses/LICENSE,sha256=gs0ay_wrvZSukzd8tstR8_WMHViGB6wQ84fQJooqOOQ,1078
|
|
5
|
+
pyside6-uic/__main__.py,sha256=2eRFIw5_D7CxR25tcjZhMBcw5kbAjnu7Slh5J9dMix8,254
|
|
6
|
+
depzip-0.1.dist-info/METADATA,sha256=6gJylwI8iKqTkMpUdDzlCkBFAW1Lo6KYoYiePcxLXYk,2365
|
|
7
|
+
depzip-0.1.dist-info/WHEEL,sha256=ZjXRCNaQ9YSypEK2TE0LRB0sy2OVXSszb4Sx1XjM99k,97
|
|
8
|
+
depzip-0.1.dist-info/top_level.txt,sha256=oFVxF4y4pAmGuFzO1o5fm3doPVrEX3seUXOgfQ7d92Y,19
|
|
9
|
+
depzip-0.1.dist-info/RECORD,,
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Pavel Demin
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
|
7
|
+
the Software without restriction, including without limitation the rights to
|
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
|
10
|
+
subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
19
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
20
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
pyside6-uic/__main__.py
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
3
|
+
import PySide6
|
|
4
|
+
import subprocess as sp
|
|
5
|
+
|
|
6
|
+
if len(sys.argv) != 2:
|
|
7
|
+
sys.exit(1)
|
|
8
|
+
|
|
9
|
+
uic = os.path.join(PySide6.__path__[0], "uic.exe")
|
|
10
|
+
cmd = [uic, "-g", "python", sys.argv[1]]
|
|
11
|
+
sys.exit(sp.run(cmd, stderr=sp.PIPE, shell=True).returncode)
|