# Data types

gel-python automatically converts Gel types to the corresponding Python types and vice versa.

The table below shows the correspondence between Gel and Python types.

| Gel Type                            | Python Type                                                                                                                                                                              |
| ----------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Set`                               | [`gel.Set`](https://docs.geldata.com/reference/using/python/api/types.md#gel.Set)                                                                                                        |
| `array<anytype>`                    | [`gel.Array`](https://docs.geldata.com/reference/using/python/api/types.md#gel.Array)                                                                                                    |
| `anytuple`                          | [`gel.Tuple`](https://docs.geldata.com/reference/using/python/api/types.md#gel.Tuple) or [`gel.NamedTuple`](https://docs.geldata.com/reference/using/python/api/types.md#gel.NamedTuple) |
| `anyenum`                           | [`gel.EnumValue`](https://docs.geldata.com/reference/using/python/api/types.md#gel.EnumValue)                                                                                            |
| `Object`                            | [`gel.Object`](https://docs.geldata.com/reference/using/python/api/types.md#gel.Object)                                                                                                  |
| `bool`                              | [`bool`](https://docs.python.org/3/library/functions.html#bool)                                                                                                                          |
| `bytes`                             | [`bytes`](https://docs.python.org/3/library/stdtypes.html#bytes)                                                                                                                         |
| `str`                               | [`str`](https://docs.python.org/3/library/stdtypes.html#str)                                                                                                                             |
| `cal::local_date`                   | [`datetime.date`](https://docs.python.org/3/library/datetime.html#datetime.date)                                                                                                         |
| `cal::local_time`                   | offset-naive [`datetime.time `](https://docs.python.org/3/library/datetime.html#datetime.time)                                                                                           |
| `cal::local_datetime`               | offset-naive [`datetime.datetime `](https://docs.python.org/3/library/datetime.html#datetime.datetime)                                                                                   |
| `cal::relative_duration`            | [`gel.RelativeDuration`](https://docs.geldata.com/reference/using/python/api/types.md#gel.RelativeDuration)                                                                              |
| `cal::date_duration`                | [`gel.DateDuration`](https://docs.geldata.com/reference/using/python/api/types.md#gel.DateDuration)                                                                                      |
| `datetime`                          | offset-aware [`datetime.datetime `](https://docs.python.org/3/library/datetime.html#datetime.datetime)                                                                                   |
| `duration`                          | [`datetime.timedelta `](https://docs.python.org/3/library/datetime.html#datetime.timedelta)                                                                                              |
| `float32`, `float64`                | [`float`](https://docs.python.org/3/library/functions.html#float)                                                                                                                        |
| `int16`, `int32`, `int64`, `bigint` | [`int`](https://docs.python.org/3/library/functions.html#int)                                                                                                                            |
| `decimal`                           | [`Decimal`](https://docs.python.org/3/library/decimal.html#decimal.Decimal)                                                                                                              |
| `json`                              | [`str`](https://docs.python.org/3/library/stdtypes.html#str)                                                                                                                             |
| `uuid`                              | [`uuid.UUID`](https://docs.python.org/3/library/uuid.html#uuid.UUID)                                                                                                                     |

> Note: Inexact single-precision `float` values may have a different representation when decoded into a Python float. This is inherent to the implementation of limited-precision floating point types. If you need the decimal representation to match, cast the expression to `float64` or `decimal` in your query.

## Sets

## Class: Set

```py
Set
```

This is [`list`](https://docs.python.org/3/library/stdtypes.html#list) since version 1.0.


## Objects

## Class: Object

```py
Object
```

An immutable representation of an object instance returned from a query.

`gel.Object` instances are dataclass-compatible since version 1.0, for example, `dataclasses.is_dataclass()` will return `True`, and `dataclasses.asdict()` will work on `gel.Object` instances.

`gel.Object.__hash__` is just `object.__hash__` in version 1.0. Similarly, `==` is equivalent to the `is` operator comparing `gel.Object` instances, and `<`, `<=`, `>`, `>=` are not allowed on `gel.Object` instances.

The value of an object property or a link can be accessed through a corresponding attribute:

```pycon
>>> import gel
>>> client = gel.create_client()
>>> r = client.query_single('''
...     SELECT schema::ObjectType {name}
...     FILTER .name = 'std::Object'
...     LIMIT 1''')
>>> r
Object{name := 'std::Object'}
>>> r.name
'std::Object'
```

## Describe: obj[linkname]

```
obj[linkname]
```

Return a [`gel.Link`](https://docs.geldata.com/reference/using/python/api/types.md#gel.Link) or a [`gel.LinkSet`](https://docs.geldata.com/reference/using/python/api/types.md#gel.LinkSet) instance representing the instance(s) of link *linkname* associated with *obj*.

Example:

```pycon
>>> import gel
>>> client = gel.create_client()
>>> r = client.query_single('''
...     SELECT schema::Property {name, annotations: {name, @value}}
...     FILTER .name = 'listen_port'
...            AND .source.name = 'cfg::Config'
...     LIMIT 1''')
>>> r
Object {
    name: 'listen_port',
    annotations: {
        Object {
            name: 'cfg::system',
            @value: 'true'
        }
    }
}
>>> r['annotations']
LinkSet(name='annotations')
>>> l = list(r['annotations])[0]
>>> l.value
'true'
```



## Links

## Class: Link

```py
Link
```

An immutable representation of an object link.

Links are created when [`gel.Object`](https://docs.geldata.com/reference/using/python/api/types.md#gel.Object) is accessed via a `[]` operator. Using Link objects explicitly is useful for accessing link properties.


## Class: LinkSet

```py
LinkSet
```

An immutable representation of a set of Links.

LinkSets are created when a multi link on [`gel.Object`](https://docs.geldata.com/reference/using/python/api/types.md#gel.Object) is accessed via a `[]` operator.


## Tuples

## Class: Tuple

```py
Tuple
```

This is [`tuple`](https://docs.python.org/3/library/stdtypes.html#tuple) since version 1.0.


## Named Tuples

## Class: NamedTuple

```py
NamedTuple
```

An immutable value representing a Gel named tuple value.

`gel.NamedTuple` is a subclass of [`tuple`](https://docs.python.org/3/library/stdtypes.html#tuple) and is duck-type compatible with `collections.namedtuple` since version 1.0.

Instances of `gel.NamedTuple` generally behave similarly to [`namedtuple`](https://docs.python.org/3/library/collections.html#collections.namedtuple):

```pycon
>>> import gel
>>> client = gel.create_client()
>>> r = client.query_single('''SELECT (a := 1, b := 'a', c := [3])''')
>>> r
(a := 1, b := 'a', c := [3])
>>> r.b
'a'
>>> r[0]
1
>>> r == (1, 'a', [3])
True
>>> r._fields
('a', 'b', 'c')
```


## Arrays

## Class: Array

```py
Array
```

This is [`list`](https://docs.python.org/3/library/stdtypes.html#list) since version 1.0.


## RelativeDuration

## Class: RelativeDuration

```py
RelativeDuration
```

An immutable value representing a Gel `cal::relative_duration` value.

```pycon
>>> import gel
>>> client = gel.create_client()
>>> r = client.query_single('''SELECT <cal::relative_duration>"1 year 2 days 3 seconds"''')
>>> r
<gel.RelativeDuration "P1Y2DT3S">
>>> r.months
12
>>> r.days
2
>>> r.microseconds
3000000
```


## DateDuration

## Class: DateDuration

```py
DateDuration
```

An immutable value representing a Gel `cal::date_duration` value.

```pycon
>>> import gel
>>> client = gel.create_client()
>>> r = client.query_single('''SELECT <cal::date_duration>"1 year 2 days"''')
>>> r
<gel.DateDuration "P1Y2D">
>>> r.months
12
>>> r.days
2
```


## EnumValue

## Class: EnumValue

```py
EnumValue
```

An immutable value representing a Gel enum value.

Since version 1.0, `gel.EnumValue` is a subclass of [`enum.Enum`](https://docs.python.org/3/library/enum.html#enum.Enum). Actual enum values are instances of ad-hoc enum classes created by the codecs to represent the actual members defined in your Gel schema.

```pycon
>>> import gel
>>> client = gel.create_client()
>>> r = client.query_single("""SELECT <Color>'red'""")
>>> r
<gel.EnumValue 'red'>
>>> str(r)
'red'
>>> r.value  # added in 1.0
'red'
>>> r.name  # added in 1.0, simply str.upper() of r.value
'RED'
```


