We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Use sentinel value for input parameters that aren't sent by the clients
When using input types with optional fields we cannot differentiate by fields that have sent as null and fields that haven't been sent at all.

So I think we should use a sentinel value that tells the field is unset, and also behaves as falsy:

```python
class _Unset:
    def __bool__(self): return False

UNSET = _Unset()

# this utility might be useful, so we don't have to use an internal representation
def is_unset(value: Any):
    return value is UNSET
```

then we can use this class when instantiating the input types for a resolver:)

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `strawberry/utils/arguments.py`
Content:
```
1 import enum
2 from dataclasses import is_dataclass
3 from datetime import date, datetime, time
4 
5 from ..exceptions import UnsupportedTypeError
6 from .str_converters import to_camel_case, to_snake_case
7 from .typing import get_list_annotation, get_optional_annotation, is_list, is_optional
8 
9 
10 SCALAR_TYPES = [int, str, float, bytes, bool, datetime, date, time]
11 
12 
13 def _to_type(value, annotation):
14     if value is None:
15         return None
16 
17     if is_optional(annotation):
18         annotation = get_optional_annotation(annotation)
19 
20     # TODO: change this to be a is_scalar util and make sure it works with any scalar
21     if getattr(annotation, "__supertype__", annotation) in SCALAR_TYPES:
22         return value
23 
24     # Convert Enum fields to instances using the value. This is safe
25     # because graphql-core has already validated the input.
26     if isinstance(annotation, enum.EnumMeta):
27         return annotation(value)
28 
29     if is_list(annotation):
30         annotation = get_list_annotation(annotation)
31 
32         return [_to_type(x, annotation) for x in value]
33 
34     if is_dataclass(annotation):
35         fields = annotation.__dataclass_fields__
36 
37         kwargs = {}
38 
39         for name, field in fields.items():
40             dict_name = name
41 
42             if hasattr(field, "field_name") and field.field_name:
43                 dict_name = field.field_name
44             else:
45                 dict_name = to_camel_case(name)
46 
47             kwargs[name] = _to_type(value.get(dict_name), field.type)
48 
49         return annotation(**kwargs)
50 
51     raise UnsupportedTypeError(annotation)
52 
53 
54 def convert_args(args, annotations):
55     """Converts a nested dictionary to a dictionary of strawberry input types."""
56 
57     converted_args = {}
58 
59     for key, value in args.items():
60         key = to_snake_case(key)
61         annotation = annotations[key]
62 
63         converted_args[key] = _to_type(value, annotation)
64 
65     return converted_args
66
```
--- 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/strawberry/utils/arguments.py b/strawberry/utils/arguments.py
--- a/strawberry/utils/arguments.py
+++ b/strawberry/utils/arguments.py
@@ -1,19 +1,49 @@
 import enum
+import typing
 from dataclasses import is_dataclass
 from datetime import date, datetime, time
 
 from ..exceptions import UnsupportedTypeError
-from .str_converters import to_camel_case, to_snake_case
+from .str_converters import to_camel_case
 from .typing import get_list_annotation, get_optional_annotation, is_list, is_optional
 
 
 SCALAR_TYPES = [int, str, float, bytes, bool, datetime, date, time]
 
 
-def _to_type(value, annotation):
+class _Unset:
+    def __str__(self):
+        return ""
+
+    def __bool__(self):
+        return False
+
+
+UNSET = _Unset()
+
+
+def is_unset(value: typing.Any) -> bool:
+    return value is UNSET
+
+
+def convert_args(
+    value: typing.Union[typing.Dict[str, typing.Any], typing.Any],
+    annotation: typing.Union[typing.Dict[str, typing.Type], typing.Type],
+):
+    """Converts a nested dictionary to a dictionary of actual types.
+
+    It deals with conversion of input types to proper dataclasses and
+    also uses a sentinel value for unset values."""
+
+    if annotation == {}:
+        return value
+
     if value is None:
         return None
 
