Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Candid type representations in Python #20

Closed
lastmjs opened this issue Sep 28, 2022 · 4 comments
Closed

Candid type representations in Python #20

lastmjs opened this issue Sep 28, 2022 · 4 comments
Assignees
Milestone

Comments

@lastmjs
Copy link
Member

lastmjs commented Sep 28, 2022

How to represent records, variants, arrays, and other non-primitives in Python typing, how to represent all types (make an issue for each showing how they should look). I just found this awesome Rust/Python types chart: https://pyo3.rs/v0.13.2/conversions/tables.html

text

# str should be an alias to text
text = str

blob

blob = bytes

# or

blob = bytearray

nat and natN

nat = int
nat64 = int
nat32 = int
nat16 = int
nat8 = int

int and intN

# int is builtin
int64 = int
int32 = int
int16 = int
int8 = int

float32

float32 = float

float64

float64 = float

bool

# bool is builtin

null

# None should be an alias to null
null = None

vec t

T = TypeVar('T')
list[T]

# example

@query
def first_list(list_a: list[int], list_b: list[nat]) -> list[int]:
    return list_a

opt t

T = TypeVar('T')
opt = Optional[T]

# example

@query
def first_opt(opt_a: opt[str], opt_b: opt[bool]) -> opt[str]:
    return opt_a

record

# kybra module
record = TypedDict

# example
from kybra import record

MyRecord = record('MyRecord', {
    'prop1': str,
    'prop2': int
})

# or

class MyRecord(record):
    prop1: str,
   prop2: int

# or ideally I think we want this, behaving like a data class or TypedDict
@record
class MyRecord:
    prop1: str,
    prop2: int

tuple

my_tuple = tuple[str, str]

variant

# TODO consider what to do after figuring out records
# TODO we might want to see what ic-py is doing
# We might just want to do some weird inheritance thing with TypedDict, like Variant
# We might want to do that for records and variants

# kybra module
variant = TypedDict

# example
from kybra import variant

MyVariant = variant('MyVariant', {
    'prop1': str,
    'prop2': int
})

# or

class MyVariant(variant):
    prop1: str,
    prop2: int

# or ideally I think we want this, behaving like a data class or TypedDict
@variant
class MyVariant:
    prop1: str,
    prop2: int

func

# kybra module

def Func(callable: Callable) -> Type[tuple[int, str]]:
    return type((0, ''))

# example
from kybra import Func

MyFunc: TypeAlias = Func(Query[[], str])

service

principal

Use the Principal type from https://github.com/rocklabs-io/ic-py

from ic.principal import Principal
p = Principal() # default is management canister id `aaaaa-aa`
p1 = Principal(bytes=b'') # create an instance from bytes
p2 = Principal.anonymous() # create anonymous principal
p3 = Principal.self_authenticating(pubkey) # create a principal from public key
p4 = Principal.from_str('aaaaa-aa') # create an instance from string
p5 = Principal.from_hex('xxx') # create an instance from hex

reserved

from typing import Any

reserved = Any

empty

from typing import NoReturn

empty = NoReturn

canister

from kybra import canister, Query, Update, Oneway

@canister
class MyCanister:
    read: Query[[int, str], str]
    write: Update[[], str]
    oneway: Oneway[[], None]
@lastmjs lastmjs mentioned this issue Sep 28, 2022
30 tasks
@lastmjs lastmjs self-assigned this Sep 28, 2022
@lastmjs lastmjs added this to the 0.1.0 (Beta) milestone Sep 28, 2022
@lastmjs
Copy link
Member Author

lastmjs commented Oct 11, 2022

Consider data classes for variants and records

@lastmjs
Copy link
Member Author

lastmjs commented Oct 12, 2022

For variant and record I'm beginning to think it isn't possible to design exactly what we want with Python's type system. So, I think we should consider just using TypedDict and/or decorators. For variants, the user will just have to deal with an optional type of some kind for each branch...maybe we can create a type called branch or arm or case that is null or a certain type...I guess opt could be that?

@lastmjs
Copy link
Member Author

lastmjs commented Oct 12, 2022

Look at this library: https://github.com/jspahrsummers/adt/blob/master/adt/case.py

I think we might want to just do a Case similar to how they do it...variant will have cases, record will not. Now we need to figure out how to make these TypedDict...I think the getItem function might be key here

@lastmjs
Copy link
Member Author

lastmjs commented Oct 14, 2022

All of the major designs are done, now time to implement

@lastmjs lastmjs closed this as completed Oct 14, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant