|
19 | 19 | import re
|
20 | 20 | import zipfile
|
21 | 21 |
|
| 22 | +# Putting this a package's __init__.py causes it to set __path__ so that it is |
| 23 | +# possible to import modules and subpackages from other directories on sys.path. |
| 24 | +INITPY_CONTENTS = ''' |
| 25 | +try: |
| 26 | + import pkg_resources |
| 27 | + pkg_resources.declare_namespace(__name__) |
| 28 | +except ImportError: |
| 29 | + import pkgutil |
| 30 | + __path__ = pkgutil.extend_path(__path__, __name__) |
| 31 | +''' |
| 32 | + |
22 | 33 |
|
23 | 34 | class Wheel(object):
|
24 | 35 |
|
@@ -85,6 +96,35 @@ def dependencies(self):
|
85 | 96 | def expand(self, directory):
|
86 | 97 | with zipfile.ZipFile(self.path(), 'r') as whl:
|
87 | 98 | whl.extractall(directory)
|
| 99 | + names = set(whl.namelist()) |
| 100 | + |
| 101 | + # Workaround for https://github.com/bazelbuild/rules_python/issues/14 |
| 102 | + for initpy in self.get_init_paths(names): |
| 103 | + with open(os.path.join(directory, initpy), 'w') as f: |
| 104 | + f.write(INITPY_CONTENTS) |
| 105 | + |
| 106 | + def get_init_paths(self, names): |
| 107 | + # Overwrite __init__.py in these directories. |
| 108 | + # (required as googleapis-common-protos has an empty __init__.py, which |
| 109 | + # blocks google.api.core from google-cloud-core) |
| 110 | + NAMESPACES = ["google/api"] |
| 111 | + |
| 112 | + # Find package directories without __init__.py, or where the __init__.py |
| 113 | + # must be overwritten to create a working namespace. This is based on |
| 114 | + # Bazel's PythonUtils.getInitPyFiles(). |
| 115 | + init_paths = set() |
| 116 | + for n in names: |
| 117 | + if os.path.splitext(n)[1] not in ['.so', '.py', '.pyc']: |
| 118 | + continue |
| 119 | + while os.path.sep in n: |
| 120 | + n = os.path.dirname(n) |
| 121 | + initpy = os.path.join(n, '__init__.py') |
| 122 | + initpyc = os.path.join(n, '__init__.pyc') |
| 123 | + if (initpy in names or initpyc in names) and n not in NAMESPACES: |
| 124 | + continue |
| 125 | + init_paths.add(initpy) |
| 126 | + |
| 127 | + return init_paths |
88 | 128 |
|
89 | 129 |
|
90 | 130 | parser = argparse.ArgumentParser(
|
|
0 commit comments