protobuf-protoc-bin 0.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.
@@ -0,0 +1,84 @@
1
+ name: Build wheels
2
+
3
+ on: push
4
+
5
+ jobs:
6
+ build_wheels:
7
+ name: Build wheels on ${{ matrix.os }}
8
+ runs-on: ${{ matrix.os }}
9
+ strategy:
10
+ matrix:
11
+ os: [ubuntu-latest, windows-latest, macos-latest]
12
+
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+
16
+ - uses: actions/setup-python@v5
17
+ with:
18
+ python-version: '3.12'
19
+
20
+ - run: |
21
+ python -m pip install -U pip
22
+ pip install build
23
+
24
+ - run: python -m build --wheel -v
25
+ - if: matrix.os == 'ubuntu-latest'
26
+ run: python -m build --sdist -v
27
+
28
+ - uses: actions/upload-artifact@v4
29
+ with:
30
+ name: dist-${{ matrix.os }}
31
+ retention-days: 1
32
+ path: dist
33
+
34
+ combine_artifacts:
35
+ name: Combine artifacts
36
+ needs: build_wheels
37
+ runs-on: ubuntu-latest
38
+ steps:
39
+ - uses: actions/download-artifact@v4
40
+ with: # Download all artifacts so far
41
+ path: dist
42
+ merge-multiple: true
43
+ - uses: actions/upload-artifact@v4
44
+ with:
45
+ name: package
46
+ path: dist
47
+
48
+ test_artifacts:
49
+ name: Test distributions
50
+ needs: combine_artifacts
51
+ runs-on: ${{ matrix.os }}
52
+ strategy:
53
+ matrix:
54
+ os: [ubuntu-latest, ubuntu-20.04, macos-latest, macos-13, macos-12, windows-latest]
55
+ steps:
56
+ - uses: actions/checkout @v4
57
+ - uses: actions/download-artifact@v4
58
+ with:
59
+ name: package
60
+ path: dist
61
+ - uses: actions/setup-python@v5
62
+ with:
63
+ python-version: "3.12"
64
+ # Now install the package from the local wheels and try to use it:
65
+ - run: |
66
+ pip install --no-index --find-links ./dist protobuf_protoc_bin
67
+ protoc --version
68
+ python -m unittest discover tests/
69
+
70
+ # Publish to PyPi if tests succeeded and this job is for a pushed tag that starts with 'v'
71
+ publish:
72
+ name: Publish distributions
73
+ needs: test_artifacts
74
+ runs-on: ubuntu-latest
75
+ if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags/v')
76
+ steps:
77
+ - uses: actions/download-artifact@v4
78
+ with:
79
+ name: package
80
+ path: dist
81
+ - uses: pypa/gh-action-pypi-publish@release/v1
82
+ with:
83
+ repository-url: https://test.pypi.org/legacy/
84
+ password: ${{ secrets.TEST_PYPI_API_TOKEN }}
@@ -0,0 +1,166 @@
1
+ # Custom
2
+ **/_version.py
3
+ *_pb2.*
4
+
5
+ # Byte-compiled / optimized / DLL files
6
+ __pycache__/
7
+ *.py[cod]
8
+ *$py.class
9
+
10
+ # Downloads
11
+ resources/
12
+
13
+ # C extensions
14
+ *.so
15
+
16
+ # Distribution / packaging
17
+ .Python
18
+ build/
19
+ develop-eggs/
20
+ dist/
21
+ downloads/
22
+ eggs/
23
+ .eggs/
24
+ lib/
25
+ lib64/
26
+ parts/
27
+ sdist/
28
+ var/
29
+ wheels/
30
+ share/python-wheels/
31
+ *.egg-info/
32
+ .installed.cfg
33
+ *.egg
34
+ MANIFEST
35
+
36
+ # PyInstaller
37
+ # Usually these files are written by a python script from a template
38
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
39
+ *.manifest
40
+ *.spec
41
+
42
+ # Installer logs
43
+ pip-log.txt
44
+ pip-delete-this-directory.txt
45
+
46
+ # Unit test / coverage reports
47
+ htmlcov/
48
+ .tox/
49
+ .nox/
50
+ .coverage
51
+ .coverage.*
52
+ .cache
53
+ nosetests.xml
54
+ coverage.xml
55
+ *.cover
56
+ *.py,cover
57
+ .hypothesis/
58
+ .pytest_cache/
59
+ cover/
60
+
61
+ # Translations
62
+ *.mo
63
+ *.pot
64
+
65
+ # Django stuff:
66
+ *.log
67
+ local_settings.py
68
+ db.sqlite3
69
+ db.sqlite3-journal
70
+
71
+ # Flask stuff:
72
+ instance/
73
+ .webassets-cache
74
+
75
+ # Scrapy stuff:
76
+ .scrapy
77
+
78
+ # Sphinx documentation
79
+ docs/_build/
80
+
81
+ # PyBuilder
82
+ .pybuilder/
83
+ target/
84
+
85
+ # Jupyter Notebook
86
+ .ipynb_checkpoints
87
+
88
+ # IPython
89
+ profile_default/
90
+ ipython_config.py
91
+
92
+ # pyenv
93
+ # For a library or package, you might want to ignore these files since the code is
94
+ # intended to run in multiple environments; otherwise, check them in:
95
+ # .python-version
96
+
97
+ # pipenv
98
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
99
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
100
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
101
+ # install all needed dependencies.
102
+ #Pipfile.lock
103
+
104
+ # poetry
105
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
106
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
107
+ # commonly ignored for libraries.
108
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
109
+ #poetry.lock
110
+
111
+ # pdm
112
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
113
+ #pdm.lock
114
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
115
+ # in version control.
116
+ # https://pdm.fming.dev/latest/usage/project/#working-with-version-control
117
+ .pdm.toml
118
+ .pdm-python
119
+ .pdm-build/
120
+
121
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
122
+ __pypackages__/
123
+
124
+ # Celery stuff
125
+ celerybeat-schedule
126
+ celerybeat.pid
127
+
128
+ # SageMath parsed files
129
+ *.sage.py
130
+
131
+ # Environments
132
+ .env
133
+ .venv
134
+ .venv*
135
+ env/
136
+ venv/
137
+ ENV/
138
+ env.bak/
139
+ venv.bak/
140
+
141
+ # Spyder project settings
142
+ .spyderproject
143
+ .spyproject
144
+
145
+ # Rope project settings
146
+ .ropeproject
147
+
148
+ # mkdocs documentation
149
+ /site
150
+
151
+ # mypy
152
+ .mypy_cache/
153
+ .dmypy.json
154
+ dmypy.json
155
+
156
+ # Pyre type checker
157
+ .pyre/
158
+
159
+ # pytype static type analyzer
160
+ .pytype/
161
+
162
+ # Cython debug symbols
163
+ cython_debug/
164
+
165
+ # PyCharm
166
+ .idea/
@@ -0,0 +1,49 @@
1
+ Metadata-Version: 2.1
2
+ Name: protobuf-protoc-bin
3
+ Version: 0.0
4
+ Summary: Pip package to host the protobuf protoc binary
5
+ Author-email: Robert Roos <robert.roos@demcon.com>
6
+ Requires-Python: >=2.7
7
+ Description-Content-Type: text/markdown
8
+
9
+ # Protobuf Protoc Bin
10
+
11
+ This Python package is an installer for [protobuf](https://protobuf.dev/)'s `protoc` compiler.
12
+
13
+ Use this package to install a specific version of `protoc` in your project, without having to figure out the installation externally.
14
+
15
+ This package is not maintained by or affiliated with the official protobuf group!
16
+
17
+ This repository does not host any binaries on itself.
18
+ Instead, the binaries are downloaded from the official protobuf Github during package built or during source installation.
19
+
20
+ ## How to install
21
+
22
+ The package is hosted on PyPi at https://pypi.org/project/protobuf-protoc-bin (WIP).
23
+ It can be installed via PIP as normal with:
24
+ ```shell
25
+ pip install protobuf-protoc-bin
26
+ ```
27
+
28
+ The wheels hosted on PyPi do contain a copy of the protoc releases.
29
+ You can also install this package directly from the Github source.
30
+ During an installation from source, `protoc` will be downloaded fresh from the official Protobuf releases:
31
+ ```
32
+ pip install "git+https://github.com/RobertoRoos/protobuf-protoc-bin.git@<tag>"
33
+ ```
34
+ (Replacing `<tag>` with a version like `v27.3`.)
35
+
36
+ ## How to require
37
+
38
+ To require `protoc` only during a build script, include it in your `pyproject.toml` with:
39
+ ```
40
+ [build-system]
41
+ requires = [..., "protobuf-protoc-bin==27.3"]
42
+ # ...
43
+ ```
44
+
45
+ Or make it part of an additional install group in your regular environment (with the Poetry backend):
46
+ ```
47
+ [tool.poetry.group.dev.dependencies]
48
+ protobuf-protoc-bin = "27.3"
49
+ ```
@@ -0,0 +1,41 @@
1
+ # Protobuf Protoc Bin
2
+
3
+ This Python package is an installer for [protobuf](https://protobuf.dev/)'s `protoc` compiler.
4
+
5
+ Use this package to install a specific version of `protoc` in your project, without having to figure out the installation externally.
6
+
7
+ This package is not maintained by or affiliated with the official protobuf group!
8
+
9
+ This repository does not host any binaries on itself.
10
+ Instead, the binaries are downloaded from the official protobuf Github during package built or during source installation.
11
+
12
+ ## How to install
13
+
14
+ The package is hosted on PyPi at https://pypi.org/project/protobuf-protoc-bin (WIP).
15
+ It can be installed via PIP as normal with:
16
+ ```shell
17
+ pip install protobuf-protoc-bin
18
+ ```
19
+
20
+ The wheels hosted on PyPi do contain a copy of the protoc releases.
21
+ You can also install this package directly from the Github source.
22
+ During an installation from source, `protoc` will be downloaded fresh from the official Protobuf releases:
23
+ ```
24
+ pip install "git+https://github.com/RobertoRoos/protobuf-protoc-bin.git@<tag>"
25
+ ```
26
+ (Replacing `<tag>` with a version like `v27.3`.)
27
+
28
+ ## How to require
29
+
30
+ To require `protoc` only during a build script, include it in your `pyproject.toml` with:
31
+ ```
32
+ [build-system]
33
+ requires = [..., "protobuf-protoc-bin==27.3"]
34
+ # ...
35
+ ```
36
+
37
+ Or make it part of an additional install group in your regular environment (with the Poetry backend):
38
+ ```
39
+ [tool.poetry.group.dev.dependencies]
40
+ protobuf-protoc-bin = "27.3"
41
+ ```
@@ -0,0 +1,24 @@
1
+ [build-system]
2
+ requires = ["setuptools", "setuptools-scm", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "protobuf-protoc-bin"
7
+ # Versioning is done dynamically
8
+ description = "Pip package to host the protobuf protoc binary"
9
+ authors = [
10
+ {name = "Robert Roos", email = "robert.roos@demcon.com"}
11
+ ]
12
+ readme = "README.md"
13
+ dynamic = ["version"]
14
+ requires-python = ">=2.7"
15
+
16
+ [tool.setuptools]
17
+ package-dir = {"" = "src"}
18
+ packages = ["protobuf_protoc_bin"]
19
+
20
+ [tool.setuptools_scm]
21
+ version_file = "src/protobuf_protoc_bin/_version.py"
22
+ # Use the tag directly, without local changes:
23
+ version_scheme = "only-version"
24
+ local_scheme = "no-local-version"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,162 @@
1
+ import os
2
+ import platform
3
+ import re
4
+ import shutil
5
+ import stat
6
+ import sysconfig
7
+ import urllib.error
8
+ import urllib.request
9
+ from pathlib import Path
10
+ from tempfile import TemporaryDirectory
11
+
12
+ from setuptools import setup
13
+ from setuptools.command.install import install
14
+ from wheel.bdist_wheel import bdist_wheel
15
+
16
+
17
+ class CustomInstallCommand(install):
18
+ """Download `protoc` binary and install with package."""
19
+
20
+ PKG_ROOT = Path(__file__).parent.absolute()
21
+
22
+ def run(self):
23
+ install.run(self) # Avoid `super()` for legacy reasons
24
+
25
+ version = self._get_version()
26
+ plat = self._get_platform()
27
+
28
+ base_url = "https://github.com/protocolbuffers/protobuf/releases"
29
+
30
+ if version == "0.0": # Typical for un-tagged CI build
31
+ print("Finding latest protoc release...")
32
+ new_url: str = urllib.request.urlopen(f"{base_url}/latest").geturl()
33
+ _, _, new_version = new_url.rpartition("/")
34
+ version = new_version.lstrip("v")
35
+
36
+ with TemporaryDirectory() as temp_dir:
37
+ download_dir = Path(temp_dir).absolute()
38
+ zip_file = download_dir / "protoc.zip"
39
+ url = f"{base_url}/download/v{version}/protoc-{version}-{plat}.zip"
40
+ print(f"Downloading {url}...")
41
+ try:
42
+ urllib.request.urlretrieve(url, zip_file)
43
+ except urllib.error.HTTPError as err:
44
+ raise RuntimeError(
45
+ f"Failed to download protoc version `{version}`: " + str(err)
46
+ )
47
+
48
+ shutil.unpack_archive(zip_file, download_dir)
49
+
50
+ # Copy binary:
51
+ bin_filename = "protoc" + (".exe" if "win" in plat.lower() else "")
52
+ protoc_download_path = download_dir / "bin" / bin_filename
53
+ protoc_dest = Path(self.install_scripts).absolute() / bin_filename
54
+ protoc_dest.parent.mkdir(parents=True, exist_ok=True)
55
+ self.copy_file(
56
+ str(protoc_download_path),
57
+ str(protoc_dest),
58
+ )
59
+ # Allow executing of new file:
60
+ os.chmod(
61
+ protoc_dest,
62
+ stat.S_IRUSR
63
+ | stat.S_IWUSR
64
+ | stat.S_IXUSR
65
+ | stat.S_IRGRP
66
+ | stat.S_IXGRP
67
+ | stat.S_IROTH
68
+ | stat.S_IXOTH, # Set to 755 mode
69
+ )
70
+
71
+ # Copy 'include' directory als well
72
+ # But protoc requires its include/ to be in the folder adjacent to the
73
+ # binary, not in a regular system include/ folder
74
+ include_download_path = download_dir / "include"
75
+ # The 'google' directory will be created in here:
76
+ include_dest = protoc_dest.parent / "include"
77
+ include_dest.mkdir(parents=True, exist_ok=True)
78
+ self.copy_tree(str(include_download_path), str(include_dest))
79
+
80
+ def _get_version(self) -> str:
81
+ """Get current package version (or raise exception)."""
82
+ with open(
83
+ self.PKG_ROOT / "src" / "protobuf_protoc_bin" / "_version.py", "r"
84
+ ) as fh:
85
+ re_version = re.compile(r'.*version = [\'"](.*)[\'"]')
86
+ while line := fh.readline():
87
+ if match := re_version.search(line):
88
+ return match.group(1)
89
+
90
+ raise RuntimeError(f"Failed to parse version from pyproject.toml")
91
+
92
+ @staticmethod
93
+ def _get_platform() -> str:
94
+ """Detect necessary platform tag for protoc download.
95
+
96
+ See available tags from https://github.com/protocolbuffers/protobuf/releases/latest
97
+ """
98
+ system = platform.system().lower()
99
+ arch = [x.lower() if isinstance(x, str) else x for x in platform.architecture()]
100
+
101
+ if system == "windows":
102
+ if "64bit" in arch:
103
+ return "win64"
104
+ return "win32"
105
+
106
+ if system == "linux":
107
+ if "64bit" in arch:
108
+ return "linux-x86_64"
109
+ return "linux-x86_32"
110
+ # Other Linux types are still ignored
111
+
112
+ if system == "darwin":
113
+ if "64bit" in arch:
114
+ return "osx-x86_64"
115
+ return "osx-universal_binary"
116
+
117
+ raise RuntimeError(
118
+ f"Could not choose protoc download for system `{system}` ({arch})"
119
+ )
120
+
121
+
122
+ class CustomWheel(bdist_wheel):
123
+ """Custom command to mark our wheel as platform-specific.
124
+
125
+ Without this, all wheels are marked as `None` and are considered platform
126
+ independent, which is not true as we included a specific `protoc` binary.
127
+
128
+ The tag produced here is different from the tag used for `protoc` in
129
+ :meth:`CustomInstallCommand._get_platform`.
130
+ """
131
+
132
+ def get_tag(self):
133
+ """
134
+
135
+ See https://packaging.python.org/en/latest/specifications/platform-compatibility-tags/
136
+ """
137
+ impl_tag = "py2.py3" # Same wheel across Python versions
138
+ abi_tag = "none" # Same wheeel across ABI versions (not a C-extension)
139
+ # But we need to differentiate on the platform for the compiled adslib:
140
+ plat_tag = sysconfig.get_platform().replace("-", "_").replace(".", "_")
141
+
142
+ if plat_tag.startswith("linux_"):
143
+ # But the basic Linux prefix is deprecated, use new scheme instead:
144
+ plat_tag = "manylinux_2_24" + plat_tag[5:]
145
+
146
+ # MacOS platform tags area already okay
147
+
148
+ # We also keep Windows tags in place, instead of using `any`, to prevent an
149
+ # obscure Linux platform to getting a wheel without adslib source
150
+
151
+ return impl_tag, abi_tag, plat_tag
152
+
153
+
154
+ # noinspection PyTypeChecker
155
+ setup(
156
+ cmdclass={
157
+ "install": CustomInstallCommand,
158
+ "bdist_wheel": CustomWheel,
159
+ }
160
+ )
161
+
162
+ # Rely on `pyproject.toml` for all other info instead
@@ -0,0 +1,9 @@
1
+ """
2
+ This is a package placeholder for the `protoc` executable.
3
+
4
+ No actual Python code is included.
5
+ """
6
+
7
+ from ._version import __version__, __version_tuple__
8
+
9
+ # `_version.py` will be generated by "setuptools_scm"
@@ -0,0 +1,16 @@
1
+ # file generated by setuptools_scm
2
+ # don't change, don't track in version control
3
+ TYPE_CHECKING = False
4
+ if TYPE_CHECKING:
5
+ from typing import Tuple, Union
6
+ VERSION_TUPLE = Tuple[Union[int, str], ...]
7
+ else:
8
+ VERSION_TUPLE = object
9
+
10
+ version: str
11
+ __version__: str
12
+ __version_tuple__: VERSION_TUPLE
13
+ version_tuple: VERSION_TUPLE
14
+
15
+ __version__ = version = '0.0'
16
+ __version_tuple__ = version_tuple = (0, 0)
@@ -0,0 +1,49 @@
1
+ Metadata-Version: 2.1
2
+ Name: protobuf-protoc-bin
3
+ Version: 0.0
4
+ Summary: Pip package to host the protobuf protoc binary
5
+ Author-email: Robert Roos <robert.roos@demcon.com>
6
+ Requires-Python: >=2.7
7
+ Description-Content-Type: text/markdown
8
+
9
+ # Protobuf Protoc Bin
10
+
11
+ This Python package is an installer for [protobuf](https://protobuf.dev/)'s `protoc` compiler.
12
+
13
+ Use this package to install a specific version of `protoc` in your project, without having to figure out the installation externally.
14
+
15
+ This package is not maintained by or affiliated with the official protobuf group!
16
+
17
+ This repository does not host any binaries on itself.
18
+ Instead, the binaries are downloaded from the official protobuf Github during package built or during source installation.
19
+
20
+ ## How to install
21
+
22
+ The package is hosted on PyPi at https://pypi.org/project/protobuf-protoc-bin (WIP).
23
+ It can be installed via PIP as normal with:
24
+ ```shell
25
+ pip install protobuf-protoc-bin
26
+ ```
27
+
28
+ The wheels hosted on PyPi do contain a copy of the protoc releases.
29
+ You can also install this package directly from the Github source.
30
+ During an installation from source, `protoc` will be downloaded fresh from the official Protobuf releases:
31
+ ```
32
+ pip install "git+https://github.com/RobertoRoos/protobuf-protoc-bin.git@<tag>"
33
+ ```
34
+ (Replacing `<tag>` with a version like `v27.3`.)
35
+
36
+ ## How to require
37
+
38
+ To require `protoc` only during a build script, include it in your `pyproject.toml` with:
39
+ ```
40
+ [build-system]
41
+ requires = [..., "protobuf-protoc-bin==27.3"]
42
+ # ...
43
+ ```
44
+
45
+ Or make it part of an additional install group in your regular environment (with the Poetry backend):
46
+ ```
47
+ [tool.poetry.group.dev.dependencies]
48
+ protobuf-protoc-bin = "27.3"
49
+ ```
@@ -0,0 +1,13 @@
1
+ .gitignore
2
+ README.md
3
+ pyproject.toml
4
+ setup.py
5
+ .github/workflows/build.yml
6
+ src/protobuf_protoc_bin/__init__.py
7
+ src/protobuf_protoc_bin/_version.py
8
+ src/protobuf_protoc_bin.egg-info/PKG-INFO
9
+ src/protobuf_protoc_bin.egg-info/SOURCES.txt
10
+ src/protobuf_protoc_bin.egg-info/dependency_links.txt
11
+ src/protobuf_protoc_bin.egg-info/top_level.txt
12
+ tests/example.proto
13
+ tests/test_protoc.py
@@ -0,0 +1 @@
1
+ protobuf_protoc_bin
@@ -0,0 +1,10 @@
1
+ syntax = "proto3";
2
+
3
+ import "google/protobuf/timestamp.proto";
4
+
5
+ package example;
6
+
7
+ message MyMessage {
8
+ google.protobuf.Timestamp my_timestamp = 1;
9
+ bool my_bool = 2;
10
+ }
@@ -0,0 +1,40 @@
1
+ import subprocess
2
+ import unittest
3
+ from pathlib import Path
4
+ from tempfile import TemporaryDirectory
5
+
6
+
7
+ class ProtocBasicTests(unittest.TestCase):
8
+
9
+ tests_dir = Path(__file__).parent.absolute()
10
+
11
+ def test_version(self):
12
+ """Test basic calling of `protoc` executable."""
13
+ output = subprocess.run(
14
+ ["protoc", "--version"], check=True, capture_output=True
15
+ )
16
+ self.assertEqual(0, output.returncode)
17
+ self.assertGreater(len(output.stdout), 5)
18
+
19
+ def test_compile(self):
20
+ """Test compilation with `protoc`."""
21
+ proto_file = self.tests_dir / "example.proto"
22
+
23
+ with TemporaryDirectory() as temp:
24
+ temp = Path(temp)
25
+ output = subprocess.run(
26
+ [
27
+ "protoc",
28
+ "--proto_path",
29
+ str(self.tests_dir),
30
+ "--python_out",
31
+ str(temp),
32
+ proto_file,
33
+ ],
34
+ check=True,
35
+ capture_output=True,
36
+ )
37
+ self.assertEqual(0, output.returncode)
38
+ self.assertFalse(output.stderr)
39
+ dest_file = temp / "example_pb2.py"
40
+ self.assertTrue(dest_file.is_file())