def DataClass(name, columns, constraint=None): """ Use the DataClass to define a class, but with some extra features: 1. restrict the datatype of property 2. restrict if `required`, or if `nulls` are allowed 3. generic constraints on object properties It is expected that this class become a real class (or be removed) in the long term because it is expensive to use and should only be good for verifying program correctness, not user input. :param name: Name of the class we are creating :param columns: Each columns[i] has properties { "name", - (required) name of the property "required", - False if it must be defined (even if None) "nulls", - True if property can be None, or missing "default", - A default value, if none is provided "type" - a Python datatype } :param constraint: a JSON query Expression for extra constraints (return true if all constraints are met) :return: The class that has been created """ columns = wrap([{ "name": c, "required": True, "nulls": False, "type": object } if is_text(c) else c for c in columns]) slots = columns.name required = wrap( filter(lambda c: c.required and not c.nulls and not c.default, columns)).name nulls = wrap(filter(lambda c: c.nulls, columns)).name defaults = {c.name: coalesce(c.default, None) for c in columns} types = {c.name: coalesce(c.jx_type, object) for c in columns} code = expand_template( """ from __future__ import unicode_literals from mo_future import is_text, is_binary from collections import Mapping meta = None types_ = {{types}} defaults_ = {{defaults}} class {{class_name}}(Mapping): __slots__ = {{slots}} def _constraint(row, rownum, rows): try: return {{constraint_expr}} except Exception as e: Log.error( "constraint\\n{" + "{code}}\\nnot satisfied {" + "{expect}}\\n{" + "{value|indent}}", code={{constraint_expr|quote}}, expect={{constraint}}, value=row, cause=e ) def __init__(self, **kwargs): if not kwargs: return for s in {{slots}}: object.__setattr__(self, s, kwargs.get(s, {{defaults}}.get(s, None))) missed = {{required}}-set(kwargs.keys()) if missed: Log.error("Expecting properties {"+"{missed}}", missed=missed) illegal = set(kwargs.keys())-set({{slots}}) if illegal: Log.error("{"+"{names}} are not a valid properties", names=illegal) self._constraint(0, [self]) def __getitem__(self, item): return getattr(self, item) def __setitem__(self, item, value): setattr(self, item, value) return self def __setattr__(self, item, value): if item not in {{slots}}: Log.error("{"+"{item|quote}} not valid attribute", item=item) object.__setattr__(self, item, value) self._constraint(0, [self]) def __getattr__(self, item): Log.error("{"+"{item|quote}} not valid attribute", item=item) def __hash__(self): return object.__hash__(self) def __eq__(self, other): if isinstance(other, {{class_name}}) and dict(self)==dict(other) and self is not other: Log.error("expecting to be same object") return self is other def __dict__(self): return {k: getattr(self, k) for k in {{slots}}} def items(self): return ((k, getattr(self, k)) for k in {{slots}}) def __copy__(self): _set = object.__setattr__ output = object.__new__({{class_name}}) {{assign}} return output def __iter__(self): return {{slots}}.__iter__() def __len__(self): return {{len_slots}} def __str__(self): return str({{dict}}) """, { "class_name": name, "slots": "(" + (", ".join(quote(s) for s in slots)) + ")", "required": "{" + (", ".join(quote(s) for s in required)) + "}", "nulls": "{" + (", ".join(quote(s) for s in nulls)) + "}", "defaults": Literal(defaults).to_python(), "len_slots": len(slots), "dict": "{" + (", ".join(quote(s) + ": self." + s for s in slots)) + "}", "assign": "; ".join("_set(output, " + quote(s) + ", self." + s + ")" for s in slots), "types": "{" + (",".join(quote(k) + ": " + v.__name__ for k, v in types.items())) + "}", "constraint_expr": Python[jx_expression(not ENABLE_CONSTRAINTS or constraint)].to_python(), "constraint": value2json(constraint), }, ) output = _exec(code, name) register_data(output) return output
return text_type(obj) def __str__(self): obj = _get(self, OBJ) return str(obj) def __len__(self): obj = _get(self, OBJ) return len(obj) def __call__(self, *args, **kwargs): obj = _get(self, OBJ) return obj(*args, **kwargs) register_data(DataObject) def datawrap(v): type_ = _get(v, CLASS) if type_ is dict: m = Data() _set(m, SLOT, v) # INJECT m.__dict__=v SO THERE IS NO COPY return m elif type_ is list: return FlatList(v) elif type_ in (Data, DataObject, none_type, FlatList, text_type, binary_type, int, float, Decimal, datetime, date, NullType, none_type): return v
def DataClass(name, columns, constraint=None): """ Use the DataClass to define a class, but with some extra features: 1. restrict the datatype of property 2. restrict if `required`, or if `nulls` are allowed 3. generic constraints on object properties It is expected that this class become a real class (or be removed) in the long term because it is expensive to use and should only be good for verifying program correctness, not user input. :param name: Name of the class we are creating :param columns: Each columns[i] has properties { "name", - (required) name of the property "required", - False if it must be defined (even if None) "nulls", - True if property can be None, or missing "default", - A default value, if none is provided "type" - a Python datatype } :param constraint: a JSON query Expression for extra constraints (return true if all constraints are met) :return: The class that has been created """ columns = wrap( [ {"name": c, "required": True, "nulls": False, "type": object} if is_text(c) else c for c in columns ] ) slots = columns.name required = wrap( filter(lambda c: c.required and not c.nulls and not c.default, columns) ).name nulls = wrap(filter(lambda c: c.nulls, columns)).name defaults = {c.name: coalesce(c.default, None) for c in columns} types = {c.name: coalesce(c.jx_type, object) for c in columns} code = expand_template( """ from __future__ import unicode_literals from mo_future import is_text, is_binary from collections import Mapping meta = None types_ = {{types}} defaults_ = {{defaults}} class {{class_name}}(Mapping): __slots__ = {{slots}} def _constraint(row, rownum, rows): try: return {{constraint_expr}} except Exception as e: return False def __init__(self, **kwargs): if not kwargs: return for s in {{slots}}: object.__setattr__(self, s, kwargs.get(s, {{defaults}}.get(s, None))) missed = {{required}}-set(kwargs.keys()) if missed: Log.error("Expecting properties {"+"{missed}}", missed=missed) illegal = set(kwargs.keys())-set({{slots}}) if illegal: Log.error("{"+"{names}} are not a valid properties", names=illegal) if not self._constraint(0, [self]): Log.error("constraint not satisfied {"+"{expect}}\\n{"+"{value|indent}}", expect={{constraint}}, value=self) def __getitem__(self, item): return getattr(self, item) def __setitem__(self, item, value): setattr(self, item, value) return self def __setattr__(self, item, value): if item not in {{slots}}: Log.error("{"+"{item|quote}} not valid attribute", item=item) object.__setattr__(self, item, value) if not self._constraint(0, [self]): Log.error("constraint not satisfied {"+"{expect}}\\n{"+"{value|indent}}", expect={{constraint}}, value=self) def __getattr__(self, item): Log.error("{"+"{item|quote}} not valid attribute", item=item) def __hash__(self): return object.__hash__(self) def __eq__(self, other): if isinstance(other, {{class_name}}) and dict(self)==dict(other) and self is not other: Log.error("expecting to be same object") return self is other def __dict__(self): return {k: getattr(self, k) for k in {{slots}}} def items(self): return ((k, getattr(self, k)) for k in {{slots}}) def __copy__(self): _set = object.__setattr__ output = object.__new__({{class_name}}) {{assign}} return output def __iter__(self): return {{slots}}.__iter__() def __len__(self): return {{len_slots}} def __str__(self): return str({{dict}}) """, { "class_name": name, "slots": "(" + (", ".join(quote(s) for s in slots)) + ")", "required": "{" + (", ".join(quote(s) for s in required)) + "}", "nulls": "{" + (", ".join(quote(s) for s in nulls)) + "}", "defaults": Literal(defaults).to_python(), "len_slots": len(slots), "dict": "{" + (", ".join(quote(s) + ": self." + s for s in slots)) + "}", "assign": "; ".join( "_set(output, " + quote(s) + ", self." + s + ")" for s in slots ), "types": "{" + (",".join(quote(k) + ": " + v.__name__ for k, v in types.items())) + "}", "constraint_expr": Python[jx_expression(constraint)].to_python(), "constraint": value2json(constraint), }, ) output = _exec(code, name) register_data(output) return output
# encoding: utf-8 # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. # # Contact: Kyle Lahnakoski ([email protected]) # from __future__ import absolute_import, division, unicode_literals from mo_dots import Data from mo_dots.datas import register_data class Push(Data): pass register_data(Push)
class Revision(Data): def __hash__(self): return hash((self.branch.name.lower(), self.changeset.id[:12])) def __eq__(self, other): if other == None: return False return (self.branch.name.lower(), self.changeset.id[:12]) == ( other.branch.name.lower(), other.changeset.id[:12], ) register_data(Revision, ) revision_schema = { "settings": { "index.number_of_replicas": 1, "index.number_of_shards": 6, "analysis": { "tokenizer": { "left250": { "type": "pattern", "pattern": "^.{1,250}" } }, "analyzer": { "description_limit": { "type": "custom",
# encoding: utf-8 # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. # # Contact: Kyle Lahnakoski ([email protected]) # from __future__ import absolute_import, division, unicode_literals from mo_dots import Data from mo_dots.datas import register_data class Changeset(Data): def __hash__(self): return hash(self.id) def __eq__(self, other): if other == None: return False return self.id == other.id register_data(Changeset)
return text_type(obj) def __str__(self): obj = _get(self, OBJ) return str(obj) def __len__(self): obj = _get(self, OBJ) return len(obj) def __call__(self, *args, **kwargs): obj = _get(self, OBJ) return obj(*args, **kwargs) register_data(DataObject) def datawrap(v): type_ = _get(v, CLASS) if type_ is dict: m = Data() _set(m, SLOT, v) # INJECT m.__dict__=v SO THERE IS NO COPY return m elif type_ is list: return FlatList(v) elif type_ in (Data, DataObject, none_type, FlatList, text_type, binary_type, int, float, Decimal, datetime, date, NullType, none_type): return v elif type_ in generator_types: return (wrap(vv) for vv in v)