python-msilib 0.4.3__tar.gz → 0.6.0__tar.gz
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.
- python_msilib-0.6.0/Makefile +61 -0
- {python_msilib-0.4.3/src/python_msilib.egg-info → python_msilib-0.6.0}/PKG-INFO +3 -9
- {python_msilib-0.4.3 → python_msilib-0.6.0}/README.md +2 -1
- {python_msilib-0.4.3 → python_msilib-0.6.0}/pyproject.toml +15 -55
- {python_msilib-0.4.3 → python_msilib-0.6.0}/src/msilib/__init__.py +2 -1
- {python_msilib-0.4.3 → python_msilib-0.6.0}/src/msilib/_msi.c +2 -2
- {python_msilib-0.4.3 → python_msilib-0.6.0}/src/msilib/include/_msi.h +8 -1
- {python_msilib-0.4.3 → python_msilib-0.6.0}/src/msilib/include/pythoncapi_compat.h +54 -6
- {python_msilib-0.4.3 → python_msilib-0.6.0}/src/msilib/schema.py +3 -3
- {python_msilib-0.4.3 → python_msilib-0.6.0/src/python_msilib.egg-info}/PKG-INFO +3 -9
- {python_msilib-0.4.3 → python_msilib-0.6.0}/src/python_msilib.egg-info/SOURCES.txt +0 -1
- {python_msilib-0.4.3 → python_msilib-0.6.0}/tests/test_msilib.py +44 -0
- python_msilib-0.4.3/Makefile +0 -83
- python_msilib-0.4.3/src/python_msilib.egg-info/requires.txt +0 -9
- {python_msilib-0.4.3 → python_msilib-0.6.0}/LICENSE +0 -0
- {python_msilib-0.4.3 → python_msilib-0.6.0}/MANIFEST.in +0 -0
- {python_msilib-0.4.3 → python_msilib-0.6.0}/setup.cfg +0 -0
- {python_msilib-0.4.3 → python_msilib-0.6.0}/src/msilib/sequence.py +0 -0
- {python_msilib-0.4.3 → python_msilib-0.6.0}/src/msilib/text.py +0 -0
- {python_msilib-0.4.3 → python_msilib-0.6.0}/src/python_msilib.egg-info/dependency_links.txt +0 -0
- {python_msilib-0.4.3 → python_msilib-0.6.0}/src/python_msilib.egg-info/not-zip-safe +0 -0
- {python_msilib-0.4.3 → python_msilib-0.6.0}/src/python_msilib.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Makefile to automate some tools
|
|
2
|
+
SHELL=/bin/bash
|
|
3
|
+
PATH := $(shell python -c "import sysconfig; print(sysconfig.get_path('scripts'))"):$(PATH)
|
|
4
|
+
|
|
5
|
+
PY_PLATFORM := $(shell python -c "import sysconfig; print(sysconfig.get_platform())")
|
|
6
|
+
PRE_COMMIT_OPTIONS := --show-diff-on-failure --color=always --all-files --hook-stage=manual --no-progress
|
|
7
|
+
|
|
8
|
+
COV_TMPDIR := $(shell mktemp -d)
|
|
9
|
+
|
|
10
|
+
.PHONY: all
|
|
11
|
+
all: install
|
|
12
|
+
|
|
13
|
+
.PHONY: prek
|
|
14
|
+
prek: install
|
|
15
|
+
@(prek run $(PRE_COMMIT_OPTIONS) || true)
|
|
16
|
+
@prek cache gc -q
|
|
17
|
+
|
|
18
|
+
.PHONY: clean
|
|
19
|
+
clean: uninstall
|
|
20
|
+
@rm -f .coverage* || true
|
|
21
|
+
@rm -rf build dist wheelhouse
|
|
22
|
+
@prek cache clean -q
|
|
23
|
+
|
|
24
|
+
.PHONY: install
|
|
25
|
+
install:
|
|
26
|
+
./ci/install-tools.sh --dev
|
|
27
|
+
if ! [ -f .git/hooks/pre-commit ]; then\
|
|
28
|
+
prek install --install-hooks --overwrite -t pre-commit;\
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
.PHONY: uninstall
|
|
32
|
+
uninstall:
|
|
33
|
+
@prek uninstall -q
|
|
34
|
+
@rm -f .git/hooks/pre-commit
|
|
35
|
+
|
|
36
|
+
.PHONY: upgrade
|
|
37
|
+
upgrade: install
|
|
38
|
+
prek auto-update --freeze
|
|
39
|
+
$(MAKE) prek
|
|
40
|
+
|
|
41
|
+
.PHONY: wheel
|
|
42
|
+
wheel:
|
|
43
|
+
./ci/build-wheel.sh --install
|
|
44
|
+
|
|
45
|
+
.PHONY: tests
|
|
46
|
+
tests: wheel
|
|
47
|
+
./ci/install-tools.sh --tests
|
|
48
|
+
cp pyproject.toml $(COV_TMPDIR)/
|
|
49
|
+
cp -a tests/ $(COV_TMPDIR)/
|
|
50
|
+
cd $(COV_TMPDIR) && pytest -nauto -v || true
|
|
51
|
+
|
|
52
|
+
.PHONY: cov
|
|
53
|
+
cov: wheel
|
|
54
|
+
./ci/install-tools.sh --tests
|
|
55
|
+
@rm -rf build/coverage_html_report
|
|
56
|
+
cp pyproject.toml $(COV_TMPDIR)/
|
|
57
|
+
cp -a tests/ $(COV_TMPDIR)/
|
|
58
|
+
cd $(COV_TMPDIR) && coverage run || true
|
|
59
|
+
coverage combine --keep --quiet -a $(COV_TMPDIR)/
|
|
60
|
+
coverage report
|
|
61
|
+
coverage html --show-contexts
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-msilib
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6.0
|
|
4
4
|
Summary: Read and write Microsoft Installer files
|
|
5
5
|
Author-email: Marcelo Duarte <marcelotduarte@users.noreply.github.com>, " Martin v. Löwis" <loewis@users.noreply.github.com>
|
|
6
6
|
License-Expression: PSF-2.0
|
|
@@ -26,13 +26,6 @@ Classifier: Topic :: Utilities
|
|
|
26
26
|
Requires-Python: >=3.13
|
|
27
27
|
Description-Content-Type: text/markdown
|
|
28
28
|
License-File: LICENSE
|
|
29
|
-
Provides-Extra: dev
|
|
30
|
-
Requires-Dist: bump-my-version==1.2.4; extra == "dev"
|
|
31
|
-
Requires-Dist: cibuildwheel==3.3.0; extra == "dev"
|
|
32
|
-
Requires-Dist: pre-commit==4.4.0; extra == "dev"
|
|
33
|
-
Provides-Extra: tests
|
|
34
|
-
Requires-Dist: coverage==7.12.0; extra == "tests"
|
|
35
|
-
Requires-Dist: pytest==9.0.1; extra == "tests"
|
|
36
29
|
Dynamic: license-file
|
|
37
30
|
|
|
38
31
|
# python-msilib
|
|
@@ -40,7 +33,7 @@ Dynamic: license-file
|
|
|
40
33
|
Read and write Microsoft Installer files.
|
|
41
34
|
|
|
42
35
|
This library is legacy code borrowed from Python 3.12, intended to allow
|
|
43
|
-
cx_Freeze's `bdist_msi` command to continue working in Python 3.13
|
|
36
|
+
cx_Freeze's `bdist_msi` command to continue working in Python 3.13+.
|
|
44
37
|
|
|
45
38
|
[](https://pypi.org/project/python-msilib/)
|
|
46
39
|
[](https://pypistats.org/packages/python-msilib)
|
|
@@ -49,6 +42,7 @@ cx_Freeze's `bdist_msi` command to continue working in Python 3.13 and 3.14.
|
|
|
49
42
|
[](https://www.python.org/)
|
|
50
43
|
[](https://htmlpreview.github.io/?https://github.com/marcelotduarte/python-msilib/blob/python-coverage-comment-action-data/htmlcov/index.html)
|
|
51
44
|
[](https://github.com/astral-sh/ruff)
|
|
45
|
+
[](https://github.com/j178/prek)
|
|
52
46
|
|
|
53
47
|
## Installation
|
|
54
48
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Read and write Microsoft Installer files.
|
|
4
4
|
|
|
5
5
|
This library is legacy code borrowed from Python 3.12, intended to allow
|
|
6
|
-
cx_Freeze's `bdist_msi` command to continue working in Python 3.13
|
|
6
|
+
cx_Freeze's `bdist_msi` command to continue working in Python 3.13+.
|
|
7
7
|
|
|
8
8
|
[](https://pypi.org/project/python-msilib/)
|
|
9
9
|
[](https://pypistats.org/packages/python-msilib)
|
|
@@ -12,6 +12,7 @@ cx_Freeze's `bdist_msi` command to continue working in Python 3.13 and 3.14.
|
|
|
12
12
|
[](https://www.python.org/)
|
|
13
13
|
[](https://htmlpreview.github.io/?https://github.com/marcelotduarte/python-msilib/blob/python-coverage-comment-action-data/htmlcov/index.html)
|
|
14
14
|
[](https://github.com/astral-sh/ruff)
|
|
15
|
+
[](https://github.com/j178/prek)
|
|
15
16
|
|
|
16
17
|
## Installation
|
|
17
18
|
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
[build-system]
|
|
2
2
|
requires = [
|
|
3
|
-
|
|
4
|
-
# setuptools 78.1.1 fix path traversal vulnerability
|
|
5
|
-
"setuptools>=78.1.1,<=80.9.0",
|
|
3
|
+
"setuptools~=82.0",
|
|
6
4
|
]
|
|
7
5
|
build-backend = "setuptools.build_meta"
|
|
8
6
|
|
|
9
7
|
[project]
|
|
10
8
|
name = "python-msilib"
|
|
9
|
+
version = "0.6.0"
|
|
11
10
|
description = "Read and write Microsoft Installer files"
|
|
12
11
|
classifiers = [
|
|
13
12
|
"Development Status :: 5 - Production/Stable",
|
|
@@ -26,7 +25,6 @@ classifiers = [
|
|
|
26
25
|
"Topic :: System :: Software Distribution",
|
|
27
26
|
"Topic :: Utilities",
|
|
28
27
|
]
|
|
29
|
-
dynamic = ["version"]
|
|
30
28
|
keywords = ["msilib"]
|
|
31
29
|
license = "PSF-2.0"
|
|
32
30
|
license-files = ["LICENSE"]
|
|
@@ -41,30 +39,26 @@ email = "marcelotduarte@users.noreply.github.com"
|
|
|
41
39
|
name = " Martin v. Löwis"
|
|
42
40
|
email = "loewis@users.noreply.github.com"
|
|
43
41
|
|
|
44
|
-
[project.optional-dependencies]
|
|
45
|
-
dev = [
|
|
46
|
-
"bump-my-version==1.2.4",
|
|
47
|
-
"cibuildwheel==3.3.0",
|
|
48
|
-
"pre-commit==4.4.0",
|
|
49
|
-
]
|
|
50
|
-
tests = [
|
|
51
|
-
"coverage==7.12.0",
|
|
52
|
-
"pytest==9.0.1",
|
|
53
|
-
]
|
|
54
|
-
|
|
55
42
|
[project.urls]
|
|
56
43
|
Source = "https://github.com/marcelotduarte/python-msilib"
|
|
57
44
|
Changelog = "https://github.com/marcelotduarte/python-msilib/releases"
|
|
58
45
|
Documentation = "https://docs.python.org/3.12/library/msilib.html"
|
|
59
46
|
|
|
47
|
+
[dependency-groups]
|
|
48
|
+
dev = [
|
|
49
|
+
"cibuildwheel>=3.4.1",
|
|
50
|
+
"prek>=0.3.8,<0.4.0",
|
|
51
|
+
]
|
|
52
|
+
tests = [
|
|
53
|
+
"coverage>=7.13.0",
|
|
54
|
+
"pytest>=9.0.3",
|
|
55
|
+
]
|
|
56
|
+
|
|
60
57
|
[tool.setuptools]
|
|
61
58
|
include-package-data = true
|
|
62
59
|
package-dir = {"" = "src"}
|
|
63
60
|
zip-safe = false
|
|
64
61
|
|
|
65
|
-
[tool.setuptools.dynamic]
|
|
66
|
-
version = {attr = "msilib.__version__"}
|
|
67
|
-
|
|
68
62
|
[[tool.setuptools.ext-modules]]
|
|
69
63
|
name = "msilib._msi"
|
|
70
64
|
sources = ["src/msilib/_msi.c"]
|
|
@@ -78,44 +72,9 @@ libraries = ["msi","rpcrt4", "cabinet"]
|
|
|
78
72
|
namespaces = false
|
|
79
73
|
where = ["src"]
|
|
80
74
|
|
|
81
|
-
[tool.bumpversion]
|
|
82
|
-
commit = true
|
|
83
|
-
current_version = "0.4.3"
|
|
84
|
-
message = "Bump version: {current_version} → {new_version} [ci skip]"
|
|
85
|
-
parse = """(?x)
|
|
86
|
-
(?P<major>0|[1-9]\\d*)\\.
|
|
87
|
-
(?P<minor>0|[1-9]\\d*)\\.
|
|
88
|
-
(?P<patch>0|[1-9]\\d*)
|
|
89
|
-
(?:
|
|
90
|
-
\\.(?P<optional>0|[1-9]\\d*) # pull request number (optional)
|
|
91
|
-
)?
|
|
92
|
-
(?:
|
|
93
|
-
- # dash separator for pre-release section
|
|
94
|
-
(?P<pre>[a-zA-Z-]+)\\. # pre-release label
|
|
95
|
-
(?P<build>0|[1-9]\\d*) # pre-release version number
|
|
96
|
-
)? # pre-release section is optional
|
|
97
|
-
"""
|
|
98
|
-
serialize = [
|
|
99
|
-
"{major}.{minor}.{patch}.{optional}-{pre}.{build}",
|
|
100
|
-
"{major}.{minor}.{patch}-{pre}.{build}",
|
|
101
|
-
"{major}.{minor}.{patch}"
|
|
102
|
-
]
|
|
103
|
-
sign_tags = true
|
|
104
|
-
tag = true
|
|
105
|
-
tag_name = "{new_version}"
|
|
106
|
-
verbose = true
|
|
107
|
-
|
|
108
|
-
[[tool.bumpversion.files]]
|
|
109
|
-
filename = "src/msilib/__init__.py"
|
|
110
|
-
|
|
111
|
-
[tool.bumpversion.parts.pre]
|
|
112
|
-
values = ["dev", "final"]
|
|
113
|
-
optional_value = "final"
|
|
114
|
-
|
|
115
75
|
[tool.cibuildwheel]
|
|
116
76
|
build-frontend = "build[uv]"
|
|
117
77
|
build-verbosity = 1
|
|
118
|
-
enable = ["cpython-freethreading"]
|
|
119
78
|
|
|
120
79
|
[tool.coverage.html]
|
|
121
80
|
directory = "build/coverage_html_report"
|
|
@@ -225,12 +184,13 @@ ignore = [
|
|
|
225
184
|
|
|
226
185
|
[tool.ruff.lint.per-file-ignores]
|
|
227
186
|
"src/msilib/__init__.py" = [
|
|
228
|
-
"S101", # Use of `assert` detected
|
|
229
|
-
"S608",
|
|
230
187
|
"A002",
|
|
188
|
+
"A005",
|
|
231
189
|
"ANN201",
|
|
232
190
|
"ERA001",
|
|
233
191
|
"PLW0603", # global
|
|
192
|
+
"S101", # Use of `assert` detected
|
|
193
|
+
"S608",
|
|
234
194
|
]
|
|
235
195
|
"src/msilib/schema.py" = [
|
|
236
196
|
"E501", # Line too long
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
# Licensed to PSF under a Contributor Agreement.
|
|
5
5
|
import contextlib
|
|
6
6
|
import fnmatch
|
|
7
|
+
import importlib.metadata
|
|
7
8
|
import os
|
|
8
9
|
import platform
|
|
9
10
|
import re
|
|
@@ -56,7 +57,7 @@ from msilib._msi import (
|
|
|
56
57
|
UuidCreate,
|
|
57
58
|
)
|
|
58
59
|
|
|
59
|
-
__version__ =
|
|
60
|
+
__version__ = importlib.metadata.version("python-msilib")
|
|
60
61
|
|
|
61
62
|
__all__ = [
|
|
62
63
|
"CAB",
|
|
@@ -260,7 +260,7 @@ static PyObject* _msi_FCICreate_impl(
|
|
|
260
260
|
}
|
|
261
261
|
|
|
262
262
|
ccab.cb = INT_MAX; /* no need to split CAB into multiple media */
|
|
263
|
-
ccab.cbFolderThresh =
|
|
263
|
+
ccab.cbFolderThresh = 10000000; /* flush directory after this many bytes */
|
|
264
264
|
ccab.cbReserveCFData = 0;
|
|
265
265
|
ccab.cbReserveCFFolder = 0;
|
|
266
266
|
ccab.cbReserveCFHeader = 0;
|
|
@@ -310,7 +310,7 @@ static PyObject* _msi_FCICreate_impl(
|
|
|
310
310
|
}
|
|
311
311
|
|
|
312
312
|
if (!FCIAddFile(hfci, filename, cabname, FALSE, cb_getnextcabinet,
|
|
313
|
-
cb_status, cb_getopeninfo,
|
|
313
|
+
cb_status, cb_getopeninfo, TCOMPfromLZXWindow(21)))
|
|
314
314
|
goto err;
|
|
315
315
|
}
|
|
316
316
|
|
|
@@ -2,9 +2,16 @@
|
|
|
2
2
|
preserve
|
|
3
3
|
[clinic start generated code]*/
|
|
4
4
|
|
|
5
|
-
// Add _PyArg_NoPositional and _PyArg_BadArgument
|
|
5
|
+
// Add _PyArg_NoPositional and _PyArg_BadArgument (Python 3.13.0b2+)
|
|
6
6
|
#define Py_BUILD_CORE
|
|
7
|
+
#if PY_VERSION_HEX >= 0x030D00B2
|
|
7
8
|
#include <internal/pycore_modsupport.h>
|
|
9
|
+
#endif
|
|
10
|
+
|
|
11
|
+
// Compatible _PyCFunction_CAST (Python 3.10)
|
|
12
|
+
#ifndef _PyCFunction_CAST
|
|
13
|
+
#define _PyCFunction_CAST(func) ((PyCFunctionObject*)func)
|
|
14
|
+
#endif
|
|
8
15
|
|
|
9
16
|
#define _MSI_SENTINEL { NULL, NULL }
|
|
10
17
|
|
|
@@ -1425,6 +1425,11 @@ PyUnicodeWriter_WriteStr(PyUnicodeWriter *writer, PyObject *obj)
|
|
|
1425
1425
|
static inline int
|
|
1426
1426
|
PyUnicodeWriter_WriteRepr(PyUnicodeWriter *writer, PyObject *obj)
|
|
1427
1427
|
{
|
|
1428
|
+
if (obj == NULL) {
|
|
1429
|
+
return _PyUnicodeWriter_WriteASCIIString((_PyUnicodeWriter*)writer,
|
|
1430
|
+
"<NULL>", 6);
|
|
1431
|
+
}
|
|
1432
|
+
|
|
1428
1433
|
PyObject *str = PyObject_Repr(obj);
|
|
1429
1434
|
if (str == NULL) {
|
|
1430
1435
|
return -1;
|
|
@@ -1569,6 +1574,11 @@ static inline int PyLong_IsZero(PyObject *obj)
|
|
|
1569
1574
|
|
|
1570
1575
|
// gh-124502 added PyUnicode_Equal() to Python 3.14.0a0
|
|
1571
1576
|
#if PY_VERSION_HEX < 0x030E00A0
|
|
1577
|
+
|
|
1578
|
+
#if PY_VERSION_HEX >= 0x030d0000 && !defined(PYPY_VERSION)
|
|
1579
|
+
PyAPI_FUNC(int) _PyUnicode_Equal(PyObject *str1, PyObject *str2);
|
|
1580
|
+
#endif
|
|
1581
|
+
|
|
1572
1582
|
static inline int PyUnicode_Equal(PyObject *str1, PyObject *str2)
|
|
1573
1583
|
{
|
|
1574
1584
|
if (!PyUnicode_Check(str1)) {
|
|
@@ -1583,8 +1593,6 @@ static inline int PyUnicode_Equal(PyObject *str1, PyObject *str2)
|
|
|
1583
1593
|
}
|
|
1584
1594
|
|
|
1585
1595
|
#if PY_VERSION_HEX >= 0x030d0000 && !defined(PYPY_VERSION)
|
|
1586
|
-
PyAPI_FUNC(int) _PyUnicode_Equal(PyObject *str1, PyObject *str2);
|
|
1587
|
-
|
|
1588
1596
|
return _PyUnicode_Equal(str1, str2);
|
|
1589
1597
|
#elif PY_VERSION_HEX >= 0x03060000 && !defined(PYPY_VERSION)
|
|
1590
1598
|
return _PyUnicode_EQ(str1, str2);
|
|
@@ -1607,11 +1615,14 @@ static inline PyObject* PyBytes_Join(PyObject *sep, PyObject *iterable)
|
|
|
1607
1615
|
|
|
1608
1616
|
|
|
1609
1617
|
#if PY_VERSION_HEX < 0x030E00A0
|
|
1618
|
+
|
|
1619
|
+
#if PY_VERSION_HEX >= 0x03000000 && !defined(PYPY_VERSION)
|
|
1620
|
+
PyAPI_FUNC(Py_hash_t) _Py_HashBytes(const void *src, Py_ssize_t len);
|
|
1621
|
+
#endif
|
|
1622
|
+
|
|
1610
1623
|
static inline Py_hash_t Py_HashBuffer(const void *ptr, Py_ssize_t len)
|
|
1611
1624
|
{
|
|
1612
1625
|
#if PY_VERSION_HEX >= 0x03000000 && !defined(PYPY_VERSION)
|
|
1613
|
-
PyAPI_FUNC(Py_hash_t) _Py_HashBytes(const void *src, Py_ssize_t len);
|
|
1614
|
-
|
|
1615
1626
|
return _Py_HashBytes(ptr, len);
|
|
1616
1627
|
#else
|
|
1617
1628
|
Py_hash_t hash;
|
|
@@ -1948,11 +1959,14 @@ PyLongWriter_Finish(PyLongWriter *writer)
|
|
|
1948
1959
|
|
|
1949
1960
|
// gh-127350 added Py_fopen() and Py_fclose() to Python 3.14a4
|
|
1950
1961
|
#if PY_VERSION_HEX < 0x030E00A4
|
|
1962
|
+
|
|
1963
|
+
#if 0x030400A2 <= PY_VERSION_HEX && !defined(PYPY_VERSION)
|
|
1964
|
+
PyAPI_FUNC(FILE*) _Py_fopen_obj(PyObject *path, const char *mode);
|
|
1965
|
+
#endif
|
|
1966
|
+
|
|
1951
1967
|
static inline FILE* Py_fopen(PyObject *path, const char *mode)
|
|
1952
1968
|
{
|
|
1953
1969
|
#if 0x030400A2 <= PY_VERSION_HEX && !defined(PYPY_VERSION)
|
|
1954
|
-
PyAPI_FUNC(FILE*) _Py_fopen_obj(PyObject *path, const char *mode);
|
|
1955
|
-
|
|
1956
1970
|
return _Py_fopen_obj(path, mode);
|
|
1957
1971
|
#else
|
|
1958
1972
|
FILE *f;
|
|
@@ -2659,6 +2673,40 @@ PyUnstable_Unicode_GET_CACHED_HASH(PyObject *op)
|
|
|
2659
2673
|
}
|
|
2660
2674
|
#endif
|
|
2661
2675
|
|
|
2676
|
+
#if 0x030D0000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x030F00A7 && !defined(PYPY_VERSION)
|
|
2677
|
+
// Immortal objects were implemented in Python 3.12, however there is no easy API
|
|
2678
|
+
// to make objects immortal until 3.14 which has _Py_SetImmortal(). Since
|
|
2679
|
+
// immortal objects are primarily needed for free-threading, this API is implemented
|
|
2680
|
+
// for 3.14 using _Py_SetImmortal() and uses private macros on 3.13.
|
|
2681
|
+
#if 0x030E0000 <= PY_VERSION_HEX
|
|
2682
|
+
PyAPI_FUNC(void) _Py_SetImmortal(PyObject *op);
|
|
2683
|
+
#endif
|
|
2684
|
+
|
|
2685
|
+
static inline int
|
|
2686
|
+
PyUnstable_SetImmortal(PyObject *op)
|
|
2687
|
+
{
|
|
2688
|
+
assert(op != NULL);
|
|
2689
|
+
if (!PyUnstable_Object_IsUniquelyReferenced(op) || PyUnicode_Check(op)) {
|
|
2690
|
+
return 0;
|
|
2691
|
+
}
|
|
2692
|
+
#if 0x030E0000 <= PY_VERSION_HEX
|
|
2693
|
+
_Py_SetImmortal(op);
|
|
2694
|
+
#else
|
|
2695
|
+
// Python 3.13 doesn't export _Py_SetImmortal() function
|
|
2696
|
+
if (PyObject_GC_IsTracked(op)) {
|
|
2697
|
+
PyObject_GC_UnTrack(op);
|
|
2698
|
+
}
|
|
2699
|
+
#ifdef Py_GIL_DISABLED
|
|
2700
|
+
op->ob_tid = _Py_UNOWNED_TID;
|
|
2701
|
+
op->ob_ref_local = _Py_IMMORTAL_REFCNT_LOCAL;
|
|
2702
|
+
op->ob_ref_shared = 0;
|
|
2703
|
+
#else
|
|
2704
|
+
op->ob_refcnt = _Py_IMMORTAL_REFCNT;
|
|
2705
|
+
#endif
|
|
2706
|
+
#endif
|
|
2707
|
+
return 1;
|
|
2708
|
+
}
|
|
2709
|
+
#endif
|
|
2662
2710
|
|
|
2663
2711
|
#ifdef __cplusplus
|
|
2664
2712
|
}
|
|
@@ -107,7 +107,7 @@ File.add_field(4, "FileSize", 260)
|
|
|
107
107
|
File.add_field(5, "Version", 7496)
|
|
108
108
|
File.add_field(6, "Language", 7444)
|
|
109
109
|
File.add_field(7, "Attributes", 5378)
|
|
110
|
-
File.add_field(8, "Sequence", 1282
|
|
110
|
+
File.add_field(8, "Sequence", 260) # 1282
|
|
111
111
|
|
|
112
112
|
CCPSearch = Table("CCPSearch")
|
|
113
113
|
CCPSearch.add_field(1, "Signature_", 11592)
|
|
@@ -337,7 +337,7 @@ LockPermissions.add_field(5, "Permission", 4356)
|
|
|
337
337
|
|
|
338
338
|
Media = Table("Media")
|
|
339
339
|
Media.add_field(1, "DiskId", 9474)
|
|
340
|
-
Media.add_field(2, "LastSequence", 1282
|
|
340
|
+
Media.add_field(2, "LastSequence", 260) # 1282
|
|
341
341
|
Media.add_field(3, "DiskPrompt", 8000)
|
|
342
342
|
Media.add_field(4, "Cabinet", 7679)
|
|
343
343
|
Media.add_field(5, "VolumeLabel", 7456)
|
|
@@ -419,7 +419,7 @@ ODBCTranslator.add_field(5, "File_Setup", 7496)
|
|
|
419
419
|
|
|
420
420
|
Patch = Table("Patch")
|
|
421
421
|
Patch.add_field(1, "File_", 11592)
|
|
422
|
-
Patch.add_field(2, "Sequence", 9474
|
|
422
|
+
Patch.add_field(2, "Sequence", 8452) # 9474
|
|
423
423
|
Patch.add_field(3, "PatchSize", 260)
|
|
424
424
|
Patch.add_field(4, "Attributes", 1282)
|
|
425
425
|
Patch.add_field(5, "Header", 6400)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-msilib
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6.0
|
|
4
4
|
Summary: Read and write Microsoft Installer files
|
|
5
5
|
Author-email: Marcelo Duarte <marcelotduarte@users.noreply.github.com>, " Martin v. Löwis" <loewis@users.noreply.github.com>
|
|
6
6
|
License-Expression: PSF-2.0
|
|
@@ -26,13 +26,6 @@ Classifier: Topic :: Utilities
|
|
|
26
26
|
Requires-Python: >=3.13
|
|
27
27
|
Description-Content-Type: text/markdown
|
|
28
28
|
License-File: LICENSE
|
|
29
|
-
Provides-Extra: dev
|
|
30
|
-
Requires-Dist: bump-my-version==1.2.4; extra == "dev"
|
|
31
|
-
Requires-Dist: cibuildwheel==3.3.0; extra == "dev"
|
|
32
|
-
Requires-Dist: pre-commit==4.4.0; extra == "dev"
|
|
33
|
-
Provides-Extra: tests
|
|
34
|
-
Requires-Dist: coverage==7.12.0; extra == "tests"
|
|
35
|
-
Requires-Dist: pytest==9.0.1; extra == "tests"
|
|
36
29
|
Dynamic: license-file
|
|
37
30
|
|
|
38
31
|
# python-msilib
|
|
@@ -40,7 +33,7 @@ Dynamic: license-file
|
|
|
40
33
|
Read and write Microsoft Installer files.
|
|
41
34
|
|
|
42
35
|
This library is legacy code borrowed from Python 3.12, intended to allow
|
|
43
|
-
cx_Freeze's `bdist_msi` command to continue working in Python 3.13
|
|
36
|
+
cx_Freeze's `bdist_msi` command to continue working in Python 3.13+.
|
|
44
37
|
|
|
45
38
|
[](https://pypi.org/project/python-msilib/)
|
|
46
39
|
[](https://pypistats.org/packages/python-msilib)
|
|
@@ -49,6 +42,7 @@ cx_Freeze's `bdist_msi` command to continue working in Python 3.13 and 3.14.
|
|
|
49
42
|
[](https://www.python.org/)
|
|
50
43
|
[](https://htmlpreview.github.io/?https://github.com/marcelotduarte/python-msilib/blob/python-coverage-comment-action-data/htmlcov/index.html)
|
|
51
44
|
[](https://github.com/astral-sh/ruff)
|
|
45
|
+
[](https://github.com/j178/prek)
|
|
52
46
|
|
|
53
47
|
## Installation
|
|
54
48
|
|
|
@@ -17,6 +17,5 @@ src/python_msilib.egg-info/PKG-INFO
|
|
|
17
17
|
src/python_msilib.egg-info/SOURCES.txt
|
|
18
18
|
src/python_msilib.egg-info/dependency_links.txt
|
|
19
19
|
src/python_msilib.egg-info/not-zip-safe
|
|
20
|
-
src/python_msilib.egg-info/requires.txt
|
|
21
20
|
src/python_msilib.egg-info/top_level.txt
|
|
22
21
|
tests/test_msilib.py
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
"""Test suite for the code in msilib."""
|
|
2
2
|
|
|
3
|
+
import os
|
|
4
|
+
|
|
3
5
|
import pytest
|
|
4
6
|
|
|
5
7
|
msilib = pytest.importorskip("msilib", reason="Windows tests")
|
|
6
8
|
schema = pytest.importorskip("msilib.schema", reason="Windows tests")
|
|
9
|
+
sequence = pytest.importorskip("msilib.sequence", reason="Windows tests")
|
|
7
10
|
|
|
8
11
|
|
|
9
12
|
@pytest.fixture
|
|
@@ -94,6 +97,47 @@ def test_directory_start_component_keyfile(db, tmp_path) -> None:
|
|
|
94
97
|
msilib._directories.clear() # noqa: SLF001
|
|
95
98
|
|
|
96
99
|
|
|
100
|
+
def test_large_package(db, tmp_path) -> None:
|
|
101
|
+
root_dir = tmp_path / "root"
|
|
102
|
+
root_dir.mkdir()
|
|
103
|
+
data_dir = root_dir / "data"
|
|
104
|
+
data_dir.mkdir()
|
|
105
|
+
for i in range(33000):
|
|
106
|
+
file = data_dir / f"{i:05}.dat"
|
|
107
|
+
file.write_text(f"data {i}")
|
|
108
|
+
msilib.add_tables(db, sequence)
|
|
109
|
+
try:
|
|
110
|
+
cab = msilib.CAB("distfiles")
|
|
111
|
+
feature = msilib.Feature(
|
|
112
|
+
db,
|
|
113
|
+
"default",
|
|
114
|
+
"Default Feature",
|
|
115
|
+
"Everything",
|
|
116
|
+
1,
|
|
117
|
+
directory="TARGETDIR",
|
|
118
|
+
)
|
|
119
|
+
feature.set_current()
|
|
120
|
+
root = msilib.Directory(
|
|
121
|
+
db, cab, None, root_dir, "TARGETDIR", "SourceDir"
|
|
122
|
+
)
|
|
123
|
+
db.Commit()
|
|
124
|
+
todo = [root]
|
|
125
|
+
while todo:
|
|
126
|
+
directory = todo.pop()
|
|
127
|
+
for file in os.listdir(directory.absolute):
|
|
128
|
+
if os.path.isdir(os.path.join(directory.absolute, file)):
|
|
129
|
+
sfile = directory.make_short(file)
|
|
130
|
+
new_dir = msilib.Directory(
|
|
131
|
+
db, cab, directory, file, file, f"{sfile}|{file}"
|
|
132
|
+
)
|
|
133
|
+
todo.append(new_dir)
|
|
134
|
+
else:
|
|
135
|
+
directory.add_file(file)
|
|
136
|
+
cab.commit(db)
|
|
137
|
+
finally:
|
|
138
|
+
msilib._directories.clear() # noqa: SLF001
|
|
139
|
+
|
|
140
|
+
|
|
97
141
|
def test_getproperty_uninitialized_var(db) -> None:
|
|
98
142
|
si = db.GetSummaryInformation(0)
|
|
99
143
|
with pytest.raises(msilib.MSIError):
|
python_msilib-0.4.3/Makefile
DELETED
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
# Makefile to automate some tools
|
|
2
|
-
SHELL=/bin/bash
|
|
3
|
-
PATH := $(shell python -c "import sysconfig; print(sysconfig.get_path('scripts'))"):$(PATH)
|
|
4
|
-
|
|
5
|
-
PY_PLATFORM := $(shell python -c "import sysconfig; print(sysconfig.get_platform())")
|
|
6
|
-
PRE_COMMIT_OPTIONS := --show-diff-on-failure --color=always --all-files --hook-stage=manual
|
|
7
|
-
|
|
8
|
-
COV_TMPDIR := $(shell mktemp -d)
|
|
9
|
-
|
|
10
|
-
.PHONY: all
|
|
11
|
-
all: install
|
|
12
|
-
|
|
13
|
-
.PHONY: pre-commit
|
|
14
|
-
pre-commit: install
|
|
15
|
-
@(pre-commit run $(PRE_COMMIT_OPTIONS) || true) | more
|
|
16
|
-
@pre-commit gc
|
|
17
|
-
|
|
18
|
-
.PHONY: clean
|
|
19
|
-
clean:
|
|
20
|
-
@rm -f .coverage* || true
|
|
21
|
-
@rm -rf build dist wheelhouse
|
|
22
|
-
|
|
23
|
-
.PHONY: install
|
|
24
|
-
install:
|
|
25
|
-
./ci/install-tools.sh --dev
|
|
26
|
-
if ! [ -f .git/hooks/pre-commit ]; then\
|
|
27
|
-
pre-commit install --install-hooks --overwrite -t pre-commit;\
|
|
28
|
-
fi
|
|
29
|
-
|
|
30
|
-
.PHONY: uninstall
|
|
31
|
-
uninstall:
|
|
32
|
-
@if [ -f .git/hooks/pre-commit ]; then\
|
|
33
|
-
pre-commit clean;\
|
|
34
|
-
pre-commit uninstall;\
|
|
35
|
-
rm -f .git/hooks/pre-commit;\
|
|
36
|
-
fi
|
|
37
|
-
|
|
38
|
-
.PHONY: upgrade
|
|
39
|
-
upgrade: uninstall clean install
|
|
40
|
-
pre-commit autoupdate
|
|
41
|
-
$(MAKE) pre-commit
|
|
42
|
-
|
|
43
|
-
.PHONY: wheel
|
|
44
|
-
wheel:
|
|
45
|
-
./ci/build-wheel.sh
|
|
46
|
-
|
|
47
|
-
.PHONY: tests
|
|
48
|
-
tests: wheel
|
|
49
|
-
./ci/install-tools.sh --tests
|
|
50
|
-
cp pyproject.toml $(COV_TMPDIR)/
|
|
51
|
-
cp -a tests/ $(COV_TMPDIR)/
|
|
52
|
-
cd $(COV_TMPDIR) && pytest -nauto -v || true
|
|
53
|
-
|
|
54
|
-
.PHONY: cov
|
|
55
|
-
cov: wheel
|
|
56
|
-
./ci/install-tools.sh --tests
|
|
57
|
-
@rm -rf build/coverage_html_report
|
|
58
|
-
cp pyproject.toml $(COV_TMPDIR)/
|
|
59
|
-
cp -a tests/ $(COV_TMPDIR)/
|
|
60
|
-
cd $(COV_TMPDIR) && coverage run || true
|
|
61
|
-
coverage combine --keep --quiet -a $(COV_TMPDIR)/
|
|
62
|
-
coverage report
|
|
63
|
-
coverage html --show-contexts
|
|
64
|
-
|
|
65
|
-
.PHONY: release
|
|
66
|
-
release:
|
|
67
|
-
bump-my-version show-bump 2>/dev/null
|
|
68
|
-
@echo "Run:"
|
|
69
|
-
@echo " bump-my-version bump <option>"
|
|
70
|
-
@echo "--or--"
|
|
71
|
-
@echo " bump-my-version bump patch --new-version=X.XX.X"
|
|
72
|
-
@echo "--then--"
|
|
73
|
-
@echo " git push origin `git branch --show-current`"
|
|
74
|
-
@echo " git push origin `git branch --show-current` --tags"
|
|
75
|
-
|
|
76
|
-
.PHONY: release-dev
|
|
77
|
-
release-dev:
|
|
78
|
-
if (grep "current_version" pyproject.toml | grep -q "\-dev"); then\
|
|
79
|
-
bump-my-version bump --allow-dirty --no-tag build;\
|
|
80
|
-
else\
|
|
81
|
-
bump-my-version bump --allow-dirty --no-tag minor;\
|
|
82
|
-
fi
|
|
83
|
-
git log -1
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|