from typing import Type
from pytezos.context.abstract import AbstractContext
from pytezos.michelson.micheline import Micheline
from pytezos.michelson.micheline import MichelineLiteral
from pytezos.michelson.micheline import blind_unpack
from pytezos.michelson.micheline import parse_micheline_literal
from pytezos.michelson.micheline import parse_micheline_value
from pytezos.michelson.types.base import MichelsonType
[docs]class unit:
def __repr__(self):
return 'Unit'
def __eq__(self, other):
return isinstance(other, unit)
def __lt__(self, other):
return False
Unit = unit()
[docs]class TrueLiteral(Micheline, prim='True'):
pass
[docs]class FalseLiteral(Micheline, prim='False'):
pass
[docs]class UnitLiteral(Micheline, prim='Unit'):
pass
[docs]class StringType(MichelsonType, prim='string'):
def __init__(self, value: str = ''):
super(StringType, self).__init__()
self.value = value
def __lt__(self, other: 'StringType'): # type: ignore
return self.value < other.value
def __eq__(self, other): # type: ignore
if not isinstance(other, StringType):
return False
return self.value == other.value
def __hash__(self):
return hash(self.value)
def __repr__(self):
return f'\'{self.value}\''
def __str__(self):
return self.value
def __len__(self):
return len(self.value)
[docs] @classmethod
def from_value(cls, value: str) -> 'StringType':
assert isinstance(value, str), f'expected string, got {type(value).__name__}'
assert len(value) == len(value.encode()), f'unicode symbols are not allowed: {value}'
return cls(value)
[docs] @classmethod
def dummy(cls, context: AbstractContext) -> 'StringType':
return cls()
[docs] @classmethod
def from_micheline_value(cls, val_expr) -> 'StringType':
value = parse_micheline_literal(val_expr, {'string': str})
return cls.from_value(value)
[docs] @classmethod
def from_python_object(cls, py_obj) -> 'StringType':
return cls.from_value(py_obj)
[docs] def to_literal(self) -> Type[Micheline]:
return MichelineLiteral.create(self.value)
[docs] def to_micheline_value(self, mode='readable', lazy_diff=False):
return {'string': self.value}
[docs] def to_python_object(self, try_unpack=False, lazy_diff=False, comparable=False):
return self.value
def __getitem__(self, item):
assert isinstance(item, slice), f'expected start:end, got {item}'
assert len(self.value) > 0, f'string is empty'
assert item.stop <= len(self.value), f'out of bounds {item.stop} <= {len(self.value)}'
return StringType(self.value[item.start : item.stop])
[docs]class IntType(MichelsonType, prim='int'):
def __init__(self, value: int = 0):
super(IntType, self).__init__()
self.value = value
def __lt__(self, other: 'IntType'): # type: ignore
return self.value < other.value
def __eq__(self, other): # type: ignore
if not isinstance(other, IntType):
return False
return self.value == other.value
def __hash__(self):
return hash(self.value)
def __repr__(self):
return str(self.value)
def __int__(self):
return self.value
[docs] @classmethod
def dummy(cls, context: AbstractContext) -> 'IntType':
return cls()
[docs] @classmethod
def from_value(cls, value: int) -> 'IntType':
return cls(value)
[docs] @classmethod
def from_micheline_value(cls, val_expr) -> 'IntType':
value = parse_micheline_literal(val_expr, {'int': int})
return cls(value)
[docs] @classmethod
def from_python_object(cls, py_obj) -> 'IntType':
assert isinstance(py_obj, int), f'expected integer, got {type(py_obj).__name__}'
return cls(py_obj)
[docs] def to_literal(self) -> Type[Micheline]:
return MichelineLiteral.create(self.value)
[docs] def to_micheline_value(self, mode='readable', lazy_diff=False):
return {'int': str(self.value)}
[docs] def to_python_object(self, try_unpack=False, lazy_diff=False, comparable=False):
return self.value
[docs]class NatType(IntType, prim='nat'):
[docs] @classmethod
def from_value(cls, value: int) -> 'NatType':
assert value >= 0, f'expected natural number, got {value}'
return cls(value)
[docs] @classmethod
def from_micheline_value(cls, val_expr) -> 'NatType':
value = parse_micheline_literal(val_expr, {'int': int})
return cls.from_value(value)
[docs] @classmethod
def from_python_object(cls, py_obj) -> 'NatType':
assert isinstance(py_obj, int), f'expected integer, got {type(py_obj).__name__}'
return cls.from_value(py_obj)
[docs]class BytesType(MichelsonType, prim='bytes'):
def __init__(self, value: bytes = b''):
super(BytesType, self).__init__()
self.value = value
def __lt__(self, other: 'BytesType'): # type: ignore
return self.value < other.value
def __eq__(self, other): # type: ignore
if not isinstance(other, BytesType):
return False
return self.value == other.value
def __hash__(self):
return hash(self.value)
def __repr__(self):
return f'0x{self.value.hex()}'
def __bytes__(self):
return self.value
def __len__(self):
return len(self.value)
[docs] @classmethod
def dummy(cls, context: AbstractContext) -> 'BytesType':
return cls()
[docs] @classmethod
def from_value(cls, value: bytes):
return cls(value)
[docs] @classmethod
def from_micheline_value(cls, val_expr) -> 'BytesType':
value = parse_micheline_literal(val_expr, {'bytes': bytes.fromhex})
return cls(value)
[docs] @classmethod
def from_python_object(cls, py_obj) -> 'BytesType':
if isinstance(py_obj, bytes):
value = py_obj
elif isinstance(py_obj, str):
if py_obj.startswith('0x'):
py_obj = py_obj[2:]
value = bytes.fromhex(py_obj)
else:
raise AssertionError(f'unexpected value type {py_obj}')
return cls(value)
[docs] def to_literal(self) -> Type[Micheline]:
return MichelineLiteral.create(self.value)
[docs] def to_micheline_value(self, mode='readable', lazy_diff=False):
return {'bytes': self.value.hex()}
[docs] def to_python_object(self, try_unpack=False, lazy_diff=False, comparable=False):
if try_unpack:
return blind_unpack(self.value)
return self.value
def __getitem__(self, item):
assert isinstance(item, slice), f'expected start:stop, got {item}'
assert item.stop <= len(self.value), f'index out of bounds'
return BytesType(self.value[item.start : item.stop])
[docs]class BoolType(MichelsonType, prim='bool'):
def __init__(self, value: bool):
super(BoolType, self).__init__()
self.value = value
def __lt__(self, other: 'BoolType'): # type: ignore
return self.value < other.value
def __eq__(self, other): # type: ignore
if not isinstance(other, BoolType):
return False
return self.value == other.value
def __hash__(self):
return hash(self.value)
def __repr__(self):
return str(self.value)
def __bool__(self):
return self.value
[docs] @classmethod
def dummy(cls, context: AbstractContext) -> 'BoolType':
return cls(False)
[docs] @classmethod
def from_value(cls, value: bool):
return cls(value)
[docs] @classmethod
def from_micheline_value(cls, val_expr) -> 'BoolType':
value = parse_micheline_value(
val_expr,
{
('False', 0): lambda x: False,
('True', 0): lambda x: True,
},
)
return cls(value)
[docs] @classmethod
def from_python_object(cls, py_obj) -> 'BoolType':
assert isinstance(py_obj, bool), f'expected boolean, got {type(py_obj).__name__}'
return cls(py_obj)
[docs] def to_literal(self) -> Type[Micheline]:
return TrueLiteral if self.value else FalseLiteral
[docs] def to_micheline_value(self, mode='readable', lazy_diff=False):
return {'prim': 'True' if self.value else 'False'}
[docs] def to_python_object(self, try_unpack=False, lazy_diff=False, comparable=False):
return self.value
[docs]class UnitType(MichelsonType, prim='unit'):
def __init__(self):
super(UnitType, self).__init__()
def __lt__(self, other: 'UnitType'): # type: ignore
return False
def __eq__(self, other: 'UnitType'): # type: ignore
return True
def __hash__(self):
return hash(Unit)
def __repr__(self):
return 'Unit'
[docs] @classmethod
def dummy(cls, context: AbstractContext) -> 'UnitType':
return cls()
[docs] @classmethod
def from_micheline_value(cls, val_expr) -> 'UnitType':
parse_micheline_value(val_expr, {('Unit', 0): lambda x: x})
return cls()
[docs] @classmethod
def from_python_object(cls, py_obj) -> 'UnitType':
assert py_obj is None or isinstance(py_obj, unit), f'expected None or Unit, got {type(py_obj).__name__}'
return cls()
[docs] def to_literal(self) -> Type[Micheline]:
return UnitLiteral
[docs] def to_micheline_value(self, mode='readable', lazy_diff=False):
return {'prim': 'Unit'}
[docs] def to_python_object(self, try_unpack=False, lazy_diff=False, comparable=False):
return unit()
[docs]class NeverType(MichelsonType, prim='never'):
def __lt__(self, other: 'NeverType'): # type: ignore
return False
def __eq__(self, other: 'NeverType'): # type: ignore
return True