-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #16 from zerlok/feature/docstrings
feature/docstrings
- Loading branch information
Showing
62 changed files
with
1,779 additions
and
692 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
[tool.poetry] | ||
name = "pyprotostuben" | ||
version = "0.1.3" | ||
version = "0.2.0" | ||
description = "Generate Python MyPy stub modules from protobuf files." | ||
authors = ["zerlok <[email protected]>"] | ||
readme = "README.md" | ||
|
@@ -28,12 +28,15 @@ pytest-cov = "^6.0.0" | |
ruff = "^0.7.4" | ||
grpc-stubs = "^1.53.0.5" | ||
|
||
|
||
[build-system] | ||
requires = ["poetry-core"] | ||
build-backend = "poetry.core.masonry.api" | ||
|
||
[tool.ruff] | ||
include = ["src/**/*.py", "tests/**/*.py"] | ||
extend-exclude = ["tests/**/expected_gen/**.py"] | ||
force-exclude = true | ||
line-length = 120 | ||
|
||
[tool.ruff.lint] | ||
|
@@ -54,6 +57,12 @@ ignore = [ | |
files = ["src", "tests"] | ||
strict = true | ||
|
||
|
||
[[tool.mypy.overrides]] | ||
module = ["tests.integration.cases.*.expected_gen.*"] | ||
ignore_missing_imports = true | ||
ignore_errors = true | ||
|
||
[tool.pytest.ini_options] | ||
pythonpath = [ | ||
"src", | ||
|
@@ -74,5 +83,6 @@ exclude_lines = [ | |
"pragma: no cover", | ||
"@abc.abstractmethod", | ||
"if __name__ == .__main__.:", | ||
"if t.TYPE_CHECKING:", | ||
] | ||
show_missing = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
from dataclasses import dataclass | ||
from pathlib import Path | ||
|
||
from pyprotostuben.protobuf.file import ProtoFile | ||
|
||
|
||
@dataclass(frozen=True) | ||
class GeneratedItem: | ||
source: ProtoFile | ||
path: Path | ||
content: str |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,51 +1,47 @@ | ||
import abc | ||
import ast | ||
import typing as t | ||
from dataclasses import dataclass | ||
from pathlib import Path | ||
|
||
from pyprotostuben.codegen.abc import ProtoFileGenerator | ||
from pyprotostuben.codegen.model import GeneratedItem | ||
from pyprotostuben.logging import Logger, LoggerMixin | ||
from pyprotostuben.protobuf.file import ProtoFile | ||
from pyprotostuben.protobuf.visitor.abc import visit | ||
from pyprotostuben.protobuf.visitor.decorator import ProtoVisitorDecorator | ||
from pyprotostuben.protobuf.visitor.dfs import DFSWalkingProtoVisitor | ||
from pyprotostuben.protobuf.visitor.walker import Walker | ||
|
||
|
||
class ModuleASTProtoVisitorDecoratorFactory(metaclass=abc.ABCMeta): | ||
@abc.abstractmethod | ||
def create_proto_visitor_decorator(self, modules: t.MutableMapping[Path, ast.Module]) -> ProtoVisitorDecorator: | ||
raise NotImplementedError | ||
@dataclass(frozen=True) | ||
class ModuleASTContext: | ||
file: ProtoFile | ||
modules: t.Mapping[Path, ast.Module] | ||
|
||
|
||
class ModuleASTBasedProtoFileGenerator(ProtoFileGenerator, LoggerMixin): | ||
def __init__(self, factory: ModuleASTProtoVisitorDecoratorFactory) -> None: | ||
self.__factory = factory | ||
T = t.TypeVar("T", bound=ModuleASTContext) | ||
|
||
def run(self, file: ProtoFile) -> t.Sequence[t.Tuple[ProtoFile, Path, str]]: | ||
log = self._log.bind_details(file_name=file.name) | ||
log.debug("file received") | ||
|
||
modules: t.Dict[Path, ast.Module] = {} | ||
class ModuleASTBasedProtoFileGenerator(t.Generic[T], ProtoFileGenerator, LoggerMixin): | ||
def __init__(self, context_factory: t.Callable[[ProtoFile], T], visitor: ProtoVisitorDecorator[T]) -> None: | ||
self.__context_factory = context_factory | ||
self.__walker = Walker(visitor) | ||
|
||
generator = self.__factory.create_proto_visitor_decorator(modules) | ||
log = log.bind_details(generator=generator) | ||
def run(self, file: ProtoFile) -> t.Sequence[GeneratedItem]: | ||
log = self._log.bind_details(file_name=file.name) | ||
log.debug("file received") | ||
|
||
visit(DFSWalkingProtoVisitor(generator), file.descriptor) | ||
log.debug("proto visited", modules=modules) | ||
context = self.__walker.walk(self.__context_factory(file), file.descriptor) | ||
log.debug("proto visited", context=context) | ||
|
||
return list(self.__gen_modules(file, modules, log)) | ||
return list(self.__gen_modules(context, log)) | ||
|
||
def __gen_modules( | ||
self, | ||
file: ProtoFile, | ||
modules: t.Mapping[Path, ast.Module], | ||
log: Logger, | ||
) -> t.Iterable[t.Tuple[ProtoFile, Path, str]]: | ||
for path, module_ast in modules.items(): | ||
def __gen_modules(self, context: ModuleASTContext, log: Logger) -> t.Iterable[GeneratedItem]: | ||
for path, module_ast in context.modules.items(): | ||
if not module_ast.body: | ||
continue | ||
|
||
module_content = ast.unparse(module_ast) | ||
log.info("module generated", path=path) | ||
module = GeneratedItem(context.file, path, module_content) | ||
|
||
log.info("module generated", module=module) | ||
|
||
yield file, path, module_content | ||
yield module |
Oops, something went wrong.