1
0
叶子 2 жил өмнө
parent
commit
1529a23c1b
41 өөрчлөгдсөн 134 нэмэгдсэн , 154 устгасан
  1. 1 1
      .github/workflows/build.yml
  2. 1 1
      CONTRIBUTING.md
  3. 51 74
      poetry.lock
  4. 1 1
      pynecone/app.py
  5. 1 1
      pynecone/compiler/compiler.py
  6. 1 1
      pynecone/compiler/utils.py
  7. 2 2
      pynecone/components/__init__.py
  8. 1 1
      pynecone/components/base/__init__.py
  9. 0 1
      pynecone/components/base/body.py
  10. 0 1
      pynecone/components/base/meta.py
  11. 2 2
      pynecone/components/component.py
  12. 1 1
      pynecone/components/datadisplay/list.py
  13. 0 2
      pynecone/components/datadisplay/table.py
  14. 1 1
      pynecone/components/disclosure/accordion.py
  15. 1 1
      pynecone/components/disclosure/tabs.py
  16. 0 1
      pynecone/components/forms/editable.py
  17. 1 2
      pynecone/components/graphing/plotly.py
  18. 1 2
      pynecone/components/graphing/victory.py
  19. 1 1
      pynecone/components/overlay/alertdialog.py
  20. 1 1
      pynecone/components/overlay/drawer.py
  21. 1 1
      pynecone/components/overlay/menu.py
  22. 1 1
      pynecone/components/overlay/modal.py
  23. 1 2
      pynecone/components/overlay/popover.py
  24. 2 4
      pynecone/components/tags/tag.py
  25. 1 1
      pynecone/components/typography/highlight.py
  26. 0 2
      pynecone/pc.py
  27. 1 1
      pynecone/state.py
  28. 0 1
      pynecone/style.py
  29. 2 1
      pynecone/telemetry.py
  30. 10 8
      pynecone/utils.py
  31. 12 3
      pynecone/var.py
  32. 16 3
      pyproject.toml
  33. 0 2
      tests/components/graphing/test_victory_data.py
  34. 6 6
      tests/components/layout/test_cond.py
  35. 1 4
      tests/components/test_tag.py
  36. 1 2
      tests/test_app.py
  37. 1 3
      tests/test_event.py
  38. 2 2
      tests/test_propcond.py
  39. 3 3
      tests/test_state.py
  40. 4 5
      tests/test_telemetry.py
  41. 1 1
      tests/test_utils.py

+ 1 - 1
.github/workflows/build.yml

@@ -49,6 +49,6 @@ jobs:
     - run: poetry install --no-interaction
     - run: poetry run pytest tests
     - run: poetry run pyright pynecone tests
-    - run: poetry run pydocstyle pynecone tests
+    - run: poetry run ruff check . --format github
     - run: find pynecone tests -name "*.py" -not -path pynecone/pc.py | xargs poetry run darglint
     - run: poetry run black --check pynecone tests

+ 1 - 1
CONTRIBUTING.md

@@ -87,8 +87,8 @@ poetry run pytest tests
 ```
 Next make sure all the following tests pass. This ensures that every new change has proper documentation and type checking.
 ``` bash
+poetry run ruff check .
 poetry run pyright pynecone tests
