|
16 | 16 |
|
17 | 17 | import datetime |
18 | 18 | import gc |
| 19 | +import importlib |
| 20 | +# from importlib import abc |
| 21 | +import sys |
19 | 22 |
|
20 | 23 | from google.protobuf import duration_pb2 as duration_pb |
21 | 24 | from google.protobuf import timestamp_pb2 as timestamp_pb |
@@ -730,8 +733,10 @@ def testActivationAndOtherArgs(self): |
730 | 733 | self.env.Activation(data={"var_str": "World!"}), |
731 | 734 | data={"var_str": "World!"}, |
732 | 735 | ) |
733 | | - self.assertIn("Cannot provide both activation and any other arguments", |
734 | | - str(e.exception)) |
| 736 | + self.assertIn( |
| 737 | + "Cannot provide both activation and any other arguments", |
| 738 | + str(e.exception), |
| 739 | + ) |
735 | 740 |
|
736 | 741 | def testCompilationErrorHandling(self): |
737 | 742 | # Check parser error. |
@@ -799,5 +804,103 @@ def FindFileContainingSymbol(self, symbol_name: str): # pylint: disable=invalid |
799 | 804 | raise LookupError("Could not find file containing symbol: %s" % symbol_name) |
800 | 805 |
|
801 | 806 |
|
| 807 | +class PyCelWithoutProtoSupportTest(absltest.TestCase): |
| 808 | + """Test that the environment can be created without proto support.""" |
| 809 | + |
| 810 | + def setUp(self): |
| 811 | + super().setUp() |
| 812 | + self.msg = test_all_types_pb.TestAllTypes() |
| 813 | + self.msg.single_string = "Hey" |
| 814 | + |
| 815 | + # "Unimport" descriptor_pool if it is already imported. |
| 816 | + if "google.protobuf.descriptor_pool" in sys.modules: |
| 817 | + del sys.modules["google.protobuf.descriptor_pool"] |
| 818 | + |
| 819 | + # Make it impossible to import descriptor_pool. |
| 820 | + class UnluckyFinder(importlib.abc.MetaPathFinder): |
| 821 | + |
| 822 | + def find_spec(self, fullname, unused_path, unused_target=None): |
| 823 | + if fullname == "google.protobuf.descriptor_pool": |
| 824 | + raise ImportError("Not found") |
| 825 | + return None |
| 826 | + |
| 827 | + sys.meta_path.insert(0, UnluckyFinder()) |
| 828 | + |
| 829 | + def tearDown(self): |
| 830 | + # Remove the unlucky finder from the meta path. |
| 831 | + sys.meta_path.pop(0) |
| 832 | + super().tearDown() |
| 833 | + |
| 834 | + def testEvalWithNonProtoTypes(self): |
| 835 | + cel_env = cel.NewEnv( |
| 836 | + descriptor_pool=None, |
| 837 | + variables={ |
| 838 | + "var_str": cel.Type.STRING, |
| 839 | + "var_map": cel.Type.Map(cel.Type.STRING, cel.Type.STRING), |
| 840 | + "var_list": cel.Type.List(cel.Type.STRING), |
| 841 | + }, |
| 842 | + ) |
| 843 | + data = { |
| 844 | + "var_str": "foo", |
| 845 | + "var_map": {"key": "bar"}, |
| 846 | + "var_list": ["foo", "bar", "baz"], |
| 847 | + } |
| 848 | + res = cel_env.compile("var_str").eval(data=data) |
| 849 | + self.assertEqual(res.value(), "foo") |
| 850 | + |
| 851 | + res = cel_env.compile("var_map['key']").eval(data=data) |
| 852 | + self.assertEqual(res.value(), "bar") |
| 853 | + |
| 854 | + res = cel_env.compile("var_list[2]").eval(data=data) |
| 855 | + self.assertEqual(res.value(), "baz") |
| 856 | + |
| 857 | + def testErrorOnProtoAccess(self): |
| 858 | + cel_env = cel.NewEnv( |
| 859 | + descriptor_pool=None, |
| 860 | + variables={ |
| 861 | + "var_proto": cel.Type.DYN, |
| 862 | + }, |
| 863 | + ) |
| 864 | + res = cel_env.compile("var_proto.single_string").eval( |
| 865 | + data={"var_proto": self.msg} |
| 866 | + ) |
| 867 | + self.assertEqual(res.type(), cel.Type.ERROR) |
| 868 | + self.assertIn( |
| 869 | + "Descriptor not found for message type" |
| 870 | + " 'cel.expr.conformance.proto2.TestAllTypes'", |
| 871 | + str(res.value()), |
| 872 | + ) |
| 873 | + |
| 874 | + with self.assertRaises(Exception) as e: |
| 875 | + cel_env.compile( |
| 876 | + "cel.expr.conformance.proto2.TestAllTypes{single_string: 'hello'}" |
| 877 | + ).eval() |
| 878 | + self.assertIn( |
| 879 | + "undeclared reference to 'cel.expr.conformance.proto2.TestAllTypes'", |
| 880 | + str(e.exception), |
| 881 | + ) |
| 882 | + |
| 883 | + def testErrorOnProtoCreation(self): |
| 884 | + cel_env = cel.NewEnv( |
| 885 | + descriptor_pool=None, |
| 886 | + variables={ |
| 887 | + "var_proto": cel.Type.DYN, |
| 888 | + }, |
| 889 | + ) |
| 890 | + # Disable type checking to allow the compilation to succeed. |
| 891 | + expr = cel_env.compile( |
| 892 | + "cel.expr.conformance.proto2.TestAllTypes{single_string: 'hello'}", |
| 893 | + disable_check=True, |
| 894 | + ) |
| 895 | + |
| 896 | + with self.assertRaises(Exception) as e: |
| 897 | + expr.eval() |
| 898 | + self.assertIn( |
| 899 | + "Invalid struct creation: missing type info for" |
| 900 | + " 'cel.expr.conformance.proto2.TestAllTypes'", |
| 901 | + str(e.exception), |
| 902 | + ) |
| 903 | + |
| 904 | + |
802 | 905 | if __name__ == "__main__": |
803 | 906 | absltest.main() |
0 commit comments