Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions sample_lego.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import asyncio
from thingsdb.client import Client
from thingsdb.model import Collection, Thing, ThingStrict, Enum
from thingsdb.model import Collection, Thing, ThingStrict, Enum, EnumMember
from thingsdb.util import event


class Color(Enum):
RED = "#f00"
BLUE = "#0f0"
GREEN = "#00f"
GREEN = "#0f0"
BLUE = "#00f"


class Brick(Thing):
Expand Down Expand Up @@ -53,13 +53,25 @@ async def example():
# ... now the collection will be watched for 100 seconds
while True:
await asyncio.sleep(3)

if lego and lego.bricks:

print('Color:', Color.RED is lego.bricks[0].color)
print('Is Enum', isinstance(Color.GREEN, Enum))
print('Is EnumMember', isinstance(Color.GREEN, EnumMember))
print('Is Color', isinstance(Color.GREEN, Color))
print('Is True', Color.GREEN == Color("#0f0"))
print('Is True', Color.GREEN == Color["GREEN"])
print('Is True', getattr(Color, 'GREEN') == Color["GREEN"])
print('Is True', Color.RED.value == lego.bricks[0].color.value)
print('Is True', Color.RED.value == lego.bricks[0].color._value)

brick = lego.bricks[0]
await brick.emit('new-color', 'RED')
break
await lego.query('.bricks.push(Brick{});')

await asyncio.sleep(300)
await asyncio.sleep(5)

finally:
client.close()
Expand Down
1 change: 1 addition & 0 deletions thingsdb/client/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from ..exceptions import ForbiddenError



_WATCH_MISSING = \
'auto reconnect cannot act on node changes since `WATCH` privileges on ' \
'the `@node` scope are missing'
Expand Down
3 changes: 2 additions & 1 deletion thingsdb/model/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from .collection import Collection
from .enum import Enum
from .enummember import EnumMember
from .collection import Collection
from .thing import Thing, ThingStrict, ThingHash
45 changes: 37 additions & 8 deletions thingsdb/model/enum.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,55 @@
from .member import Member
from .enummember import EnumMember

_enums_lookup = {} # enums lookup by name

class Enum:

class _GetAttr(type):
def __getitem__(cls, name):
for k, v in cls.__dict__.items():
if k == name:
return v
raise KeyError(f'no member with name `{k}`')


class Enum(metaclass=_GetAttr):

_visited = 0 # For build, 0=not visited, 1=new_type, 2=set_type, 3=build

def __new__(cls, *args):
if len(args) != 1:
return super().__new__(cls)

value = args[0]
for v in cls.__dict__.values():
if isinstance(v, EnumMember) and v._value == value:
return v
raise ValueError(f'no member with value `{value}`')

def __init_subclass__(cls, **kwargs):
if issubclass(cls, EnumMember):
return

cls._name = getattr(cls, '__NAME__', cls.__name__)
cls._id = None
cls._memberclass = type(f'{cls._name}Member', (EnumMember, cls), {})

# upgrade attributes to member instances
for k, v in cls.__dict__.items():
if k.startswith('_'):
continue
setattr(cls, k, Member(cls._name, k, v))
setattr(cls, k, cls._memberclass(cls._name, k, v))

# register for lookup by name
_enums_lookup[cls._name] = cls

@staticmethod
def _update_enum(enums, data, convert):
name = data['name']
members = [Member(name, k, convert(v)) for k, v in data['members']]

enum = _enums_lookup.get(name)
cls = EnumMember if enum is None else enum._memberclass

members = [cls(name, k, convert(v)) for k, v in data['members']]

if enum is not None:
enum._id = data['enum_id']
for member in members:
Expand All @@ -36,10 +61,12 @@ def _update_enum(enums, data, convert):
def _upd_enum_add(enums, data, convert):
members = enums[data['enum_id']]
name = members[0]._enum_name
member = Member(name, data['name'], convert(data['value']))
enum = _enums_lookup.get(name)
cls = EnumMember if enum is None else enum._memberclass

member = cls(name, data['name'], convert(data['value']))
members.append(member)

enum = _enums_lookup.get(name)
if enum is not None:
setattr(enum, member.name, member)

Expand Down Expand Up @@ -93,7 +120,9 @@ async def _new_type(cls, client, collection):
if cls._visited > 0:
return
cls._visited += 1
members = (m for m in cls.__dict__.values() if isinstance(m, Member))
members = (
m for m in cls.__dict__.values()
if isinstance(m, EnumMember))
query = f'''
set_enum('{cls._name}', {{
{', '.join(f'{m.name}: {m.value!r}' for m in members)}
Expand Down
25 changes: 25 additions & 0 deletions thingsdb/model/enummember.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
class EnumMember:

@property
def name(self):
return self._name

@property
def value(self):
return self._value

def __new__(cls, enum_name, name, value):
instance = object.__new__(cls)
instance._name = name
instance._value = value
instance._enum_name = enum_name
return instance

def __repr__(self):
return f'{self._enum_name}{{{self._name}}}'

def __eq__(self, other):
return self is other or self._value == other

def __ne__(self, other):
return not self.__eq__(other)
16 changes: 0 additions & 16 deletions thingsdb/model/member.py

This file was deleted.

2 changes: 1 addition & 1 deletion thingsdb/util/convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ def convert(arg):
if isinstance(arg, (list, tuple)):
return [convert(v) for v in arg]

return arg
return getattr(arg, '_value', arg)
2 changes: 0 additions & 2 deletions thingsdb/util/fmt.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ def _wrap(value, blobs):
name = f'blob{idx}'
blobs[name] = value
return name
if isinstance(value, Member):
return value.name()
if isinstance(value, dict):
thing_id = value.get('#')
if thing_id is None:
Expand Down
2 changes: 1 addition & 1 deletion thingsdb/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '0.6.5'
__version__ = '0.6.6'