+    if is_unset(value):
+        return value
+
     if is_optional(annotation):
         annotation = get_optional_annotation(annotation)
 
@@ -24,19 +54,27 @@
     # Convert Enum fields to instances using the value. This is safe
     # because graphql-core has already validated the input.
     if isinstance(annotation, enum.EnumMeta):
-        return annotation(value)
+        return annotation(value)  # type: ignore
 
     if is_list(annotation):
         annotation = get_list_annotation(annotation)
 
-        return [_to_type(x, annotation) for x in value]
+        return [convert_args(x, annotation) for x in value]
+
+    fields = None
 
-    if is_dataclass(annotation):
-        fields = annotation.__dataclass_fields__
+    # we receive dicts when converting resolvers arguments to
+    # actual types
+    if isinstance(annotation, dict):
+        fields = annotation.items()
 
+    elif is_dataclass(annotation):
+        fields = annotation.__dataclass_fields__.items()
+
+    if fields:
         kwargs = {}
 
-        for name, field in fields.items():
+        for name, field in fields:
             dict_name = name
 
             if hasattr(field, "field_name") and field.field_name:
@@ -44,22 +82,19 @@
             else:
                 dict_name = to_camel_case(name)
 
-            kwargs[name] = _to_type(value.get(dict_name), field.type)
-
-        return annotation(**kwargs)
-
-    raise UnsupportedTypeError(annotation)
-
-
-def convert_args(args, annotations):
-    """Converts a nested dictionary to a dictionary of strawberry input types."""
+            # dataclasses field have a .type attribute
+            if hasattr(field, "type"):
+                field_type = field.type
+            # meanwhile when using dicts the value of the field is
+            # the actual type, for example in: { 'name': str }
+            else:
+                field_type = field
 
-    converted_args = {}
+            kwargs[name] = convert_args(value.get(dict_name, UNSET), field_type)
 
-    for key, value in args.items():
-        key = to_snake_case(key)
-        annotation = annotations[key]
+        if is_dataclass(annotation):
+            return annotation(**kwargs)  # type: ignore
 
-        converted_args[key] = _to_type(value, annotation)
+        return kwargs
 
-    return converted_args
+    raise UnsupportedTypeError(annotation)

