Files
OpenShell/tasks/scripts/generate_python_proto.py
T
Polite_realism 36ee06f7b1 fix(rpm): build the Python SDK from older protoc and install every SDK module (#4439)
* fix(python): let proto stub generation skip .pyi for older protoc

Add a --no-pyi option to generate_python_proto.py for toolchains whose protoc predates --pyi_out, such as Fedora's grpcio-tools 1.48, and list python3-googleapis-common-protos and python3-httpx in the spec's Recommends and dist-info Requires-Dist, which the SDK needs to import. Default behavior is unchanged. Contributes to #3510.

Signed-off-by: politerealism <burdcat17@gmail.com>

* fix(rpm): install every SDK module and record the license accounting

The python3-openshell %install copied only __init__.py, sandbox.py and
_proto/, but the package imports .errors, .mutations and .providers and ships a
py.typed marker, so an installed RPM could not import openshell. Install the
missing files and add a %check that fails if any relative import in the
installed package has no matching installed module. Importing the package needs
grpcio, which the build environment lacks, so the check is static.

Set License to the minimal SPDX expression covering every crate linked into the
shipped binaries, keep the pure-Python subpackage at Apache-2.0, and note how
the non-crate content is covered.

Signed-off-by: politerealism <burdcat17@gmail.com>

---------

Signed-off-by: politerealism <burdcat17@gmail.com>
2026-10-14 18:52:32 +00:00

112 lines
3.2 KiB
Python

# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
"""Generate Python protobuf stubs and make their imports package-relative."""
import argparse
import re
import subprocess
import sys
from pathlib import Path
PROTO_FILES = [
"proto/openshell.proto",
"proto/datamodel.proto",
"proto/options.proto",
"proto/sandbox.proto",
]
LINE_REWRITES = {
"python/openshell/_proto/openshell_pb2_grpc.py": [
(
r"^import openshell_pb2 as openshell__pb2$",
"from . import openshell_pb2 as openshell__pb2",
),
(
r"^import sandbox_pb2 as sandbox__pb2$",
"from . import sandbox_pb2 as sandbox__pb2",
),
],
"python/openshell/_proto/openshell_pb2.py": [
(
r"^import datamodel_pb2 as datamodel__pb2$",
"from . import datamodel_pb2 as datamodel__pb2",
),
(
r"^import options_pb2 as options__pb2$",
"from . import options_pb2 as options__pb2",
),
(
r"^import sandbox_pb2 as sandbox__pb2$",
"from . import sandbox_pb2 as sandbox__pb2",
),
],
"python/openshell/_proto/datamodel_pb2.py": [
(
r"^import options_pb2 as options__pb2$",
"from . import options_pb2 as options__pb2",
),
(
r"^import sandbox_pb2 as sandbox__pb2$",
"from . import sandbox_pb2 as sandbox__pb2",
),
],
"python/openshell/_proto/datamodel_pb2_grpc.py": [
(
r"^import datamodel_pb2 as datamodel__pb2$",
"from . import datamodel_pb2 as datamodel__pb2",
),
],
"python/openshell/_proto/sandbox_pb2.py": [
(
r"^import datamodel_pb2 as datamodel__pb2$",
"from . import datamodel_pb2 as datamodel__pb2",
),
],
"python/openshell/_proto/sandbox_pb2_grpc.py": [
(
r"^import sandbox_pb2 as sandbox__pb2$",
"from . import sandbox_pb2 as sandbox__pb2",
),
],
}
def main() -> None:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument(
"--no-pyi",
action="store_true",
help=(
"Skip .pyi type stubs. Needed with protoc older than 3.20 "
"(e.g. Fedora's grpcio-tools 1.48), which has no --pyi_out."
),
)
args = parser.parse_args()
subprocess.run(
[
sys.executable,
"-m",
"grpc_tools.protoc",
"-Iproto",
"--python_out=python/openshell/_proto",
*([] if args.no_pyi else ["--pyi_out=python/openshell/_proto"]),
"--grpc_python_out=python/openshell/_proto",
*PROTO_FILES,
],
check=True,
)
for path, rules in LINE_REWRITES.items():
file_path = Path(path)
text = file_path.read_text()
text = text.replace("from . from . import", "from . import")
for pattern, replacement in rules:
text = re.sub(pattern, replacement, text, flags=re.MULTILINE)
file_path.write_text(text)
if __name__ == "__main__":
main()