def mock_cel_environment_bool(monkeypatch): mock_runner = Mock(evaluate=Mock(return_value=celtypes.BoolType(False))) mock_env = Mock(compile=Mock(return_value=sentinel.AST), program=Mock(return_value=mock_runner)) mock_env_class = Mock(return_value=mock_env) monkeypatch.setattr(celpy.__main__, "Environment", mock_env_class) return mock_env_class
def test_json_to_cel(): """GIVEN JSON doc; WHEN json_to_cell(); THEN expected conversions applied.""" doc = [ { "bool": True }, { "numbers": [2.71828, 42] }, { "null": None }, { "string": 'embedded "quote"' }, ] actual = celpy.json_to_cel(doc) expected = celtypes.ListType([ celtypes.MapType( {celtypes.StringType("bool"): celtypes.BoolType(True)}), celtypes.MapType({ celtypes.StringType("numbers"): celtypes.ListType( [celtypes.DoubleType(2.71828), celtypes.IntType(42)]) }), celtypes.MapType({celtypes.StringType("null"): None}), celtypes.MapType({ celtypes.StringType("string"): celtypes.StringType('embedded "quote"') }), ]) assert actual == expected
def json_to_cel(document: JSON) -> celtypes.Value: """Convert parsed JSON object from Python to CEL to the extent possible. It's difficult to distinguish strings which should be timestamps or durations. :: >>> from pprint import pprint >>> from celpy.adapter import json_to_cel >>> doc = json.loads('["str", 42, 3.14, null, true, {"hello": "world"}]') >>> cel = json_to_cel(doc) >>> pprint(cel) ListType([StringType('str'), IntType(42), DoubleType(3.14), None, BoolType(True), \ MapType({StringType('hello'): StringType('world')})]) """ if isinstance(document, bool): return celtypes.BoolType(document) elif isinstance(document, float): return celtypes.DoubleType(document) elif isinstance(document, int): return celtypes.IntType(document) elif isinstance(document, str): return celtypes.StringType(document) elif document is None: return None elif isinstance(document, List): return celtypes.ListType([json_to_cel(item) for item in document]) elif isinstance(document, Dict): return celtypes.MapType({ json_to_cel(key): json_to_cel(value) for key, value in document.items() }) else: raise ValueError( f"unexpected type {type(document)} in JSON structure {document!r}")
def intersect(left: celtypes.ListType, right: celtypes.ListType) -> celtypes.BoolType: """ Compute the intersection between two lists. It's true if the result is non-empty: there is an item in both lists. It's false if the result is empty: there is no common item between the lists. """ return celtypes.BoolType(bool(set(left) & set(right)))
def difference(left: celtypes.ListType, right: celtypes.ListType) -> celtypes.BoolType: """ Compute the difference between two lists. This is ordered set difference: left - right. It's true if the result is non-empty: there is an item in the left, not present in the right. It's false if the result is empty: the lists are the same. """ return celtypes.BoolType(bool(set(left) - set(right)))
def glob(text: celtypes.StringType, pattern: celtypes.StringType) -> celtypes.BoolType: """Compare a string with a pattern. While ``"*.py".glob(some_string)`` seems logical because the pattern the more persistent object, this seems to cause confusion. We use ``some_string.glob("*.py")`` to express a regex-like rule. This parallels the CEL `.matches()` method. We also support ``glob(some_string, "*.py")``. """ return celtypes.BoolType(fnmatch.fnmatch(text, pattern))
def test_encoder(): cel_obj = celtypes.MapType( { celtypes.StringType("bool"): celtypes.BoolType(True), celtypes.StringType("numbers"): celtypes.ListType([ celtypes.DoubleType(2.71828), celtypes.UintType(42) ]), celtypes.StringType("null"): None, celtypes.StringType("string"): celtypes.StringType('embedded "quote"'), celtypes.StringType("bytes"): celtypes.BytesType(bytes([0x62, 0x79, 0x74, 0x65, 0x73])), celtypes.StringType("timestamp"): celtypes.TimestampType('2009-02-13T23:31:30Z'), celtypes.StringType("duration"): celtypes.DurationType('42s'), } ) json_text = json.dumps(cel_obj, cls=celpy.CELJSONEncoder) assert ( json_text == '{"bool": true, "numbers": [2.71828, 42], "null": null, ' '"string": "embedded \\"quote\\"", "bytes": "Ynl0ZXM=", ' '"timestamp": "2009-02-13T23:31:30Z", "duration": "42s"}' )