-
Notifications
You must be signed in to change notification settings - Fork 240
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Clean up python bindings generator, and add support for sequences.
This is a significant refactor of the python bindings generator, with the aim of making the generated code a bit cleaner and of better hiding many of our implementation details from the public API. To help prove out the approach, it adds previously-missing support for sequence types. The key idea here is that, for any given `ComponentInterface`, we can finitely enumerate all the possible types used in that interface (including recursive types like sequences) and can give each such type a unique name. This lets us define per-type helper methods on the internal helper objects like `RustBuffer`, rather than putting these as "hidden" methods on the public classes. For example, for each type that lowers into a `RustBuffer`, there is a corresponding `RustBuffer.allocFrom{{ type_name }}` classmethod for lowering it and a `RustBuffer.consumeInto{{ type_name }}` for lifting it. If you squint, this is a little bit like defining private traits and then emitting a monomorphised implementation for each concrete type, except within the constraints of python's much looser type system.
- Loading branch information
Showing
15 changed files
with
798 additions
and
184 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 |
---|---|---|
@@ -0,0 +1,110 @@ | ||
from rondpoint import * | ||
|
||
dico = Dictionnaire(Enumeration.DEUX, True, 0, 123456789) | ||
copyDico = copie_dictionnaire(dico) | ||
assert dico == copyDico | ||
|
||
assert copie_enumeration(Enumeration.DEUX) == Enumeration.DEUX | ||
assert copie_enumerations([Enumeration.UN, Enumeration.DEUX]) == [Enumeration.UN, Enumeration.DEUX] | ||
assert copie_carte({"1": Enumeration.UN, "2": Enumeration.DEUX}) == {"1": Enumeration.UN, "2": Enumeration.DEUX} | ||
|
||
assert switcheroo(False) is True | ||
|
||
# Test the roundtrip across the FFI. | ||
# This shows that the values we send come back in exactly the same state as we sent them. | ||
# i.e. it shows that lowering from python and lifting into rust is symmetrical with | ||
# lowering from rust and lifting into python. | ||
rt = Retourneur() | ||
|
||
def affirmAllerRetour(vals, identique): | ||
for v in vals: | ||
id_v = identique(v) | ||
assert id_v == v, f"Round-trip failure: {v} => {id_v}" | ||
|
||
# Booleans | ||
affirmAllerRetour([True, False], rt.identique_boolean) | ||
|
||
# Bytes. | ||
affirmAllerRetour([-128, -1, 0, 1, 127], rt.identique_i8) | ||
affirmAllerRetour([0x00, 0x12, 0xFF], rt.identique_u8) | ||
|
||
# Shorts | ||
affirmAllerRetour([-32768, -1, 0, 1, 32767], rt.identique_i16) | ||
affirmAllerRetour([0x0000, 0x1234, 0xFFFF], rt.identique_u16) | ||
|
||
# Ints | ||
affirmAllerRetour([-2147483648, -1, 0, 1, 2147483647], rt.identique_i32) | ||
affirmAllerRetour([0x00000000, 0x12345678, 0xFFFFFFFF], rt.identique_u32) | ||
|
||
# Longs | ||
affirmAllerRetour([-9223372036854775808, -1, 0, 1, 9223372036854775807], rt.identique_i64) | ||
affirmAllerRetour([0x0000000000000000, 0x1234567890ABCDEF, 0xFFFFFFFFFFFFFFFF], rt.identique_u64) | ||
|
||
# Floats | ||
# XXX TODO: MIN_FLOAT/MAX_FLOAT, 1/3 | ||
affirmAllerRetour([0.0, 0.5, 0.25, 1.0], rt.identique_float) | ||
|
||
# Doubles | ||
# XXX TODO: MIN_DOUBLE/MAX_DOUBLE, 1/3 | ||
affirmAllerRetour([0.0, 0.5, 0.25, 1.0], rt.identique_double) | ||
|
||
# Strings | ||
affirmAllerRetour(["", "abc", "été", "ښي لاس ته لوستلو لوستل", "😻emoji 👨👧👦multi-emoji, 🇨🇭a flag, a canal, panama"], rt.identique_string) | ||
|
||
# Test one way across the FFI. | ||
# | ||
# We send one representation of a value to lib.rs, and it transforms it into another, a string. | ||
# lib.rs sends the string back, and then we compare here in python. | ||
# | ||
# This shows that the values are transformed into strings the same way in both python and rust. | ||
# i.e. if we assume that the string return works (we test this assumption elsewhere) | ||
# we show that lowering from python and lifting into rust has values that both python and rust | ||
# both stringify in the same way. i.e. the same values. | ||
# | ||
# If we roundtripping proves the symmetry of our lowering/lifting from here to rust, and lowering/lifting from rust to here, | ||
# and this convinces us that lowering/lifting from here to rust is correct, then | ||
# together, we've shown the correctness of the return leg. | ||
st = Stringifier() | ||
|
||
def affirmEnchaine(vals, toString, rustyStringify=lambda v: str(v).lower()): | ||
for v in vals: | ||
str_v = toString(v) | ||
assert rustyStringify(v) == str_v, f"String compare error {v} => {str_v}" | ||
|
||
# Test the efficacy of the string transport from rust. If this fails, but everything else | ||
# works, then things are very weird. | ||
wellKnown = st.well_known_string("python") | ||
assert "uniffi 💚 python!" == wellKnown | ||
|
||
# Booleans | ||
affirmEnchaine([True, False], st.to_string_boolean) | ||
|
||
# Bytes. | ||
affirmEnchaine([-128, -1, 0, 1, 127], st.to_string_i8) | ||
affirmEnchaine([0x00, 0x12, 0xFF], st.to_string_u8) | ||
|
||
# Shorts | ||
affirmEnchaine([-32768, -1, 0, 1, 32767], st.to_string_i16) | ||
affirmEnchaine([0x0000, 0x1234, 0xFFFF], st.to_string_u16) | ||
|
||
# Ints | ||
affirmEnchaine([-2147483648, -1, 0, 1, 2147483647], st.to_string_i32) | ||
affirmEnchaine([0x00000000, 0x12345678, 0xFFFFFFFF], st.to_string_u32) | ||
|
||
# Longs | ||
affirmEnchaine([-9223372036854775808, -1, 0, 1, 9223372036854775807], st.to_string_i64) | ||
affirmEnchaine([0x0000000000000000, 0x1234567890ABCDEF, 0xFFFFFFFFFFFFFFFF], st.to_string_u64) | ||
|
||
# Floats | ||
# XXX TODO: MIN_FLOAT/MAX_FLOAT, 1/3 | ||
def rustyFloatToStr(v): | ||
"""Rust doesn't include the decimal part of whole enumber floats when stringifying.""" | ||
if int(v) == v: | ||
return str(int(v)) | ||
return str(v) | ||
|
||
affirmEnchaine([0.0, 0.5, 0.25, 1.0], st.to_string_float, rustyFloatToStr) | ||
|
||
# Doubles | ||
# XXX TODO: MIN_DOUBLE/MAX_DOUBLE, 1/3 | ||
affirmEnchaine([0.0, 0.5, 0.25, 1.0], st.to_string_double, rustyFloatToStr) |
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
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,4 +1,4 @@ | ||
class {{ e.name() }}(enum.Enum): | ||
class {{ e.name()|class_name_py }}(enum.Enum): | ||
{% for variant in e.variants() -%} | ||
{{ variant|enum_name_py }} = {{ loop.index }} | ||
{% endfor -%} | ||
{% endfor %} |
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
Oops, something went wrong.