prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Distros are coupled with instrumentations
  As mentioned [here](https://github.com/open-telemetry/opentelemetry-python/discussions/2005#discussion-3489738).
  
  </issue>
  <code>
  [start of opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation/sitecustomize.py]
  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 from os.path import abspath, dirname, pathsep
  19 from re import sub
  20 
  21 from pkg_resources import iter_entry_points
  22 
  23 from opentelemetry.environment_variables import (
  24     OTEL_PYTHON_DISABLED_INSTRUMENTATIONS,
  25 )
  26 from opentelemetry.instrumentation.dependencies import (
  27     get_dist_dependency_conflicts,
  28 )
  29 from opentelemetry.instrumentation.distro import BaseDistro, DefaultDistro
  30 
  31 logger = getLogger(__file__)
  32 
  33 
  34 def _load_distros() -> BaseDistro:
  35     for entry_point in iter_entry_points("opentelemetry_distro"):
  36         try:
  37             distro = entry_point.load()()
  38             if not isinstance(distro, BaseDistro):
  39                 logger.debug(
  40                     "%s is not an OpenTelemetry Distro. Skipping",
  41                     entry_point.name,
  42                 )
  43                 continue
  44             logger.debug(
  45                 "Distribution %s will be configured", entry_point.name
  46             )
  47             return distro
  48         except Exception as exc:  # pylint: disable=broad-except
  49             logger.exception(
  50                 "Distribution %s configuration failed", entry_point.name
  51             )
  52             raise exc
  53     return DefaultDistro()
  54 
  55 
  56 def _load_instrumentors(distro):
  57     package_to_exclude = environ.get(OTEL_PYTHON_DISABLED_INSTRUMENTATIONS, [])
  58     if isinstance(package_to_exclude, str):
  59         package_to_exclude = package_to_exclude.split(",")
  60         # to handle users entering "requests , flask" or "requests, flask" with spaces
  61         package_to_exclude = [x.strip() for x in package_to_exclude]
  62 
  63     for entry_point in iter_entry_points("opentelemetry_instrumentor"):
  64         if entry_point.name in package_to_exclude:
  65             logger.debug(
  66                 "Instrumentation skipped for library %s", entry_point.name
  67             )
  68             continue
  69 
  70         try:
  71             conflict = get_dist_dependency_conflicts(entry_point.dist)
  72             if conflict:
  73                 logger.debug(
  74                     "Skipping instrumentation %s: %s",
  75                     entry_point.name,
  76                     conflict,
  77                 )
  78                 continue
  79 
  80             # tell instrumentation to not run dep checks again as we already did it above
  81             distro.load_instrumentor(entry_point, skip_dep_check=True)
  82             logger.debug("Instrumented %s", entry_point.name)
  83         except Exception as exc:  # pylint: disable=broad-except
  84             logger.exception("Instrumenting of %s failed", entry_point.name)
  85             raise exc
  86 
  87 
  88 def _load_configurators():
  89     configured = None
  90     for entry_point in iter_entry_points("opentelemetry_configurator"):
  91         if configured is not None:
  92             logger.warning(
  93                 "Configuration of %s not loaded, %s already loaded",
  94                 entry_point.name,
  95                 configured,
  96             )
  97             continue
  98         try:
  99             entry_point.load()().configure()  # type: ignore
  100             configured = entry_point.name
  101         except Exception as exc:  # pylint: disable=broad-except
  102             logger.exception("Configuration of %s failed", entry_point.name)
  103             raise exc
  104 
  105 
  106 def initialize():
  107     try:
  108         distro = _load_distros()
  109         distro.configure()
  110         _load_configurators()
  111         _load_instrumentors(distro)
  112     except Exception:  # pylint: disable=broad-except
  113         logger.exception("Failed to auto initialize opentelemetry")
  114     finally:
  115         environ["PYTHONPATH"] = sub(
  116             r"{}{}?".format(dirname(abspath(__file__)), pathsep),
  117             "",
  118             environ["PYTHONPATH"],
  119         )
  120 
  121 
  122 if (
  123     hasattr(sys, "argv")
  124     and sys.argv[0].split(path.sep)[-1] == "celery"
  125     and "worker" in sys.argv[1:]
  126 ):
  127     from celery.signals import worker_process_init  # pylint:disable=E0401
  128 
  129     @worker_process_init.connect(weak=False)
  130     def init_celery(*args, **kwargs):
  131         initialize()
  132 
  133 
  134 else:
  135     initialize()
  136
  [end of opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation/sitecustomize.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/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
  @@ -60,6 +60,9 @@
           # to handle users entering "requests , flask" or "requests, flask" with spaces
           package_to_exclude = [x.strip() for x in package_to_exclude]
   
  +    for entry_point in iter_entry_points("opentelemetry_pre_instrument"):
  +        entry_point.load()()
  +
       for entry_point in iter_entry_points("opentelemetry_instrumentor"):
           if entry_point.name in package_to_exclude:
               logger.debug(
  @@ -84,6 +87,9 @@
               logger.exception("Instrumenting of %s failed", entry_point.name)
               raise exc
   
  +    for entry_point in iter_entry_points("opentelemetry_post_instrument"):
  +        entry_point.load()()
  +
   
   def _load_configurators():
       configured = None
  
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@@ -60,6 +60,9 @@\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_pre_instrument\"):\n+        entry_point.load()()\n+\n     for entry_point in iter_entry_points(\"opentelemetry_instrumentor\"):\n         if entry_point.name in package_to_exclude:\n             logger.debug(\n@@ -84,6 +87,9 @@\n             logger.exception(\"Instrumenting of %s failed\", entry_point.name)\n             raise exc\n \n+    for entry_point in iter_entry_points(\"opentelemetry_post_instrument\"):\n+        entry_point.load()()\n+\n \n def _load_configurators():\n     configured = None\n", "issue": "Distros are coupled with instrumentations\nAs mentioned [here](https://github.com/open-telemetry/opentelemetry-python/discussions/2005#discussion-3489738).\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\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)\nfrom opentelemetry.instrumentation.dependencies import (\n    get_dist_dependency_conflicts,\n)\nfrom opentelemetry.instrumentation.distro import BaseDistro, DefaultDistro\n\nlogger = getLogger(__file__)\n\n\ndef _load_distros() -> BaseDistro:\n    for entry_point in iter_entry_points(\"opentelemetry_distro\"):\n        try:\n            distro = entry_point.load()()\n            if not isinstance(distro, BaseDistro):\n                logger.debug(\n                    \"%s is not an OpenTelemetry Distro. Skipping\",\n                    entry_point.name,\n                )\n                continue\n            logger.debug(\n                \"Distribution %s will be configured\", entry_point.name\n            )\n            return distro\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    return DefaultDistro()\n\n\ndef _load_instrumentors(distro):\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        if entry_point.name in package_to_exclude:\n            logger.debug(\n                \"Instrumentation skipped for library %s\", entry_point.name\n            )\n            continue\n\n        try:\n            conflict = get_dist_dependency_conflicts(entry_point.dist)\n            if conflict:\n                logger.debug(\n                    \"Skipping instrumentation %s: %s\",\n                    entry_point.name,\n                    conflict,\n                )\n                continue\n\n            # tell instrumentation to not run dep checks again as we already did it above\n            distro.load_instrumentor(entry_point, skip_dep_check=True)\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        distro = _load_distros()\n        distro.configure()\n        _load_configurators()\n        _load_instrumentors(distro)\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"}]}