prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  `./pants run ...` does not work for non-venv-mode `pex_binary` targets that re-exec sys.argv[0].
  In short, the `run` goal executes via ~:
  ```
  export PEX_PATH=/path/to/requirements.pex
  export PEX_EXTRA_SYS_PATH=/path/to/source_root_1:/path/to/cource_root2
  ./only-contains-entry-point-metadata.pex
  ```
  
  If the executed code then tries to re-execute via argv[0] (the PEX file itself), then sys.path scrubbing is engaged which strips back off the PEX_PATH and PEX_EXTRA_SYS_PATH triggered sys.path additions since those two env vars are also stripped by default. Either Pants needs to expose the `--no-strip-pex-env` option as a `pex_binary` parameter or else it needs to set this option for `pants run` unconditionally.
  
  The concrete example of apps that re-exec via sys.argv[0] are django manage.py apps.
  
  See https://github.com/pantsbuild/pex/issues/1349 where @asherf discovered the issue and the mechanism behind it was all worked out.
  
  </issue>
  <code>
  [start of src/python/pants/backend/python/goals/run_pex_binary.py]
  1 # Copyright 2020 Pants project contributors (see CONTRIBUTORS.md).
  2 # Licensed under the Apache License, Version 2.0 (see LICENSE).
  3 
  4 import os
  5 
  6 from pants.backend.python.goals.package_pex_binary import PexBinaryFieldSet
  7 from pants.backend.python.target_types import (
  8     PexBinaryDefaults,
  9     ResolvedPexEntryPoint,
  10     ResolvePexEntryPointRequest,
  11 )
  12 from pants.backend.python.util_rules.pex import Pex, PexRequest
  13 from pants.backend.python.util_rules.pex_environment import PexEnvironment
  14 from pants.backend.python.util_rules.pex_from_targets import PexFromTargetsRequest
  15 from pants.backend.python.util_rules.python_sources import (
  16     PythonSourceFiles,
  17     PythonSourceFilesRequest,
  18 )
  19 from pants.core.goals.run import RunFieldSet, RunRequest
  20 from pants.engine.fs import Digest, MergeDigests
  21 from pants.engine.rules import Get, MultiGet, collect_rules, rule
  22 from pants.engine.target import TransitiveTargets, TransitiveTargetsRequest
  23 from pants.engine.unions import UnionRule
  24 from pants.util.logging import LogLevel
  25 
  26 
  27 @rule(level=LogLevel.DEBUG)
  28 async def create_pex_binary_run_request(
  29     field_set: PexBinaryFieldSet,
  30     pex_binary_defaults: PexBinaryDefaults,
  31     pex_env: PexEnvironment,
  32 ) -> RunRequest:
  33     entry_point, transitive_targets = await MultiGet(
  34         Get(
  35             ResolvedPexEntryPoint,
  36             ResolvePexEntryPointRequest(field_set.entry_point),
  37         ),
  38         Get(TransitiveTargets, TransitiveTargetsRequest([field_set.address])),
  39     )
  40 
  41     # Note that we get an intermediate PexRequest here (instead of going straight to a Pex)
  42     # so that we can get the interpreter constraints for use in runner_pex_request.
  43     requirements_pex_request = await Get(
  44         PexRequest,
  45         PexFromTargetsRequest,
  46         PexFromTargetsRequest.for_requirements([field_set.address], internal_only=True),
  47     )
  48 
  49     requirements_request = Get(Pex, PexRequest, requirements_pex_request)
  50 
  51     sources_request = Get(
  52         PythonSourceFiles, PythonSourceFilesRequest(transitive_targets.closure, include_files=True)
  53     )
  54 
  55     output_filename = f"{field_set.address.target_name}.pex"
  56     runner_pex_request = Get(
  57         Pex,
  58         PexRequest(
  59             output_filename=output_filename,
  60             interpreter_constraints=requirements_pex_request.interpreter_constraints,
  61             additional_args=field_set.generate_additional_args(pex_binary_defaults),
  62             internal_only=True,
  63             # Note that the entry point file is not in the PEX itself. It's loaded by setting
  64             # `PEX_EXTRA_SYS_PATH`.
  65             # TODO(John Sirois): Support ConsoleScript in PexBinary targets:
  66             #  https://github.com/pantsbuild/pants/issues/11619
  67             main=entry_point.val,
  68         ),
  69     )
  70 
  71     requirements, sources, runner_pex = await MultiGet(
  72         requirements_request, sources_request, runner_pex_request
  73     )
  74 
  75     merged_digest = await Get(
  76         Digest,
  77         MergeDigests(
  78             [requirements.digest, sources.source_files.snapshot.digest, runner_pex.digest]
  79         ),
  80     )
  81 
  82     def in_chroot(relpath: str) -> str:
  83         return os.path.join("{chroot}", relpath)
  84 
  85     args = pex_env.create_argv(in_chroot(runner_pex.name), python=runner_pex.python)
  86 
  87     chrooted_source_roots = [in_chroot(sr) for sr in sources.source_roots]
  88     extra_env = {
  89         **pex_env.environment_dict(python_configured=runner_pex.python is not None),
  90         "PEX_PATH": in_chroot(requirements_pex_request.output_filename),
  91         "PEX_EXTRA_SYS_PATH": ":".join(chrooted_source_roots),
  92     }
  93 
  94     return RunRequest(digest=merged_digest, args=args, extra_env=extra_env)
  95 
  96 
  97 def rules():
  98     return [*collect_rules(), UnionRule(RunFieldSet, PexBinaryFieldSet)]
  99
  [end of src/python/pants/backend/python/goals/run_pex_binary.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/src/python/pants/backend/python/goals/run_pex_binary.py b/src/python/pants/backend/python/goals/run_pex_binary.py
  --- a/src/python/pants/backend/python/goals/run_pex_binary.py
  +++ b/src/python/pants/backend/python/goals/run_pex_binary.py
  @@ -58,7 +58,13 @@
           PexRequest(
               output_filename=output_filename,
               interpreter_constraints=requirements_pex_request.interpreter_constraints,
  -            additional_args=field_set.generate_additional_args(pex_binary_defaults),
  +            additional_args=(
  +                *field_set.generate_additional_args(pex_binary_defaults),
  +                # N.B.: Since we cobble together the runtime environment via PEX_PATH and
  +                # PEX_EXTRA_SYS_PATH below, it's important for any app that re-executes itself that
  +                # these environment variables are not stripped.
  +                "--no-strip-pex-env",
  +            ),
               internal_only=True,
               # Note that the entry point file is not in the PEX itself. It's loaded by setting
               # `PEX_EXTRA_SYS_PATH`.
  
verification_info: {"golden_diff": "diff --git a/src/python/pants/backend/python/goals/run_pex_binary.py b/src/python/pants/backend/python/goals/run_pex_binary.py\n--- a/src/python/pants/backend/python/goals/run_pex_binary.py\n+++ b/src/python/pants/backend/python/goals/run_pex_binary.py\n@@ -58,7 +58,13 @@\n         PexRequest(\n             output_filename=output_filename,\n             interpreter_constraints=requirements_pex_request.interpreter_constraints,\n-            additional_args=field_set.generate_additional_args(pex_binary_defaults),\n+            additional_args=(\n+                *field_set.generate_additional_args(pex_binary_defaults),\n+                # N.B.: Since we cobble together the runtime environment via PEX_PATH and\n+                # PEX_EXTRA_SYS_PATH below, it's important for any app that re-executes itself that\n+                # these environment variables are not stripped.\n+                \"--no-strip-pex-env\",\n+            ),\n             internal_only=True,\n             # Note that the entry point file is not in the PEX itself. It's loaded by setting\n             # `PEX_EXTRA_SYS_PATH`.\n", "issue": "`./pants run ...` does not work for non-venv-mode `pex_binary` targets that re-exec sys.argv[0].\nIn short, the `run` goal executes via ~:\r\n```\r\nexport PEX_PATH=/path/to/requirements.pex\r\nexport PEX_EXTRA_SYS_PATH=/path/to/source_root_1:/path/to/cource_root2\r\n./only-contains-entry-point-metadata.pex\r\n```\r\n\r\nIf the executed code then tries to re-execute via argv[0] (the PEX file itself), then sys.path scrubbing is engaged which strips back off the PEX_PATH and PEX_EXTRA_SYS_PATH triggered sys.path additions since those two env vars are also stripped by default. Either Pants needs to expose the `--no-strip-pex-env` option as a `pex_binary` parameter or else it needs to set this option for `pants run` unconditionally.\r\n\r\nThe concrete example of apps that re-exec via sys.argv[0] are django manage.py apps.\r\n\r\nSee https://github.com/pantsbuild/pex/issues/1349 where @asherf discovered the issue and the mechanism behind it was all worked out.\n", "before_files": [{"content": "# Copyright 2020 Pants project contributors (see CONTRIBUTORS.md).\n# Licensed under the Apache License, Version 2.0 (see LICENSE).\n\nimport os\n\nfrom pants.backend.python.goals.package_pex_binary import PexBinaryFieldSet\nfrom pants.backend.python.target_types import (\n    PexBinaryDefaults,\n    ResolvedPexEntryPoint,\n    ResolvePexEntryPointRequest,\n)\nfrom pants.backend.python.util_rules.pex import Pex, PexRequest\nfrom pants.backend.python.util_rules.pex_environment import PexEnvironment\nfrom pants.backend.python.util_rules.pex_from_targets import PexFromTargetsRequest\nfrom pants.backend.python.util_rules.python_sources import (\n    PythonSourceFiles,\n    PythonSourceFilesRequest,\n)\nfrom pants.core.goals.run import RunFieldSet, RunRequest\nfrom pants.engine.fs import Digest, MergeDigests\nfrom pants.engine.rules import Get, MultiGet, collect_rules, rule\nfrom pants.engine.target import TransitiveTargets, TransitiveTargetsRequest\nfrom pants.engine.unions import UnionRule\nfrom pants.util.logging import LogLevel\n\n\n@rule(level=LogLevel.DEBUG)\nasync def create_pex_binary_run_request(\n    field_set: PexBinaryFieldSet,\n    pex_binary_defaults: PexBinaryDefaults,\n    pex_env: PexEnvironment,\n) -> RunRequest:\n    entry_point, transitive_targets = await MultiGet(\n        Get(\n            ResolvedPexEntryPoint,\n            ResolvePexEntryPointRequest(field_set.entry_point),\n        ),\n        Get(TransitiveTargets, TransitiveTargetsRequest([field_set.address])),\n    )\n\n    # Note that we get an intermediate PexRequest here (instead of going straight to a Pex)\n    # so that we can get the interpreter constraints for use in runner_pex_request.\n    requirements_pex_request = await Get(\n        PexRequest,\n        PexFromTargetsRequest,\n        PexFromTargetsRequest.for_requirements([field_set.address], internal_only=True),\n    )\n\n    requirements_request = Get(Pex, PexRequest, requirements_pex_request)\n\n    sources_request = Get(\n        PythonSourceFiles, PythonSourceFilesRequest(transitive_targets.closure, include_files=True)\n    )\n\n    output_filename = f\"{field_set.address.target_name}.pex\"\n    runner_pex_request = Get(\n        Pex,\n        PexRequest(\n            output_filename=output_filename,\n            interpreter_constraints=requirements_pex_request.interpreter_constraints,\n            additional_args=field_set.generate_additional_args(pex_binary_defaults),\n            internal_only=True,\n            # Note that the entry point file is not in the PEX itself. It's loaded by setting\n            # `PEX_EXTRA_SYS_PATH`.\n            # TODO(John Sirois): Support ConsoleScript in PexBinary targets:\n            #  https://github.com/pantsbuild/pants/issues/11619\n            main=entry_point.val,\n        ),\n    )\n\n    requirements, sources, runner_pex = await MultiGet(\n        requirements_request, sources_request, runner_pex_request\n    )\n\n    merged_digest = await Get(\n        Digest,\n        MergeDigests(\n            [requirements.digest, sources.source_files.snapshot.digest, runner_pex.digest]\n        ),\n    )\n\n    def in_chroot(relpath: str) -> str:\n        return os.path.join(\"{chroot}\", relpath)\n\n    args = pex_env.create_argv(in_chroot(runner_pex.name), python=runner_pex.python)\n\n    chrooted_source_roots = [in_chroot(sr) for sr in sources.source_roots]\n    extra_env = {\n        **pex_env.environment_dict(python_configured=runner_pex.python is not None),\n        \"PEX_PATH\": in_chroot(requirements_pex_request.output_filename),\n        \"PEX_EXTRA_SYS_PATH\": \":\".join(chrooted_source_roots),\n    }\n\n    return RunRequest(digest=merged_digest, args=args, extra_env=extra_env)\n\n\ndef rules():\n    return [*collect_rules(), UnionRule(RunFieldSet, PexBinaryFieldSet)]\n", "path": "src/python/pants/backend/python/goals/run_pex_binary.py"}]}