prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  format_baggage does not escape non-ascii in baggage keys
  https://github.com/open-telemetry/opentelemetry-python/blob/4250078e43ddb24c88e19270c7af01ae63336fb9/opentelemetry-api/src/opentelemetry/baggage/propagation/__init__.py#L100
  
  The cpp implementation does this, and it looks like in python test strings there is url encoding.
  https://github.com/open-telemetry/opentelemetry-cpp/blob/61d3c5e318830d10a0859befa046aa4847593764/api/include/opentelemetry/baggage/baggage.h#L174
  
  </issue>
  <code>
  [start of opentelemetry-api/src/opentelemetry/baggage/propagation/__init__.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 typing
  16 import urllib.parse
  17 
  18 from opentelemetry import baggage
  19 from opentelemetry.context import get_current
  20 from opentelemetry.context.context import Context
  21 from opentelemetry.propagators import textmap
  22 
  23 
  24 class W3CBaggagePropagator(textmap.TextMapPropagator):
  25     """Extracts and injects Baggage which is used to annotate telemetry."""
  26 
  27     _MAX_HEADER_LENGTH = 8192
  28     _MAX_PAIR_LENGTH = 4096
  29     _MAX_PAIRS = 180
  30     _BAGGAGE_HEADER_NAME = "baggage"
  31 
  32     def extract(
  33         self,
  34         carrier: textmap.CarrierT,
  35         context: typing.Optional[Context] = None,
  36         getter: textmap.Getter = textmap.default_getter,
  37     ) -> Context:
  38         """Extract Baggage from the carrier.
  39 
  40         See
  41         `opentelemetry.propagators.textmap.TextMapPropagator.extract`
  42         """
  43 
  44         if context is None:
  45             context = get_current()
  46 
  47         header = _extract_first_element(
  48             getter.get(carrier, self._BAGGAGE_HEADER_NAME)
  49         )
  50 
  51         if not header or len(header) > self._MAX_HEADER_LENGTH:
  52             return context
  53 
  54         baggage_entries = header.split(",")
  55         total_baggage_entries = self._MAX_PAIRS
  56         for entry in baggage_entries:
  57             if total_baggage_entries <= 0:
  58                 return context
  59             total_baggage_entries -= 1
  60             if len(entry) > self._MAX_PAIR_LENGTH:
  61                 continue
  62             try:
  63                 name, value = entry.split("=", 1)
  64             except Exception:  # pylint: disable=broad-except
  65                 continue
  66             context = baggage.set_baggage(
  67                 urllib.parse.unquote(name).strip(),
  68                 urllib.parse.unquote(value).strip(),
  69                 context=context,
  70             )
  71 
  72         return context
  73 
  74     def inject(
  75         self,
  76         carrier: textmap.CarrierT,
  77         context: typing.Optional[Context] = None,
  78         setter: textmap.Setter = textmap.default_setter,
  79     ) -> None:
  80         """Injects Baggage into the carrier.
  81 
  82         See
  83         `opentelemetry.propagators.textmap.TextMapPropagator.inject`
  84         """
  85         baggage_entries = baggage.get_all(context=context)
  86         if not baggage_entries:
  87             return
  88 
  89         baggage_string = _format_baggage(baggage_entries)
  90         setter.set(carrier, self._BAGGAGE_HEADER_NAME, baggage_string)
  91 
  92     @property
  93     def fields(self) -> typing.Set[str]:
  94         """Returns a set with the fields set in `inject`."""
  95         return {self._BAGGAGE_HEADER_NAME}
  96 
  97 
  98 def _format_baggage(baggage_entries: typing.Mapping[str, object]) -> str:
  99     return ",".join(
  100         key + "=" + urllib.parse.quote_plus(str(value))
  101         for key, value in baggage_entries.items()
  102     )
  103 
  104 
  105 def _extract_first_element(
  106     items: typing.Optional[typing.Iterable[textmap.CarrierT]],
  107 ) -> typing.Optional[textmap.CarrierT]:
  108     if items is None:
  109         return None
  110     return next(iter(items), None)
  111
  [end of opentelemetry-api/src/opentelemetry/baggage/propagation/__init__.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-api/src/opentelemetry/baggage/propagation/__init__.py b/opentelemetry-api/src/opentelemetry/baggage/propagation/__init__.py
  --- a/opentelemetry-api/src/opentelemetry/baggage/propagation/__init__.py
  +++ b/opentelemetry-api/src/opentelemetry/baggage/propagation/__init__.py
  @@ -13,9 +13,9 @@
   # limitations under the License.
   #
   import typing
  -import urllib.parse
  +from urllib.parse import quote_plus, unquote_plus
   
  -from opentelemetry import baggage
  +from opentelemetry.baggage import get_all, set_baggage
   from opentelemetry.context import get_current
   from opentelemetry.context.context import Context
   from opentelemetry.propagators import textmap
  @@ -63,9 +63,9 @@
                   name, value = entry.split("=", 1)
               except Exception:  # pylint: disable=broad-except
                   continue
  -            context = baggage.set_baggage(
  -                urllib.parse.unquote(name).strip(),
  -                urllib.parse.unquote(value).strip(),
  +            context = set_baggage(
  +                unquote_plus(name).strip(),
  +                unquote_plus(value).strip(),
                   context=context,
               )
   
  @@ -82,7 +82,7 @@
           See
           `opentelemetry.propagators.textmap.TextMapPropagator.inject`
           """
  -        baggage_entries = baggage.get_all(context=context)
  +        baggage_entries = get_all(context=context)
           if not baggage_entries:
               return
   
  @@ -97,7 +97,7 @@
   
   def _format_baggage(baggage_entries: typing.Mapping[str, object]) -> str:
       return ",".join(
  -        key + "=" + urllib.parse.quote_plus(str(value))
  +        quote_plus(str(key)) + "=" + quote_plus(str(value))
           for key, value in baggage_entries.items()
       )
  
verification_info: {"golden_diff": "diff --git a/opentelemetry-api/src/opentelemetry/baggage/propagation/__init__.py b/opentelemetry-api/src/opentelemetry/baggage/propagation/__init__.py\n--- a/opentelemetry-api/src/opentelemetry/baggage/propagation/__init__.py\n+++ b/opentelemetry-api/src/opentelemetry/baggage/propagation/__init__.py\n@@ -13,9 +13,9 @@\n # limitations under the License.\n #\n import typing\n-import urllib.parse\n+from urllib.parse import quote_plus, unquote_plus\n \n-from opentelemetry import baggage\n+from opentelemetry.baggage import get_all, set_baggage\n from opentelemetry.context import get_current\n from opentelemetry.context.context import Context\n from opentelemetry.propagators import textmap\n@@ -63,9 +63,9 @@\n                 name, value = entry.split(\"=\", 1)\n             except Exception:  # pylint: disable=broad-except\n                 continue\n-            context = baggage.set_baggage(\n-                urllib.parse.unquote(name).strip(),\n-                urllib.parse.unquote(value).strip(),\n+            context = set_baggage(\n+                unquote_plus(name).strip(),\n+                unquote_plus(value).strip(),\n                 context=context,\n             )\n \n@@ -82,7 +82,7 @@\n         See\n         `opentelemetry.propagators.textmap.TextMapPropagator.inject`\n         \"\"\"\n-        baggage_entries = baggage.get_all(context=context)\n+        baggage_entries = get_all(context=context)\n         if not baggage_entries:\n             return\n \n@@ -97,7 +97,7 @@\n \n def _format_baggage(baggage_entries: typing.Mapping[str, object]) -> str:\n     return \",\".join(\n-        key + \"=\" + urllib.parse.quote_plus(str(value))\n+        quote_plus(str(key)) + \"=\" + quote_plus(str(value))\n         for key, value in baggage_entries.items()\n     )\n", "issue": "format_baggage does not escape non-ascii in baggage keys\nhttps://github.com/open-telemetry/opentelemetry-python/blob/4250078e43ddb24c88e19270c7af01ae63336fb9/opentelemetry-api/src/opentelemetry/baggage/propagation/__init__.py#L100\r\n\r\nThe cpp implementation does this, and it looks like in python test strings there is url encoding.\r\nhttps://github.com/open-telemetry/opentelemetry-cpp/blob/61d3c5e318830d10a0859befa046aa4847593764/api/include/opentelemetry/baggage/baggage.h#L174\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 typing\nimport urllib.parse\n\nfrom opentelemetry import baggage\nfrom opentelemetry.context import get_current\nfrom opentelemetry.context.context import Context\nfrom opentelemetry.propagators import textmap\n\n\nclass W3CBaggagePropagator(textmap.TextMapPropagator):\n    \"\"\"Extracts and injects Baggage which is used to annotate telemetry.\"\"\"\n\n    _MAX_HEADER_LENGTH = 8192\n    _MAX_PAIR_LENGTH = 4096\n    _MAX_PAIRS = 180\n    _BAGGAGE_HEADER_NAME = \"baggage\"\n\n    def extract(\n        self,\n        carrier: textmap.CarrierT,\n        context: typing.Optional[Context] = None,\n        getter: textmap.Getter = textmap.default_getter,\n    ) -> Context:\n        \"\"\"Extract Baggage from the carrier.\n\n        See\n        `opentelemetry.propagators.textmap.TextMapPropagator.extract`\n        \"\"\"\n\n        if context is None:\n            context = get_current()\n\n        header = _extract_first_element(\n            getter.get(carrier, self._BAGGAGE_HEADER_NAME)\n        )\n\n        if not header or len(header) > self._MAX_HEADER_LENGTH:\n            return context\n\n        baggage_entries = header.split(\",\")\n        total_baggage_entries = self._MAX_PAIRS\n        for entry in baggage_entries:\n            if total_baggage_entries <= 0:\n                return context\n            total_baggage_entries -= 1\n            if len(entry) > self._MAX_PAIR_LENGTH:\n                continue\n            try:\n                name, value = entry.split(\"=\", 1)\n            except Exception:  # pylint: disable=broad-except\n                continue\n            context = baggage.set_baggage(\n                urllib.parse.unquote(name).strip(),\n                urllib.parse.unquote(value).strip(),\n                context=context,\n            )\n\n        return context\n\n    def inject(\n        self,\n        carrier: textmap.CarrierT,\n        context: typing.Optional[Context] = None,\n        setter: textmap.Setter = textmap.default_setter,\n    ) -> None:\n        \"\"\"Injects Baggage into the carrier.\n\n        See\n        `opentelemetry.propagators.textmap.TextMapPropagator.inject`\n        \"\"\"\n        baggage_entries = baggage.get_all(context=context)\n        if not baggage_entries:\n            return\n\n        baggage_string = _format_baggage(baggage_entries)\n        setter.set(carrier, self._BAGGAGE_HEADER_NAME, baggage_string)\n\n    @property\n    def fields(self) -> typing.Set[str]:\n        \"\"\"Returns a set with the fields set in `inject`.\"\"\"\n        return {self._BAGGAGE_HEADER_NAME}\n\n\ndef _format_baggage(baggage_entries: typing.Mapping[str, object]) -> str:\n    return \",\".join(\n        key + \"=\" + urllib.parse.quote_plus(str(value))\n        for key, value in baggage_entries.items()\n    )\n\n\ndef _extract_first_element(\n    items: typing.Optional[typing.Iterable[textmap.CarrierT]],\n) -> typing.Optional[textmap.CarrierT]:\n    if items is None:\n        return None\n    return next(iter(items), None)\n", "path": "opentelemetry-api/src/opentelemetry/baggage/propagation/__init__.py"}]}