chore: support bzlmod (#744)

diff --git a/.bazelrc b/.bazelrc
index 97ad7c3..a4bcccf 100644
--- a/.bazelrc
+++ b/.bazelrc
@@ -3,8 +3,8 @@
 # This lets us glob() up all the files inside the examples to make them inputs to tests
 # (Note, we cannot use `common --deleted_packages` because the bazel version command doesn't support it)
 # To update these lines, run tools/bazel_integration_test/update_deleted_packages.sh
-build --deleted_packages=examples/build_file_generation,examples/pip_install,examples/pip_parse,examples/pip_parse_vendored,examples/pip_repository_annotations,examples/py_import,examples/relative_requirements,tests/pip_repository_entry_points,tests/pip_deps
-query --deleted_packages=examples/build_file_generation,examples/pip_install,examples/pip_parse,examples/pip_parse_vendored,examples/pip_repository_annotations,examples/py_import,examples/relative_requirements,tests/pip_repository_entry_points,tests/pip_deps
+build --deleted_packages=examples/build_file_generation,examples/bzlmod,examples/pip_install,examples/pip_parse,examples/pip_parse_vendored,examples/pip_repository_annotations,examples/py_import,examples/relative_requirements,tests/pip_repository_entry_points,tests/pip_deps
+query --deleted_packages=examples/build_file_generation,examples/bzlmod,examples/pip_install,examples/pip_parse,examples/pip_parse_vendored,examples/pip_repository_annotations,examples/py_import,examples/relative_requirements,tests/pip_repository_entry_points,tests/pip_deps
 
 test --test_output=errors
 
diff --git a/BUILD b/BUILD
index d30cea0..ebdf74e 100644
--- a/BUILD
+++ b/BUILD
@@ -26,6 +26,7 @@
     name = "distribution",
     srcs = [
         "BUILD",
+        "MODULE.bazel",
         "WORKSPACE",
         "internal_deps.bzl",
         "internal_setup.bzl",
diff --git a/MODULE.bazel b/MODULE.bazel
new file mode 100644
index 0000000..ed619e4
--- /dev/null
+++ b/MODULE.bazel
@@ -0,0 +1,17 @@
+module(
+    name = "rules_python",
+    compatibility_level = 1,
+    version = "0.0.0",
+)
+
+pip_install = use_extension("@rules_python//python:extensions.bzl", "pip_install")
+
+use_repo(
+    pip_install,
+    "pypi__click",
+    "pypi__pip",
+    "pypi__pip_tools",
+    "pypi__pkginfo",
+    "pypi__setuptools",
+    "pypi__wheel",
+)
diff --git a/examples/BUILD b/examples/BUILD
index a1789f9..41dd875 100644
--- a/examples/BUILD
+++ b/examples/BUILD
@@ -42,3 +42,7 @@
     name = "relative_requirements_example",
     timeout = "long",
 )
+
+bazel_integration_test(
+    name = "bzlmod_example",
+)
diff --git a/examples/bzlmod/.bazelrc b/examples/bzlmod/.bazelrc
new file mode 100644
index 0000000..b3a24e8
--- /dev/null
+++ b/examples/bzlmod/.bazelrc
@@ -0,0 +1 @@
+common --experimental_enable_bzlmod
diff --git a/examples/bzlmod/.gitignore b/examples/bzlmod/.gitignore
new file mode 100644
index 0000000..ac51a05
--- /dev/null
+++ b/examples/bzlmod/.gitignore
@@ -0,0 +1 @@
+bazel-*
diff --git a/examples/bzlmod/BUILD.bazel b/examples/bzlmod/BUILD.bazel
new file mode 100644
index 0000000..3e0349b
--- /dev/null
+++ b/examples/bzlmod/BUILD.bazel
@@ -0,0 +1,20 @@
+load("@rules_python//python:defs.bzl", "py_binary", "py_library", "py_test")
+
+py_library(
+    name = "lib",
+    srcs = ["__init__.py"],
+)
+
+py_binary(
+    name = "bzlmod",
+    srcs = ["__main__.py"],
+    main = "__main__.py",
+    visibility = ["//:__subpackages__"],
+    deps = [":lib"],
+)
+
+py_test(
+    name = "test",
+    srcs = ["test.py"],
+    deps = [":lib"],
+)
diff --git a/examples/bzlmod/MODULE.bazel b/examples/bzlmod/MODULE.bazel
new file mode 100644
index 0000000..e3fc51a
--- /dev/null
+++ b/examples/bzlmod/MODULE.bazel
@@ -0,0 +1,12 @@
+module(
+    name = "example_bzlmod",
+    compatibility_level = 1,
+    version = "0.0.0",
+)
+
+bazel_dep(name = "rules_python", version = "0.0.0")
+
+local_path_override(
+    module_name = "rules_python",
+    path = "../..",
+)
diff --git a/examples/bzlmod/WORKSPACE b/examples/bzlmod/WORKSPACE
new file mode 100644
index 0000000..78cc252
--- /dev/null
+++ b/examples/bzlmod/WORKSPACE
@@ -0,0 +1,2 @@
+# Empty file indicating the root of a Bazel workspace.
+# Dependencies and setup are in MODULE.bazel.
diff --git a/examples/bzlmod/__init__.py b/examples/bzlmod/__init__.py
new file mode 100644
index 0000000..da9768f
--- /dev/null
+++ b/examples/bzlmod/__init__.py
@@ -0,0 +1,8 @@
+# TODO: bzlmod should grant access to pip_install dependencies as well
+# import requests
+
+
+def main(url):
+    # r = requests.get(url)
+    # return r.text
+    return url
diff --git a/examples/bzlmod/__main__.py b/examples/bzlmod/__main__.py
new file mode 100644
index 0000000..04bcfb0
--- /dev/null
+++ b/examples/bzlmod/__main__.py
@@ -0,0 +1,4 @@
+from __init__ import main
+
+if __name__ == "__main__":
+    print(main("https://example.com"))
diff --git a/examples/bzlmod/test.py b/examples/bzlmod/test.py
new file mode 100644
index 0000000..5d725a8
--- /dev/null
+++ b/examples/bzlmod/test.py
@@ -0,0 +1,12 @@
+import unittest
+
+from __init__ import main
+
+
+class ExampleTest(unittest.TestCase):
+    def test_main(self):
+        self.assertEquals("http://google.com", main("http://google.com"))
+
+
+if __name__ == "__main__":
+    unittest.main()
diff --git a/python/extensions.bzl b/python/extensions.bzl
new file mode 100644
index 0000000..9c1c87a
--- /dev/null
+++ b/python/extensions.bzl
@@ -0,0 +1,10 @@
+"Module extensions for use with bzlmod"
+
+load("@rules_python//python/pip_install:repositories.bzl", "pip_install_dependencies")
+
+def _pip_install_impl(_):
+    pip_install_dependencies()
+
+pip_install = module_extension(
+    implementation = _pip_install_impl,
+)