Search code examples
pythonbazeldrake

Unexpected path in PYTHONPATH when using Drake as a Bazel external


I'm using drake as an external in another bazel project and it's adding ...runfiles/drake as well as ...runfiles/drake/bindings to the PYTHONPATH. The latter pretty much only includes pydrake (which is what I want), but the former is including a bunch of other directories as modules including common , examples, tools, and bindings which results in name collisions with my own project. Is this expected behavior? What's the best way to deal with this? I tested the examples in drake-external-examples/drake_bazel_external and I'm seeing the same issue (relevant commit here).


Solution

  • TL;DR Best way to handle this is to make sure your imports are scoped to your project; e.g. instead of from common import foo, instead do from drake_bazel_external.common import foo.

    Here's a snippet from a sample Bazel project that does this with Python:

    https://github.com/EricCousineau-TRI/repro/blob/39f79009a2e89b987f072276d1921a282f63e6a1/python/bazel_py_example/mid/py3_bin.py#L3


    To root cause, here's my attempt to instrument your repro with some more output, pinned to [email protected]:

    drake_bazel_external/apps/bar.py (branch)

    Here's a preview of the Python paths, which corroborate what you're seeing:

    path:
      {source_tree}/apps
      {runfiles}
      {runfiles}/drake/bindings
      {runfiles}/lcmtypes_bot2_core/lcmtypes
      {runfiles}/lcmtypes_bot2_core
      {runfiles}/lcmtypes_robotlocomotion/lcmtypes
      {runfiles}/lcmtypes_robotlocomotion
      {runfiles}/meshcat_python/src
      {runfiles}/spdlog
      {runfiles}/meshcat_python
      {runfiles}/lcm
      {runfiles}/ignition_math
      {runfiles}/drake
      {runfiles}/drake_external_examples
      /usr/lib/python36.zip
      /usr/lib/python3.6
      /usr/lib/python3.6/lib-dynload
      /usr/lib/python3/dist-packages
    common: {runfiles}/drake/common/__init__.py
    

    Ultimately, this is expected behavior. Here's the Drake issue, and a related bazelbuild issue:

    Best method is to use project-specific imports. For now, try to avoid this by using a more specific import.

    I will re-open the Drake issue, but will keep it pegged at low priority since there's a better solution (IMO), and will require more infrastructure work to make it happen.

    Thanks!

    EDIT: To be specific, the thing that is most acutely tripping up your example is the fact that Bazel is generating @drake//common:__init__.py. It's only generated because of the legacy_create_init flag, as well as the fact that we want the file libdrake_marker.so.

    There's still the fact that drake (among other repositories) are on the Python at all.

    EDIT 2: Filed a new issue on Jeremy's request: https://github.com/RobotLocomotion/drake/issues/13320