diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 70865c7..e1393d7 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -1,6 +1,6 @@ --- name: "Lint" -on: # yamllint disable-line rule:truthy +on: # yamllint disable-line rule:truthy push: branches: - "main" @@ -8,42 +8,23 @@ on: # yamllint disable-line rule:truthy branches: ["*"] jobs: lint: - name: "Format & Lint" + # Uses pre-commit to run all checks runs-on: "ubuntu-latest" - strategy: - matrix: - python-version: - - "3.10" - fail-fast: false steps: - uses: "actions/checkout@v4" - - uses: "bewuethr/yamllint-action@v1.3.0" + - name: "Install Poetry" + uses: "snok/install-poetry@v1" with: - config-file: ".yamllint" + # This should come from pyproject.toml but poetry + # wasn't picking it up for whatever reason. + virtualenvs-in-project: true + virtualenvs-path: ".venv" - uses: "actions/setup-python@v5" with: - python-version: "3.10" - - name: "Setup Python Environment" - run: "pip install -U pip virtualenv" - - name: "Install Dependencies" - run: | - virtualenv ~/.cache/virtualenv/authzedpy - source ~/.cache/virtualenv/authzedpy/bin/activate - pip install poetry - poetry env info - poetry install --only dev - - name: "Pyflakes" - run: | - source ~/.cache/virtualenv/authzedpy/bin/activate - find . -name "*.py" | grep -v "_pb2" | xargs pyflakes - - name: "Blacken" - run: | - source ~/.cache/virtualenv/authzedpy/bin/activate - black --check --diff . - - name: "Isort" - run: | - source ~/.cache/virtualenv/authzedpy/bin/activate - find . -name "*.py" | grep -v "_pb2" | xargs isort --check --diff + python-version: "3.11" + cache: 'poetry' + - run: "poetry install" + - uses: "pre-commit/action@v3.0.1" codeql: name: "Analyze with CodeQL" runs-on: "ubuntu-latest" @@ -75,24 +56,3 @@ jobs: uses: "github/codeql-action/upload-sarif@v3" with: sarif_file: "trivy-results.sarif" - mypy: - name: "Type Check with Mypy" - runs-on: "ubuntu-latest" - steps: - - uses: "actions/checkout@v4" - - uses: "actions/setup-python@v5" - with: - python-version: "3.10" - - name: "Setup Python Environment" - run: "pip install -U pip virtualenv" - - name: "Install Dependencies" - run: | - virtualenv ~/.cache/virtualenv/authzedpy - source ~/.cache/virtualenv/authzedpy/bin/activate - pip install poetry - poetry env info - poetry install --only dev - - name: "mypy" - run: | - source ~/.cache/virtualenv/authzedpy/bin/activate - mypy authzed diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..8bce2f6 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,20 @@ +--- +repos: + - repo: "https://github.com/astral-sh/ruff-pre-commit" + # Ruff version. + rev: "v0.6.1" + hooks: + # Run the linter. + - id: "ruff" + exclude: ".*_pb2.*" + # Run the formatter. + - id: "ruff-format" + exclude: ".*_pb2.*" + - repo: "https://github.com/adrienverge/yamllint" + rev: "v1.35.1" + hooks: + - id: "yamllint" + - repo: "https://github.com/RobertCraigie/pyright-python" + rev: "v1.1.376" + hooks: + - id: "pyright" diff --git a/authzed/api/v1/__init__.py b/authzed/api/v1/__init__.py index ce41adb..4ea46ea 100644 --- a/authzed/api/v1/__init__.py +++ b/authzed/api/v1/__init__.py @@ -64,7 +64,9 @@ from authzed.api.v1.watch_service_pb2_grpc import WatchServiceStub -class Client(SchemaServiceStub, PermissionsServiceStub, ExperimentalServiceStub, WatchServiceStub): +class Client( + SchemaServiceStub, PermissionsServiceStub, ExperimentalServiceStub, WatchServiceStub +): """ v1 Authzed gRPC API client - Auto-detects sync or async depending on if initialized within an event loop """ diff --git a/authzed/api/v1/__init__.pyi b/authzed/api/v1/__init__.pyi index 5d3463f..08e3e1a 100644 --- a/authzed/api/v1/__init__.pyi +++ b/authzed/api/v1/__init__.pyi @@ -64,11 +64,19 @@ from authzed.api.v1.schema_service_pb2 import ( WriteSchemaRequest, WriteSchemaResponse, ) -from authzed.api.v1.schema_service_pb2_grpc import SchemaServiceAsyncStub, SchemaServiceStub +from authzed.api.v1.schema_service_pb2_grpc import ( + SchemaServiceAsyncStub, + SchemaServiceStub, +) from authzed.api.v1.watch_service_pb2 import WatchRequest, WatchResponse -from authzed.api.v1.watch_service_pb2_grpc import WatchServiceAsyncStub, WatchServiceStub +from authzed.api.v1.watch_service_pb2_grpc import ( + WatchServiceAsyncStub, + WatchServiceStub, +) -class Client(SchemaServiceStub, PermissionsServiceStub, ExperimentalServiceStub, WatchServiceStub): +class Client( + SchemaServiceStub, PermissionsServiceStub, ExperimentalServiceStub, WatchServiceStub +): """The Client is typed as a synchronous client (though in practice it works with both sync and async code). If you are using the async code, you should switch to the AsyncClient class instead in order to get proper type hints """ diff --git a/examples/v1/bulk_check_permissions.py b/examples/v1/bulk_check_permissions.py index 8576c10..824b090 100644 --- a/examples/v1/bulk_check_permissions.py +++ b/examples/v1/bulk_check_permissions.py @@ -47,5 +47,11 @@ ) ) assert len(resp.pairs) == 2 -assert resp.pairs[0].item.permissionship == CheckPermissionResponse.PERMISSIONSHIP_HAS_PERMISSION -assert resp.pairs[1].item.permissionship == CheckPermissionResponse.PERMISSIONSHIP_HAS_PERMISSION +assert ( + resp.pairs[0].item.permissionship + == CheckPermissionResponse.PERMISSIONSHIP_HAS_PERMISSION +) +assert ( + resp.pairs[1].item.permissionship + == CheckPermissionResponse.PERMISSIONSHIP_HAS_PERMISSION +) diff --git a/examples/v1/bulk_import_export_relationships.py b/examples/v1/bulk_import_export_relationships.py index f133131..1a3c1bb 100644 --- a/examples/v1/bulk_import_export_relationships.py +++ b/examples/v1/bulk_import_export_relationships.py @@ -60,7 +60,7 @@ ) ] -import_reps = client.BulkImportRelationships(((req for req in reqs))) +import_reps = client.BulkImportRelationships((req for req in reqs)) assert import_reps.num_loaded == 2 export_resp = client.BulkExportRelationships( diff --git a/examples/v1alpha1/read_schema_async.py b/examples/v1alpha1/read_schema_async.py index 10b3b6e..a2a35d0 100644 --- a/examples/v1alpha1/read_schema_async.py +++ b/examples/v1alpha1/read_schema_async.py @@ -7,7 +7,9 @@ async def async_new_client(): # Within an async context, the client's methods are all async: client = Client("grpc.authzed.com:443", bearer_token_credentials("mytoken")) - resp = await client.ReadSchema(ReadSchemaRequest(object_definitions_names=["example/user"])) + resp = await client.ReadSchema( + ReadSchemaRequest(object_definitions_names=["example/user"]) + ) print(resp) diff --git a/poetry.lock b/poetry.lock index e9ca190..2b7112e 100644 --- a/poetry.lock +++ b/poetry.lock @@ -26,61 +26,15 @@ files = [ six = ">=1.6.1,<2.0" wheel = ">=0.23.0,<1.0" -[[package]] -name = "black" -version = "24.8.0" -description = "The uncompromising code formatter." -optional = false -python-versions = ">=3.8" -files = [ - {file = "black-24.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:09cdeb74d494ec023ded657f7092ba518e8cf78fa8386155e4a03fdcc44679e6"}, - {file = "black-24.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:81c6742da39f33b08e791da38410f32e27d632260e599df7245cccee2064afeb"}, - {file = "black-24.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:707a1ca89221bc8a1a64fb5e15ef39cd755633daa672a9db7498d1c19de66a42"}, - {file = "black-24.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:d6417535d99c37cee4091a2f24eb2b6d5ec42b144d50f1f2e436d9fe1916fe1a"}, - {file = "black-24.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fb6e2c0b86bbd43dee042e48059c9ad7830abd5c94b0bc518c0eeec57c3eddc1"}, - {file = "black-24.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:837fd281f1908d0076844bc2b801ad2d369c78c45cf800cad7b61686051041af"}, - {file = "black-24.8.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:62e8730977f0b77998029da7971fa896ceefa2c4c4933fcd593fa599ecbf97a4"}, - {file = "black-24.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:72901b4913cbac8972ad911dc4098d5753704d1f3c56e44ae8dce99eecb0e3af"}, - {file = "black-24.8.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:7c046c1d1eeb7aea9335da62472481d3bbf3fd986e093cffd35f4385c94ae368"}, - {file = "black-24.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:649f6d84ccbae73ab767e206772cc2d7a393a001070a4c814a546afd0d423aed"}, - {file = "black-24.8.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2b59b250fdba5f9a9cd9d0ece6e6d993d91ce877d121d161e4698af3eb9c1018"}, - {file = "black-24.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:6e55d30d44bed36593c3163b9bc63bf58b3b30e4611e4d88a0c3c239930ed5b2"}, - {file = "black-24.8.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:505289f17ceda596658ae81b61ebbe2d9b25aa78067035184ed0a9d855d18afd"}, - {file = "black-24.8.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b19c9ad992c7883ad84c9b22aaa73562a16b819c1d8db7a1a1a49fb7ec13c7d2"}, - {file = "black-24.8.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1f13f7f386f86f8121d76599114bb8c17b69d962137fc70efe56137727c7047e"}, - {file = "black-24.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:f490dbd59680d809ca31efdae20e634f3fae27fba3ce0ba3208333b713bc3920"}, - {file = "black-24.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:eab4dd44ce80dea27dc69db40dab62d4ca96112f87996bca68cd75639aeb2e4c"}, - {file = "black-24.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3c4285573d4897a7610054af5a890bde7c65cb466040c5f0c8b732812d7f0e5e"}, - {file = "black-24.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9e84e33b37be070ba135176c123ae52a51f82306def9f7d063ee302ecab2cf47"}, - {file = "black-24.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:73bbf84ed136e45d451a260c6b73ed674652f90a2b3211d6a35e78054563a9bb"}, - {file = "black-24.8.0-py3-none-any.whl", hash = "sha256:972085c618ee94f402da1af548a4f218c754ea7e5dc70acb168bfaca4c2542ed"}, - {file = "black-24.8.0.tar.gz", hash = "sha256:2500945420b6784c38b9ee885af039f5e7471ef284ab03fa35ecdde4688cd83f"}, -] - -[package.dependencies] -click = ">=8.0.0" -mypy-extensions = ">=0.4.3" -packaging = ">=22.0" -pathspec = ">=0.9.0" -platformdirs = ">=2" -tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""} - -[package.extras] -colorama = ["colorama (>=0.4.3)"] -d = ["aiohttp (>=3.7.4)", "aiohttp (>=3.7.4,!=3.9.0)"] -jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] -uvloop = ["uvloop (>=0.15.2)"] - [[package]] name = "cachetools" -version = "5.4.0" +version = "5.5.0" description = "Extensible memoizing collections and decorators" optional = false python-versions = ">=3.7" files = [ - {file = "cachetools-5.4.0-py3-none-any.whl", hash = "sha256:3ae3b49a3d5e28a77a0be2b37dbcb89005058959cb2323858c2657c4a8cab474"}, - {file = "cachetools-5.4.0.tar.gz", hash = "sha256:b8adc2e7c07f105ced7bc56dbb6dfbe7c4a00acce20e2227b3f355be89bc6827"}, + {file = "cachetools-5.5.0-py3-none-any.whl", hash = "sha256:02134e8439cdc2ffb62023ce1debca2944c3f289d66bb17ead3ab3dede74b292"}, + {file = "cachetools-5.5.0.tar.gz", hash = "sha256:2cc24fb4cbe39633fb7badd9db9ca6295d766d9c2995f245725a46715d050f2a"}, ] [[package]] @@ -193,20 +147,6 @@ files = [ {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, ] -[[package]] -name = "click" -version = "8.1.7" -description = "Composable command line interface toolkit" -optional = false -python-versions = ">=3.7" -files = [ - {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, - {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "platform_system == \"Windows\""} - [[package]] name = "colorama" version = "0.4.6" @@ -271,13 +211,13 @@ grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0.dev0)"] [[package]] name = "google-auth" -version = "2.33.0" +version = "2.34.0" description = "Google Authentication Library" optional = false python-versions = ">=3.7" files = [ - {file = "google_auth-2.33.0-py2.py3-none-any.whl", hash = "sha256:8eff47d0d4a34ab6265c50a106a3362de6a9975bb08998700e389f857e4d39df"}, - {file = "google_auth-2.33.0.tar.gz", hash = "sha256:d6a52342160d7290e334b4d47ba390767e4438ad0d45b7630774533e82655b95"}, + {file = "google_auth-2.34.0-py2.py3-none-any.whl", hash = "sha256:72fd4733b80b6d777dcde515628a9eb4a577339437012874ea286bca7261ee65"}, + {file = "google_auth-2.34.0.tar.gz", hash = "sha256:8eb87396435c19b20d32abd2f984e31c191a15284af72eb922f10e5bde9c04cc"}, ] [package.dependencies] @@ -287,7 +227,7 @@ rsa = ">=3.1.4,<5" [package.extras] aiohttp = ["aiohttp (>=3.6.2,<4.0.0.dev0)", "requests (>=2.20.0,<3.0.0.dev0)"] -enterprise-cert = ["cryptography (==36.0.2)", "pyopenssl (==22.0.0)"] +enterprise-cert = ["cryptography", "pyopenssl"] pyopenssl = ["cryptography (>=38.0.3)", "pyopenssl (>=20.0.0)"] reauth = ["pyu2f (>=0.1.5)"] requests = ["requests (>=2.20.0,<3.0.0.dev0)"] @@ -463,20 +403,6 @@ files = [ {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, ] -[[package]] -name = "isort" -version = "5.13.2" -description = "A Python utility / library to sort Python imports." -optional = false -python-versions = ">=3.8.0" -files = [ - {file = "isort-5.13.2-py3-none-any.whl", hash = "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6"}, - {file = "isort-5.13.2.tar.gz", hash = "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109"}, -] - -[package.extras] -colors = ["colorama (>=0.4.6)"] - [[package]] name = "jinja2" version = "3.1.4" @@ -579,64 +505,6 @@ build = ["blurb", "twine", "wheel"] docs = ["sphinx"] test = ["pytest", "pytest-cov"] -[[package]] -name = "mypy" -version = "1.11.1" -description = "Optional static typing for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "mypy-1.11.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a32fc80b63de4b5b3e65f4be82b4cfa362a46702672aa6a0f443b4689af7008c"}, - {file = "mypy-1.11.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c1952f5ea8a5a959b05ed5f16452fddadbaae48b5d39235ab4c3fc444d5fd411"}, - {file = "mypy-1.11.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e1e30dc3bfa4e157e53c1d17a0dad20f89dc433393e7702b813c10e200843b03"}, - {file = "mypy-1.11.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2c63350af88f43a66d3dfeeeb8d77af34a4f07d760b9eb3a8697f0386c7590b4"}, - {file = "mypy-1.11.1-cp310-cp310-win_amd64.whl", hash = "sha256:a831671bad47186603872a3abc19634f3011d7f83b083762c942442d51c58d58"}, - {file = "mypy-1.11.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7b6343d338390bb946d449677726edf60102a1c96079b4f002dedff375953fc5"}, - {file = "mypy-1.11.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e4fe9f4e5e521b458d8feb52547f4bade7ef8c93238dfb5bbc790d9ff2d770ca"}, - {file = "mypy-1.11.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:886c9dbecc87b9516eff294541bf7f3655722bf22bb898ee06985cd7269898de"}, - {file = "mypy-1.11.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fca4a60e1dd9fd0193ae0067eaeeb962f2d79e0d9f0f66223a0682f26ffcc809"}, - {file = "mypy-1.11.1-cp311-cp311-win_amd64.whl", hash = "sha256:0bd53faf56de9643336aeea1c925012837432b5faf1701ccca7fde70166ccf72"}, - {file = "mypy-1.11.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f39918a50f74dc5969807dcfaecafa804fa7f90c9d60506835036cc1bc891dc8"}, - {file = "mypy-1.11.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0bc71d1fb27a428139dd78621953effe0d208aed9857cb08d002280b0422003a"}, - {file = "mypy-1.11.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b868d3bcff720dd7217c383474008ddabaf048fad8d78ed948bb4b624870a417"}, - {file = "mypy-1.11.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a707ec1527ffcdd1c784d0924bf5cb15cd7f22683b919668a04d2b9c34549d2e"}, - {file = "mypy-1.11.1-cp312-cp312-win_amd64.whl", hash = "sha256:64f4a90e3ea07f590c5bcf9029035cf0efeae5ba8be511a8caada1a4893f5525"}, - {file = "mypy-1.11.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:749fd3213916f1751fff995fccf20c6195cae941dc968f3aaadf9bb4e430e5a2"}, - {file = "mypy-1.11.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b639dce63a0b19085213ec5fdd8cffd1d81988f47a2dec7100e93564f3e8fb3b"}, - {file = "mypy-1.11.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4c956b49c5d865394d62941b109728c5c596a415e9c5b2be663dd26a1ff07bc0"}, - {file = "mypy-1.11.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:45df906e8b6804ef4b666af29a87ad9f5921aad091c79cc38e12198e220beabd"}, - {file = "mypy-1.11.1-cp38-cp38-win_amd64.whl", hash = "sha256:d44be7551689d9d47b7abc27c71257adfdb53f03880841a5db15ddb22dc63edb"}, - {file = "mypy-1.11.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2684d3f693073ab89d76da8e3921883019ea8a3ec20fa5d8ecca6a2db4c54bbe"}, - {file = "mypy-1.11.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:79c07eb282cb457473add5052b63925e5cc97dfab9812ee65a7c7ab5e3cb551c"}, - {file = "mypy-1.11.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11965c2f571ded6239977b14deebd3f4c3abd9a92398712d6da3a772974fad69"}, - {file = "mypy-1.11.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a2b43895a0f8154df6519706d9bca8280cda52d3d9d1514b2d9c3e26792a0b74"}, - {file = "mypy-1.11.1-cp39-cp39-win_amd64.whl", hash = "sha256:1a81cf05975fd61aec5ae16501a091cfb9f605dc3e3c878c0da32f250b74760b"}, - {file = "mypy-1.11.1-py3-none-any.whl", hash = "sha256:0624bdb940255d2dd24e829d99a13cfeb72e4e9031f9492148f410ed30bcab54"}, - {file = "mypy-1.11.1.tar.gz", hash = "sha256:f404a0b069709f18bbdb702eb3dcfe51910602995de00bd39cea3050b5772d08"}, -] - -[package.dependencies] -mypy-extensions = ">=1.0.0" -tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typing-extensions = ">=4.6.0" - -[package.extras] -dmypy = ["psutil (>=4.0)"] -install-types = ["pip"] -mypyc = ["setuptools (>=50)"] -reports = ["lxml"] - -[[package]] -name = "mypy-extensions" -version = "1.0.0" -description = "Type system extensions for programs checked with the mypy type checker." -optional = false -python-versions = ">=3.5" -files = [ - {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, - {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, -] - [[package]] name = "mypy-protobuf" version = "3.6.0" @@ -653,43 +521,27 @@ protobuf = ">=4.25.3" types-protobuf = ">=4.24" [[package]] -name = "packaging" -version = "24.1" -description = "Core utilities for Python packages" +name = "nodeenv" +version = "1.9.1" +description = "Node.js virtual environment builder" optional = false -python-versions = ">=3.8" -files = [ - {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, - {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, -] - -[[package]] -name = "pathspec" -version = "0.12.1" -description = "Utility library for gitignore style pattern matching of file paths." -optional = false -python-versions = ">=3.8" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ - {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, - {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, + {file = "nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9"}, + {file = "nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f"}, ] [[package]] -name = "platformdirs" -version = "4.2.2" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." +name = "packaging" +version = "24.1" +description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "platformdirs-4.2.2-py3-none-any.whl", hash = "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee"}, - {file = "platformdirs-4.2.2.tar.gz", hash = "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3"}, + {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, + {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, ] -[package.extras] -docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] -type = ["mypy (>=1.8)"] - [[package]] name = "pluggy" version = "1.5.0" @@ -785,16 +637,23 @@ files = [ pyasn1 = ">=0.4.6,<0.7.0" [[package]] -name = "pyflakes" -version = "3.2.0" -description = "passive checker of Python programs" +name = "pyright" +version = "1.1.376" +description = "Command line wrapper for pyright" optional = false -python-versions = ">=3.8" +python-versions = ">=3.7" files = [ - {file = "pyflakes-3.2.0-py2.py3-none-any.whl", hash = "sha256:84b5be138a2dfbb40689ca07e2152deb896a65c3a3e24c251c5c62489568074a"}, - {file = "pyflakes-3.2.0.tar.gz", hash = "sha256:1c61603ff154621fb2a9172037d84dca3500def8c8b630657d1701f026f8af3f"}, + {file = "pyright-1.1.376-py3-none-any.whl", hash = "sha256:0f2473b12c15c46b3207f0eec224c3cea2bdc07cd45dd4a037687cbbca0fbeff"}, + {file = "pyright-1.1.376.tar.gz", hash = "sha256:bffd63b197cd0810395bb3245c06b01f95a85ddf6bfa0e5644ed69c841e954dd"}, ] +[package.dependencies] +nodeenv = ">=1.6.0" + +[package.extras] +all = ["twine (>=3.4.1)"] +dev = ["twine (>=3.4.1)"] + [[package]] name = "pytest" version = "8.3.2" @@ -872,19 +731,19 @@ pyasn1 = ">=0.1.3" [[package]] name = "setuptools" -version = "72.2.0" +version = "73.0.1" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-72.2.0-py3-none-any.whl", hash = "sha256:f11dd94b7bae3a156a95ec151f24e4637fb4fa19c878e4d191bfb8b2d82728c4"}, - {file = "setuptools-72.2.0.tar.gz", hash = "sha256:80aacbf633704e9c8bfa1d99fa5dd4dc59573efcf9e4042c13d3bcef91ac2ef9"}, + {file = "setuptools-73.0.1-py3-none-any.whl", hash = "sha256:b208925fcb9f7af924ed2dc04708ea89791e24bde0d3020b27df0e116088b34e"}, + {file = "setuptools-73.0.1.tar.gz", hash = "sha256:d59a3e788ab7e012ab2c4baed1b376da6366883ee20d7a5fc426816e3d7b1193"}, ] [package.extras] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.text (>=3.7)", "more-itertools (>=8.8)", "ordered-set (>=3.1.1)", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.text (>=3.7)", "more-itertools (>=8.8)", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.11.*)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (<0.4)", "pytest-ruff (>=0.2.1)", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.11.*)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (<0.4)", "pytest-ruff (>=0.2.1)", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] [[package]] name = "six" @@ -974,4 +833,4 @@ test = ["pytest (>=6.0.0)", "setuptools (>=65)"] [metadata] lock-version = "2.0" python-versions = "^3.8" -content-hash = "642389a8d5853c26297b3e557d803b2ca1ca573e0ff6fc6f2a6a37ad5e34e3a2" +content-hash = "dc8e405da6e53ef4068d9b2430e90fb6acd436fdc1892b2367e2b0caa2a2344d" diff --git a/pyproject.toml b/pyproject.toml index 1db5cd2..538f5e7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,3 +1,9 @@ +[virtualenvs] +# This puts the virtualenv inside the dir, +# which also means that pyright will always be able +# to find it. +in-project = true + [tool.poetry] authors = ["Authzed "] description = "Client library for SpiceDB." @@ -21,23 +27,32 @@ python = "^3.8" typing-extensions = ">=3.7.4,<5" [tool.poetry.group.dev.dependencies] -black = ">=23.3,<25.0" grpc-stubs = "^1.53" grpcio-tools = ">=1.63,<1.66" -isort = "^5.6.4" -mypy = "1.11.1" mypy-protobuf = "3.6.0" mock = "^5.1.0" -pyflakes = "^3.0.1" pytest = ">=7.1.3,<9.0.0" pytest-asyncio = ">=0.21,<0.24" protoc-gen-validate = ">=0.4.1,<=1.1.0" types-protobuf = ">=5.26,<6.0" +pyright = "^1.1.376" [tool.black] exclude = '(^\.(.*)|^(.*)_pb2(_grpc)?\.py)' line-length = 100 +[tool.pyright] +include = ["authzed"] +exclude = ["**/*.py"] +venvPath = "." +venv = ".venv" +# NOTE: this isn't ideal. The issue here appears to be with the code that's +# generated for google grpc Statuses, and pyright complains that Status isn't +# on the module, which *does* appear to be true. It's unclear whether this is +# an issue with our usage or with the package that generates types. +# TODO: try using pyi to generate the stubs rather than mypy +reportAttributeAccessIssue = "warning" + [tool.mypy] explicit_package_bases = true diff --git a/tests/v1_test.py b/tests/v1_test.py index 63e502e..fd822fd 100644 --- a/tests/v1_test.py +++ b/tests/v1_test.py @@ -61,7 +61,9 @@ async def async_client(token) -> AsyncClient: # The configs array paramaterizes the tests in this file to run with different clients. # To make changes, modify both the configs array and the config fixture -Config = Literal["Client_autodetect_sync", "Client_autodetect_async", "SyncClient", "AsyncClient"] +Config = Literal[ + "Client_autodetect_sync", "Client_autodetect_async", "SyncClient", "AsyncClient" +] configs: List[Config] = [ "Client_autodetect_sync", "Client_autodetect_async", @@ -200,7 +202,10 @@ async def test_caveated_check(client): context=None, ) resp = await maybe_await(client.CheckPermission(req)) - assert resp.permissionship == CheckPermissionResponse.PERMISSIONSHIP_CONDITIONAL_PERMISSION + assert ( + resp.permissionship + == CheckPermissionResponse.PERMISSIONSHIP_CONDITIONAL_PERMISSION + ) assert "likes" in resp.partial_caveat_info.missing_required_context @@ -272,10 +277,12 @@ async def test_bulk_check(client): assert len(resp.pairs) == 2 assert ( - resp.pairs[0].item.permissionship == CheckPermissionResponse.PERMISSIONSHIP_HAS_PERMISSION + resp.pairs[0].item.permissionship + == CheckPermissionResponse.PERMISSIONSHIP_HAS_PERMISSION ) assert ( - resp.pairs[1].item.permissionship == CheckPermissionResponse.PERMISSIONSHIP_HAS_PERMISSION + resp.pairs[1].item.permissionship + == CheckPermissionResponse.PERMISSIONSHIP_HAS_PERMISSION ) @@ -308,7 +315,9 @@ async def test_bulk_export_import(client): # do bulk import reqs = [BulkImportRelationshipsRequest(relationships=rels)] - import_rels = await maybe_await(empty_client.BulkImportRelationships(((req for req in reqs)))) + import_rels = await maybe_await( + empty_client.BulkImportRelationships((req for req in reqs)) + ) assert import_rels.num_loaded == 4 # validate all relationships were imported @@ -381,7 +390,9 @@ async def write_test_tuples(client): resource=post_one, relation="caveated_reader", subject=beatrice, - optional_caveat=ContextualizedCaveat(caveat_name="likes_harry_potter"), + optional_caveat=ContextualizedCaveat( + caveat_name="likes_harry_potter" + ), ), ), ] @@ -420,7 +431,9 @@ async def maybe_await(resp: T) -> T: return resp -async def maybe_async_iterable_to_list(iterable: Union[Iterable[T], AsyncIterable[T]]) -> List[T]: +async def maybe_async_iterable_to_list( + iterable: Union[Iterable[T], AsyncIterable[T]], +) -> List[T]: items = [] if isinstance(iterable, AsyncIterable): async for item in iterable: