aromanovich / jsl

A Python DSL for describing JSON schemas
http://jsl.readthedocs.org/
Other
218 stars 21 forks source link

In DocumentMeta remove collected fields from attrs #29

Open ivan-klass opened 7 years ago

ivan-klass commented 7 years ago

JSL looks to me as very nice and powerful library. I'm trying to mix-in jsl.Document into another class using multiple inheritance (so it becomes something similar to Django model). I know it's not a good way, but it's so convenient in IDE to use type-hints, like in example below:


from typing import Optional, Text

class TestModel(JsonModel, jsl.Document):
    foo = jsl.StringField(required=True)  # type: Text
    bar = jsl.StringField(required=False) # type: Optional[Text]

tm = TestModel(foo='abcd')
tm.foo += 'efgh'
tm.bar  # want it to be not accessible

So, everything is fine, but I have to go deep in magic methods because class instances has field attributes. As I understand, all of them are already put into _fields and _backend.properties. So why not remove them as direct attributes? In DocumentMeta.__new__, before calling type.__new

        for f in fields:
            attrs.pop(f)

Thanks! I really appreciate your amazing work!

ivan-klass commented 7 years ago

I've solved this like in following:

class RemoveFieldAttrsMeta(jsl.document.DocumentMeta):
    """
    Removes field descriptions from instances
    """
    @classmethod
    def collect_fields(mcs, bases, attrs):
        fields = super(RemoveFieldAttrsMeta, mcs).collect_fields(bases, attrs)
        for f in fields:
            attrs.pop(f, None)   # if field is from base, it's not in attrs
        return fields

class TestModel(with_metaclass(RemoveFieldAttrsMeta, jsl.Document, JsonModel)):
slavaatsig commented 7 years ago

@klass-ivan why not generate attrs instances from JSL document? I mean like having get_attrs method next to get_schema and generate a corresponding attrs instance dynamically like shown in documentation

I’ve opened a feature request for that.