Skip to content

Commit c19a79c

Browse files
committed
Python bindings IR -- Implement the pipeline
Added pipeline code and updated the templates to work with the new system. My main workflow loop for this was: - Commenting out the template code using `{#` and `#}` - Running `cargo test py` on one of the examples/fixtures. - Uncommenting/upating the template code and implementing any pipeline passes needed to make the tests pass. I also removed some of the redundant fields. `Function.inputs` field is redundant when there's `Function.callable.inputs`.
1 parent 782e05f commit c19a79c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+1297
-1906
lines changed

Cargo.lock

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

examples/custom-types/uniffi.toml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,10 @@ lower = "{}.toString()"
5050

5151
[bindings.python.custom_types.Url]
5252
# We're going to be the urllib.parse.ParseResult class, which is the closest
53-
# thing Python has to a Url class. No need to specify `type_name` though,
54-
# since Python is loosely typed.
55-
# modules to import
53+
# thing Python has to a Url class.
54+
55+
# `type_name` is optional, but it improves Python's optional type-checking
56+
type_name = "urllib.parse.ParseResult"
5657
imports = ["urllib.parse"]
5758
# Function to lift a string from Rust into a Python URL.
5859
lift = "urllib.parse.urlparse({})"

uniffi_bindgen/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ fs-err = "2.7.0"
2525
glob = "0.3"
2626
goblin = "0.8"
2727
heck = "0.5"
28-
indexmap = { version = "2.2" }
28+
indexmap = { version = "2.2", features = ["serde"] }
2929
once_cell = "1.12"
3030
serde = { version = "1", features = ["derive"] }
3131
tempfile = "3"
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/* This Source Code Form is subject to the terms of the Mozilla Public
2+
* License, v. 2.0. If a copy of the MPL was not distributed with this
3+
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4+
5+
/// Template filters for Askama
6+
///
7+
/// In general, prefer adding fields using a pipeline pass to writing filters.
8+
/// That's allows devs to use the `pipeline` command to follow what's going on.
9+
///
10+
/// We currently only use filter functions for a couple reasons:
11+
///
12+
/// * When we want to leverage `AsRef` to implement something for any type that has an `AsRef`
13+
/// relationship. This could be done using a pipeline pass, but it could be annoying/distracting
14+
/// to add fields like `type_name,` `lower_fn`, etc. to so many different Node structs.
15+
/// * When we want to implement somewhat complex display logic, like in the `docstring` filter.
16+
/// Implementing this as a pipeline pass means the pass would need to know how much each
17+
/// docstring gets indented, which doesn't seem right.
18+
use super::pipeline::nodes::*;
19+
use askama::Result;
20+
21+
pub fn type_name(ty: impl AsRef<TypeNode>) -> Result<String> {
22+
Ok(ty.as_ref().type_name.clone())
23+
}
24+
25+
pub fn ffi_converter_name(ty: impl AsRef<TypeNode>) -> Result<String> {
26+
Ok(ty.as_ref().ffi_converter_name.clone())
27+
}
28+
29+
pub fn lower_fn(ty: impl AsRef<TypeNode>) -> Result<String> {
30+
Ok(format!("{}.lower", ty.as_ref().ffi_converter_name))
31+
}
32+
33+
pub fn check_lower_fn(ty: impl AsRef<TypeNode>) -> Result<String> {
34+
Ok(format!("{}.check_lower", ty.as_ref().ffi_converter_name))
35+
}
36+
37+
pub fn lift_fn(ty: impl AsRef<TypeNode>) -> Result<String> {
38+
Ok(format!("{}.lift", ty.as_ref().ffi_converter_name))
39+
}
40+
41+
pub fn write_fn(ty: impl AsRef<TypeNode>) -> Result<String> {
42+
Ok(format!("{}.write", ty.as_ref().ffi_converter_name))
43+
}
44+
45+
pub fn read_fn(ty: impl AsRef<TypeNode>) -> Result<String> {
46+
Ok(format!("{}.read", ty.as_ref().ffi_converter_name))
47+
}
48+
49+
/// Get the idiomatic Python rendering of docstring
50+
///
51+
/// If the docstring is set, this returns an indented Python docstring with
52+
/// a trailing newline. If not, it returns the empty string.
53+
///
54+
/// This makes it so the template code can use something like
55+
/// `{{ item.docstring|docstring(4) -}}` to render the correct docstring in both cases.
56+
pub fn docstring(docstring: &Option<String>, indent: usize) -> Result<String> {
57+
let Some(docstring) = docstring.as_deref() else {
58+
return Ok("".to_string());
59+
};
60+
let docstring = textwrap::dedent(docstring);
61+
let indent = " ".repeat(indent);
62+
// Escape triple quotes to avoid syntax error
63+
let escaped = docstring.replace(r#"""""#, r#"\"\"\""#);
64+
let indented = textwrap::indent(&escaped, &indent);
65+
Ok(format!("\"\"\"\n{indented}\n\"\"\"\n{indent}"))
66+
}

uniffi_bindgen/src/bindings/python/gen_python/callback_interface.rs

Lines changed: 0 additions & 31 deletions
This file was deleted.

uniffi_bindgen/src/bindings/python/gen_python/compounds.rs

Lines changed: 0 additions & 118 deletions
This file was deleted.

uniffi_bindgen/src/bindings/python/gen_python/custom.rs

Lines changed: 0 additions & 26 deletions
This file was deleted.

uniffi_bindgen/src/bindings/python/gen_python/enum_.rs

Lines changed: 0 additions & 39 deletions
This file was deleted.

uniffi_bindgen/src/bindings/python/gen_python/miscellany.rs

Lines changed: 0 additions & 26 deletions
This file was deleted.

0 commit comments

Comments
 (0)