prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  sitecustomize is being run multiple times
  When `opentelemetry-instrument` is run, the path of `opentelemetry-python`'s `sitecustomize.py` file is added to `PYTHONPATH`. This works fine unless the command executed by `opentelemetry-instrument` is also calling the `python` executable, which would make this `sitecustomize` be executed more than once. This is bad because this means multiple instrumentations may happen.
  
  I'll be modifying `sitecustomize` to remove its path from `PYTHONPATH` after it has been executed.
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation/sitecustomize.py`
  Content:
  ```
  1 # Copyright The OpenTelemetry Authors
  2 #
  3 # Licensed under the Apache License, Version 2.0 (the "License");
  4 # you may not use this file except in compliance with the License.
  5 # You may obtain a copy of the License at
  6 #
  7 #     http://www.apache.org/licenses/LICENSE-2.0
  8 #
  9 # Unless required by applicable law or agreed to in writing, software
  10 # distributed under the License is distributed on an "AS IS" BASIS,
  11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12 # See the License for the specific language governing permissions and
  13 # limitations under the License.
  14 
  15 import sys
  16 from logging import getLogger
  17 from os import environ, path
  18 
  19 from pkg_resources import iter_entry_points
  20 
  21 from opentelemetry.environment_variables import (
  22     OTEL_PYTHON_DISABLED_INSTRUMENTATIONS,
  23 )
  24 
  25 logger = getLogger(__file__)
  26 
  27 
  28 def _load_distros():
  29     for entry_point in iter_entry_points("opentelemetry_distro"):
  30         try:
  31             entry_point.load()().configure()  # type: ignore
  32             logger.debug("Distribution %s configured", entry_point.name)
  33         except Exception as exc:  # pylint: disable=broad-except
  34             logger.exception(
  35                 "Distribution %s configuration failed", entry_point.name
  36             )
  37             raise exc
  38 
  39 
  40 def _load_instrumentors():
  41     package_to_exclude = environ.get(OTEL_PYTHON_DISABLED_INSTRUMENTATIONS, [])
  42     if isinstance(package_to_exclude, str):
  43         package_to_exclude = package_to_exclude.split(",")
  44         # to handle users entering "requests , flask" or "requests, flask" with spaces
  45         package_to_exclude = [x.strip() for x in package_to_exclude]
  46 
  47     for entry_point in iter_entry_points("opentelemetry_instrumentor"):
  48         try:
  49             if entry_point.name in package_to_exclude:
  50                 logger.debug(
  51                     "Instrumentation skipped for library %s", entry_point.name
  52                 )
  53                 continue
  54             entry_point.load()().instrument()  # type: ignore
  55             logger.debug("Instrumented %s", entry_point.name)
  56         except Exception as exc:  # pylint: disable=broad-except
  57             logger.exception("Instrumenting of %s failed", entry_point.name)
  58             raise exc
  59 
  60 
  61 def _load_configurators():
  62     configured = None
  63     for entry_point in iter_entry_points("opentelemetry_configurator"):
  64         if configured is not None:
  65             logger.warning(
  66                 "Configuration of %s not loaded, %s already loaded",
  67                 entry_point.name,
  68                 configured,
  69             )
  70             continue
  71         try:
  72             entry_point.load()().configure()  # type: ignore
  73             configured = entry_point.name
  74         except Exception as exc:  # pylint: disable=broad-except
  75             logger.exception("Configuration of %s failed", entry_point.name)
  76             raise exc
  77 
  78 
  79 def initialize():
  80     try:
  81         _load_distros()
  82         _load_configurators()
  83         _load_instrumentors()
  84     except Exception:  # pylint: disable=broad-except
  85         logger.exception("Failed to auto initialize opentelemetry")
  86 
  87 
  88 if (
  89     hasattr(sys, "argv")
  90     and sys.argv[0].split(path.sep)[-1] == "celery"
  91     and "worker" in sys.argv[1:]
  92 ):
  93     from celery.signals import worker_process_init  # pylint:disable=E0401
  94 
  95     @worker_process_init.connect(weak=False)
  96     def init_celery(*args, **kwargs):
  97         initialize()
  98 
  99 
  100 else:
  101     initialize()
  102
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation/sitecustomize.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation/sitecustomize.py
  --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation/sitecustomize.py
  +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation/sitecustomize.py
  @@ -15,6 +15,8 @@
   import sys
   from logging import getLogger
   from os import environ, path
  +from os.path import abspath, dirname, pathsep
  +from re import sub
   
   from pkg_resources import iter_entry_points
   
  @@ -83,6 +85,12 @@
           _load_instrumentors()
       except Exception:  # pylint: disable=broad-except
           logger.exception("Failed to auto initialize opentelemetry")
  +    finally:
  +        environ["PYTHONPATH"] = sub(
  +            r"{}{}?".format(dirname(abspath(__file__)), pathsep),
  +            "",
  +            environ["PYTHONPATH"],
  +        )
   
   
   if (
  
verification_info: {"golden_diff": "diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation/sitecustomize.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation/sitecustomize.py\n--- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation/sitecustomize.py\n+++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation/sitecustomize.py\n@@ -15,6 +15,8 @@\n import sys\n from logging import getLogger\n from os import environ, path\n+from os.path import abspath, dirname, pathsep\n+from re import sub\n \n from pkg_resources import iter_entry_points\n \n@@ -83,6 +85,12 @@\n         _load_instrumentors()\n     except Exception:  # pylint: disable=broad-except\n         logger.exception(\"Failed to auto initialize opentelemetry\")\n+    finally:\n+        environ[\"PYTHONPATH\"] = sub(\n+            r\"{}{}?\".format(dirname(abspath(__file__)), pathsep),\n+            \"\",\n+            environ[\"PYTHONPATH\"],\n+        )\n \n \n if (\n", "issue": "sitecustomize is being run multiple times\nWhen `opentelemetry-instrument` is run, the path of `opentelemetry-python`'s `sitecustomize.py` file is added to `PYTHONPATH`. This works fine unless the command executed by `opentelemetry-instrument` is also calling the `python` executable, which would make this `sitecustomize` be executed more than once. This is bad because this means multiple instrumentations may happen.\r\n\r\nI'll be modifying `sitecustomize` to remove its path from `PYTHONPATH` after it has been executed.\n", "before_files": [{"content": "# Copyright The OpenTelemetry Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nimport sys\nfrom logging import getLogger\nfrom os import environ, path\n\nfrom pkg_resources import iter_entry_points\n\nfrom opentelemetry.environment_variables import (\n    OTEL_PYTHON_DISABLED_INSTRUMENTATIONS,\n)\n\nlogger = getLogger(__file__)\n\n\ndef _load_distros():\n    for entry_point in iter_entry_points(\"opentelemetry_distro\"):\n        try:\n            entry_point.load()().configure()  # type: ignore\n            logger.debug(\"Distribution %s configured\", entry_point.name)\n        except Exception as exc:  # pylint: disable=broad-except\n            logger.exception(\n                \"Distribution %s configuration failed\", entry_point.name\n            )\n            raise exc\n\n\ndef _load_instrumentors():\n    package_to_exclude = environ.get(OTEL_PYTHON_DISABLED_INSTRUMENTATIONS, [])\n    if isinstance(package_to_exclude, str):\n        package_to_exclude = package_to_exclude.split(\",\")\n        # to handle users entering \"requests , flask\" or \"requests, flask\" with spaces\n        package_to_exclude = [x.strip() for x in package_to_exclude]\n\n    for entry_point in iter_entry_points(\"opentelemetry_instrumentor\"):\n        try:\n            if entry_point.name in package_to_exclude:\n                logger.debug(\n                    \"Instrumentation skipped for library %s\", entry_point.name\n                )\n                continue\n            entry_point.load()().instrument()  # type: ignore\n            logger.debug(\"Instrumented %s\", entry_point.name)\n        except Exception as exc:  # pylint: disable=broad-except\n            logger.exception(\"Instrumenting of %s failed\", entry_point.name)\n            raise exc\n\n\ndef _load_configurators():\n    configured = None\n    for entry_point in iter_entry_points(\"opentelemetry_configurator\"):\n        if configured is not None:\n            logger.warning(\n                \"Configuration of %s not loaded, %s already loaded\",\n                entry_point.name,\n                configured,\n            )\n            continue\n        try:\n            entry_point.load()().configure()  # type: ignore\n            configured = entry_point.name\n        except Exception as exc:  # pylint: disable=broad-except\n            logger.exception(\"Configuration of %s failed\", entry_point.name)\n            raise exc\n\n\ndef initialize():\n    try:\n        _load_distros()\n        _load_configurators()\n        _load_instrumentors()\n    except Exception:  # pylint: disable=broad-except\n        logger.exception(\"Failed to auto initialize opentelemetry\")\n\n\nif (\n    hasattr(sys, \"argv\")\n    and sys.argv[0].split(path.sep)[-1] == \"celery\"\n    and \"worker\" in sys.argv[1:]\n):\n    from celery.signals import worker_process_init  # pylint:disable=E0401\n\n    @worker_process_init.connect(weak=False)\n    def init_celery(*args, **kwargs):\n        initialize()\n\n\nelse:\n    initialize()\n", "path": "opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation/sitecustomize.py"}], "after_files": [{"content": "# Copyright The OpenTelemetry Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nimport sys\nfrom logging import getLogger\nfrom os import environ, path\nfrom os.path import abspath, dirname, pathsep\nfrom re import sub\n\nfrom pkg_resources import iter_entry_points\n\nfrom opentelemetry.environment_variables import (\n    OTEL_PYTHON_DISABLED_INSTRUMENTATIONS,\n)\n\nlogger = getLogger(__file__)\n\n\ndef _load_distros():\n    for entry_point in iter_entry_points(\"opentelemetry_distro\"):\n        try:\n            entry_point.load()().configure()  # type: ignore\n            logger.debug(\"Distribution %s configured\", entry_point.name)\n        except Exception as exc:  # pylint: disable=broad-except\n            logger.exception(\n                \"Distribution %s configuration failed\", entry_point.name\n            )\n            raise exc\n\n\ndef _load_instrumentors():\n    package_to_exclude = environ.get(OTEL_PYTHON_DISABLED_INSTRUMENTATIONS, [])\n    if isinstance(package_to_exclude, str):\n        package_to_exclude = package_to_exclude.split(\",\")\n        # to handle users entering \"requests , flask\" or \"requests, flask\" with spaces\n        package_to_exclude = [x.strip() for x in package_to_exclude]\n\n    for entry_point in iter_entry_points(\"opentelemetry_instrumentor\"):\n        try:\n            if entry_point.name in package_to_exclude:\n                logger.debug(\n                    \"Instrumentation skipped for library %s\", entry_point.name\n                )\n                continue\n            entry_point.load()().instrument()  # type: ignore\n            logger.debug(\"Instrumented %s\", entry_point.name)\n        except Exception as exc:  # pylint: disable=broad-except\n            logger.exception(\"Instrumenting of %s failed\", entry_point.name)\n            raise exc\n\n\ndef _load_configurators():\n    configured = None\n    for entry_point in iter_entry_points(\"opentelemetry_configurator\"):\n        if configured is not None:\n            logger.warning(\n                \"Configuration of %s not loaded, %s already loaded\",\n                entry_point.name,\n                configured,\n            )\n            continue\n        try:\n            entry_point.load()().configure()  # type: ignore\n            configured = entry_point.name\n        except Exception as exc:  # pylint: disable=broad-except\n            logger.exception(\"Configuration of %s failed\", entry_point.name)\n            raise exc\n\n\ndef initialize():\n    try:\n        _load_distros()\n        _load_configurators()\n        _load_instrumentors()\n    except Exception:  # pylint: disable=broad-except\n        logger.exception(\"Failed to auto initialize opentelemetry\")\n    finally:\n        environ[\"PYTHONPATH\"] = sub(\n            r\"{}{}?\".format(dirname(abspath(__file__)), pathsep),\n            \"\",\n            environ[\"PYTHONPATH\"],\n        )\n\n\nif (\n    hasattr(sys, \"argv\")\n    and sys.argv[0].split(path.sep)[-1] == \"celery\"\n    and \"worker\" in sys.argv[1:]\n):\n    from celery.signals import worker_process_init  # pylint:disable=E0401\n\n    @worker_process_init.connect(weak=False)\n    def init_celery(*args, **kwargs):\n        initialize()\n\n\nelse:\n    initialize()\n", "path": "opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation/sitecustomize.py"}]}