diff --git a/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/PythonType.kt b/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/PythonType.kt index e052a3ffa83..c8543297aca 100644 --- a/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/PythonType.kt +++ b/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/PythonType.kt @@ -162,3 +162,11 @@ fun PythonType.render(fullyQualified: Boolean = true): String { } return "$namespace$base" } + +/** + * Renders [PythonType] with proper escaping for Docstrings. + */ +fun PythonType.renderAsDocstring(): String = + this.render(). + replace("[", "\\["). + replace("]", "\\]") diff --git a/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonApplicationGenerator.kt b/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonApplicationGenerator.kt index d00cb935ed2..c5644b4d9ef 100644 --- a/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonApplicationGenerator.kt +++ b/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonApplicationGenerator.kt @@ -23,7 +23,7 @@ import software.amazon.smithy.rust.codegen.core.util.toPascalCase import software.amazon.smithy.rust.codegen.core.util.toSnakeCase import software.amazon.smithy.rust.codegen.server.python.smithy.PythonServerCargoDependency import software.amazon.smithy.rust.codegen.server.python.smithy.PythonType -import software.amazon.smithy.rust.codegen.server.python.smithy.render +import software.amazon.smithy.rust.codegen.server.python.smithy.renderAsDocstring import software.amazon.smithy.rust.codegen.server.smithy.ServerCargoDependency import software.amazon.smithy.rust.codegen.server.smithy.generators.protocol.ServerProtocol @@ -106,7 +106,7 @@ class PythonApplicationGenerator( ##[#{pyo3}::pyclass] ##[derive(Debug)] /// :generic Ctx: - /// :extends typing.Generic[Ctx]: + /// :extends typing.Generic\[Ctx\]: /// :rtype None: pub struct App { handlers: #{HashMap}, @@ -261,7 +261,7 @@ class PythonApplicationGenerator( /// Register a context object that will be shared between handlers. /// /// :param context Ctx: - /// :rtype ${PythonType.None.render()}: + /// :rtype ${PythonType.None.renderAsDocstring()}: ##[pyo3(text_signature = "(${'$'}self, context)")] pub fn context(&mut self, context: #{pyo3}::PyObject) { self.context = Some(context); @@ -269,8 +269,8 @@ class PythonApplicationGenerator( /// Register a Python function to be executed inside a Tower middleware layer. /// - /// :param func ${middlewareFunc.render()}: - /// :rtype ${PythonType.None.render()}: + /// :param func ${middlewareFunc.renderAsDocstring()}: + /// :rtype ${PythonType.None.renderAsDocstring()}: ##[pyo3(text_signature = "(${'$'}self, func)")] pub fn middleware(&mut self, py: #{pyo3}::Python, func: #{pyo3}::PyObject) -> #{pyo3}::PyResult<()> { let handler = #{SmithyPython}::PyMiddlewareHandler::new(py, func)?; @@ -285,12 +285,12 @@ class PythonApplicationGenerator( /// Main entrypoint: start the server on multiple workers. /// - /// :param address ${PythonType.Optional(PythonType.Str).render()}: - /// :param port ${PythonType.Optional(PythonType.Int).render()}: - /// :param backlog ${PythonType.Optional(PythonType.Int).render()}: - /// :param workers ${PythonType.Optional(PythonType.Int).render()}: - /// :param tls ${PythonType.Optional(tlsConfig).render()}: - /// :rtype ${PythonType.None.render()}: + /// :param address ${PythonType.Optional(PythonType.Str).renderAsDocstring()}: + /// :param port ${PythonType.Optional(PythonType.Int).renderAsDocstring()}: + /// :param backlog ${PythonType.Optional(PythonType.Int).renderAsDocstring()}: + /// :param workers ${PythonType.Optional(PythonType.Int).renderAsDocstring()}: + /// :param tls ${PythonType.Optional(tlsConfig).renderAsDocstring()}: + /// :rtype ${PythonType.None.renderAsDocstring()}: ##[pyo3(text_signature = "(${'$'}self, address=None, port=None, backlog=None, workers=None, tls=None)")] pub fn run( &mut self, @@ -307,7 +307,7 @@ class PythonApplicationGenerator( /// Lambda entrypoint: start the server on Lambda. /// - /// :rtype ${PythonType.None.render()}: + /// :rtype ${PythonType.None.renderAsDocstring()}: ##[pyo3(text_signature = "(${'$'}self)")] pub fn run_lambda( &mut self, @@ -358,8 +358,8 @@ class PythonApplicationGenerator( /// Method to register `$name` Python implementation inside the handlers map. /// It can be used as a function decorator in Python. /// - /// :param func ${handler.render()}: - /// :rtype ${PythonType.None.render()}: + /// :param func ${handler.renderAsDocstring()}: + /// :rtype ${PythonType.None.renderAsDocstring()}: ##[pyo3(text_signature = "(${'$'}self, func)")] pub fn $name(&mut self, py: #{pyo3}::Python, func: #{pyo3}::PyObject) -> #{pyo3}::PyResult<()> { use #{SmithyPython}::PyApp; diff --git a/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonServerStructureGenerator.kt b/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonServerStructureGenerator.kt index 3fd98d27ead..31480a91082 100644 --- a/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonServerStructureGenerator.kt +++ b/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonServerStructureGenerator.kt @@ -24,7 +24,7 @@ import software.amazon.smithy.rust.codegen.core.util.hasTrait import software.amazon.smithy.rust.codegen.server.python.smithy.PythonServerCargoDependency import software.amazon.smithy.rust.codegen.server.python.smithy.PythonType import software.amazon.smithy.rust.codegen.server.python.smithy.pythonType -import software.amazon.smithy.rust.codegen.server.python.smithy.render +import software.amazon.smithy.rust.codegen.server.python.smithy.renderAsDocstring /** * To share structures defined in Rust with Python, `pyo3` provides the `PyClass` trait. @@ -101,15 +101,15 @@ class PythonServerStructureGenerator( writable { forEachMember(members) { _, memberName, memberSymbol -> val memberType = memberSymbol.rustType().pythonType() - rust("/// :param $memberName ${memberType.render()}:") + rust("/// :param $memberName ${memberType.renderAsDocstring()}:") } - rust("/// :rtype ${PythonType.None.render()}:") + rust("/// :rtype ${PythonType.None.renderAsDocstring()}:") } private fun renderSymbolSignature(symbol: Symbol): Writable = writable { val pythonType = symbol.rustType().pythonType() - rust("/// :type ${pythonType.render()}:") + rust("/// :type ${pythonType.renderAsDocstring()}:") } } diff --git a/rust-runtime/aws-smithy-http-server-python/examples/stubgen.py b/rust-runtime/aws-smithy-http-server-python/examples/stubgen.py index 0491bff3709..4e6b8043275 100644 --- a/rust-runtime/aws-smithy-http-server-python/examples/stubgen.py +++ b/rust-runtime/aws-smithy-http-server-python/examples/stubgen.py @@ -33,7 +33,11 @@ def __init__(self, path: Path, root_module_name: str) -> None: self.generics = set([]) def fix_path(self, path: str) -> str: - return path.replace(ROOT_MODULE_NAME_PLACEHOLDER, self.root_module_name) + return ( + path.replace(ROOT_MODULE_NAME_PLACEHOLDER, self.root_module_name) + .replace("\\[", "[") + .replace("\\]", "]") + ) def submodule(self, path: Path) -> Writer: w = Writer(path, self.root_module_name) @@ -287,7 +291,7 @@ def make_class( class_sig = DocstringParser.parse_class(klass) if class_sig: (generics, extends) = class_sig - base_classes.extend(extends) + base_classes.extend(map(writer.fix_and_include, extends)) for g in generics: writer.generic(g) diff --git a/rust-runtime/aws-smithy-http-server-python/src/error.rs b/rust-runtime/aws-smithy-http-server-python/src/error.rs index dc5a00af0d0..760839b8acd 100644 --- a/rust-runtime/aws-smithy-http-server-python/src/error.rs +++ b/rust-runtime/aws-smithy-http-server-python/src/error.rs @@ -41,7 +41,7 @@ impl From for PyErr { /// to build a [aws_smithy_http_server::response::Response] from it. /// /// :param message str: -/// :param status_code typing.Optional[int]: +/// :param status_code typing.Optional\[int\]: /// :rtype None: #[pyclass(name = "MiddlewareException", extends = BasePyException)] #[pyo3(text_signature = "($self, message, status_code=None)")] diff --git a/rust-runtime/aws-smithy-http-server-python/src/lambda.rs b/rust-runtime/aws-smithy-http-server-python/src/lambda.rs index 6ecc8b5c25d..3823e8d93f6 100644 --- a/rust-runtime/aws-smithy-http-server-python/src/lambda.rs +++ b/rust-runtime/aws-smithy-http-server-python/src/lambda.rs @@ -146,14 +146,14 @@ pub struct PyLambdaContext { /// The X-Ray trace ID for the current invocation. /// - /// :type typing.Optional[str]: + /// :type typing.Optional\[str\]: #[pyo3(get)] xray_trace_id: Option, /// The client context object sent by the AWS mobile SDK. This field is /// empty unless the function is invoked using an AWS mobile SDK. /// - /// :type typing.Optional[ClientContext]: + /// :type typing.Optional\[ClientContext\]: #[pyo3(get)] client_context: Option, @@ -161,7 +161,7 @@ pub struct PyLambdaContext { /// unless the invocation request to the Lambda APIs was made using AWS /// credentials issues by Amazon Cognito Identity Pools. /// - /// :type typing.Optional[CognitoIdentity]: + /// :type typing.Optional\[CognitoIdentity\]: #[pyo3(get)] identity: Option, diff --git a/rust-runtime/aws-smithy-http-server-python/src/logging.rs b/rust-runtime/aws-smithy-http-server-python/src/logging.rs index af2049f1a90..80d4966ac0b 100644 --- a/rust-runtime/aws-smithy-http-server-python/src/logging.rs +++ b/rust-runtime/aws-smithy-http-server-python/src/logging.rs @@ -87,8 +87,8 @@ fn setup_tracing_subscriber( /// is not exported in `logging.__all__`, as it is not intended to be called directly. /// - A new class `logging.TracingHandler` provides a `logging.Handler` that delivers all records to `python_tracing`. /// -/// :param level typing.Optional[int]: -/// :param logfile typing.Optional[pathlib.Path]: +/// :param level typing.Optional\[int\]: +/// :param logfile typing.Optional\[pathlib.Path\]: /// :rtype None: #[pyclass(name = "TracingHandler")] #[pyo3(text_signature = "($self, level=None, logfile=None)")]