diff --git a/datasette/app.py b/datasette/app.py index 6a6a60b2..5e4be23b 100644 --- a/datasette/app.py +++ b/datasette/app.py @@ -2,7 +2,10 @@ from __future__ import annotations from asgi_csrf import Errors import asyncio -from typing import Any, Dict, Iterable, List +from typing import TYPE_CHECKING, Any, Dict, Iterable, List + +if TYPE_CHECKING: + from datasette.permissions import AllowedResource, Resource import asgi_csrf import collections import dataclasses @@ -117,8 +120,7 @@ from .tracer import AsgiTracer from .plugins import pm, DEFAULT_PLUGINS, get_plugins from .version import __version__ -from .permissions import PermissionSQL -from .resources import InstanceResource, DatabaseResource, TableResource +from .resources import DatabaseResource, TableResource app_root = Path(__file__).parent.parent @@ -1176,7 +1178,6 @@ class Datasette: if table.private: print(f"{table.child} is private") """ - from datasette.permissions import Resource action_obj = self.actions.get(action) if not action_obj: @@ -1217,7 +1218,7 @@ class Datasette: for allowed in debug_info: print(f"{allowed.resource}: {allowed.reason}") """ - from datasette.permissions import AllowedResource, Resource + from datasette.permissions import AllowedResource action_obj = self.actions.get(action) if not action_obj: @@ -1277,7 +1278,6 @@ class Datasette: """ from datasette.utils.actions_sql import check_permission_for_resource from datasette.resources import InstanceResource - import datetime if resource is None: resource = InstanceResource() diff --git a/datasette/cli.py b/datasette/cli.py index 9606a9a0..24d87279 100644 --- a/datasette/cli.py +++ b/datasette/cli.py @@ -146,7 +146,6 @@ def inspect(files, inspect_file, sqlite_extensions): This can then be passed to "datasette --inspect-file" to speed up count operations against immutable database files. """ - app = Datasette([], immutables=files, sqlite_extensions=sqlite_extensions) inspect_data = run_sync(lambda: inspect_(files, sqlite_extensions)) if inspect_file == "-": sys.stdout.write(json.dumps(inspect_data, indent=2)) diff --git a/datasette/default_permissions.py b/datasette/default_permissions.py index 3ad84a6d..32164260 100644 --- a/datasette/default_permissions.py +++ b/datasette/default_permissions.py @@ -1,3 +1,10 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from datasette.app import Datasette + from datasette import hookimpl from datasette.permissions import PermissionSQL from datasette.utils import actor_matches_allow diff --git a/datasette/events.py b/datasette/events.py index 88f90129..5cd5ba3d 100644 --- a/datasette/events.py +++ b/datasette/events.py @@ -2,7 +2,6 @@ from abc import ABC, abstractproperty from dataclasses import asdict, dataclass, field from datasette.hookspecs import hookimpl from datetime import datetime, timezone -from typing import Optional @dataclass diff --git a/datasette/filters.py b/datasette/filters.py index 795f472b..95cc5f37 100644 --- a/datasette/filters.py +++ b/datasette/filters.py @@ -3,7 +3,6 @@ from datasette.resources import DatabaseResource from datasette.views.base import DatasetteError from datasette.utils.asgi import BadRequest import json -import numbers from .utils import detect_json1, escape_sqlite, path_with_removed_args diff --git a/datasette/permissions.py b/datasette/permissions.py index 0f691405..42811aa0 100644 --- a/datasette/permissions.py +++ b/datasette/permissions.py @@ -1,6 +1,6 @@ from abc import ABC, abstractmethod from dataclasses import dataclass -from typing import Any, Dict, Optional, NamedTuple +from typing import Any, Dict, NamedTuple class Resource(ABC): diff --git a/datasette/plugins.py b/datasette/plugins.py index 288c536b..392ab60d 100644 --- a/datasette/plugins.py +++ b/datasette/plugins.py @@ -50,7 +50,7 @@ def after(outcome, hook_name, hook_impls, kwargs): results = outcome.get_result() if not isinstance(results, list): results = [results] - print(f"Results:", file=sys.stderr) + print("Results:", file=sys.stderr) pprint(results, width=40, indent=4, stream=sys.stderr) diff --git a/datasette/renderer.py b/datasette/renderer.py index 483c81e9..acf23e59 100644 --- a/datasette/renderer.py +++ b/datasette/renderer.py @@ -20,7 +20,7 @@ def convert_specific_columns_to_json(rows, columns, json_cols): if column in json_cols: try: value = json.loads(value) - except (TypeError, ValueError) as e: + except (TypeError, ValueError): pass new_row.append(value) new_rows.append(new_row) diff --git a/datasette/utils/asgi.py b/datasette/utils/asgi.py index 1699847e..40214cbe 100644 --- a/datasette/utils/asgi.py +++ b/datasette/utils/asgi.py @@ -1,4 +1,3 @@ -import hashlib import json from datasette.utils import MultiParams, calculate_etag from mimetypes import guess_type diff --git a/datasette/views/database.py b/datasette/views/database.py index 15eb271d..41eb4c57 100644 --- a/datasette/views/database.py +++ b/datasette/views/database.py @@ -9,7 +9,6 @@ import os import re import sqlite_utils import textwrap -from typing import List from datasette.events import AlterTableEvent, CreateTableEvent, InsertRowsEvent from datasette.database import QueryInterrupted @@ -71,7 +70,6 @@ class DatabaseView(View): metadata = await datasette.get_database_metadata(database) # Get all tables/views this actor can see in bulk with private flag - from datasette.resources import TableResource allowed_tables = await datasette.allowed_resources( "view-table", request.actor, parent=database, include_is_private=True @@ -344,7 +342,6 @@ async def get_tables(datasette, request, db, allowed_dict): allowed_dict: Dict mapping table name -> Resource object with .private attribute """ tables = [] - database = db.name table_counts = await db.table_counts(100) hidden_table_names = set(await db.hidden_table_names()) all_foreign_keys = await db.get_all_foreign_keys() @@ -512,7 +509,6 @@ class QueryView(View): database = db.name # Get all tables/views this actor can see in bulk with private flag - from datasette.resources import TableResource allowed_tables = await datasette.allowed_resources( "view-table", request.actor, parent=database, include_is_private=True diff --git a/datasette/views/index.py b/datasette/views/index.py index a5758cf8..a6bfc4d9 100644 --- a/datasette/views/index.py +++ b/datasette/views/index.py @@ -1,6 +1,5 @@ import json -from datasette import Forbidden from datasette.plugins import pm from datasette.utils import ( add_cors_headers, diff --git a/datasette/views/row.py b/datasette/views/row.py index 31d31bee..c9b74b12 100644 --- a/datasette/views/row.py +++ b/datasette/views/row.py @@ -247,7 +247,7 @@ class RowUpdateView(BaseView): if not isinstance(data, dict): return _error(["JSON must be a dictionary"]) - if not "update" in data or not isinstance(data["update"], dict): + if "update" not in data or not isinstance(data["update"], dict): return _error(["JSON must contain an update dictionary"]) invalid_keys = set(data.keys()) - {"update", "return", "alter"} diff --git a/datasette/views/table.py b/datasette/views/table.py index 3c7c976f..007c0c85 100644 --- a/datasette/views/table.py +++ b/datasette/views/table.py @@ -166,7 +166,6 @@ async def display_columns_and_rows( column_details = { col.name: col for col in await db.table_column_details(table_name) } - table_config = await datasette.table_config(database_name, table_name) pks = await db.primary_keys(table_name) pks_for_display = pks if not pks_for_display: diff --git a/tests/conftest.py b/tests/conftest.py index 6e00c5d8..4749fe6a 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -231,3 +231,27 @@ def ds_unix_domain_socket_server(tmp_path_factory): yield ds_proc, uds # Shut it down at the end of the pytest session ds_proc.terminate() + + +# Import fixtures from fixtures.py to make them available +from .fixtures import ( # noqa: E402, F401 + app_client, + app_client_base_url_prefix, + app_client_conflicting_database_names, + app_client_csv_max_mb_one, + app_client_immutable_and_inspect_file, + app_client_larger_cache_size, + app_client_no_files, + app_client_returned_rows_matches_page_size, + app_client_shorter_time_limit, + app_client_two_attached_databases, + app_client_two_attached_databases_crossdb_enabled, + app_client_two_attached_databases_one_immutable, + app_client_with_cors, + app_client_with_dot, + app_client_with_trace, + generate_compound_rows, + generate_sortable_rows, + make_app_client, + TEMP_PLUGIN_SECRET_FILE, +) diff --git a/tests/test_api.py b/tests/test_api.py index 84b33a09..31798668 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -1,6 +1,5 @@ from datasette.app import Datasette from datasette.plugins import DEFAULT_PLUGINS -from datasette.utils.sqlite import supports_table_xinfo from datasette.version import __version__ from .fixtures import ( # noqa app_client, diff --git a/tests/test_auth.py b/tests/test_auth.py index 3b3be2fc..1e1cd622 100644 --- a/tests/test_auth.py +++ b/tests/test_auth.py @@ -1,5 +1,4 @@ from bs4 import BeautifulSoup as Soup -from .fixtures import app_client from .utils import cookie_was_deleted, last_event from click.testing import CliRunner from datasette.utils import baseconv diff --git a/tests/test_canned_queries.py b/tests/test_canned_queries.py index c84c8cdb..ed6202a4 100644 --- a/tests/test_canned_queries.py +++ b/tests/test_canned_queries.py @@ -2,7 +2,7 @@ from bs4 import BeautifulSoup as Soup import json import pytest import re -from .fixtures import make_app_client, app_client +from .fixtures import make_app_client @pytest.fixture diff --git a/tests/test_cli.py b/tests/test_cli.py index a18c8f09..537089ac 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -1,5 +1,4 @@ from .fixtures import ( - app_client, make_app_client, TestClient as _TestClient, EXPECTED_PLUGINS, diff --git a/tests/test_crossdb.py b/tests/test_crossdb.py index bc4eaf22..1ec1a05c 100644 --- a/tests/test_crossdb.py +++ b/tests/test_crossdb.py @@ -2,7 +2,6 @@ from datasette.cli import cli from click.testing import CliRunner import urllib import sqlite3 -from .fixtures import app_client_two_attached_databases_crossdb_enabled def test_crossdb_join(app_client_two_attached_databases_crossdb_enabled): diff --git a/tests/test_html.py b/tests/test_html.py index a6dc52c0..e6d3eb93 100644 --- a/tests/test_html.py +++ b/tests/test_html.py @@ -1,4 +1,3 @@ -from asgi_csrf import Errors from bs4 import BeautifulSoup as Soup from datasette.app import Datasette from datasette.utils import allowed_pragmas diff --git a/tests/test_internals_database.py b/tests/test_internals_database.py index 89a17047..4a078f75 100644 --- a/tests/test_internals_database.py +++ b/tests/test_internals_database.py @@ -6,7 +6,6 @@ from datasette.app import Datasette from datasette.database import Database, Results, MultipleValues from datasette.utils.sqlite import sqlite3, sqlite_version from datasette.utils import Column -from .fixtures import app_client, app_client_two_attached_databases_crossdb_enabled import pytest import time import uuid diff --git a/tests/test_internals_datasette.py b/tests/test_internals_datasette.py index 629427b0..60bcfe25 100644 --- a/tests/test_internals_datasette.py +++ b/tests/test_internals_datasette.py @@ -3,7 +3,7 @@ Tests for the datasette.app.Datasette class """ import dataclasses -from datasette import Forbidden, Context +from datasette import Context from datasette.app import Datasette, Database from datasette.resources import DatabaseResource from itsdangerous import BadSignature diff --git a/tests/test_plugins.py b/tests/test_plugins.py index 205c04bd..0460d9c8 100644 --- a/tests/test_plugins.py +++ b/tests/test_plugins.py @@ -1,6 +1,5 @@ from bs4 import BeautifulSoup as Soup from .fixtures import ( - app_client, make_app_client, TABLES, TEMP_PLUGIN_SECRET_FILE, @@ -9,7 +8,7 @@ from .fixtures import ( ) # noqa from click.testing import CliRunner from datasette.app import Datasette -from datasette import cli, hookimpl, Permission +from datasette import cli, hookimpl from datasette.filters import FilterArguments from datasette.plugins import get_plugins, DEFAULT_PLUGINS, pm from datasette.permissions import PermissionSQL diff --git a/tests/test_table_html.py b/tests/test_table_html.py index 81dbaa69..e3ddb4b0 100644 --- a/tests/test_table_html.py +++ b/tests/test_table_html.py @@ -8,7 +8,7 @@ from .fixtures import ( # noqa import pathlib import pytest import urllib.parse -from .utils import assert_footer_links, inner_html +from .utils import inner_html @pytest.mark.asyncio