-poetry run pydocstyle pynecone tests
 find pynecone tests -name "*.py" -not -path pynecone/pc.py | xargs poetry run darglint
 ```
 Finally run `black` to format your code.

+ 51 - 74
poetry.lock

@@ -384,14 +384,14 @@ files = [
 
 [[package]]
 name = "importlib-metadata"
-version = "4.13.0"
+version = "6.0.0"
 description = "Read metadata from Python packages"
 category = "main"
 optional = false
 python-versions = ">=3.7"
 files = [
-    {file = "importlib_metadata-4.13.0-py3-none-any.whl", hash = "sha256:8a8a81bcf996e74fee46f0d16bd3eaa382a7eb20fd82445c3ad11f4090334116"},
-    {file = "importlib_metadata-4.13.0.tar.gz", hash = "sha256:dd0173e8f150d6815e098fd354f6414b0f079af4644ddfe90c71e2fc6174346d"},
+    {file = "importlib_metadata-6.0.0-py3-none-any.whl", hash = "sha256:7efb448ec9a5e313a57655d35aa54cd3e01b7e1fbcf72dce1bf06119420f5bad"},
+    {file = "importlib_metadata-6.0.0.tar.gz", hash = "sha256:e354bedeb60efa6affdcc8ae121b73544a7aa74156d047311948f6d711cd378d"},
 ]
 
 [package.dependencies]
@@ -399,7 +399,7 @@ typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""}
 zipp = ">=0.5"
 
 [package.extras]
-docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)"]
+docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
 perf = ["ipython"]
 testing = ["flake8 (<5)", "flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)"]
 
@@ -415,24 +415,6 @@ files = [
     {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"},
 ]
 
-[[package]]
-name = "isort"
-version = "5.11.5"
-description = "A Python utility / library to sort Python imports."
-category = "dev"
-optional = false
-python-versions = ">=3.7.0"
-files = [
-    {file = "isort-5.11.5-py3-none-any.whl", hash = "sha256:ba1d72fb2595a01c7895a5128f9585a5cc4b6d395f1c8d514989b9a7eb2a8746"},
-    {file = "isort-5.11.5.tar.gz", hash = "sha256:6be1f76a507cb2ecf16c7cf14a37e41609ca082330be4e3436a18ef74add55db"},
-]
-
-[package.extras]
-colors = ["colorama (>=0.4.3,<0.5.0)"]
-pipfile-deprecated-finder = ["pip-shims (>=0.5.2)", "pipreqs", "requirementslib"]
-plugins = ["setuptools"]
-requirements-deprecated-finder = ["pip-api", "pipreqs"]
-
 [[package]]
 name = "mypy-extensions"
 version = "1.0.0"
@@ -486,22 +468,22 @@ files = [
 
 [[package]]
 name = "platformdirs"
-version = "2.6.2"
+version = "3.0.0"
 description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
 category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
-    {file = "platformdirs-2.6.2-py3-none-any.whl", hash = "sha256:83c8f6d04389165de7c9b6f0c682439697887bca0aa2f1c87ef1826be3584490"},
-    {file = "platformdirs-2.6.2.tar.gz", hash = "sha256:e1fea1fe471b9ff8332e229df3cb7de4f53eeea4998d3b6bfff542115e998bd2"},
+    {file = "platformdirs-3.0.0-py3-none-any.whl", hash = "sha256:b1d5eb14f221506f50d6604a561f4c5786d9e80355219694a1b244bcd96f4567"},
+    {file = "platformdirs-3.0.0.tar.gz", hash = "sha256:8a1228abb1ef82d788f74139988b137e78692984ec7b08eaa6c65f1723af28f9"},
 ]
 
 [package.dependencies]
 typing-extensions = {version = ">=4.4", markers = "python_version < \"3.8\""}
 
 [package.extras]
-docs = ["furo (>=2022.12.7)", "proselint (>=0.13)", "sphinx (>=5.3)", "sphinx-autodoc-typehints (>=1.19.5)"]
-test = ["appdirs (==1.4.4)", "covdefaults (>=2.2.2)", "pytest (>=7.2)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"]
+docs = ["furo (>=2022.12.7)", "proselint (>=0.13)", "sphinx (>=6.1.3)", "sphinx-autodoc-typehints (>=1.22,!=1.23.4)"]
+test = ["appdirs (==1.4.4)", "covdefaults (>=2.2.2)", "pytest (>=7.2.1)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"]
 
 [[package]]
 name = "plotly"
@@ -617,25 +599,6 @@ typing-extensions = ">=4.1.0"
 dotenv = ["python-dotenv (>=0.10.4)"]
 email = ["email-validator (>=1.0.3)"]
 
-[[package]]
-name = "pydocstyle"
-version = "6.3.0"
-description = "Python docstring style checker"
-category = "dev"
-optional = false
-python-versions = ">=3.6"
-files = [
-    {file = "pydocstyle-6.3.0-py3-none-any.whl", hash = "sha256:118762d452a49d6b05e194ef344a55822987a462831ade91ec5c06fd2169d019"},
-    {file = "pydocstyle-6.3.0.tar.gz", hash = "sha256:7ce43f0c0ac87b07494eb9c0b462c0b73e6ff276807f204d6b53edc72b7e44e1"},
-]
-
-[package.dependencies]
-importlib-metadata = {version = ">=2.0.0,<5.0.0", markers = "python_version < \"3.8\""}
-snowballstemmer = ">=2.2.0"
-
-[package.extras]
-toml = ["tomli (>=1.2.3)"]
-
 [[package]]
 name = "pygments"
 version = "2.14.0"
@@ -653,14 +616,14 @@ plugins = ["importlib-metadata"]
 
 [[package]]
 name = "pyright"
-version = "1.1.292"
+version = "1.1.293"
 description = "Command line wrapper for pyright"
 category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
-    {file = "pyright-1.1.292-py3-none-any.whl", hash = "sha256:23d1f14b15afe38bb7a7117b9861ad0546aff078da312d294e60a727445c23ff"},
-    {file = "pyright-1.1.292.tar.gz", hash = "sha256:035ea1af6fabfdcc80c0afb545f677bd377114157d69779cce2a642ff894e51c"},
+    {file = "pyright-1.1.293-py3-none-any.whl", hash = "sha256:afc05309e775a9869c864da4e8c0c7a3e3be9d8fe202e780c3bae981bbb13936"},
+    {file = "pyright-1.1.293.tar.gz", hash = "sha256:9397fdfcbc684fe5b87abbf9c27f540fe3b8d75999a5f187519cae1d065be38c"},
 ]
 
 [package.dependencies]
@@ -772,14 +735,14 @@ client = ["requests (>=2.21.0)", "websocket-client (>=0.54.0)"]
 
 [[package]]
 name = "redis"
-version = "4.4.2"
+version = "4.5.1"
 description = "Python client for Redis database and key-value store"
 category = "main"
 optional = false
 python-versions = ">=3.7"
 files = [
-    {file = "redis-4.4.2-py3-none-any.whl", hash = "sha256:e6206448e2f8a432871d07d432c13ed6c2abcf6b74edb436c99752b1371be387"},
-    {file = "redis-4.4.2.tar.gz", hash = "sha256:a010f6cb7378065040a02839c3f75c7e0fb37a87116fb4a95be82a95552776c7"},
+    {file = "redis-4.5.1-py3-none-any.whl", hash = "sha256:5deb072d26e67d2be1712603bfb7947ec3431fb0eec9c578994052e33035af6d"},
+    {file = "redis-4.5.1.tar.gz", hash = "sha256:1eec3741cda408d3a5f84b78d089c8b8d895f21b3b050988351e925faf202864"},
 ]
 
 [package.dependencies]
@@ -829,16 +792,42 @@ typing-extensions = {version = ">=4.0.0,<5.0", markers = "python_version < \"3.9
 [package.extras]
 jupyter = ["ipywidgets (>=7.5.1,<8.0.0)"]
 
+[[package]]
+name = "ruff"
+version = "0.0.244"
+description = "An extremely fast Python linter, written in Rust."
+category = "dev"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "ruff-0.0.244-py3-none-macosx_10_7_x86_64.whl", hash = "sha256:5d65a0adffa51314cf9f1036c51dbcde0462b23b49a3d8e3a696a221f9f46f54"},
+    {file = "ruff-0.0.244-py3-none-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:3d6bf5094f2c447f5ff8d10c670dc1bc8b7f70cb5f4e43afe1d0624b934c1284"},
+    {file = "ruff-0.0.244-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c0f54790b297d5df8120a348c91426a0375c40f62880d30438e46922399b29bf"},
+    {file = "ruff-0.0.244-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:88e263e3d7267b4b10f5c1fc1446c5d6b47824c6d78e5c3a97ef79c83d9cb837"},
+    {file = "ruff-0.0.244-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8044c79098e3f2deaf970ab468bf5661b193163369bfe5bbda636e6363aa7932"},
+    {file = "ruff-0.0.244-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:258e5e3386a8efdff9f253395cc03a3a88204442ac8db50aeb0a529e2862d57b"},
+    {file = "ruff-0.0.244-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bd09c523aeed4d81f358093dc4df384a4db42ff5f9627c9506c26c2becbe19a7"},
+    {file = "ruff-0.0.244-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c98f0d4a4e052e8b0e27b47e83563026d749b07a21a097780cd283c2f885ad3c"},
+    {file = "ruff-0.0.244-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2359f840c95364d779b86a822fe025fa416eb14adc661c1263bc39e90065f0bd"},
+    {file = "ruff-0.0.244-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:8b85ced1e75b7cf1dd90d0708f8e46e2d58fc124334492cc5103f24d832a3922"},
+    {file = "ruff-0.0.244-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:9c2d49c2021bf80f3e66968c1a41f89061911ffb7ed1f0d39a3204a45fc97ba7"},
+    {file = "ruff-0.0.244-py3-none-musllinux_1_2_i686.whl", hash = "sha256:da77d573c7a5b27bad43468fb7e47e78e22715426beb4e673106d24a9a584838"},
+    {file = "ruff-0.0.244-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:9f16fc3380753310af2a10e2867dfc133849e51c545561ec0a389aa93b3058b0"},
+    {file = "ruff-0.0.244-py3-none-win32.whl", hash = "sha256:b3fc70a4c5d5a0ab8e5b3c3e818ca224913eee84f65bf63ee212af2bbd5f1792"},
+    {file = "ruff-0.0.244-py3-none-win_amd64.whl", hash = "sha256:78bbc5d1cca0a8752f6e4b3f4485f4c4f2428543a0777d1bde865aa43bdab190"},
+    {file = "ruff-0.0.244.tar.gz", hash = "sha256:7c05773e990348a6d7628b9b7294fe76303bc870dd94d9c34154bc1560053050"},
+]
+
 [[package]]
 name = "setuptools"
-version = "67.1.0"
+version = "67.2.0"
 description = "Easily download, build, install, upgrade, and uninstall Python packages"
 category = "main"
 optional = false
 python-versions = ">=3.7"
 files = [
-    {file = "setuptools-67.1.0-py3-none-any.whl", hash = "sha256:a7687c12b444eaac951ea87a9627c4f904ac757e7abdc5aac32833234af90378"},
-    {file = "setuptools-67.1.0.tar.gz", hash = "sha256:e261cdf010c11a41cb5cb5f1bf3338a7433832029f559a6a7614bd42a967c300"},
+    {file = "setuptools-67.2.0-py3-none-any.whl", hash = "sha256:16ccf598aab3b506593c17378473978908a2734d7336755a8769b480906bec1c"},
+    {file = "setuptools-67.2.0.tar.gz", hash = "sha256:b440ee5f7e607bb8c9de15259dba2583dd41a38879a7abc1d43a71c59524da48"},
 ]
 
 [package.extras]
@@ -858,18 +847,6 @@ files = [
     {file = "sniffio-1.3.0.tar.gz", hash = "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101"},
 ]
 
-[[package]]
-name = "snowballstemmer"
-version = "2.2.0"
-description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms."
-category = "dev"
-optional = false
-python-versions = "*"
-files = [
-    {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"},
-    {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"},
-]
-
 [[package]]
 name = "sqlalchemy"
 version = "1.4.41"
@@ -999,14 +976,14 @@ full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart", "pyyam
 
 [[package]]
 name = "tenacity"
-version = "8.1.0"
+version = "8.2.0"
 description = "Retry code until it succeeds"
 category = "main"
 optional = false
 python-versions = ">=3.6"
 files = [
-    {file = "tenacity-8.1.0-py3-none-any.whl", hash = "sha256:35525cd47f82830069f0d6b73f7eb83bc5b73ee2fff0437952cedf98b27653ac"},
-    {file = "tenacity-8.1.0.tar.gz", hash = "sha256:e48c437fdf9340f5666b92cd7990e96bc5fc955e1298baf4a907e3972067a445"},
+    {file = "tenacity-8.2.0-py3-none-any.whl", hash = "sha256:b723061a78ed0f4524190eae321d3d84100227d51c5677035b6615d91895e0d6"},
+    {file = "tenacity-8.2.0.tar.gz", hash = "sha256:a43bcd8910406e0884ca0db3db7bed581f389c1d05165e992a1ddabfc81df05e"},
 ]
 
 [package.extras]
@@ -1125,14 +1102,14 @@ standard = ["colorama (>=0.4)", "httptools (>=0.5.0)", "python-dotenv (>=0.13)",
 
 [[package]]
 name = "zipp"
-version = "3.12.0"
+version = "3.12.1"
 description = "Backport of pathlib-compatible object wrapper for zip files"
 category = "main"
 optional = false
 python-versions = ">=3.7"
 files = [
-    {file = "zipp-3.12.0-py3-none-any.whl", hash = "sha256:9eb0a4c5feab9b08871db0d672745b53450d7f26992fd1e4653aa43345e97b86"},
-    {file = "zipp-3.12.0.tar.gz", hash = "sha256:73efd63936398aac78fd92b6f4865190119d6c91b531532e798977ea8dd402eb"},
+    {file = "zipp-3.12.1-py3-none-any.whl", hash = "sha256:6c4fe274b8f85ec73c37a8e4e3fa00df9fb9335da96fb789e3b96b318e5097b3"},
+    {file = "zipp-3.12.1.tar.gz", hash = "sha256:a3cac813d40993596b39ea9e93a18e8a2076d5c378b8bc88ec32ab264e04ad02"},
 ]
 
 [package.extras]
@@ -1142,4 +1119,4 @@ testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools"
 [metadata]
 lock-version = "2.0"
 python-versions = "^3.7"
-content-hash = "dbef0407da32ffd7878a44913923144d62359cfa057c3942f421d7bdae84c4bf"
+content-hash = "29af23359858d18a743ff85426e7496fb7e47bdda6d746294aea4a360df6e617"

+ 1 - 1
pynecone/app.py

@@ -33,7 +33,7 @@ class App(Base):
     api: FastAPI = None  # type: ignore
 
     # The Socket.IO AsyncServer.
-    sio: AsyncServer = None
+    sio: Optional[AsyncServer] = None
 
     # The state class to use for the app.
     state: Type[State] = DefaultState

+ 1 - 1
pynecone/compiler/compiler.py

@@ -3,7 +3,7 @@ from __future__ import annotations
 
 import json
 from functools import wraps
-from typing import TYPE_CHECKING, Callable, List, Set, Tuple, Type
+from typing import Callable, List, Set, Tuple, Type
 
 from pynecone import constants
 from pynecone.compiler import templates, utils

+ 1 - 1
pynecone/compiler/utils.py

@@ -8,6 +8,7 @@ from pynecone import constants, utils
 from pynecone.compiler import templates
 from pynecone.components.base import (
     Body,
+    ColorModeScript,
     Description,
     DocumentHead,
     Head,
@@ -17,7 +18,6 @@ from pynecone.components.base import (
     Main,
     Script,
     Title,
-    ColorModeScript,
 )
 from pynecone.components.component import Component, CustomComponent, ImportDict
 from pynecone.state import State

+ 2 - 2
pynecone/components/__init__.py

@@ -19,7 +19,6 @@ from .typography import *
 
 if TYPE_CHECKING:
     from typing import Any
-    from pynecone.var import Var
 
 # Add the convenience methods for all the components.
 locals().update(
@@ -109,9 +108,10 @@ def cond(condition: Any, c1: Any, c2: Any = None):
         The conditional component.
     """
     # Import here to avoid circular imports.
-    from .tags.tag import PropCond
     from pynecone.var import Var
 
+    from .tags.tag import PropCond
+
     # Convert the condition to a Var.
     cond_var = Var.create(condition)
     assert cond_var is not None, "The condition must be set."

+ 1 - 1
pynecone/components/base/__init__.py

@@ -1,7 +1,7 @@
 """Base components."""
 
 from .body import Body
-from .document import DocumentHead, Html, Main, Script, ColorModeScript
+from .document import ColorModeScript, DocumentHead, Html, Main, Script
 from .head import Head
 from .link import Link
 from .meta import Description, Image, Title

+ 0 - 1
pynecone/components/base/body.py

@@ -2,7 +2,6 @@
 
 from pynecone.components.component import Component
 from pynecone.components.tags import Tag
-from pynecone.var import Var
 
 
 class Body(Component):

+ 0 - 1
pynecone/components/base/meta.py

@@ -4,7 +4,6 @@ from typing import Optional
 
 from pynecone.components.base.bare import Bare
 from pynecone.components.component import Component
-from pynecone.components.tags import Tag
 
 
 class Title(Component):

+ 2 - 2
pynecone/components/component.py

@@ -5,7 +5,7 @@ from __future__ import annotations
 import typing
 from abc import ABC
 from functools import wraps
-from typing import Any, Callable, Dict, List, Optional, Set, Tuple, Type, Union
+from typing import Any, Callable, Dict, List, Optional, Set, Type, Union
 
 from pynecone import constants, utils
 from pynecone.base import Base
@@ -292,7 +292,7 @@ class Component(Base, ABC):
 
         # Special case for props named `type_`.
         if hasattr(self, "type_"):
-            props["type"] = getattr(self, "type_")
+            props["type"] = self.type_  # type: ignore
 
         return tag.add_props(**props)
 

+ 1 - 1
pynecone/components/datadisplay/list.py

@@ -1,6 +1,6 @@
 """List components."""
 
-from pynecone.components.component import Component
+from pynecone.components import Component
 from pynecone.components.libs.chakra import ChakraComponent
 from pynecone.var import Var
 

+ 0 - 2
pynecone/components/datadisplay/table.py

@@ -1,8 +1,6 @@
 """Table components."""
 
-from typing import List
 from pynecone.components.component import Component
-
 from pynecone.components.libs.chakra import ChakraComponent
 from pynecone.var import Var
 

+ 1 - 1
pynecone/components/disclosure/accordion.py

@@ -1,8 +1,8 @@
 """Container to stack elements with spacing."""
 
 from typing import List, Optional, Union
-from pynecone.components.component import Component
 
+from pynecone.components.component import Component
 from pynecone.components.libs.chakra import ChakraComponent
 from pynecone.var import Var
 

+ 1 - 1
pynecone/components/disclosure/tabs.py

@@ -54,7 +54,7 @@ class Tabs(ChakraComponent):
             for label, panel in items:
                 tabs.append(Tab.create(label))
                 panels.append(TabPanel.create(panel))
-            children = [TabList.create(*tabs), TabPanels.create(*panels)]
+            children = [TabList.create(*tabs), TabPanels.create(*panels)]  # type: ignore
         return super().create(*children, **props)
 
 

+ 0 - 1
pynecone/components/forms/editable.py

@@ -3,7 +3,6 @@
 from typing import Set
 
 from pynecone.components.libs.chakra import ChakraComponent
-from pynecone.components.tags import Tag
 from pynecone.var import Var
 
 

+ 1 - 2
pynecone/components/graphing/plotly.py

@@ -1,9 +1,8 @@
 """Component for displaying a plotly graph."""
 
-from typing import Dict, Union
+from typing import Dict
 
 from plotly.graph_objects import Figure
-from plotly.io import to_json
 
 from pynecone.components.component import Component
 from pynecone.components.tags import Tag

+ 1 - 2
pynecone/components/graphing/victory.py

@@ -1,9 +1,8 @@
 """Victory graphing components."""
 
-from typing import Any, Dict, List, Optional, Union
+from typing import Any, Dict, List, Optional
 
 from pynecone.components.component import Component
-from pynecone.components.tags import Tag
 from pynecone.style import Style
 from pynecone.var import Var
 

+ 1 - 1
pynecone/components/overlay/alertdialog.py

@@ -3,8 +3,8 @@
 from typing import Set
 
 from pynecone.components.component import Component
-from pynecone.components.media.icon import Icon
 from pynecone.components.libs.chakra import ChakraComponent
+from pynecone.components.media.icon import Icon
 from pynecone.var import Var
 
 

+ 1 - 1
pynecone/components/overlay/drawer.py

@@ -1,8 +1,8 @@
 """Container to stack elements with spacing."""
 
 from typing import Set
-from pynecone.components.component import Component
 
+from pynecone.components.component import Component
 from pynecone.components.libs.chakra import ChakraComponent
 from pynecone.components.media.icon import Icon
 from pynecone.var import Var

+ 1 - 1
pynecone/components/overlay/menu.py

@@ -1,8 +1,8 @@
 """Menu components."""
 
 from typing import Set
-from pynecone.components.component import Component
 
+from pynecone.components.component import Component
 from pynecone.components.libs.chakra import ChakraComponent
 from pynecone.var import Var
 

+ 1 - 1
pynecone/components/overlay/modal.py

@@ -1,8 +1,8 @@
 """Modal components."""
 
 from typing import Set
-from pynecone.components.component import Component
 
+from pynecone.components.component import Component
 from pynecone.components.libs.chakra import ChakraComponent
 from pynecone.components.media import Icon
 from pynecone.var import Var

+ 1 - 2
pynecone/components/overlay/popover.py

@@ -1,9 +1,8 @@
 """Popover components."""
 
 from typing import Set
-from pynecone.components.component import Component
-from pynecone.components.forms.button import Button
 
+from pynecone.components.component import Component
 from pynecone.components.libs.chakra import ChakraComponent
 from pynecone.var import Var
 

+ 2 - 4
pynecone/components/tags/tag.py

@@ -82,16 +82,14 @@ class Tag(Base):
             return json.dumps(prop)
 
         elif isinstance(prop, Figure):
-            prop = json.loads(to_json(prop))["data"]
+            prop = json.loads(to_json(prop))["data"]  # type: ignore
 
         # For dictionaries, convert any properties to strings.
         else:
             if isinstance(prop, dict):
                 # Convert any var keys to strings.
                 prop = {
-                    key: str(val)
-                    if isinstance(val, Var) or isinstance(val, PropCond)
-                    else val
+                    key: str(val) if isinstance(val, (Var, PropCond)) else val
                     for key, val in prop.items()
                 }
 

+ 1 - 1
pynecone/components/typography/highlight.py

@@ -1,6 +1,6 @@
 """A heading component."""
 
-from typing import List, Union
+from typing import List
 
 from pynecone.components.libs.chakra import ChakraComponent
 from pynecone.var import Var

+ 0 - 2
pynecone/pc.py

@@ -8,8 +8,6 @@ import typer
 
 from pynecone import constants, utils
 
-from rich.prompt import Prompt
-
 # Create the app.
 cli = typer.Typer()
 

+ 1 - 1
pynecone/state.py

@@ -13,7 +13,7 @@ from redis import Redis
 from pynecone import constants, utils
 from pynecone.base import Base
 from pynecone.event import Event, EventHandler, window_alert
-from pynecone.var import BaseVar, ComputedVar, PCList, Var
+from pynecone.var import BaseVar, ComputedVar, Var
 
 Delta = Dict[str, Any]
 

+ 0 - 1
pynecone/style.py

@@ -6,7 +6,6 @@ from pynecone import constants, utils
 from pynecone.event import EventChain
 from pynecone.var import BaseVar, Var
 
-
 toggle_color_mode = BaseVar(name=constants.TOGGLE_COLOR_MODE, type_=EventChain)
 
 

+ 2 - 1
pynecone/telemetry.py

@@ -1,8 +1,9 @@
 """Anonymous telemetry for Pynecone."""
 
+import multiprocessing
 import platform
+
 import psutil
-import multiprocessing
 
 from pynecone import constants
 from pynecone.base import Base

+ 10 - 8
pynecone/utils.py

@@ -18,7 +18,6 @@ from collections import defaultdict
 from pathlib import Path
 from subprocess import DEVNULL, PIPE, STDOUT
 from types import ModuleType
-from typing import _GenericAlias  # type: ignore
 from typing import (
     TYPE_CHECKING,
     Any,
@@ -29,11 +28,12 @@ from typing import (
     Tuple,
     Type,
     Union,
+    _GenericAlias,  # type: ignore  # type: ignore
 )
-from typing import _GenericAlias  # type: ignore
 from urllib.parse import urlparse
-import psutil
+
 import plotly.graph_objects as go
+import psutil
 import typer
 import uvicorn
 from plotly.io import to_json
@@ -298,7 +298,7 @@ def get_config() -> Config:
     try:
         return __import__(constants.CONFIG_MODULE).config
     except ImportError:
-        return Config(app_name="")
+        return Config(app_name="")  # type: ignore
 
 
 def check_node_version(min_version):
@@ -319,7 +319,7 @@ def check_node_version(min_version):
         version = result.stdout.decode().strip().split("v")[1]
         # Compare the version numbers
         return version.split(".") >= min_version.split(".")
-    except Exception as e:
+    except Exception:
         return False
 
 
@@ -475,10 +475,12 @@ def is_latest_template() -> bool:
     Returns:
         Whether the app is using the latest template.
     """
-    template_version = open(constants.PCVERSION_TEMPLATE_FILE).read()
+    with open(constants.PCVERSION_TEMPLATE_FILE) as f:  # type: ignore
+        template_version = f.read()
     if not os.path.exists(constants.PCVERSION_APP_FILE):
         return False
-    app_version = open(constants.PCVERSION_APP_FILE).read()
+    with open(constants.PCVERSION_APP_FILE) as f:  # type: ignore
+        app_version = f.read()
     return app_version >= template_version
 
 
@@ -1149,7 +1151,7 @@ def format_state(value: Any) -> Dict:
 
     # Convert plotly figures to JSON.
     if isinstance(value, go.Figure):
-        return json.loads(to_json(value))["data"]
+        return json.loads(to_json(value))["data"]  # type: ignore
 
     # Convert pandas dataframes to JSON.
     if is_dataframe(type(value)):

+ 12 - 3
pynecone/var.py

@@ -3,8 +3,17 @@ from __future__ import annotations
 
 import json
 from abc import ABC
-from typing import _GenericAlias  # type: ignore
-from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional, Type, Union
+from typing import (
+    TYPE_CHECKING,
+    Any,
+    Callable,
+    Dict,
+    List,
+    Optional,
+    Type,
+    Union,
+    _GenericAlias,  # type: ignore
+)
 
 from plotly.graph_objects import Figure
 from plotly.io import to_json
@@ -61,7 +70,7 @@ class Var(ABC):
 
         # Special case for plotly figures.
         if isinstance(value, Figure):
-            value = json.loads(to_json(value))["data"]
+            value = json.loads(to_json(value))["data"]  # type: ignore
             type_ = Figure
 
         name = value if isinstance(value, str) else json.dumps(value)

+ 16 - 3
pyproject.toml

@@ -42,11 +42,10 @@ pytest = "^7.1.2"
 pytest-mock = "^3.10.0"
 pyright = "^1.1.229"
 darglint = "^1.8.1"
-pydocstyle = "^6.1.1"
 toml = "^0.10.2"
-isort = "^5.10.1"
 pytest-asyncio = "^0.20.1"
 black = "^22.10.0"
+ruff = "^0.0.244"
 
 [tool.poetry.scripts]
 pc = "pynecone.pc:main"
@@ -55,4 +54,18 @@ pc = "pynecone.pc:main"
 requires = ["poetry-core>=1.0.0"]
 build-backend = "poetry.core.masonry.api"
 
-[tool.pyright]
+[tool.pyright]
+
+[tool.ruff]
+
+select = ["B", "D", "E", "F", "I", "SIM", "W"]
+
+ignore = ["B008", "D203", "D205", "D213", "D401", "D406", "D407", "E501", "F403", "F405", "F541"]
+
+target-version = "py37"
+
+[tool.ruff.per-file-ignores]
+
+"__init__.py" = ["F401"]
+"tests/*.py" = ["D100", "D103", "D104"]
+"pynecone/.templates/*.py" = ["D100", "D103", "D104"]

+ 0 - 2
tests/components/graphing/test_victory_data.py

@@ -1,5 +1,3 @@
-import pytest
-
 from pynecone import data
 
 # Test data.

+ 6 - 6
tests/components/layout/test_cond.py

@@ -13,7 +13,7 @@ from pynecone.components.typography.text import Text
 @pytest.fixture
 def cond_state(request):
     class CondState(pc.State):
-        value: request.param["value_type"] = request.param["value"]
+        value: request.param["value_type"] = request.param["value"]  # noqa
 
     return CondState
 
@@ -28,7 +28,7 @@ def cond_state(request):
     indirect=True,
 )
 def test_validate_cond(cond_state: pc.Var):
-    """Test if cond can be a pc.Val with any values
+    """Test if cond can be a pc.Val with any values.
 
     Args:
         cond_state: A fixture.
@@ -71,18 +71,18 @@ def test_prop_cond(c1: Any, c2: Any):
     assert isinstance(prop_cond, PropCond)
     assert prop_cond.prop1 == c1
     assert prop_cond.prop2 == c2
-    assert prop_cond.cond == True
+    assert prop_cond.cond == True  # noqa
 
 
 def test_cond_no_else():
-    """Test if cond can be used without else"""
+    """Test if cond can be used without else."""
     # Components should support the use of cond without else
     comp = cond(True, Text.create("hello"))
     assert isinstance(comp, Cond)
-    assert comp.cond == True
+    assert comp.cond == True  # noqa
     assert comp.comp1 == Text.create("hello")
     assert comp.comp2 == Fragment.create()
 
     # Props do not support the use of cond without else
     with pytest.raises(ValueError):
-        prop_cond = cond(True, "hello")
+        cond(True, "hello")

+ 1 - 4
tests/components/test_tag.py

@@ -1,10 +1,8 @@
-import platform
 from typing import Dict
 
 import pytest
 
-from pynecone.components import Box
-from pynecone.components.tags import CondTag, IterTag, Tag
+from pynecone.components.tags import CondTag, Tag
 from pynecone.components.tags.tag import PropCond
 from pynecone.event import EventChain, EventHandler, EventSpec
 from pynecone.var import BaseVar, Var
@@ -144,7 +142,6 @@ def test_format_tag(tag: Tag, expected: str, windows_platform: bool):
         expected: The expected formatted tag.
         windows_platform: Whether the system is windows.
     """
-
     expected = expected.replace("\n", "\r\n") if windows_platform else expected
     assert str(tag) == expected
 

+ 1 - 2
tests/test_app.py

@@ -1,11 +1,10 @@
 import os.path
-from typing import List, Tuple, Type
+from typing import Type
 
 import pytest
 
 from pynecone.app import App, DefaultState
 from pynecone.components import Box
-from pynecone.event import Event
 from pynecone.middleware import HydrateMiddleware
 from pynecone.state import State
 from pynecone.style import Style

+ 1 - 3
tests/test_event.py

@@ -1,6 +1,4 @@
-import pytest
-
-from pynecone.event import Event, EventHandler, EventSpec
+from pynecone.event import Event, EventHandler
 from pynecone.var import Var
 
 

+ 2 - 2
tests/test_propcond.py

@@ -3,8 +3,8 @@ from typing import Any
 import pytest
 
 from pynecone.components.tags.tag import PropCond
-from pynecone.var import BaseVar, Var
 from pynecone.utils import wrap
+from pynecone.var import BaseVar
 
 
 @pytest.mark.parametrize(
@@ -16,7 +16,7 @@ from pynecone.utils import wrap
     ],
 )
 def test_validate_propcond(prop1: Any, prop2: Any):
-    """Test the creation of conditional props
+    """Test the creation of conditional props.
 
     Args:
         prop1: truth condition value

+ 3 - 3
tests/test_state.py

@@ -1,6 +1,7 @@
 from typing import Dict, List
 
 import pytest
+from plotly.graph_objects import Figure
 
 from pynecone import utils
 from pynecone.base import Base
@@ -8,7 +9,6 @@ from pynecone.constants import RouteVar
 from pynecone.event import Event
 from pynecone.state import State
 from pynecone.var import BaseVar, ComputedVar
-from plotly.graph_objects import Figure
 
 
 class Object(Base):
@@ -651,7 +651,7 @@ def test_add_var(test_state):
 
     test_state.add_var("dynamic_list", List[int], [5, 10])
     assert test_state.dynamic_list == [5, 10]
-    assert getattr(test_state, "dynamic_list") == [5, 10]
+    assert test_state.dynamic_list == [5, 10]
 
     # how to test that one?
     # test_state.dynamic_list.append(15)
@@ -659,4 +659,4 @@ def test_add_var(test_state):
 
     test_state.add_var("dynamic_dict", Dict[str, int], {"k1": 5, "k2": 10})
     assert test_state.dynamic_dict == {"k1": 5, "k2": 10}
-    assert getattr(test_state, "dynamic_dict") == {"k1": 5, "k2": 10}
+    assert test_state.dynamic_dict == {"k1": 5, "k2": 10}

+ 4 - 5
tests/test_telemetry.py

@@ -1,7 +1,6 @@
-import pytest
+import json
 
 from pynecone import telemetry
-import json
 
 
 def versiontuple(v):
@@ -15,7 +14,7 @@ def test_telemetry():
     # Check that the user OS is one of the supported operating systems.
     tel.get_os()
 
-    assert tel.user_os != None
+    assert tel.user_os is not None
     assert tel.user_os in ["Linux", "Darwin", "Java", "Windows"]
 
     # Check that the CPU count and memory are greater than 0.
@@ -30,12 +29,12 @@ def test_telemetry():
 
     # Check that the Pynecone version is not None.
     tel.get_python_version()
-    assert tel.pynecone_version != None
+    assert tel.pynecone_version is not None
 
     # Check that the Python version is greater than 3.7.
     tel.get_pynecone_version()
 
-    assert tel.python_version != None
+    assert tel.python_version is not None
     assert versiontuple(tel.python_version) >= versiontuple("3.7")
 
     # Check the json method.

+ 1 - 1
tests/test_utils.py

@@ -231,7 +231,7 @@ def test_format_route(route: str, expected: bool):
 
 def test_setup_frontend(tmp_path, mocker):
     """Test checking if assets content have been
-    copied into the .web/public folder
+    copied into the .web/public folder.
 
     Args:
         tmp_path: root path of test case data directory