Skip to content

Commit 51198af

Browse files
authored
v2.0.0b5 (#1312)
- Bump minimum Python version to 3.10 - Better error message if ASGI dependencies are missing - Removed `reactpy.types.ContextProviderType` top-level export. Use `reactpy.types.ContextProvider` instead. - Removed `reactpy.types.LayoutType` top-level export. Use `reactpy.types.BaseLayout` instead. - No longer require a package `name` within `reactjs_component_from_*` - Remove `pip` dependency - Convert `orjson` into an ASGI only dependency - Fix `@reactpy/client`'s dependency path for `event-to-object` - Fix #1001 - Fix #624 - Fix #1198 - Fix #1201
1 parent 78c8f1a commit 51198af

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+1144
-638
lines changed

.github/copilot-instructions.md

Lines changed: 153 additions & 118 deletions
Large diffs are not rendered by default.

.github/workflows/check.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ jobs:
2727
job-name: "python-{0} {1}"
2828
run-cmd: "hatch test"
2929
runs-on: '["ubuntu-latest", "macos-latest", "windows-latest"]'
30-
python-version: '["3.10", "3.11", "3.12", "3.13"]'
30+
python-version: '["3.11", "3.12", "3.13", "3.14"]'
3131
test-documentation:
3232
# Temporarily disabled while we transition from Sphinx to MkDocs
3333
# https://github.com/reactive-python/reactpy/pull/1052

.prettierrc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{
22
"proseWrap": "never",
3-
"trailingComma": "all"
3+
"trailingComma": "all",
4+
"endOfLine": "auto"
45
}

.serena/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/cache

.serena/memories/code_style.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Code Style & Conventions
2+
3+
- **Formatting**: Enforced by `hatch fmt`.
4+
- **Type Hints**: Required, checked by `hatch run python:type_check`.
5+
- **JS Linting**: Enforced by `hatch run javascript:check`.
6+
- **Tests**: All tests must pass. Failures not allowed.
7+
- **Documentation**: Must be updated with code changes.
8+
- **Changelog**: Required for significant changes.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Development Workflow
2+
3+
1. **Bootstrap**: Install Python 3.9+, Hatch, Bun.
4+
2. **Changes**: Modify code.
5+
3. **Format**: `hatch fmt`.
6+
4. **Type Check**: `hatch run python:type_check`.
7+
5. **JS Check**: `hatch run javascript:check` (if JS changed).
8+
6. **Test**: `hatch test`.
9+
7. **Validate**: Manual component/server tests.
10+
8. **Build JS**: `hatch run javascript:build` (if JS changed).
11+
9. **Docs**: Update if Python source changed.
12+
10. **Changelog**: Add entry in `docs/source/about/changelog.rst`.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# ReactPy Overview
2+
3+
## Purpose
4+
ReactPy builds UIs in Python without JS, using React-like components and a Python-to-JS bridge.
5+
6+
## Tech Stack
7+
- **Python**: 3.9+
8+
- **Build**: Hatch
9+
- **JS Runtime**: Bun
10+
- **Deps**: fastjsonschema, requests, lxml, anyio
11+
12+
## Structure
13+
- `src/reactpy/`: Python source (core, web, executors).
14+
- `src/js/`: JS packages (client, app).
15+
- `tests/`: Test suite.
16+
- `docs/`: Documentation.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Suggested Commands (Hatch)
2+
3+
## Python
4+
- **Test**: `hatch test` (All must pass)
5+
- **Coverage**: `hatch test --cover`
6+
- **Format**: `hatch fmt`
7+
- **Check Format**: `hatch fmt --check`
8+
- **Type Check**: `hatch run python:type_check`
9+
- **Build**: `hatch build --clean`
10+
11+
## JavaScript
12+
- **Build**: `hatch run javascript:build` (Rebuild after JS changes)
13+
- **Check**: `hatch run javascript:check`
14+
- **Fix**: `hatch run javascript:fix`
15+
16+
## Shell
17+
- **Dev Shell**: `hatch shell`

.serena/project.yml

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# list of languages for which language servers are started; choose from:
2+
# al bash clojure cpp csharp csharp_omnisharp
3+
# dart elixir elm erlang fortran go
4+
# haskell java julia kotlin lua markdown
5+
# nix perl php python python_jedi r
6+
# rego ruby ruby_solargraph rust scala swift
7+
# terraform typescript typescript_vts yaml zig
8+
# Note:
9+
# - For C, use cpp
10+
# - For JavaScript, use typescript
11+
# Special requirements:
12+
# - csharp: Requires the presence of a .sln file in the project folder.
13+
# When using multiple languages, the first language server that supports a given file will be used for that file.
14+
# The first language is the default language and the respective language server will be used as a fallback.
15+
# Note that when using the JetBrains backend, language servers are not used and this list is correspondingly ignored.
16+
languages:
17+
- python
18+
19+
# the encoding used by text files in the project
20+
# For a list of possible encodings, see https://docs.python.org/3.11/library/codecs.html#standard-encodings
21+
encoding: "utf-8"
22+
23+
# whether to use the project's gitignore file to ignore files
24+
# Added on 2025-04-07
25+
ignore_all_files_in_gitignore: true
26+
27+
# list of additional paths to ignore
28+
# same syntax as gitignore, so you can use * and **
29+
# Was previously called `ignored_dirs`, please update your config if you are using that.
30+
# Added (renamed) on 2025-04-07
31+
ignored_paths: []
32+
33+
# whether the project is in read-only mode
34+
# If set to true, all editing tools will be disabled and attempts to use them will result in an error
35+
# Added on 2025-04-18
36+
read_only: false
37+
38+
# list of tool names to exclude. We recommend not excluding any tools, see the readme for more details.
39+
# Below is the complete list of tools for convenience.
40+
# To make sure you have the latest list of tools, and to view their descriptions,
41+
# execute `uv run scripts/print_tool_overview.py`.
42+
#
43+
# * `activate_project`: Activates a project by name.
44+
# * `check_onboarding_performed`: Checks whether project onboarding was already performed.
45+
# * `create_text_file`: Creates/overwrites a file in the project directory.
46+
# * `delete_lines`: Deletes a range of lines within a file.
47+
# * `delete_memory`: Deletes a memory from Serena's project-specific memory store.
48+
# * `execute_shell_command`: Executes a shell command.
49+
# * `find_referencing_code_snippets`: Finds code snippets in which the symbol at the given location is referenced.
50+
# * `find_referencing_symbols`: Finds symbols that reference the symbol at the given location (optionally filtered by type).
51+
# * `find_symbol`: Performs a global (or local) search for symbols with/containing a given name/substring (optionally filtered by type).
52+
# * `get_current_config`: Prints the current configuration of the agent, including the active and available projects, tools, contexts, and modes.
53+
# * `get_symbols_overview`: Gets an overview of the top-level symbols defined in a given file.
54+
# * `initial_instructions`: Gets the initial instructions for the current project.
55+
# Should only be used in settings where the system prompt cannot be set,
56+
# e.g. in clients you have no control over, like Claude Desktop.
57+
# * `insert_after_symbol`: Inserts content after the end of the definition of a given symbol.
58+
# * `insert_at_line`: Inserts content at a given line in a file.
59+
# * `insert_before_symbol`: Inserts content before the beginning of the definition of a given symbol.
60+
# * `list_dir`: Lists files and directories in the given directory (optionally with recursion).
61+
# * `list_memories`: Lists memories in Serena's project-specific memory store.
62+
# * `onboarding`: Performs onboarding (identifying the project structure and essential tasks, e.g. for testing or building).
63+
# * `prepare_for_new_conversation`: Provides instructions for preparing for a new conversation (in order to continue with the necessary context).
64+
# * `read_file`: Reads a file within the project directory.
65+
# * `read_memory`: Reads the memory with the given name from Serena's project-specific memory store.
66+
# * `remove_project`: Removes a project from the Serena configuration.
67+
# * `replace_lines`: Replaces a range of lines within a file with new content.
68+
# * `replace_symbol_body`: Replaces the full definition of a symbol.
69+
# * `restart_language_server`: Restarts the language server, may be necessary when edits not through Serena happen.
70+
# * `search_for_pattern`: Performs a search for a pattern in the project.
71+
# * `summarize_changes`: Provides instructions for summarizing the changes made to the codebase.
72+
# * `switch_modes`: Activates modes by providing a list of their names
73+
# * `think_about_collected_information`: Thinking tool for pondering the completeness of collected information.
74+
# * `think_about_task_adherence`: Thinking tool for determining whether the agent is still on track with the current task.
75+
# * `think_about_whether_you_are_done`: Thinking tool for determining whether the task is truly completed.
76+
# * `write_memory`: Writes a named memory (for future reference) to Serena's project-specific memory store.
77+
excluded_tools: []
78+
79+
# initial prompt for the project. It will always be given to the LLM upon activating the project
80+
# (contrary to the memories, which are loaded on demand).
81+
initial_prompt: ""
82+
83+
project_name: "reactpy"
84+
included_optional_tools: []

docs/source/about/changelog.rst

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -17,44 +17,49 @@ Unreleased
1717

1818
**Added**
1919

20+
- :pull:`1113` - Added support for Python 3.12, 3.13, and 3.14.
21+
- :pull:`1281` - Added type hints to ``reactpy.html`` attributes.
22+
- :pull:`1285` - Added support for nested components in web modules
23+
- :pull:`1289` - Added support for inline JavaScript as event handlers or other attributes that expect a callable via ``reactpy.types.InlineJavaScript``
24+
- :pull:`1308` - Event functions can now call ``event.preventDefault()`` and ``event.stopPropagation()`` methods directly on the event data object, rather than using the ``@event`` decorator.
25+
- :pull:`1308` - Event data now supports accessing properties via dot notation (ex. ``event.target.value``).
26+
- :pull:`1308` - Added ``reactpy.types.Event`` to provide type hints for the standard ``data`` function argument (for example ``def on_click(event: Event): ...``).
27+
- :pull:`1113` - Added ``asgi`` and ``jinja`` installation extras (for example ``pip install reactpy[asgi, jinja]``).
28+
- :pull:`1267` - Added ``shutdown_timeout`` parameter to the ``reactpy.use_async_effect`` hook.
2029
- :pull:`1113` - Added ``reactpy.executors.asgi.ReactPy`` that can be used to run ReactPy in standalone mode via ASGI.
2130
- :pull:`1269` - Added ``reactpy.executors.asgi.ReactPyCsr`` that can be used to run ReactPy in standalone mode via ASGI, but rendered entirely client-sided.
2231
- :pull:`1113` - Added ``reactpy.executors.asgi.ReactPyMiddleware`` that can be used to utilize ReactPy within any ASGI compatible framework.
2332
- :pull:`1269` - Added ``reactpy.templatetags.ReactPyJinja`` that can be used alongside ``ReactPyMiddleware`` to embed several ReactPy components into your existing application. This includes the following template tags: ``{% component %}``, ``{% pyscript_component %}``, and ``{% pyscript_setup %}``.
2433
- :pull:`1269` - Added ``reactpy.pyscript_component`` that can be used to embed ReactPy components into your existing application.
25-
- :pull:`1113` - Added ``asgi`` and ``jinja`` installation extras (for example ``pip install reactpy[asgi, jinja]``).
26-
- :pull:`1113` - Added support for Python 3.12 and 3.13.
2734
- :pull:`1264` - Added ``reactpy.use_async_effect`` hook.
28-
- :pull:`1267` - Added ``shutdown_timeout`` parameter to the ``reactpy.use_async_effect`` hook.
29-
- :pull:`1281` - ``reactpy.html`` will now automatically flatten lists recursively (ex. ``reactpy.html(["child1", ["child2"]])``)
3035
- :pull:`1281` - Added ``reactpy.Vdom`` primitive interface for creating VDOM dictionaries.
31-
- :pull:`1281` - Added type hints to ``reactpy.html`` attributes.
32-
- :pull:`1285` - Added support for nested components in web modules
33-
- :pull:`1289` - Added support for inline JavaScript as event handlers or other attributes that expect a callable via ``reactpy.types.InlineJavaScript``
3436
- :pull:`1307` - Added ``reactpy.web.reactjs_component_from_file`` to import ReactJS components from a file.
3537
- :pull:`1307` - Added ``reactpy.web.reactjs_component_from_url`` to import ReactJS components from a URL.
3638
- :pull:`1307` - Added ``reactpy.web.reactjs_component_from_string`` to import ReactJS components from a string.
37-
- :pull:`1308` - Event functions can now call ``event.preventDefault()`` and ``event.stopPropagation()`` methods directly on the event data object, rather than using the ``@event`` decorator.
38-
- :pull:`1308` - Event data now supports accessing properties via dot notation (ex. ``event.target.value``).
3939

4040
**Changed**
4141

4242
- :pull:`1251` - Substitute client-side usage of ``react`` with ``preact``.
43-
- :pull:`1239` - Script elements no longer support behaving like effects. They now strictly behave like plain HTML script elements.
43+
- :pull:`1239` - Script elements no longer support behaving like effects. They now strictly behave like plain HTML scripts.
4444
- :pull:`1255` - The ``reactpy.html`` module has been modified to allow for auto-creation of any HTML nodes. For example, you can create a ``<data-table>`` element by calling ``html.data_table()``.
4545
- :pull:`1256` - Change ``set_state`` comparison method to check equality with ``==`` more consistently.
4646
- :pull:`1257` - Add support for rendering ``@component`` children within ``vdom_to_html``.
4747
- :pull:`1113` - Renamed the ``use_location`` hook's ``search`` attribute to ``query_string``.
4848
- :pull:`1113` - Renamed the ``use_location`` hook's ``pathname`` attribute to ``path``.
4949
- :pull:`1113` - Renamed ``reactpy.config.REACTPY_DEBUG_MODE`` to ``reactpy.config.REACTPY_DEBUG``.
50-
- :pull:`1113` - ``@reactpy/client`` now exports ``React`` and ``ReactDOM``.
5150
- :pull:`1263` - ReactPy no longer auto-converts ``snake_case`` props to ``camelCase``. It is now the responsibility of the user to ensure that props are in the correct format.
51+
- :pull:`1196` - Rewrite the ``event-to-object`` package to be more robust at handling properties on events.
52+
- :pull:`1312` - Custom JS components will now automatically assume you are using ReactJS in the absence of a ``bind`` function.
53+
- :pull:`1312` - Refactor layout rendering logic to improve readability and maintainability.
54+
- :pull:`1113` - ``@reactpy/client`` now exports ``React`` and ``ReactDOM``.
55+
- :pull:`1281` - ``reactpy.html`` will now automatically flatten lists recursively (ex. ``reactpy.html(["child1", ["child2"]])``)
5256
- :pull:`1278` - ``reactpy.utils.reactpy_to_string`` will now retain the user's original casing for ``data-*`` and ``aria-*`` attributes.
5357
- :pull:`1278` - ``reactpy.utils.string_to_reactpy`` has been upgraded to handle more complex scenarios without causing ReactJS rendering errors.
5458
- :pull:`1281` - ``reactpy.core.vdom._CustomVdomDictConstructor`` has been moved to ``reactpy.types.CustomVdomConstructor``.
5559
- :pull:`1281` - ``reactpy.core.vdom._EllipsisRepr`` has been moved to ``reactpy.types.EllipsisRepr``.
5660
- :pull:`1281` - ``reactpy.types.VdomDictConstructor`` has been renamed to ``reactpy.types.VdomConstructor``.
57-
- :pull:`1196` - Rewrite the ``event-to-object`` package to be more robust at handling properties on events.
61+
- :pull:`1312` - ``REACTPY_ASYNC_RENDERING`` can now de-duplicate and cascade renders where necessary.
62+
- :pull:`1312` - ``REACTPY_ASYNC_RENDERING`` is now defaulted to ``True`` for up to 40x performance improvements.
5863

5964
**Deprecated**
6065

@@ -63,10 +68,15 @@ Unreleased
6368
-:pull:`1307` - ``reactpy.web.module_from_url`` is deprecated. Use ``reactpy.web.reactjs_component_from_url`` instead.
6469
-:pull:`1307` - ``reactpy.web.module_from_string`` is deprecated. Use ``reactpy.web.reactjs_component_from_string`` instead.
6570

66-
6771
**Removed**
6872

73+
- :pull:`1113` - Removed support for Python 3.9 and 3.10.
6974
- :pull:`1255` - Removed the ability to import ``reactpy.html.*`` elements directly. You must now call ``html.*`` to access the elements.
75+
- :pull:`1113` - Removed backend specific installation extras (such as ``pip install reactpy[starlette]``).
76+
- :pull:`1264` - Removed support for async functions within ``reactpy.use_effect`` hook. Use ``reactpy.use_async_effect`` instead.
77+
- :pull:`1113` - Removed deprecated function ``module_from_template``.
78+
- :pull:`1311` - Removed deprecated exception type ``reactpy.core.serve.Stop``.
79+
- :pull:`1311` - Removed deprecated component ``reactpy.widgets.hotswap``.
7080
- :pull:`1255` - Removed ``reactpy.sample`` module.
7181
- :pull:`1255` - Removed ``reactpy.svg`` module. Contents previously within ``reactpy.svg.*`` can now be accessed via ``html.svg.*``.
7282
- :pull:`1255` - Removed ``reactpy.html._`` function. Use ``html.fragment`` instead.
@@ -75,24 +85,21 @@ Unreleased
7585
- :pull:`1113` - Removed ``reactpy.core.types`` module. Use ``reactpy.types`` instead.
7686
- :pull:`1278` - Removed ``reactpy.utils.html_to_vdom``. Use ``reactpy.utils.string_to_reactpy`` instead.
7787
- :pull:`1278` - Removed ``reactpy.utils.vdom_to_html``. Use ``reactpy.utils.reactpy_to_string`` instead.
78-
- :pull:`1113` - Removed backend specific installation extras (such as ``pip install reactpy[starlette]``).
79-
- :pull:`1113` - Removed deprecated function ``module_from_template``.
80-
- :pull:`1113` - Removed support for Python 3.9.
81-
- :pull:`1264` - Removed support for async functions within ``reactpy.use_effect`` hook. Use ``reactpy.use_async_effect`` instead.
8288
- :pull:`1281` - Removed ``reactpy.vdom``. Use ``reactpy.Vdom`` instead.
8389
- :pull:`1281` - Removed ``reactpy.core.make_vdom_constructor``. Use ``reactpy.Vdom`` instead.
8490
- :pull:`1281` - Removed ``reactpy.core.custom_vdom_constructor``. Use ``reactpy.Vdom`` instead.
85-
- :pull:`1311` - Removed ``reactpy.core.serve.Stop`` type due to extended deprecation.
86-
- :pull:`1311` - Removed ``reactpy.Layout`` top-level export. Use ``reactpy.core.layout.Layout`` instead.
87-
- :pull:`1311` - Removed ``reactpy.widgets.hotswap`` due to extended deprecation.
88-
91+
- :pull:`1311` - Removed ``reactpy.Layout`` top-level re-export. Use ``reactpy.core.layout.Layout`` instead.
92+
- :pull:`1312` - Removed ``reactpy.types.LayoutType``. Use ``reactpy.types.BaseLayout`` instead.
93+
- :pull:`1312` - Removed ``reactpy.types.ContextProviderType``. Use ``reactpy.types.ContextProvider`` instead.
94+
- :pull:`1312` - Removed ``reactpy.core.hooks._ContextProvider``. Use ``reactpy.types.ContextProvider`` instead.
8995

9096
**Fixed**
9197

9298
- :pull:`1239` - Fixed a bug where script elements would not render to the DOM as plain text.
9399
- :pull:`1271` - Fixed a bug where the ``key`` property provided within server-side ReactPy code was failing to propagate to the front-end JavaScript components.
94100
- :pull:`1254` - Fixed a bug where ``RuntimeError("Hook stack is in an invalid state")`` errors could be generated when using a webserver that reuses threads.
95101

102+
96103
v1.1.0
97104
------
98105
:octicon:`milestone` *released on 2024-11-24*
@@ -102,7 +109,7 @@ v1.1.0
102109
- :pull:`1118` - ``module_from_template`` is broken with a recent release of ``requests``
103110
- :pull:`1131` - ``module_from_template`` did not work when using Flask backend
104111
- :pull:`1200` - Fixed ``UnicodeDecodeError`` when using ``reactpy.web.export``
105-
- :pull:`1224` - Fixes needless unmounting of JavaScript components during each ReactPy render.
112+
- :pull:`1224` - Fixed needless unmounting of JavaScript components during each ReactPy render.
106113
- :pull:`1126` - Fixed missing ``event["target"]["checked"]`` on checkbox inputs
107114
- :pull:`1191` - Fixed missing static files on `sdist` Python distribution
108115

0 commit comments

Comments
 (0)