diff --git a/docs/lg-arc4.md b/docs/lg-arc4.md index f22aa64e7d..f2022d061d 100644 --- a/docs/lg-arc4.md +++ b/docs/lg-arc4.md @@ -109,6 +109,15 @@ from algopy import arc4 FourBytes: t.TypeAlias = arc4.StaticArray[arc4.Byte, t.Literal[4]] ``` + +### Address +**Type:** `algopy.arc4.Address` +**Encoding:** A byte array 32 bytes long +**Native equivalent:** [`algopy.Account`](#algopy.Account) + +Address represents an Algorand address's public key, and can be used instead of `algopy.Account` when needing to +reference an address in an ARC4 struct, tuple or return type. It is a subclass of `arc4.StaticArray[arc4.Byte, typing.Literal[32]]` + ### Dynamic arrays **Type:** `algopy.arc4.DynamicArray` @@ -138,9 +147,11 @@ ARC4 Tuples are immutable statically sized arrays of mixed item types. Item type **Type:** `algopy.arc4.Struct` **Encoding:** See [ARC4 Container Packing](#ARC4-Container-Packing) -**Native equivalent:** _none_ +**Native equivalent:** `typing.NamedTuple` -ARC4 Structs are mutable named tuples. Items can be accessed and mutated via names instead of indexes. +ARC4 Structs are named tuples. The class keyword `frozen` can be used to indicate if a struct can be mutated. +Items can be accessed and mutated via names instead of indexes. Structs do not have a `.native` property, +but a NamedTuple can be used in ABI methods are will be encoded/decode to an ARC4 struct automatically. ```python import typing @@ -149,7 +160,7 @@ from algopy import arc4 Decimal: typing.TypeAlias = arc4.UFixedNxM[typing.Literal[64], typing.Literal[9]] -class Vector(arc4.Struct, kw_only=True): +class Vector(arc4.Struct, kw_only=True, frozen=True): x: Decimal y: Decimal ``` @@ -200,7 +211,16 @@ class Reference(ARC4Contract): ... ``` +### Mutability + +To ensure semantic compatability the compiler will also check for any usages of mutable ARC4 types (arrays and structs) and ensure that any additional references are copied using the `.copy()` method. + +Python values are passed by reference, and when an object (eg. an array or struct) is mutated in one place, all references to that object see the mutated version. In Python this is managed via the heap. +In Algorand Python these mutable values are instead stored on the stack, so when an additional reference is made (i.e. by assigning to another variable) a copy is added to the stack. +Which means if one reference is mutated, the other references would not see the change. +In order to keep the semantics the same, the compiler forces the addition of `.copy()` each time a new reference to the same object to match what will happen on the AVM. +Struct types can be indicated as `frozen` which will eliminate the need for a `.copy()` as long as the struct also contains no mutable fields (such as arrays or another mutable struct) ## Typed clients diff --git a/docs/lg-types.md b/docs/lg-types.md index 4f0ca59545..99ac4aabbc 100644 --- a/docs/lg-types.md +++ b/docs/lg-types.md @@ -201,8 +201,11 @@ if a: ### Account -[`Account`](#algopy.Account) represents a logical Account, backed by a `bytes[]` representing the -public key. It has various account related methods that can be called from the type. +[`Account`](#algopy.Account) represents a logical Account, backed by a `bytes[32]` representing the +bytes of the public key (without the checksum). It has various account related methods that can be called from the type. + +Also see [`algopy.arc4.Address`](#algopy.arc4.Address) if needing to represent the address as a distinct type. + ### Asset @@ -230,8 +233,26 @@ In saying that, there are many places where built-in Python types can be used an ### tuple -Python tuples are supported as arguments to subroutines, local variables, return types. Nested tuples -are _not_ currently supported. +Python tuples are supported as arguments to subroutines, local variables, return types. + +### typing.NamedTuple + +Python named tuples are also supported using [`typing.NamedTuple`](https://docs.python.org/3/library/typing.html#typing.NamedTuple). + +```{note} +Default field values and subclassing a NamedTuple are not supported +``` + +```python +import typing + +import algopy + + +class Pair(typing.NamedTuple): + foo: algopy.Bytes + bar: algopy.Bytes +``` ### None