Switch from pkgutil to importlib.resources. For loading resources, use `importlib.resources.files()` instead of `pkgutil.get_data()`. This works across project boundaries with Bazel 7, as well as through the `embossc` driver. Also packaged resource loading into a utility function, so that further changes can be more easily accomodated.
diff --git a/compiler/back_end/cpp/BUILD b/compiler/back_end/cpp/BUILD index 3d31ec2..427b724 100644 --- a/compiler/back_end/cpp/BUILD +++ b/compiler/back_end/cpp/BUILD
@@ -53,6 +53,7 @@ "//compiler/util:ir_pb2", "//compiler/util:ir_util", "//compiler/util:name_conversion", + "//compiler/util:resources", ], )
diff --git a/compiler/back_end/cpp/header_generator.py b/compiler/back_end/cpp/header_generator.py index 922d80b..a761bde 100644 --- a/compiler/back_end/cpp/header_generator.py +++ b/compiler/back_end/cpp/header_generator.py
@@ -29,11 +29,11 @@ from compiler.util import ir_pb2 from compiler.util import ir_util from compiler.util import name_conversion +from compiler.util import resources from compiler.util import traverse_ir -_TEMPLATES = code_template.parse_templates(pkgutil.get_data( - "compiler.back_end.cpp", - "generated_code_templates").decode(encoding="UTF-8")) +_TEMPLATES = code_template.parse_templates(resources.load( + "compiler.back_end.cpp", "generated_code_templates")) _CPP_RESERVED_WORDS = set(( # C keywords. A few of these are not (yet) C++ keywords, but some compilers
diff --git a/compiler/front_end/BUILD b/compiler/front_end/BUILD index 024524d..776efed 100644 --- a/compiler/front_end/BUILD +++ b/compiler/front_end/BUILD
@@ -98,6 +98,7 @@ ":lr1", ":module_ir", ":tokenizer", + "//compiler/util:resources", "//compiler/util:simple_memoizer", ], ) @@ -137,6 +138,7 @@ "//compiler/util:ir_pb2", "//compiler/util:error", "//compiler/util:parser_types", + "//compiler/util:resources", ], ) @@ -322,6 +324,7 @@ "//compiler/util:ir_pb2", "//compiler/util:error", "//compiler/util:ir_util", + "//compiler/util:resources", "//compiler/util:traverse_ir", ], )
diff --git a/compiler/front_end/constraints.py b/compiler/front_end/constraints.py index 6beaf31..5f67d7c 100644 --- a/compiler/front_end/constraints.py +++ b/compiler/front_end/constraints.py
@@ -14,12 +14,11 @@ """Routines to check miscellaneous constraints on the IR.""" -import pkgutil - from compiler.front_end import attributes from compiler.util import error from compiler.util import ir_pb2 from compiler.util import ir_util +from compiler.util import resources from compiler.util import traverse_ir @@ -394,9 +393,8 @@ global _RESERVED_WORDS _RESERVED_WORDS = {} language = None - for line in pkgutil.get_data( - "compiler.front_end", - "reserved_words").decode(encoding="UTF-8").splitlines(): + for line in resources.load( + "compiler.front_end", "reserved_words").splitlines(): stripped_line = line.partition("#")[0].strip() if not stripped_line: continue
diff --git a/compiler/front_end/glue.py b/compiler/front_end/glue.py index c19385d..0dceaf9 100644 --- a/compiler/front_end/glue.py +++ b/compiler/front_end/glue.py
@@ -19,7 +19,6 @@ """ import collections -import pkgutil from compiler.front_end import attribute_checker from compiler.front_end import constraints @@ -36,6 +35,7 @@ from compiler.util import error from compiler.util import ir_pb2 from compiler.util import parser_types +from compiler.util import resources _IrDebugInfo = collections.namedtuple("IrDebugInfo", ["ir", "debug_info", "errors"]) @@ -202,9 +202,7 @@ def get_prelude(): """Returns the module IR and debug info of the Emboss Prelude.""" return parse_module_text( - pkgutil.get_data("compiler.front_end", - "prelude.emb").decode(encoding="UTF-8"), - "") + resources.load("compiler.front_end", "prelude.emb"), "") def parse_emboss_file(file_name, file_reader, stop_before_step=None):
diff --git a/compiler/front_end/parser.py b/compiler/front_end/parser.py index 600b644..6ece324 100644 --- a/compiler/front_end/parser.py +++ b/compiler/front_end/parser.py
@@ -14,11 +14,10 @@ """Routines to generate a shift-reduce parser from the module_ir module.""" -import pkgutil - from compiler.front_end import lr1 from compiler.front_end import module_ir from compiler.front_end import tokenizer +from compiler.util import resources from compiler.util import simple_memoizer @@ -104,9 +103,8 @@ @simple_memoizer.memoize def _load_module_parser(): - path = "compiler.front_end" error_examples = parse_error_examples( - pkgutil.get_data(path, "error_examples").decode("utf-8")) + resources.load("compiler.front_end", "error_examples")) return generate_parser(module_ir.START_SYMBOL, module_ir.PRODUCTIONS, error_examples)
diff --git a/compiler/util/BUILD b/compiler/util/BUILD index 4c34cc1..d0e3d3f 100644 --- a/compiler/util/BUILD +++ b/compiler/util/BUILD
@@ -167,3 +167,9 @@ ":name_conversion", ], ) + +py_library( + name = "resources", + srcs = ["resources.py"], + deps = [], +)
diff --git a/compiler/util/resources.py b/compiler/util/resources.py new file mode 100644 index 0000000..606b1d9 --- /dev/null +++ b/compiler/util/resources.py
@@ -0,0 +1,23 @@ +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Routines to load resource files from within the compiler.""" + +import importlib.resources + +def load(package, file, encoding="utf-8"): + """Returns the contents of `file` from the Python package loader.""" + with importlib.resources.files( + package).joinpath(file).open("r", encoding=encoding) as f: + return f.read()