posit-dev / posit-dev/py-shiny

How to properly type annotate reactive objects

Open
#1,676 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

needs-triage
Dominant language
Python
Stars
1.8k
Forks
135
Avg merge
2d 18h
Merged PRs (30d)
21

Description

I have some trouble with properly type hinting reactive objects when working with modules servers.

I use pyright as my LSP and I want to properly type annotate the return types of module server objects (that are reactive) such that in other code the static type checking is correct.

Type hinting reactive Calc:

Say I have reactive calc that returns an object of type 'T'. How do I type annotate the output of my module server in the following situation.

from shiny import module, reactive

@module.server
def mod_server(input, output, session) -> ???:
    @reactive.calc
    def my_calc() -> T:
         return object_of_type_T
    return my_calc

My pyright LSP is saying that the return type of mod_server is of type Calc_[T]. But I see that Calc_ is explicitly listed as not exported over here: https://github.com/posit-dev/py-shiny/blob/main/shiny/reactive/__init__.py#L16

I could define type my own generic type that represent a ReactiveCalc function, but then pyright would complain about mismatch between listed return type and the Calc_[T] return.

Am I missing something?

Type hinting input.xxx

Secondly, how to properly annotate input.xxx reactives? Such that my Lsp would display the correct type for: input.xxx().

Eg. how would I type annotate the return of the following module server? (inspired by the module communcation article )

from shiny import module, render, ui

@module.ui
def city_state_ui():
    return ui.input_selectize("state", "State", choices=["NY", "CO", "OR", "MI"], selected="NY")

@module.server 
def mod_server(input, output, session) -> ???:
    return input.state

Reactive value

Type hinting with reactive value objects seems to be supported. At least the following type hinting results in expected behaviour:

from shiny import reactive
from shiny.reactive import Value 
x : Value[int] = reactive.value(1)

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with shiny/reactive/init.py at the noted Calc_ export and review the module communication article's returning-reactives example. Trace the annotations for reactive.calc, input.state, and reactive.Value to determine the documented public types. Done means the supported annotation approach and expected return types are clear for both module-server cases.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
developer-experience
Issue type
Documentation
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.