# `SnakeBridge.Dynamic`
[🔗](https://github.com/nshkrdotcom/snakebridge/blob/v0.16.0/lib/snakebridge/dynamic.ex#L1)

Dynamic dispatch for calling methods on Python objects without generated code.

Use this module when:
- Python returns an object of a class you did not generate bindings for
- You need to call methods dynamically at runtime
- You want a no-codegen escape hatch for refs

# `opts`

```elixir
@type opts() :: keyword()
```

# `ref`

```elixir
@type ref() :: SnakeBridge.Ref.t() | map()
```

# `call`

```elixir
@spec call(ref(), atom() | String.t(), list(), opts()) ::
  {:ok, term()} | {:error, SnakeBridge.Runtime.error_reason()}
```

Calls a method on a Python object reference.

# `get_attr`

```elixir
@spec get_attr(ref(), atom() | String.t(), opts()) ::
  {:ok, term()} | {:error, SnakeBridge.Runtime.error_reason()}
```

Gets an attribute from a Python object reference.

# `ref?`

```elixir
@spec ref?(term()) :: boolean()
```

Checks if a value is a valid Python reference.

# `set_attr`

```elixir
@spec set_attr(ref(), atom() | String.t(), term(), opts()) ::
  {:ok, term()} | {:error, SnakeBridge.Runtime.error_reason()}
```

Sets an attribute on a Python object reference.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
