Skip to content

Commit 2f4808f

Browse files
authored
append Raises line to function docstrings as appropriate (#55)
If the WIT representation of a function returns `result<A,B>`, then we generate a Python function that returns `A` and raises `Err(B)`. Since there's currently no way of representing the `Err(B)` part in the function's signature, we do the next best thing: put it in the docstring. Fixes #53 Signed-off-by: Joel Dice <joel.dice@fermyon.com>
1 parent d7eadf2 commit 2f4808f

2 files changed

Lines changed: 47 additions & 23 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/summary.rs

Lines changed: 46 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ struct FunctionCode {
173173
static_method: &'static str,
174174
return_type: String,
175175
result_count: usize,
176+
error: Option<String>,
176177
}
177178

178179
pub struct Summary<'a> {
@@ -751,9 +752,9 @@ impl<'a> Summary<'a> {
751752

752753
let result_types = function.results.types().collect::<Vec<_>>();
753754

754-
let (return_statement, return_type) =
755+
let (return_statement, return_type, error) =
755756
if let wit_parser::FunctionKind::Constructor(_) = function.wit_kind {
756-
("return".to_owned(), "None".to_owned())
757+
("return".to_owned(), "None".to_owned(), None)
757758
} else {
758759
let indent = if let wit_parser::FunctionKind::Freestanding = function.wit_kind {
759760
""
@@ -762,18 +763,29 @@ impl<'a> Summary<'a> {
762763
};
763764

764765
match result_types.as_slice() {
765-
[] => ("return".to_owned(), "None".to_owned()),
766+
[] => ("return".to_owned(), "None".to_owned(), None),
766767
[ty] => match special_return(*ty) {
767-
SpecialReturn::Result(result) => (
768-
format!(
769-
"if isinstance(result[0], Err):
768+
SpecialReturn::Result(result) => {
769+
let error = if let Some(ty) = result.err {
770+
Some(type_name(ty))
771+
} else {
772+
Some("None".into())
773+
};
774+
775+
(
776+
format!(
777+
"if isinstance(result[0], Err):
770778
{indent} raise result[0]
771779
{indent} else:
772780
{indent} return result[0].value"
773-
),
774-
result.ok.map(type_name).unwrap_or_else(|| "None".into()),
775-
),
776-
SpecialReturn::None => ("return result[0]".to_owned(), type_name(*ty)),
781+
),
782+
result.ok.map(type_name).unwrap_or_else(|| "None".into()),
783+
error,
784+
)
785+
}
786+
SpecialReturn::None => {
787+
("return result[0]".to_owned(), type_name(*ty), None)
788+
}
777789
},
778790
_ => (
779791
"return result".to_owned(),
@@ -785,6 +797,7 @@ impl<'a> Summary<'a> {
785797
.collect::<Vec<_>>()
786798
.join(", ")
787799
),
800+
None,
788801
),
789802
}
790803
};
@@ -805,6 +818,7 @@ impl<'a> Summary<'a> {
805818
static_method,
806819
return_type: format!(" -> {return_type}"),
807820
result_count,
821+
error,
808822
}
809823
}
810824

@@ -949,7 +963,14 @@ impl<'a> Summary<'a> {
949963
},
950964
}
951965

952-
let docstring = |docs: Option<&str>, indent_level| {
966+
let docstring = |docs: Option<&str>, indent_level, error: Option<&str>| {
967+
let docs = match (docs, error.map(|e| format!("Raises: Err({e})"))) {
968+
(Some(docs), Some(error_docs)) => Some(format!("{docs}\n\n{error_docs}")),
969+
(Some(docs), None) => Some(docs.to_owned()),
970+
(None, Some(error_docs)) => Some(error_docs),
971+
(None, None) => None,
972+
};
973+
953974
if let Some(docs) = docs {
954975
let newline = '\n';
955976
let indent = (0..indent_level)
@@ -1000,7 +1021,7 @@ impl<'a> Summary<'a> {
10001021
fields = "pass".to_owned()
10011022
}
10021023

1003-
let docs = docstring(docs, 1);
1024+
let docs = docstring(docs, 1, None);
10041025

10051026
format!(
10061027
"
@@ -1078,7 +1099,7 @@ class {name}:
10781099
.collect::<Vec<_>>()
10791100
.join("\n ");
10801101

1081-
let docs = docstring(ty.docs.contents.as_deref(), 1);
1102+
let docs = docstring(ty.docs.contents.as_deref(), 1, None);
10821103

10831104
Code::Shared(format!(
10841105
"
@@ -1102,7 +1123,7 @@ class {camel}(Enum):
11021123
flags
11031124
};
11041125

1105-
let docs = docstring(ty.docs.contents.as_deref(), 1);
1126+
let docs = docstring(ty.docs.contents.as_deref(), 1, None);
11061127

11071128
Code::Shared(format!(
11081129
"
@@ -1114,7 +1135,7 @@ class {camel}(Flag):
11141135
TypeDefKind::Resource => {
11151136
let camel = camel();
11161137

1117-
let docs = docstring(ty.docs.contents.as_deref(), 1);
1138+
let docs = docstring(ty.docs.contents.as_deref(), 1, None);
11181139

11191140
let empty = &ResourceInfo::default();
11201141

@@ -1134,9 +1155,10 @@ class {camel}(Flag):
11341155
return_statement,
11351156
static_method,
11361157
result_count,
1158+
error,
11371159
} = self.function_code(function, &mut names, &seen, Some(id));
11381160

1139-
let docs = docstring(function.docs, 2);
1161+
let docs = docstring(function.docs, 2, error.as_deref());
11401162

11411163
if let wit_parser::FunctionKind::Constructor(_) = function.wit_kind {
11421164
if stub_runtime_calls {
@@ -1246,10 +1268,11 @@ class {camel}:
12461268
params,
12471269
return_type,
12481270
static_method,
1271+
error,
12491272
..
12501273
} = self.function_code(function, &mut names, &seen, Some(id));
12511274

1252-
let docs = docstring(function.docs, 2);
1275+
let docs = docstring(function.docs, 2, error.as_deref());
12531276

12541277
format!(
12551278
"{static_method}
@@ -1393,12 +1416,13 @@ class {camel}(Protocol):
13931416
return_type,
13941417
return_statement,
13951418
result_count,
1419+
error,
13961420
..
13971421
} = self.function_code(function, &mut names, &seen, None);
13981422

13991423
match function.kind {
14001424
FunctionKind::Import => {
1401-
let docs = docstring(function.docs, 1);
1425+
let docs = docstring(function.docs, 1, error.as_deref());
14021426

14031427
let code = if stub_runtime_calls {
14041428
format!(
@@ -1440,7 +1464,7 @@ def {snake}({params}){return_type}:
14401464
format!("self, {params}")
14411465
};
14421466

1443-
let docs = docstring(function.docs, 2);
1467+
let docs = docstring(function.docs, 2, error.as_deref());
14441468

14451469
let code = format!(
14461470
"
@@ -1531,7 +1555,7 @@ Result = Union[Ok[T], Err[E]]
15311555
.map(|&interface| import("..", interface))
15321556
.collect::<Vec<_>>()
15331557
.join("\n");
1534-
let docs = docstring(code.docs, 0);
1558+
let docs = docstring(code.docs, 0, None);
15351559

15361560
let imports = if stub_runtime_calls {
15371561
imports
@@ -1567,7 +1591,7 @@ from ..types import Result, Ok, Err, Some
15671591
.map(|interface| import("..", interface))
15681592
.collect::<Vec<_>>()
15691593
.join("\n");
1570-
let docs = docstring(code.docs, 0);
1594+
let docs = docstring(code.docs, 0, None);
15711595

15721596
write!(
15731597
file,
@@ -1637,7 +1661,7 @@ from ..types import Result, Ok, Err, Some
16371661
.map(|&interface| import(".", interface))
16381662
.collect::<Vec<_>>()
16391663
.join("\n");
1640-
let docs = docstring(world_exports.docs, 0);
1664+
let docs = docstring(world_exports.docs, 0, None);
16411665

16421666
let imports = if stub_runtime_calls {
16431667
imports

0 commit comments

Comments
 (0)