{"golden_diff": "diff --git a/strawberry/utils/arguments.py b/strawberry/utils/arguments.py\n--- a/strawberry/utils/arguments.py\n+++ b/strawberry/utils/arguments.py\n@@ -1,19 +1,49 @@\n import enum\n+import typing\n from dataclasses import is_dataclass\n from datetime import date, datetime, time\n \n from ..exceptions import UnsupportedTypeError\n-from .str_converters import to_camel_case, to_snake_case\n+from .str_converters import to_camel_case\n from .typing import get_list_annotation, get_optional_annotation, is_list, is_optional\n \n \n SCALAR_TYPES = [int, str, float, bytes, bool, datetime, date, time]\n \n \n-def _to_type(value, annotation):\n+class _Unset:\n+    def __str__(self):\n+        return \"\"\n+\n+    def __bool__(self):\n+        return False\n+\n+\n+UNSET = _Unset()\n+\n+\n+def is_unset(value: typing.Any) -> bool:\n+    return value is UNSET\n+\n+\n+def convert_args(\n+    value: typing.Union[typing.Dict[str, typing.Any], typing.Any],\n+    annotation: typing.Union[typing.Dict[str, typing.Type], typing.Type],\n+):\n+    \"\"\"Converts a nested dictionary to a dictionary of actual types.\n+\n+    It deals with conversion of input types to proper dataclasses and\n+    also uses a sentinel value for unset values.\"\"\"\n+\n+    if annotation == {}:\n+        return value\n+\n     if value is None:\n         return None\n \n+    if is_unset(value):\n+        return value\n+\n     if is_optional(annotation):\n         annotation = get_optional_annotation(annotation)\n \n@@ -24,19 +54,27 @@\n     # Convert Enum fields to instances using the value. This is safe\n     # because graphql-core has already validated the input.\n     if isinstance(annotation, enum.EnumMeta):\n-        return annotation(value)\n+        return annotation(value)  # type: ignore\n \n     if is_list(annotation):\n         annotation = get_list_annotation(annotation)\n \n-        return [_to_type(x, annotation) for x in value]\n+        return [convert_args(x, annotation) for x in value]\n+\n+    fields = None\n \n-    if is_dataclass(annotation):\n-        fields = annotation.__dataclass_fields__\n+    # we receive dicts when converting resolvers arguments to\n+    # actual types\n+    if isinstance(annotation, dict):\n+        fields = annotation.items()\n \n+    elif is_dataclass(annotation):\n+        fields = annotation.__dataclass_fields__.items()\n+\n+    if fields:\n         kwargs = {}\n \n-        for name, field in fields.items():\n+        for name, field in fields:\n             dict_name = name\n \n             if hasattr(field, \"field_name\") and field.field_name:\n@@ -44,22 +82,19 @@\n             else:\n                 dict_name = to_camel_case(name)\n \n-            kwargs[name] = _to_type(value.get(dict_name), field.type)\n-\n-        return annotation(**kwargs)\n-\n-    raise UnsupportedTypeError(annotation)\n-\n-\n-def convert_args(args, annotations):\n-    \"\"\"Converts a nested dictionary to a dictionary of strawberry input types.\"\"\"\n+            # dataclasses field have a .type attribute\n+            if hasattr(field, \"type\"):\n+                field_type = field.type\n+            # meanwhile when using dicts the value of the field is\n+            # the actual type, for example in: { 'name': str }\n+            else:\n+                field_type = field\n \n-    converted_args = {}\n+            kwargs[name] = convert_args(value.get(dict_name, UNSET), field_type)\n \n-    for key, value in args.items():\n-        key = to_snake_case(key)\n-        annotation = annotations[key]\n+        if is_dataclass(annotation):\n+            return annotation(**kwargs)  # type: ignore\n \n-        converted_args[key] = _to_type(value, annotation)\n+        return kwargs\n \n-    return converted_args\n+    raise UnsupportedTypeError(annotation)\n", "issue": "Use sentinel value for input parameters that aren't sent by the clients\nWhen using input types with optional fields we cannot differentiate by fields that have sent as null and fields that haven't been sent at all.\r\n\r\nSo I think we should use a sentinel value that tells the field is unset, and also behaves as falsy:\r\n\r\n```python\r\nclass _Unset:\r\n    def __bool__(self): return False\r\n\r\nUNSET = _Unset()\r\n\r\n# this utility might be useful, so we don't have to use an internal representation\r\ndef is_unset(value: Any):\r\n    return value is UNSET\r\n```\r\n\r\nthen we can use this class when instantiating the input types for a resolver:)\n", "before_files": [{"content": "import enum\nfrom dataclasses import is_dataclass\nfrom datetime import date, datetime, time\n\nfrom ..exceptions import UnsupportedTypeError\nfrom .str_converters import to_camel_case, to_snake_case\nfrom .typing import get_list_annotation, get_optional_annotation, is_list, is_optional\n\n\nSCALAR_TYPES = [int, str, float, bytes, bool, datetime, date, time]\n\n\ndef _to_type(value, annotation):\n    if value is None:\n        return None\n\n    if is_optional(annotation):\n        annotation = get_optional_annotation(annotation)\n\n    # TODO: change this to be a is_scalar util and make sure it works with any scalar\n    if getattr(annotation, \"__supertype__\", annotation) in SCALAR_TYPES:\n        return value\n\n    # Convert Enum fields to instances using the value. This is safe\n    # because graphql-core has already validated the input.\n    if isinstance(annotation, enum.EnumMeta):\n        return annotation(value)\n\n    if is_list(annotation):\n        annotation = get_list_annotation(annotation)\n\n        return [_to_type(x, annotation) for x in value]\n\n    if is_dataclass(annotation):\n        fields = annotation.__dataclass_fields__\n\n        kwargs = {}\n\n        for name, field in fields.items():\n            dict_name = name\n\n            if hasattr(field, \"field_name\") and field.field_name:\n                dict_name = field.field_name\n            else:\n                dict_name = to_camel_case(name)\n\n            kwargs[name] = _to_type(value.get(dict_name), field.type)\n\n        return annotation(**kwargs)\n\n    raise UnsupportedTypeError(annotation)\n\n\ndef convert_args(args, annotations):\n    \"\"\"Converts a nested dictionary to a dictionary of strawberry input types.\"\"\"\n\n    converted_args = {}\n\n    for key, value in args.items():\n        key = to_snake_case(key)\n        annotation = annotations[key]\n\n        converted_args[key] = _to_type(value, annotation)\n\n    return converted_args\n", "path": "strawberry/utils/arguments.py"}], "after_files": [{"content": "import enum\nimport typing\nfrom dataclasses import is_dataclass\nfrom datetime import date, datetime, time\n\nfrom ..exceptions import UnsupportedTypeError\nfrom .str_converters import to_camel_case\nfrom .typing import get_list_annotation, get_optional_annotation, is_list, is_optional\n\n\nSCALAR_TYPES = [int, str, float, bytes, bool, datetime, date, time]\n\n\nclass _Unset:\n    def __str__(self):\n        return \"\"\n\n    def __bool__(self):\n        return False\n\n\nUNSET = _Unset()\n\n\ndef is_unset(value: typing.Any) -> bool:\n    return value is UNSET\n\n\ndef convert_args(\n    value: typing.Union[typing.Dict[str, typing.Any], typing.Any],\n    annotation: typing.Union[typing.Dict[str, typing.Type], typing.Type],\n):\n    \"\"\"Converts a nested dictionary to a dictionary of actual types.\n\n    It deals with conversion of input types to proper dataclasses and\n    also uses a sentinel value for unset values.\"\"\"\n\n    if annotation == {}:\n        return value\n\n    if value is None:\n        return None\n\n    if is_unset(value):\n        return value\n\n    if is_optional(annotation):\n        annotation = get_optional_annotation(annotation)\n\n    # TODO: change this to be a is_scalar util and make sure it works with any scalar\n    if getattr(annotation, \"__supertype__\", annotation) in SCALAR_TYPES:\n        return value\n\n    # Convert Enum fields to instances using the value. This is safe\n    # because graphql-core has already validated the input.\n    if isinstance(annotation, enum.EnumMeta):\n        return annotation(value)  # type: ignore\n\n    if is_list(annotation):\n        annotation = get_list_annotation(annotation)\n\n        return [convert_args(x, annotation) for x in value]\n\n    fields = None\n\n    # we receive dicts when converting resolvers arguments to\n    # actual types\n    if isinstance(annotation, dict):\n        fields = annotation.items()\n\n    elif is_dataclass(annotation):\n        fields = annotation.__dataclass_fields__.items()\n\n    if fields:\n        kwargs = {}\n\n        for name, field in fields:\n            dict_name = name\n\n            if hasattr(field, \"field_name\") and field.field_name:\n                dict_name = field.field_name\n            else:\n                dict_name = to_camel_case(name)\n\n            # dataclasses field have a .type attribute\n            if hasattr(field, \"type\"):\n                field_type = field.type\n            # meanwhile when using dicts the value of the field is\n            # the actual type, for example in: { 'name': str }\n            else:\n                field_type = field\n\n            kwargs[name] = convert_args(value.get(dict_name, UNSET), field_type)\n\n        if is_dataclass(annotation):\n            return annotation(**kwargs)  # type: ignore\n\n        return kwargs\n\n    raise UnsupportedTypeError(annotation)\n", "path": "strawberry/utils/arguments.py"}]}