We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Algoliasearch non-text argument used in set_tag_str
See https://github.com/DataDog/dd-trace-py/pull/4727#issuecomment-1511668474, we changed a usage of `set_tag()` to `set_tag_str()` in our algoliasearch integration, but that patched function involves non-text arguments that `set_tag_str()` throws an error for.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `ddtrace/contrib/algoliasearch/patch.py`
Content:
```
1 from ddtrace import config
2 from ddtrace.ext import SpanKind
3 from ddtrace.ext import SpanTypes
4 from ddtrace.internal.constants import COMPONENT
5 from ddtrace.internal.utils.wrappers import unwrap as _u
6 from ddtrace.pin import Pin
7 from ddtrace.vendor.wrapt import wrap_function_wrapper as _w
8 
9 from .. import trace_utils
10 from ...constants import SPAN_KIND
11 from ...constants import SPAN_MEASURED_KEY
12 
13 
14 DD_PATCH_ATTR = "_datadog_patch"
15 
16 SERVICE_NAME = "algoliasearch"
17 APP_NAME = "algoliasearch"
18 
19 try:
20     import algoliasearch
21     from algoliasearch.version import VERSION
22 
23     algoliasearch_version = tuple([int(i) for i in VERSION.split(".")])
24 
25     # Default configuration
26     config._add("algoliasearch", dict(_default_service=SERVICE_NAME, collect_query_text=False))
27 except ImportError:
28     algoliasearch_version = (0, 0)
29 
30 
31 def patch():
32     if algoliasearch_version == (0, 0):
33         return
34 
35     if getattr(algoliasearch, DD_PATCH_ATTR, False):
36         return
37 
38     setattr(algoliasearch, "_datadog_patch", True)
39 
40     pin = Pin()
41 
42     if algoliasearch_version < (2, 0) and algoliasearch_version >= (1, 0):
43         _w(algoliasearch.index, "Index.search", _patched_search)
44         pin.onto(algoliasearch.index.Index)
45     elif algoliasearch_version >= (2, 0) and algoliasearch_version < (3, 0):
46         from algoliasearch import search_index
47 
48         _w(algoliasearch, "search_index.SearchIndex.search", _patched_search)
49         pin.onto(search_index.SearchIndex)
50     else:
51         return
52 
53 
54 def unpatch():
55     if algoliasearch_version == (0, 0):
56         return
57 
58     if getattr(algoliasearch, DD_PATCH_ATTR, False):
59         setattr(algoliasearch, DD_PATCH_ATTR, False)
60 
61         if algoliasearch_version < (2, 0) and algoliasearch_version >= (1, 0):
62             _u(algoliasearch.index.Index, "search")
63         elif algoliasearch_version >= (2, 0) and algoliasearch_version < (3, 0):
64             from algoliasearch import search_index
65 
66             _u(search_index.SearchIndex, "search")
67         else:
68             return
69 
70 
71 # DEV: this maps serves the dual purpose of enumerating the algoliasearch.search() query_args that
72 # will be sent along as tags, as well as converting arguments names into tag names compliant with
73 # tag naming recommendations set out here: https://docs.datadoghq.com/tagging/
74 QUERY_ARGS_DD_TAG_MAP = {
75     "page": "page",
76     "hitsPerPage": "hits_per_page",
77     "attributesToRetrieve": "attributes_to_retrieve",
78     "attributesToHighlight": "attributes_to_highlight",
79     "attributesToSnippet": "attributes_to_snippet",
80     "minWordSizefor1Typo": "min_word_size_for_1_typo",
81     "minWordSizefor2Typos": "min_word_size_for_2_typos",
82     "getRankingInfo": "get_ranking_info",
83     "aroundLatLng": "around_lat_lng",
84     "numericFilters": "numeric_filters",
85     "tagFilters": "tag_filters",
86     "queryType": "query_type",
87     "optionalWords": "optional_words",
88     "distinct": "distinct",
89 }
90 
91 
92 def _patched_search(func, instance, wrapt_args, wrapt_kwargs):
93     """
94     wrapt_args is called the way it is to distinguish it from the 'args'
95     argument to the algoliasearch.index.Index.search() method.
96     """
97 
98     if algoliasearch_version < (2, 0) and algoliasearch_version >= (1, 0):
99         function_query_arg_name = "args"
100     elif algoliasearch_version >= (2, 0) and algoliasearch_version < (3, 0):
101         function_query_arg_name = "request_options"
102     else:
103         return func(*wrapt_args, **wrapt_kwargs)
104 
105     pin = Pin.get_from(instance)
106     if not pin or not pin.enabled():
107         return func(*wrapt_args, **wrapt_kwargs)
108 
109     with pin.tracer.trace(
110         "algoliasearch.search",
111         service=trace_utils.ext_service(pin, config.algoliasearch),
112         span_type=SpanTypes.HTTP,
113     ) as span:
114         span.set_tag_str(COMPONENT, config.algoliasearch.integration_name)
115 
116         # set span.kind to the type of request being performed
117         span.set_tag_str(SPAN_KIND, SpanKind.CLIENT)
118 
119         span.set_tag(SPAN_MEASURED_KEY)
120 
121         if not span.sampled:
122             return func(*wrapt_args, **wrapt_kwargs)
123 
124         if config.algoliasearch.collect_query_text:
125             span.set_tag_str("query.text", wrapt_kwargs.get("query", wrapt_args[0]))
126 
127         query_args = wrapt_kwargs.get(function_query_arg_name, wrapt_args[1] if len(wrapt_args) > 1 else None)
128 
129         if query_args and isinstance(query_args, dict):
130             for query_arg, tag_name in QUERY_ARGS_DD_TAG_MAP.items():
131                 value = query_args.get(query_arg)
132                 if value is not None:
133                     span.set_tag_str("query.args.{}".format(tag_name), value)
134 
135         # Result would look like this
136         # {
137         #   'hits': [
138         #     {
139         #       .... your search results ...
140         #     }
141         #   ],
142         #   'processingTimeMS': 1,
143         #   'nbHits': 1,
144         #   'hitsPerPage': 20,
145         #   'exhaustiveNbHits': true,
146         #   'params': 'query=xxx',
147         #   'nbPages': 1,
148         #   'query': 'xxx',
149         #   'page': 0
150         # }
151         result = func(*wrapt_args, **wrapt_kwargs)
152 
153         if isinstance(result, dict):
154             if result.get("processingTimeMS", None) is not None:
155                 span.set_metric("processing_time_ms", int(result["processingTimeMS"]))
156 
157             if result.get("nbHits", None) is not None:
158                 span.set_metric("number_of_hits", int(result["nbHits"]))
159 
160         return result
161
```
--- 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()

