winmd2py 0.1.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.
- winmd2py-0.1.0/LICENSE +21 -0
- winmd2py-0.1.0/PKG-INFO +67 -0
- winmd2py-0.1.0/README.md +38 -0
- winmd2py-0.1.0/pyproject.toml +43 -0
- winmd2py-0.1.0/setup.cfg +4 -0
- winmd2py-0.1.0/src/winmd2py/__init__.py +11 -0
- winmd2py-0.1.0/src/winmd2py/__main__.py +3 -0
- winmd2py-0.1.0/src/winmd2py/cli.py +58 -0
- winmd2py-0.1.0/src/winmd2py/emit.py +791 -0
- winmd2py-0.1.0/src/winmd2py/metadata.py +476 -0
- winmd2py-0.1.0/src/winmd2py/model.py +665 -0
- winmd2py-0.1.0/src/winmd2py.egg-info/PKG-INFO +67 -0
- winmd2py-0.1.0/src/winmd2py.egg-info/SOURCES.txt +15 -0
- winmd2py-0.1.0/src/winmd2py.egg-info/dependency_links.txt +1 -0
- winmd2py-0.1.0/src/winmd2py.egg-info/entry_points.txt +2 -0
- winmd2py-0.1.0/src/winmd2py.egg-info/requires.txt +3 -0
- winmd2py-0.1.0/src/winmd2py.egg-info/top_level.txt +1 -0
winmd2py-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Mahmoud Komaiha
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, 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,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
winmd2py-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: winmd2py
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Generate ctypes bindings for classic COM interfaces from .winmd metadata, in pure Python
|
|
5
|
+
Author-email: Mahmoud Komaiha <mkomaiha@umich.edu>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/mkomaiha/portacom
|
|
8
|
+
Project-URL: Repository, https://github.com/mkomaiha/portacom
|
|
9
|
+
Project-URL: Issues, https://github.com/mkomaiha/portacom/issues
|
|
10
|
+
Project-URL: Changelog, https://github.com/mkomaiha/portacom/blob/main/CHANGELOG.md
|
|
11
|
+
Keywords: com,ctypes,winmd,win32metadata,bindings,code generator
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
20
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
21
|
+
Classifier: Operating System :: MacOS
|
|
22
|
+
Classifier: Topic :: Software Development :: Code Generators
|
|
23
|
+
Requires-Python: >=3.10
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
License-File: LICENSE
|
|
26
|
+
Provides-Extra: runtime
|
|
27
|
+
Requires-Dist: portacom<0.2,>=0.1; extra == "runtime"
|
|
28
|
+
Dynamic: license-file
|
|
29
|
+
|
|
30
|
+
# winmd2py
|
|
31
|
+
|
|
32
|
+
Generates [portacom](https://pypi.org/project/portacom/) ctypes bindings from
|
|
33
|
+
a `.winmd` file in the Win32 metadata format, in pure Python (no .NET).
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
pip install "winmd2py[runtime]" # the generator, and portacom, which the bindings import
|
|
37
|
+
winmd2py Windows.Win32.winmd -n Windows.Win32.Graphics.Direct3D.Dxc -o bindings
|
|
38
|
+
winmd2py Microsoft.Direct3D.D3D12.winmd --ref Windows.Win32.winmd -o d3d12
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
or from Python:
|
|
42
|
+
|
|
43
|
+
```python
|
|
44
|
+
import winmd2py
|
|
45
|
+
|
|
46
|
+
winmd2py.generate("Microsoft.Direct3D.D3D12.winmd", "d3d12", refs=["Windows.Win32.winmd"])
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
- `--ref OTHER.winmd` (repeatable) is a file whose types the input uses. Since
|
|
50
|
+
Win32Metadata 71, D3D12 is in `Microsoft.Direct3D.D3D12.winmd` and uses
|
|
51
|
+
`Windows.Win32.winmd`'s types. What is used from a reference file is
|
|
52
|
+
generated too, into partial modules, so the output needs nothing else.
|
|
53
|
+
- Without the file that declares a type, a struct that holds it by value, or an
|
|
54
|
+
interface derived from it, still imports but raises `TypeError` when used,
|
|
55
|
+
and the generator says which file to pass with `--ref`.
|
|
56
|
+
- Types and functions that the metadata declares once per architecture (x86,
|
|
57
|
+
x64, ARM64) are declared once; what differs is chosen on import by
|
|
58
|
+
`portacom.ARCH`.
|
|
59
|
+
- Delegates become classes with their signatures, so callbacks take Python
|
|
60
|
+
callables; one whose signature can't be described is passed as `void*`, and
|
|
61
|
+
reported.
|
|
62
|
+
|
|
63
|
+
The bindings follow the Windows ABI that the metadata describes. For a library
|
|
64
|
+
built differently off Windows, declare how with `portacom.use_abi()` before
|
|
65
|
+
importing them. See the
|
|
66
|
+
[project README](https://github.com/mkomaiha/portacom#readme), which also says
|
|
67
|
+
what a `.winmd` for your own IDL needs.
|
winmd2py-0.1.0/README.md
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# winmd2py
|
|
2
|
+
|
|
3
|
+
Generates [portacom](https://pypi.org/project/portacom/) ctypes bindings from
|
|
4
|
+
a `.winmd` file in the Win32 metadata format, in pure Python (no .NET).
|
|
5
|
+
|
|
6
|
+
```bash
|
|
7
|
+
pip install "winmd2py[runtime]" # the generator, and portacom, which the bindings import
|
|
8
|
+
winmd2py Windows.Win32.winmd -n Windows.Win32.Graphics.Direct3D.Dxc -o bindings
|
|
9
|
+
winmd2py Microsoft.Direct3D.D3D12.winmd --ref Windows.Win32.winmd -o d3d12
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
or from Python:
|
|
13
|
+
|
|
14
|
+
```python
|
|
15
|
+
import winmd2py
|
|
16
|
+
|
|
17
|
+
winmd2py.generate("Microsoft.Direct3D.D3D12.winmd", "d3d12", refs=["Windows.Win32.winmd"])
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
- `--ref OTHER.winmd` (repeatable) is a file whose types the input uses. Since
|
|
21
|
+
Win32Metadata 71, D3D12 is in `Microsoft.Direct3D.D3D12.winmd` and uses
|
|
22
|
+
`Windows.Win32.winmd`'s types. What is used from a reference file is
|
|
23
|
+
generated too, into partial modules, so the output needs nothing else.
|
|
24
|
+
- Without the file that declares a type, a struct that holds it by value, or an
|
|
25
|
+
interface derived from it, still imports but raises `TypeError` when used,
|
|
26
|
+
and the generator says which file to pass with `--ref`.
|
|
27
|
+
- Types and functions that the metadata declares once per architecture (x86,
|
|
28
|
+
x64, ARM64) are declared once; what differs is chosen on import by
|
|
29
|
+
`portacom.ARCH`.
|
|
30
|
+
- Delegates become classes with their signatures, so callbacks take Python
|
|
31
|
+
callables; one whose signature can't be described is passed as `void*`, and
|
|
32
|
+
reported.
|
|
33
|
+
|
|
34
|
+
The bindings follow the Windows ABI that the metadata describes. For a library
|
|
35
|
+
built differently off Windows, declare how with `portacom.use_abi()` before
|
|
36
|
+
importing them. See the
|
|
37
|
+
[project README](https://github.com/mkomaiha/portacom#readme), which also says
|
|
38
|
+
what a `.winmd` for your own IDL needs.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=77"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "winmd2py"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Generate ctypes bindings for classic COM interfaces from .winmd metadata, in pure Python"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
license-files = ["LICENSE"]
|
|
12
|
+
authors = [{ name = "Mahmoud Komaiha", email = "mkomaiha@umich.edu" }]
|
|
13
|
+
requires-python = ">=3.10"
|
|
14
|
+
dependencies = []
|
|
15
|
+
keywords = ["com", "ctypes", "winmd", "win32metadata", "bindings", "code generator"]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 3 - Alpha",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"Programming Language :: Python :: 3",
|
|
20
|
+
"Programming Language :: Python :: 3.10",
|
|
21
|
+
"Programming Language :: Python :: 3.11",
|
|
22
|
+
"Programming Language :: Python :: 3.12",
|
|
23
|
+
"Programming Language :: Python :: 3.13",
|
|
24
|
+
"Operating System :: Microsoft :: Windows",
|
|
25
|
+
"Operating System :: POSIX :: Linux",
|
|
26
|
+
"Operating System :: MacOS",
|
|
27
|
+
"Topic :: Software Development :: Code Generators",
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
[project.optional-dependencies]
|
|
31
|
+
runtime = ["portacom>=0.1,<0.2"]
|
|
32
|
+
|
|
33
|
+
[project.urls]
|
|
34
|
+
Homepage = "https://github.com/mkomaiha/portacom"
|
|
35
|
+
Repository = "https://github.com/mkomaiha/portacom"
|
|
36
|
+
Issues = "https://github.com/mkomaiha/portacom/issues"
|
|
37
|
+
Changelog = "https://github.com/mkomaiha/portacom/blob/main/CHANGELOG.md"
|
|
38
|
+
|
|
39
|
+
[project.scripts]
|
|
40
|
+
winmd2py = "winmd2py.cli:main"
|
|
41
|
+
|
|
42
|
+
[tool.setuptools.packages.find]
|
|
43
|
+
where = ["src"]
|
winmd2py-0.1.0/setup.cfg
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"""winmd2py: generate portacom ctypes bindings from a .winmd file, in pure Python.
|
|
2
|
+
|
|
3
|
+
winmd2py.generate("Windows.Win32.winmd", "bindings", ["Windows.Win32.Graphics.Direct3D.Dxc"])
|
|
4
|
+
writes the bindings of that namespace, and of what it uses, as the package "bindings".
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
__version__ = "0.1.0"
|
|
8
|
+
|
|
9
|
+
from .emit import Generator, generate # noqa: E402 (emit reads __version__)
|
|
10
|
+
|
|
11
|
+
__all__ = ["generate", "Generator", "__version__"]
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"""winmd2py FILE.winmd [-n NAMESPACE ...] [--ref OTHER.winmd ...] -o OUTDIR"""
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
import sys
|
|
5
|
+
import time
|
|
6
|
+
|
|
7
|
+
from . import __version__
|
|
8
|
+
from .emit import Generator
|
|
9
|
+
from .model import WinMD
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def main(argv=None):
|
|
13
|
+
parser = argparse.ArgumentParser(
|
|
14
|
+
prog="winmd2py",
|
|
15
|
+
description="Generate portacom ctypes bindings for classic COM interfaces from a .winmd file. "
|
|
16
|
+
"The bindings follow the Windows ABI the metadata describes; for a library built differently, "
|
|
17
|
+
"call portacom.use_abi() before importing them.",
|
|
18
|
+
)
|
|
19
|
+
parser.add_argument("winmd", help="the .winmd file (Win32 metadata format)")
|
|
20
|
+
parser.add_argument(
|
|
21
|
+
"-n",
|
|
22
|
+
"--namespace",
|
|
23
|
+
action="append",
|
|
24
|
+
dest="namespaces",
|
|
25
|
+
help="namespace to generate (repeatable; default: all namespaces in the file)",
|
|
26
|
+
)
|
|
27
|
+
parser.add_argument(
|
|
28
|
+
"--ref",
|
|
29
|
+
action="append",
|
|
30
|
+
default=[],
|
|
31
|
+
metavar="OTHER.winmd",
|
|
32
|
+
help="a .winmd whose types the file uses, such as Windows.Win32.winmd for "
|
|
33
|
+
"Microsoft.Direct3D.D3D12.winmd (repeatable); what is used from it is generated too",
|
|
34
|
+
)
|
|
35
|
+
parser.add_argument("-o", "--outdir", help="output package directory")
|
|
36
|
+
parser.add_argument("--list", action="store_true", help="list the namespaces in the file and exit")
|
|
37
|
+
parser.add_argument("-q", "--quiet", action="store_true", help="do not print what was left out or simplified")
|
|
38
|
+
parser.add_argument("--version", action="version", version=f"winmd2py {__version__}")
|
|
39
|
+
args = parser.parse_args(argv)
|
|
40
|
+
if not args.list and not args.outdir:
|
|
41
|
+
parser.error("-o/--outdir is required")
|
|
42
|
+
|
|
43
|
+
start = time.time()
|
|
44
|
+
try:
|
|
45
|
+
if args.list:
|
|
46
|
+
for ns in WinMD(args.winmd).namespaces():
|
|
47
|
+
print(ns)
|
|
48
|
+
return 0
|
|
49
|
+
generator = Generator(args.winmd, args.namespaces, refs=args.ref)
|
|
50
|
+
written = generator.generate(args.outdir)
|
|
51
|
+
except (OSError, ValueError) as error:
|
|
52
|
+
print(f"winmd2py: error: {error}", file=sys.stderr)
|
|
53
|
+
return 1
|
|
54
|
+
if not args.quiet:
|
|
55
|
+
for note in generator.notes:
|
|
56
|
+
print(f"winmd2py: {note}", file=sys.stderr)
|
|
57
|
+
print(f"winmd2py: wrote {len(written)} modules to {args.outdir} in {time.time() - start:.1f}s")
|
|
58
|
+
return 0
|