Skip to content

Commit 53ecb83

Browse files
author
Jonathon Belotti
committed
finish implementation (not yet tested for bugs)
1 parent 0b82d17 commit 53ecb83

File tree

2 files changed

+30
-22
lines changed

2 files changed

+30
-22
lines changed

src/extract_wheels.py

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import subprocess
55
import sys
66

7+
8+
from . import namespace_pkgs
79
from .wheel import Wheel
810

911
BUILD_TEMPLATE = """\
@@ -38,25 +40,31 @@ def sanitise_name(name):
3840

3941

4042
def _setup_namespace_pkg_compatibility(extracted_whl_directory):
41-
# need dist-info directory for pkg_resources to be able to find the packages
42-
dist_info = glob.glob(os.path.join(extracted_whl_directory, "*.dist-info"))[0]
43-
# fix namespace packages by adding proper __init__.py files
44-
namespace_packages = os.path.join(dist_info, "namespace_packages.txt")
45-
if os.path.exists(namespace_packages):
46-
with open(namespace_packages) as nspkg:
47-
for line in nspkg.readlines():
48-
namespace = line.strip().replace(".", os.sep)
49-
if namespace:
50-
nspkg_init = os.path.join(extracted_whl_directory, namespace, "__init__.py")
51-
with open(nspkg_init, "w") as nspkg:
52-
nspkg.writelines([
53-
"# __path__ manipulation added by rules_python_external to support namespace pkgs.\n"
54-
"__path__ = __import__('pkgutil').extend_path(__path__, __name__)\n"
55-
])
56-
57-
58-
59-
# return pkginfo.Wheel(dist_info)
43+
"""
44+
Namespace packages can be created in one of three ways. The are detailed here:
45+
https://packaging.python.org/guides/packaging-namespace-packages/#creating-a-namespace-package
46+
47+
'pkgutil-style namespace packages' (2) works in Bazel, but 'native namespace packages' (1) and
48+
'pkg_resources-style namespace packages' (3) do not.
49+
50+
We ensure compatibility with Bazel of methods 1 and 3 by converting them into method 2.
51+
"""
52+
namespace_pkg_dirs = namespace_pkgs.pkg_resources_style_namespace_packages(
53+
extracted_whl_directory
54+
)
55+
if (
56+
not namespace_pkg_dirs and
57+
(sys.version_info.major, sys.version_info.minor) >= (3, 3)
58+
):
59+
namespace_pkg_dirs = namespace_pkgs.implicit_namespace_packages(
60+
extracted_whl_directory,
61+
ignored_dirnames=[
62+
f"{extracted_whl_directory}/bin",
63+
]
64+
)
65+
66+
for ns_pkg_dir in namespace_pkg_dirs:
67+
namespace_pkgs.add_pkgutil_style_namespace_pkg_init(ns_pkg_dir)
6068

6169

6270
def extract_wheel(whl, directory, extras):

src/namespace_pkgs.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,11 @@ def implicit_namespace_packages(directory, ignored_dirnames=None) -> Set[str]:
5959
return namespace_pkg_dirs
6060

6161

62-
def add_pkgutil_style_namespace_pkg_init(dirpath) -> None:
62+
def add_pkgutil_style_namespace_pkg_init(dir_path: str) -> None:
6363
"""TODO"""
64-
ns_pkg_init_filepath = os.path.join(dirpath, "__init__.py")
64+
ns_pkg_init_filepath = os.path.join(dir_path, "__init__.py")
6565

6666
if os.path.isfile(ns_pkg_init_filepath):
67-
raise ValueError(f"{dirpath} already contains an __init__.py file.")
67+
raise ValueError(f"{dir_path} already contains an __init__.py file.")
6868
with open(ns_pkg_init_filepath, "w") as ns_pkg_init_f:
6969
ns_pkg_init_f.write(PKGUTIL_STYLE_NS_PKG_INIT_CONTENTS)

0 commit comments

Comments
 (0)