```

diff --git a/ddtrace/contrib/algoliasearch/patch.py b/ddtrace/contrib/algoliasearch/patch.py
--- a/ddtrace/contrib/algoliasearch/patch.py
+++ b/ddtrace/contrib/algoliasearch/patch.py
@@ -130,7 +130,7 @@
             for query_arg, tag_name in QUERY_ARGS_DD_TAG_MAP.items():
                 value = query_args.get(query_arg)
                 if value is not None:
-                    span.set_tag_str("query.args.{}".format(tag_name), value)
+                    span.set_tag("query.args.{}".format(tag_name), value)
 
         # Result would look like this
         # {

{"golden_diff": "diff --git a/ddtrace/contrib/algoliasearch/patch.py b/ddtrace/contrib/algoliasearch/patch.py\n--- a/ddtrace/contrib/algoliasearch/patch.py\n+++ b/ddtrace/contrib/algoliasearch/patch.py\n@@ -130,7 +130,7 @@\n             for query_arg, tag_name in QUERY_ARGS_DD_TAG_MAP.items():\n                 value = query_args.get(query_arg)\n                 if value is not None:\n-                    span.set_tag_str(\"query.args.{}\".format(tag_name), value)\n+                    span.set_tag(\"query.args.{}\".format(tag_name), value)\n \n         # Result would look like this\n         # {\n", "issue": "Algoliasearch non-text argument used in set_tag_str\nSee https://github.com/DataDog/dd-trace-py/pull/4727#issuecomment-1511668474, we changed a usage of `set_tag()` to `set_tag_str()` in our algoliasearch integration, but that patched function involves non-text arguments that `set_tag_str()` throws an error for.\r\n\n", "before_files": [{"content": "from ddtrace import config\nfrom ddtrace.ext import SpanKind\nfrom ddtrace.ext import SpanTypes\nfrom ddtrace.internal.constants import COMPONENT\nfrom ddtrace.internal.utils.wrappers import unwrap as _u\nfrom ddtrace.pin import Pin\nfrom ddtrace.vendor.wrapt import wrap_function_wrapper as _w\n\nfrom .. import trace_utils\nfrom ...constants import SPAN_KIND\nfrom ...constants import SPAN_MEASURED_KEY\n\n\nDD_PATCH_ATTR = \"_datadog_patch\"\n\nSERVICE_NAME = \"algoliasearch\"\nAPP_NAME = \"algoliasearch\"\n\ntry:\n    import algoliasearch\n    from algoliasearch.version import VERSION\n\n    algoliasearch_version = tuple([int(i) for i in VERSION.split(\".\")])\n\n    # Default configuration\n    config._add(\"algoliasearch\", dict(_default_service=SERVICE_NAME, collect_query_text=False))\nexcept ImportError:\n    algoliasearch_version = (0, 0)\n\n\ndef patch():\n    if algoliasearch_version == (0, 0):\n        return\n\n    if getattr(algoliasearch, DD_PATCH_ATTR, False):\n        return\n\n    setattr(algoliasearch, \"_datadog_patch\", True)\n\n    pin = Pin()\n\n    if algoliasearch_version < (2, 0) and algoliasearch_version >= (1, 0):\n        _w(algoliasearch.index, \"Index.search\", _patched_search)\n        pin.onto(algoliasearch.index.Index)\n    elif algoliasearch_version >= (2, 0) and algoliasearch_version < (3, 0):\n        from algoliasearch import search_index\n\n        _w(algoliasearch, \"search_index.SearchIndex.search\", _patched_search)\n        pin.onto(search_index.SearchIndex)\n    else:\n        return\n\n\ndef unpatch():\n    if algoliasearch_version == (0, 0):\n        return\n\n    if getattr(algoliasearch, DD_PATCH_ATTR, False):\n        setattr(algoliasearch, DD_PATCH_ATTR, False)\n\n        if algoliasearch_version < (2, 0) and algoliasearch_version >= (1, 0):\n            _u(algoliasearch.index.Index, \"search\")\n        elif algoliasearch_version >= (2, 0) and algoliasearch_version < (3, 0):\n            from algoliasearch import search_index\n\n            _u(search_index.SearchIndex, \"search\")\n        else:\n            return\n\n\n# DEV: this maps serves the dual purpose of enumerating the algoliasearch.search() query_args that\n# will be sent along as tags, as well as converting arguments names into tag names compliant with\n# tag naming recommendations set out here: https://docs.datadoghq.com/tagging/\nQUERY_ARGS_DD_TAG_MAP = {\n    \"page\": \"page\",\n    \"hitsPerPage\": \"hits_per_page\",\n    \"attributesToRetrieve\": \"attributes_to_retrieve\",\n    \"attributesToHighlight\": \"attributes_to_highlight\",\n    \"attributesToSnippet\": \"attributes_to_snippet\",\n    \"minWordSizefor1Typo\": \"min_word_size_for_1_typo\",\n    \"minWordSizefor2Typos\": \"min_word_size_for_2_typos\",\n    \"getRankingInfo\": \"get_ranking_info\",\n    \"aroundLatLng\": \"around_lat_lng\",\n    \"numericFilters\": \"numeric_filters\",\n    \"tagFilters\": \"tag_filters\",\n    \"queryType\": \"query_type\",\n    \"optionalWords\": \"optional_words\",\n    \"distinct\": \"distinct\",\n}\n\n\ndef _patched_search(func, instance, wrapt_args, wrapt_kwargs):\n    \"\"\"\n    wrapt_args is called the way it is to distinguish it from the 'args'\n    argument to the algoliasearch.index.Index.search() method.\n    \"\"\"\n\n    if algoliasearch_version < (2, 0) and algoliasearch_version >= (1, 0):\n        function_query_arg_name = \"args\"\n    elif algoliasearch_version >= (2, 0) and algoliasearch_version < (3, 0):\n        function_query_arg_name = \"request_options\"\n    else:\n        return func(*wrapt_args, **wrapt_kwargs)\n\n    pin = Pin.get_from(instance)\n    if not pin or not pin.enabled():\n        return func(*wrapt_args, **wrapt_kwargs)\n\n    with pin.tracer.trace(\n        \"algoliasearch.search\",\n        service=trace_utils.ext_service(pin, config.algoliasearch),\n        span_type=SpanTypes.HTTP,\n    ) as span:\n        span.set_tag_str(COMPONENT, config.algoliasearch.integration_name)\n\n        # set span.kind to the type of request being performed\n        span.set_tag_str(SPAN_KIND, SpanKind.CLIENT)\n\n        span.set_tag(SPAN_MEASURED_KEY)\n\n        if not span.sampled:\n            return func(*wrapt_args, **wrapt_kwargs)\n\n        if config.algoliasearch.collect_query_text:\n            span.set_tag_str(\"query.text\", wrapt_kwargs.get(\"query\", wrapt_args[0]))\n\n        query_args = wrapt_kwargs.get(function_query_arg_name, wrapt_args[1] if len(wrapt_args) > 1 else None)\n\n        if query_args and isinstance(query_args, dict):\n            for query_arg, tag_name in QUERY_ARGS_DD_TAG_MAP.items():\n                value = query_args.get(query_arg)\n                if value is not None:\n                    span.set_tag_str(\"query.args.{}\".format(tag_name), value)\n\n        # Result would look like this\n        # {\n        #   'hits': [\n        #     {\n        #       .... your search results ...\n        #     }\n        #   ],\n        #   'processingTimeMS': 1,\n        #   'nbHits': 1,\n        #   'hitsPerPage': 20,\n        #   'exhaustiveNbHits': true,\n        #   'params': 'query=xxx',\n        #   'nbPages': 1,\n        #   'query': 'xxx',\n        #   'page': 0\n        # }\n        result = func(*wrapt_args, **wrapt_kwargs)\n\n        if isinstance(result, dict):\n            if result.get(\"processingTimeMS\", None) is not None:\n                span.set_metric(\"processing_time_ms\", int(result[\"processingTimeMS\"]))\n\n            if result.get(\"nbHits\", None) is not None:\n                span.set_metric(\"number_of_hits\", int(result[\"nbHits\"]))\n\n        return result\n", "path": "ddtrace/contrib/algoliasearch/patch.py"}], "after_files": [{"content": "from ddtrace import config\nfrom ddtrace.ext import SpanKind\nfrom ddtrace.ext import SpanTypes\nfrom ddtrace.internal.constants import COMPONENT\nfrom ddtrace.internal.utils.wrappers import unwrap as _u\nfrom ddtrace.pin import Pin\nfrom ddtrace.vendor.wrapt import wrap_function_wrapper as _w\n\nfrom .. import trace_utils\nfrom ...constants import SPAN_KIND\nfrom ...constants import SPAN_MEASURED_KEY\n\n\nDD_PATCH_ATTR = \"_datadog_patch\"\n\nSERVICE_NAME = \"algoliasearch\"\nAPP_NAME = \"algoliasearch\"\n\ntry:\n    import algoliasearch\n    from algoliasearch.version import VERSION\n\n    algoliasearch_version = tuple([int(i) for i in VERSION.split(\".\")])\n\n    # Default configuration\n    config._add(\"algoliasearch\", dict(_default_service=SERVICE_NAME, collect_query_text=False))\nexcept ImportError:\n    algoliasearch_version = (0, 0)\n\n\ndef patch():\n    if algoliasearch_version == (0, 0):\n        return\n\n    if getattr(algoliasearch, DD_PATCH_ATTR, False):\n        return\n\n    setattr(algoliasearch, \"_datadog_patch\", True)\n\n    pin = Pin()\n\n    if algoliasearch_version < (2, 0) and algoliasearch_version >= (1, 0):\n        _w(algoliasearch.index, \"Index.search\", _patched_search)\n        pin.onto(algoliasearch.index.Index)\n    elif algoliasearch_version >= (2, 0) and algoliasearch_version < (3, 0):\n        from algoliasearch import search_index\n\n        _w(algoliasearch, \"search_index.SearchIndex.search\", _patched_search)\n        pin.onto(search_index.SearchIndex)\n    else:\n        return\n\n\ndef unpatch():\n    if algoliasearch_version == (0, 0):\n        return\n\n    if getattr(algoliasearch, DD_PATCH_ATTR, False):\n        setattr(algoliasearch, DD_PATCH_ATTR, False)\n\n        if algoliasearch_version < (2, 0) and algoliasearch_version >= (1, 0):\n            _u(algoliasearch.index.Index, \"search\")\n        elif algoliasearch_version >= (2, 0) and algoliasearch_version < (3, 0):\n            from algoliasearch import search_index\n\n            _u(search_index.SearchIndex, \"search\")\n        else:\n            return\n\n\n# DEV: this maps serves the dual purpose of enumerating the algoliasearch.search() query_args that\n# will be sent along as tags, as well as converting arguments names into tag names compliant with\n# tag naming recommendations set out here: https://docs.datadoghq.com/tagging/\nQUERY_ARGS_DD_TAG_MAP = {\n    \"page\": \"page\",\n    \"hitsPerPage\": \"hits_per_page\",\n    \"attributesToRetrieve\": \"attributes_to_retrieve\",\n    \"attributesToHighlight\": \"attributes_to_highlight\",\n    \"attributesToSnippet\": \"attributes_to_snippet\",\n    \"minWordSizefor1Typo\": \"min_word_size_for_1_typo\",\n    \"minWordSizefor2Typos\": \"min_word_size_for_2_typos\",\n    \"getRankingInfo\": \"get_ranking_info\",\n    \"aroundLatLng\": \"around_lat_lng\",\n    \"numericFilters\": \"numeric_filters\",\n    \"tagFilters\": \"tag_filters\",\n    \"queryType\": \"query_type\",\n    \"optionalWords\": \"optional_words\",\n    \"distinct\": \"distinct\",\n}\n\n\ndef _patched_search(func, instance, wrapt_args, wrapt_kwargs):\n    \"\"\"\n    wrapt_args is called the way it is to distinguish it from the 'args'\n    argument to the algoliasearch.index.Index.search() method.\n    \"\"\"\n\n    if algoliasearch_version < (2, 0) and algoliasearch_version >= (1, 0):\n        function_query_arg_name = \"args\"\n    elif algoliasearch_version >= (2, 0) and algoliasearch_version < (3, 0):\n        function_query_arg_name = \"request_options\"\n    else:\n        return func(*wrapt_args, **wrapt_kwargs)\n\n    pin = Pin.get_from(instance)\n    if not pin or not pin.enabled():\n        return func(*wrapt_args, **wrapt_kwargs)\n\n    with pin.tracer.trace(\n        \"algoliasearch.search\",\n        service=trace_utils.ext_service(pin, config.algoliasearch),\n        span_type=SpanTypes.HTTP,\n    ) as span:\n        span.set_tag_str(COMPONENT, config.algoliasearch.integration_name)\n\n        # set span.kind to the type of request being performed\n        span.set_tag_str(SPAN_KIND, SpanKind.CLIENT)\n\n        span.set_tag(SPAN_MEASURED_KEY)\n\n        if not span.sampled:\n            return func(*wrapt_args, **wrapt_kwargs)\n\n        if config.algoliasearch.collect_query_text:\n            span.set_tag_str(\"query.text\", wrapt_kwargs.get(\"query\", wrapt_args[0]))\n\n        query_args = wrapt_kwargs.get(function_query_arg_name, wrapt_args[1] if len(wrapt_args) > 1 else None)\n\n        if query_args and isinstance(query_args, dict):\n            for query_arg, tag_name in QUERY_ARGS_DD_TAG_MAP.items():\n                value = query_args.get(query_arg)\n                if value is not None:\n                    span.set_tag(\"query.args.{}\".format(tag_name), value)\n\n        # Result would look like this\n        # {\n        #   'hits': [\n        #     {\n        #       .... your search results ...\n        #     }\n        #   ],\n        #   'processingTimeMS': 1,\n        #   'nbHits': 1,\n        #   'hitsPerPage': 20,\n        #   'exhaustiveNbHits': true,\n        #   'params': 'query=xxx',\n        #   'nbPages': 1,\n        #   'query': 'xxx',\n        #   'page': 0\n        # }\n        result = func(*wrapt_args, **wrapt_kwargs)\n\n        if isinstance(result, dict):\n            if result.get(\"processingTimeMS\", None) is not None:\n                span.set_metric(\"processing_time_ms\", int(result[\"processingTimeMS\"]))\n\n            if result.get(\"nbHits\", None) is not None:\n                span.set_metric(\"number_of_hits\", int(result[\"nbHits\"]))\n\n        return result\n", "path": "ddtrace/contrib/algoliasearch/patch.py"}]}