)]}'
{
  "commit": "01968255660aa99041c0c8989a0d68c01aa2978e",
  "tree": "83ada1811986287eb6884532ef990e63b6f67a59",
  "parents": [
    "2bc357787e8d6e76fd2f58e401cf3062bcf4f415"
  ],
  "author": {
    "name": "Richard Levasseur",
    "email": "rlevasseur@google.com",
    "time": "Sat Apr 05 09:37:21 2025 -0700"
  },
  "committer": {
    "name": "GitHub",
    "email": "noreply@github.com",
    "time": "Sat Apr 05 16:37:21 2025 +0000"
  },
  "message": "feat: allow populating binary\u0027s venv site-packages with symlinks (#2617)\n\nThis implements functionality to allow libraries to populate the\nsite-packages directory\nof downstream binaries. The basic implementation is:\n* Libraries provide tuples of `(runfile path, site packages path)` in\nthe\n  `PyInfo.site_packages_symlinks` field.\n* Binaries create symlinks (using declare_symlink) in their\nsite-packages directory\n  pointing to the runfiles paths libraries provide.\n\nThe design was chosen because of the following properties:\n* The site-packages directory is relocatable\n* Populating site packages is cheap ( `O(number 3p dependencies)` )\n* Dependencies are only created once in the runfiles, no matter\nhow many how many binaries there that use them. This minimizes disk\nusage,\n  file counts, inodes, etc.\n\nThe `site_packages_symlinks` field is a depset with topological\nordering. Using topological\nordering allows dependencies closer to the binary to have precedence,\nwhich gives some\nbasic control over what entries are used.\n\nAdditionally, the runfiles path to link to can be None/empty, in which\ncase, the\ndirectory in site-packages won\u0027t be created. This allows binaries to\nprevent creation\nof directories that might e.g. conflict.\n\nFor now, this functionality is disabled by default. The flag\n`--venvs_site_packages\u003dyes`\ncan be set to allow using it, which is automatically enable it for pypi\ngenerated targets.\n\nWhen enabled, it does basic detection of implicit namespace directories,\nwhich\nallows multiple distributions to \"install\" into the the same\nsite-packages directory.\n\nThough this functionality is primarily useful for dependencies from pypi\n(e.g. via\npip.parse), it is not yet activated for those targets, for two main\nreasons:\n1. The wheel extraction code creates pkgutil-style `__init__.py` shims\nduring the repo-phase.\nThe build phase can\u0027t distinguish these artifical rules_python generated\nshims from\nactual `__init__.py` files, which breaks the implicit namespace\ndetection logic.\n2. A flag guard is needed before changing the behavior. Even though how\n3p libraries are\nadded to sys.path is an implementation detail, the behavior has been\nthere for many\n   years, so an escape hatch should be added.\n\nWork towards https://github.com/bazelbuild/rules_python/issues/2156",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "ada5c5a0a7991e5de5947a53a0d481845365a58c",
      "old_mode": 33188,
      "old_path": ".bazelrc",
      "new_id": "4e6f2fa187947351d27c30bca4dc08a964adeaa1",
      "new_mode": 33188,
      "new_path": ".bazelrc"
    },
    {
      "type": "modify",
      "old_id": "69e9330f64ce30d929687a3c244b614bdb438d2f",
      "old_mode": 33188,
      "old_path": "CHANGELOG.md",
      "new_id": "818773e5892543bc70ae486d2858ea4d630cfd11",
      "new_mode": 33188,
      "new_path": "CHANGELOG.md"
    },
    {
      "type": "modify",
      "old_id": "e4e45af7f0c598a22e10729c8be2755e298b2bf9",
      "old_mode": 33188,
      "old_path": "MODULE.bazel",
      "new_id": "c649896344709dfe4dd390f500b97f89f690c18a",
      "new_mode": 33188,
      "new_path": "MODULE.bazel"
    },
    {
      "type": "modify",
      "old_id": "bebecd18b2f28633977c5acb393a025ed41d8949",
      "old_mode": 33188,
      "old_path": "docs/BUILD.bazel",
      "new_id": "29eac6e7143f0dcbe80391e630bc604741316ba6",
      "new_mode": 33188,
      "new_path": "docs/BUILD.bazel"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "45473a7cbf8f2b4479e55634fcd5fcac8037fceb",
      "new_mode": 33188,
      "new_path": "docs/_includes/experimental_api.md"
    },
    {
      "type": "modify",
      "old_id": "79c7d0c109858039d211fe9b0dab05f12eab8155",
      "old_mode": 33188,
      "old_path": "docs/api/rules_python/python/config_settings/index.md",
      "new_id": "340335d9b1ac5d721ca35c74cdee23fde6644290",
      "new_mode": 33188,
      "new_path": "docs/api/rules_python/python/config_settings/index.md"
    },
    {
      "type": "modify",
      "old_id": "cd33475f4332af0dba40ac7d0d51a7cfa41c7197",
      "old_mode": 33188,
      "old_path": "internal_dev_deps.bzl",
      "new_id": "87690be1ada5e04482407b3fa1e579890fe32224",
      "new_mode": 33188,
      "new_path": "internal_dev_deps.bzl"
    },
    {
      "type": "modify",
      "old_id": "c52e77266652fb83f956c164b65602d1e656530a",
      "old_mode": 33188,
      "old_path": "python/BUILD.bazel",
      "new_id": "a699c81cc445d0030ca2c90b212c3dae37cf38bb",
      "new_mode": 33188,
      "new_path": "python/BUILD.bazel"
    },
    {
      "type": "modify",
      "old_id": "796cf0c9c46afb951fd4932f6f410d9a42632c7f",
      "old_mode": 33188,
      "old_path": "python/config_settings/BUILD.bazel",
      "new_id": "45354e24d9ece44833673607258e9287cc428987",
      "new_mode": 33188,
      "new_path": "python/config_settings/BUILD.bazel"
    },
    {
      "type": "modify",
      "old_id": "a7098f471005ed0bcbf765ed9973edc8aed3ae2b",
      "old_mode": 33188,
      "old_path": "python/features.bzl",
      "new_id": "8edfb698fc63d6372320bb8b0fe58e161e2d293c",
      "new_mode": 33188,
      "new_path": "python/features.bzl"
    },
    {
      "type": "modify",
      "old_id": "b042b3db6a2804c330f9c6a6a981b68b2b5124f6",
      "old_mode": 33188,
      "old_path": "python/private/attributes.bzl",
      "new_id": "8543caba7bd3c74d04c5b2342c1394e182bf7b9d",
      "new_mode": 33188,
      "new_path": "python/private/attributes.bzl"
    },
    {
      "type": "modify",
      "old_id": "50aa3ed91aff1126ec7fdded5db0a110a5d269e2",
      "old_mode": 33188,
      "old_path": "python/private/builders.bzl",
      "new_id": "54d46c2af268af149f82f4e1548f7f623e2ff23b",
      "new_mode": 33188,
      "new_path": "python/private/builders.bzl"
    },
    {
      "type": "modify",
      "old_id": "48e2653ebbf97cd181f89f1aebfbb60169414986",
      "old_mode": 33188,
      "old_path": "python/private/common.bzl",
      "new_id": "072a1bb2969568ec7ea68e72499a7053db501176",
      "new_mode": 33188,
      "new_path": "python/private/common.bzl"
    },
    {
      "type": "modify",
      "old_id": "d71442e3b5cda264231abb63a140fbdca85563a3",
      "old_mode": 33188,
      "old_path": "python/private/enum.bzl",
      "new_id": "4d0fb1069965f8ff3b98aa8b9e1115252c053a36",
      "new_mode": 33188,
      "new_path": "python/private/enum.bzl"
    },
    {
      "type": "modify",
      "old_id": "1019faa8d6fe8a13c1fce3a7828898ab269d0712",
      "old_mode": 33188,
      "old_path": "python/private/flags.bzl",
      "new_id": "c53e4610ff6302386169dc0070b128de28bd5777",
      "new_mode": 33188,
      "new_path": "python/private/flags.bzl"
    },
    {
      "type": "modify",
      "old_id": "fed46ab22389d0fba91801a3c15d444f622f156e",
      "old_mode": 33188,
      "old_path": "python/private/py_executable.bzl",
      "new_id": "f33c2b6ca1e88d9d82ddf57b7121d8fa3500221a",
      "new_mode": 33188,
      "new_path": "python/private/py_executable.bzl"
    },
    {
      "type": "modify",
      "old_id": "ef654c303ee9dd6ec999b759f3a4567398549dea",
      "old_mode": 33188,
      "old_path": "python/private/py_info.bzl",
      "new_id": "4ecd02a43803f1e3f88be93f21f7cc54e7c80e05",
      "new_mode": 33188,
      "new_path": "python/private/py_info.bzl"
    },
    {
      "type": "modify",
      "old_id": "f6c7b12578c20e3d046b973cb45cb6b7ffed14e7",
      "old_mode": 33188,
      "old_path": "python/private/py_library.bzl",
      "new_id": "edd0db579f9e61dfc5fdaaa19acda3bf35d450e6",
      "new_mode": 33188,
      "new_path": "python/private/py_library.bzl"
    },
    {
      "type": "modify",
      "old_id": "c390da26132dd8c83151b2b03b2089e3ebff8e7a",
      "old_mode": 33188,
      "old_path": "python/private/pypi/whl_library_targets.bzl",
      "new_id": "95031e6181f8a66165d95a0902b9070091ec53bb",
      "new_mode": 33188,
      "new_path": "python/private/pypi/whl_library_targets.bzl"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
      "new_mode": 33188,
      "new_path": "tests/modules/other/BUILD.bazel"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "7cd3118b81f7f23cb26a472da7664845dd318afb",
      "new_mode": 33188,
      "new_path": "tests/modules/other/MODULE.bazel"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "457033aacfcad49e5017a3a94637a3c3804c2709",
      "new_mode": 33188,
      "new_path": "tests/modules/other/nspkg_delta/BUILD.bazel"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "bb7b160deb3702579ff14f2f54ba52fed671a4cc",
      "new_mode": 33188,
      "new_path": "tests/modules/other/nspkg_delta/site-packages/nspkg/subnspkg/delta/__init__.py"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "89038e80d2c6de9f1236c982236b8da3c4497712",
      "new_mode": 33188,
      "new_path": "tests/modules/other/nspkg_gamma/BUILD.bazel"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "bb7b160deb3702579ff14f2f54ba52fed671a4cc",
      "new_mode": 33188,
      "new_path": "tests/modules/other/nspkg_gamma/site-packages/nspkg/subnspkg/gamma/__init__.py"
    },
    {
      "type": "modify",
      "old_id": "a042ed034644be46f6775dcb1c4bb5b8883796fa",
      "old_mode": 33188,
      "old_path": "tests/pypi/whl_library_targets/whl_library_targets_tests.bzl",
      "new_id": "f738e03b5d30110f4649c1f75f446c1d2745bb62",
      "new_mode": 33188,
      "new_path": "tests/pypi/whl_library_targets/whl_library_targets_tests.bzl"
    },
    {
      "type": "modify",
      "old_id": "7b3b617da1f7eb5ad1bca8bae8ae3af16597fb2c",
      "old_mode": 33188,
      "old_path": "tests/support/sh_py_run_test.bzl",
      "new_id": "9c8134ff40e310a67f4425616791685169267b68",
      "new_mode": 33188,
      "new_path": "tests/support/sh_py_run_test.bzl"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "5d02708800887532af44f8213ad673e4ba82c61b",
      "new_mode": 33188,
      "new_path": "tests/venv_site_packages_libs/BUILD.bazel"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "b944be69e324343b6337b09550ad6b5910e9c7c8",
      "new_mode": 33188,
      "new_path": "tests/venv_site_packages_libs/bin.py"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "c40c3b40801ca0e267395c380048cfc1f93f2fe6",
      "new_mode": 33188,
      "new_path": "tests/venv_site_packages_libs/nspkg_alpha/BUILD.bazel"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "b5ee093672a8468b4cdc536c116b79ad7fe83b05",
      "new_mode": 33188,
      "new_path": "tests/venv_site_packages_libs/nspkg_alpha/site-packages/nspkg/subnspkg/alpha/__init__.py"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "5d402183bda4761a4538f0b13a58a22fd6df080b",
      "new_mode": 33188,
      "new_path": "tests/venv_site_packages_libs/nspkg_beta/BUILD.bazel"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "a2a65910c754bff04dbb6936014ae67d8aed4c8a",
      "new_mode": 33188,
      "new_path": "tests/venv_site_packages_libs/nspkg_beta/site-packages/nspkg/subnspkg/beta/__init__.py"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "519b258044392e228cc9cbffe2d86f3ea34f3216",
      "new_mode": 33188,
      "new_path": "tests/venv_site_packages_libs/venv_site_packages_pypi_test.py"
    }
  ]
}
