An open source multi-tool for exploring and publishing data
This report summarizes scanner evidence for simonw/datasette, a Python project with 11,511 GitHub stars. SynthScan examined 104,211 lines of code across 304 source files, recording 1880 pattern matches distributed across 17 syntactic categories. The legacy adjusted pattern signal is 17.8 (Elevated pattern signal); it is not an authorship estimate.
Use the findings to ask whether maintainers can explain intent, verify dependencies, simplify unnecessary scaffolding, and focus review effort. Risk Payload v1 adds ownership, supply-chain, over-engineering, and review-effort vectors when available. These are prompts for human verification, not probabilities, security findings, or measured maintenance costs.
Use each vector to guide manual verification of the underlying findings.
Can maintainers explain intent, assumptions, and trade-offs? 1673 finding(s).
Are imports declared and package/API names verified? 110 finding(s).
Are wrappers, guards, and repeated structures necessary? 1637 finding(s).
Which changes need focused human review? 1880 finding(s).
This chart tracks the legacy adjusted pattern score across scan runs. Changes can reflect source changes, scan coverage, or detector/scoring versions; they do not measure AI adoption or prove that a team refactored code. Compare runs only when their scoring versions are compatible. The dashed line tracks the raw pattern-hit count.
Groups findings by configured severity weight. Severity is not a confidence estimate, security rating, or proof that a package is missing. Verify imports against the project's manifests and inspect each finding in its local design context.
This horizontal bar chart shows where configured pattern scores accumulate across directories. Treat the bars as locations to inspect, not as evidence of authorship or code quality. Use the file-level findings to decide whether a directory needs a focused ownership, dependency, complexity, or review check.
The scanner identified 1880 distinct pattern matches across 17 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a detector match to inspect in context. Expand any category row to inspect the individual file paths, line numbers, code snippets, and the lexical context (CODE, COMMENT, or STRING) in which each match was detected.
Reading the findings table: The Severity column indicates the configured finding weight (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — legacy comment-context matches receive a ×1.5 score weight. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier under the legacy scoring model.
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/test_column_types.py | 131 | async def test_column_types_table_created(ds_ct): | CODE |
| LOW | tests/test_column_types.py | 141 | async def test_config_loaded_into_internal_db(ds_ct): | CODE |
| LOW | tests/test_column_types.py | 153 | async def test_config_with_type_and_config(tmp_path_factory): | CODE |
| LOW | tests/test_column_types.py | 215 | async def test_get_column_type_missing(ds_ct): | CODE |
| LOW | tests/test_column_types.py | 222 | async def test_set_and_remove_column_type(ds_ct): | CODE |
| LOW | tests/test_column_types.py | 235 | async def test_set_column_type_with_config(ds_ct): | CODE |
| LOW | tests/test_column_types.py | 266 | async def test_set_column_type_api_with_config(ds_ct): | CODE |
| LOW | tests/test_column_types.py | 288 | async def test_clear_column_type_api(ds_ct): | CODE |
| LOW | tests/test_column_types.py | 401 | async def test_set_column_type_api_errors( | CODE |
| LOW | tests/test_column_types.py | 425 | async def test_set_column_type_api_works_for_immutable_database(tmp_path_factory): | CODE |
| LOW | tests/test_column_types.py | 454 | async def test_set_column_type_rejects_incompatible_sqlite_type(ds_ct): | CODE |
| LOW | tests/test_column_types.py | 461 | async def test_set_column_type_allows_varchar_for_text_only_type(tmp_path_factory): | CODE |
| LOW | tests/test_column_types.py | 483 | async def test_builtin_column_types_registered(ds_ct): | CODE |
| LOW | tests/test_column_types.py | 494 | async def test_column_type_class_attributes(ds_ct): | CODE |
| LOW | tests/test_column_types.py | 512 | def test_sqlite_type_from_declared_type(): | CODE |
| LOW | tests/test_column_types.py | 547 | async def test_display_columns_include_column_type(ds_ct): | CODE |
| LOW | tests/test_column_types.py | 598 | async def test_email_validation_on_insert(ds_ct): | CODE |
| LOW | tests/test_column_types.py | 611 | async def test_email_validation_passes_valid(ds_ct): | CODE |
| LOW | tests/test_column_types.py | 623 | async def test_url_validation_on_insert(ds_ct): | CODE |
| LOW | tests/test_column_types.py | 636 | async def test_json_validation_on_insert(ds_ct): | CODE |
| LOW | tests/test_column_types.py | 649 | async def test_validation_on_update(ds_ct): | CODE |
| LOW | tests/test_column_types.py | 662 | async def test_validation_allows_null(ds_ct): | CODE |
| LOW | tests/test_column_types.py | 674 | async def test_validation_allows_empty_string(ds_ct): | CODE |
| LOW | tests/test_column_types.py | 689 | async def test_column_type_base_defaults(): | CODE |
| LOW | tests/test_column_types.py | 705 | async def test_render_cell_extra_with_column_types(ds_ct): | CODE |
| LOW | tests/test_column_types.py | 719 | async def test_duplicate_column_type_name_raises_error(): | CODE |
| LOW | tests/test_column_types.py | 746 | async def test_row_endpoint_render_cell_with_column_types(ds_ct): | CODE |
| LOW | tests/test_column_types.py | 760 | async def test_transform_value_in_json_output(tmp_path_factory): | CODE |
| LOW | tests/test_column_types.py | 812 | async def test_column_type_render_cell_has_priority_over_plugins(tmp_path_factory): | CODE |
| LOW | tests/test_column_types.py | 891 | async def test_row_detail_page_html_rendering(ds_ct): | CODE |
| LOW | tests/test_column_types.py | 907 | async def test_html_table_page_rendering(ds_ct): | CODE |
| LOW | tests/test_column_types.py | 918 | async def test_set_column_type_ui_data_hidden_without_permission(ds_ct): | CODE |
| LOW | tests/test_column_types.py | 926 | async def test_set_column_type_ui_data_includes_applicable_types( | CODE |
| LOW | tests/test_column_types.py | 965 | async def test_validation_on_upsert(ds_ct): | CODE |
| LOW | tests/test_column_types.py | 980 | async def test_validation_on_upsert_passes_valid(ds_ct): | CODE |
| LOW | tests/test_column_types.py | 997 | async def test_unknown_type_warning_logged(tmp_path_factory, caplog): | CODE |
| LOW | tests/test_column_types.py | 1023 | async def test_incompatible_sqlite_type_warning_logged(tmp_path_factory, caplog): | CODE |
| LOW | tests/test_column_types.py | 1050 | async def test_config_overwrites_on_restart(tmp_path_factory): | CODE |
| LOW | tests/test_column_types.py | 1088 | async def test_no_column_types_in_config(tmp_path_factory): | CODE |
| LOW⚡ | tests/test_table_api.py | 125 | async def test_html_only_extras_are_not_available_via_json(ds_client, extra): | CODE |
| LOW⚡ | tests/test_table_api.py | 134 | async def test_html_only_extras_are_not_advertised(ds_client): | CODE |
| LOW⚡ | tests/test_table_api.py | 141 | def test_query_extra_private_for_arbitrary_sql(): | CODE |
| LOW⚡ | tests/test_table_api.py | 268 | async def test_table_shape_object_compound_primary_key(ds_client): | CODE |
| LOW⚡ | tests/test_table_api.py | 278 | async def test_table_with_slashes_in_name(ds_client): | CODE |
| LOW⚡ | tests/test_table_api.py | 288 | async def test_table_with_reserved_word_name(ds_client): | CODE |
| LOW | tests/test_table_api.py | 33 | async def test_table_not_exists_json(ds_client): | CODE |
| LOW | tests/test_table_api.py | 55 | async def test_table_shape_arrayfirst(ds_client): | CODE |
| LOW | tests/test_table_api.py | 75 | async def test_query_extras_for_arbitrary_sql(ds_client): | CODE |
| LOW | tests/test_table_api.py | 99 | async def test_query_extras_for_stored_query(ds_client): | CODE |
| LOW | tests/test_table_api.py | 155 | def test_query_extra_query_reports_bound_params(): | CODE |
| LOW | tests/test_table_api.py | 186 | def test_query_extra_query_does_not_echo_querystring(): | CODE |
| LOW | tests/test_table_api.py | 195 | def test_query_extra_private_false_when_sql_is_public(): | CODE |
| LOW | tests/test_table_api.py | 229 | async def test_table_shape_array_nl(ds_client): | CODE |
| LOW | tests/test_table_api.py | 323 | async def test_paginate_tables_and_views( | CODE |
| LOW | tests/test_table_api.py | 370 | async def test_paginate_compound_keys(ds_client): | CODE |
| LOW | tests/test_table_api.py | 391 | async def test_paginate_compound_keys_with_extra_filters(ds_client): | CODE |
| LOW | tests/test_table_api.py | 467 | async def test_sortable_and_filtered(ds_client): | CODE |
| LOW | tests/test_table_api.py | 486 | async def test_sortable_argument_errors(ds_client): | CODE |
| LOW | tests/test_table_api.py | 500 | async def test_sortable_columns_metadata(ds_client): | CODE |
| LOW | tests/test_table_api.py | 636 | async def test_searchable_invalid_column(ds_client): | CODE |
| 1461 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | tests/conftest.py | 316 | except FileNotFoundError: | CODE |
| HIGH | tests/conftest.py | 356 | except FileNotFoundError: | CODE |
| HIGH | tests/test_internals_database.py | 145 | except ValueError: | CODE |
| HIGH | tests/test_api_write.py | 1588 | except Exception: # noqa: BLE001, S110 | CODE |
| HIGH | datasette/plugins.py | 111 | except (TypeError, ModuleNotFoundError): | CODE |
| HIGH | datasette/background_tasks.py | 147 | except ValueError: | CODE |
| HIGH | datasette/csrf.py | 164 | except Exception: # noqa: BLE001, S110 | CODE |
| HIGH | datasette/_pytest_plugin.py | 123 | except ValueError: | CODE |
| HIGH | datasette/renderer.py | 26 | except (TypeError, ValueError): | CODE |
| HIGH | datasette/database.py | 1184 | except RuntimeError: | CODE |
| HIGH | datasette/database.py | 255 | except AttributeError: | CODE |
| HIGH | datasette/database.py | 242 | except Exception: # noqa: BLE001, S110 | CODE |
| HIGH | datasette/database.py | 249 | except Exception: # noqa: BLE001, S110 | CODE |
| HIGH | datasette/database.py | 261 | except Exception: # noqa: BLE001, S110 | CODE |
| HIGH | datasette/database.py | 267 | except Exception: # noqa: BLE001, S110 | CODE |
| HIGH | datasette/database.py | 1127 | except StopIteration: | CODE |
| HIGH | datasette/database.py | 278 | except OSError: | CODE |
| HIGH | datasette/database.py | 399 | except ValueError: | CODE |
| HIGH | datasette/database.py | 1119 | except StopIteration: | CODE |
| HIGH | datasette/database.py | 589 | except Exception: # noqa: BLE001, S110 | CODE |
| HIGH | datasette/database.py | 634 | except ValueError: | CODE |
| HIGH | datasette/cli.py | 65 | except ImportError: | CODE |
| HIGH | datasette/cli.py | 909 | except SpatialiteNotFound: | CODE |
| HIGH | datasette/app.py | 2343 | except QueryInterrupted: | CODE |
| HIGH | datasette/app.py | 3263 | except BadSignature: | CODE |
| HIGH | datasette/app.py | 1995 | except (ValueError, KeyError): | CODE |
| HIGH | datasette/app.py | 2396 | except Exception: # noqa: BLE001, S110 | CODE |
| HIGH | datasette/app.py | 610 | except ValueError: | CODE |
| HIGH | datasette/app.py | 2452 | except importlib.metadata.PackageNotFoundError: | CODE |
| HIGH | datasette/utils/multipart.py | 82 | except Exception: # noqa: BLE001, S110 | CODE |
| HIGH | datasette/utils/multipart.py | 160 | except Exception: # noqa: BLE001, S110 | CODE |
| HIGH | datasette/utils/multipart.py | 169 | except Exception: # noqa: BLE001, S110 | CODE |
| HIGH | datasette/utils/multipart.py | 235 | except Exception: # noqa: BLE001, S110 | CODE |
| HIGH | datasette/utils/asgi.py | 192 | except ValueError: | CODE |
| HIGH | datasette/utils/__init__.py | 1594 | except json.JSONDecodeError: | CODE |
| HIGH | datasette/utils/sqlite.py | 119 | except sqlite3.DatabaseError: | CODE |
| HIGH | datasette/views/database.py | 534 | except KeyError: | CODE |
| HIGH | datasette/views/database.py | 1034 | except InvalidSql: | CODE |
| HIGH | datasette/views/table_extras.py | 154 | except KeyError: | CODE |
| HIGH | datasette/views/table_extras.py | 128 | except KeyError: | CODE |
| HIGH | datasette/views/table_extras.py | 138 | except QueryInterrupted: | CODE |
| HIGH | datasette/views/table.py | 1391 | except json.JSONDecodeError: | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | tests/test_table_api.py | 1358 | '{"rowid": 3, "data": null}' | STRING |
| HIGH | tests/test_queries.py | 1786 | assert "window.location.href = url.toString();" not in response.text | STRING |
| HIGH | tests/test_table_html.py | 1282 | name text not null, | CODE |
| HIGH | tests/test_table_html.py | 1437 | name text not null, | CODE |
| HIGH | tests/test_write_wrapper.py | 432 | await db.execute_write("insert into groups (id, current) values (1, null)") | CODE |
| HIGH | tests/test_api_write.py | 1486 | "(1, 'one', 1.5, 1), (2, 'two', 999.5, 2), (3, null, null, null)" | STRING |
| HIGH | tests/test_playwright.py | 118 | title text not null, | CODE |
| HIGH | tests/test_playwright.py | 130 | name text not null, | CODE |
| HIGH | tests/test_playwright.py | 135 | title text not null, | CODE |
| HIGH | tests/test_playwright.py | 285 | if (!context.columnType || context.columnType.type !== "asset") { | CODE |
| HIGH | tests/test_playwright.py | 1019 | window.__discardConfirmMessages.push(message); | CODE |
| HIGH | tests/test_playwright.py | 1131 | window.appliedColumns = null; | CODE |
| HIGH | tests/test_playwright.py | 1437 | "node => node.hidden && node.disabled" | CODE |
| HIGH | tests/test_playwright.py | 1858 | window.confirm = message => { confirmations.push(message); return false; }; | CODE |
| HIGH | tests/test_playwright.py | 1766 | closeSources.push(source); | STRING |
| HIGH | tests/test_playwright.py | 2135 | return r.left >= 11 && r.top >= 11 && | STRING |
| HIGH | tests/test_playwright.py | 2136 | r.right <= innerWidth - 11 && r.bottom <= innerHeight - 11; | STRING |
| HIGH⚡ | datasette/fixtures.py | 235 | ("2019-01-14 08:00:00", 1, 1, 'CA', 1, 'SOMA', '[]', '[]', null, null), | STRING |
| HIGH⚡ | datasette/fixtures.py | 236 | ("2019-01-14 08:00:00", 1, 1, 'CA', 1, 'Tenderloin', '[]', '[]', null, null), | STRING |
| HIGH⚡ | datasette/fixtures.py | 237 | ("2019-01-15 08:00:00", 1, 1, 'CA', 1, 'Bernal Heights', '[]', '[]', null, null), | STRING |
| HIGH⚡ | datasette/fixtures.py | 238 | ("2019-01-15 08:00:00", 1, 1, 'CA', 1, 'Hayes Valley', '[]', '[]', null, null), | STRING |
| HIGH⚡ | datasette/fixtures.py | 239 | ("2019-01-15 08:00:00", 1, 1, 'CA', 2, 'Hollywood', '[]', '[]', null, null), | STRING |
| HIGH⚡ | datasette/fixtures.py | 240 | ("2019-01-15 08:00:00", 1, 1, 'CA', 2, 'Downtown', '[]', '[]', null, null), | STRING |
| HIGH⚡ | datasette/fixtures.py | 241 | ("2019-01-16 08:00:00", 1, 1, 'CA', 2, 'Los Feliz', '[]', '[]', null, null), | STRING |
| HIGH⚡ | datasette/fixtures.py | 242 | ("2019-01-16 08:00:00", 1, 1, 'CA', 2, 'Koreatown', '[]', '[]', null, null), | STRING |
| HIGH⚡ | datasette/fixtures.py | 243 | ("2019-01-16 08:00:00", 1, 1, 'MI', 3, 'Downtown', '[]', '[]', null, null), | STRING |
| HIGH⚡ | datasette/fixtures.py | 244 | ("2019-01-17 08:00:00", 1, 1, 'MI', 3, 'Greektown', '[]', '[]', null, null), | STRING |
| HIGH⚡ | datasette/fixtures.py | 245 | ("2019-01-17 08:00:00", 1, 1, 'MI', 3, 'Corktown', '[]', '[]', null, null), | STRING |
| HIGH⚡ | datasette/fixtures.py | 246 | ("2019-01-17 08:00:00", 1, 1, 'MI', 3, 'Mexicantown', '[]', '[]', null, null), | STRING |
| HIGH⚡ | datasette/fixtures.py | 247 | ("2019-01-17 08:00:00", 2, 0, 'MC', 4, 'Arcadia Planitia', '[]', '[]', null, null) | STRING |
| HIGH | datasette/fixtures.py | 273 | 3, "Burlingame Museum of PEZ Memorabilia", "214 California Drive, Burlingame, CA 94010", null, | STRING |
| HIGH | datasette/fixtures.py | 322 | INSERT INTO foreign_key_references VALUES (2, null, null, null, null, null); | STRING |
| HIGH | datasette/fixtures.py | 363 | ("insert into binary_data (data) values (null);", []), | STRING |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/conftest.py | 308 | CODE | |
| LOW | tests/test_auth.py | 308 | CODE | |
| LOW | tests/test_docs.py | 182 | CODE | |
| LOW | tests/test_html.py | 997 | CODE | |
| LOW | tests/test_internals_database.py | 1328 | CODE | |
| LOW | tests/test_queries.py | 3317 | CODE | |
| LOW | tests/test_multipart.py | 1128 | CODE | |
| LOW | tests/test_multipart.py | 1188 | CODE | |
| LOW | tests/test_telemetry.py | 196 | CODE | |
| LOW | tests/test_permissions.py | 963 | CODE | |
| LOW | tests/fixtures.py | 108 | CODE | |
| LOW | tests/plugins/my_plugin.py | 552 | CODE | |
| LOW | docs/json_api_doc.py | 8 | CODE | |
| LOW | docs/json_api_doc.py | 85 | CODE | |
| LOW | datasette/plugins.py | 92 | CODE | |
| LOW | datasette/stored_queries.py | 242 | CODE | |
| LOW | datasette/telemetry_testing.py | 208 | CODE | |
| LOW | datasette/telemetry_testing.py | 276 | CODE | |
| LOW | datasette/telemetry_testing.py | 355 | CODE | |
| LOW | datasette/renderer.py | 15 | CODE | |
| LOW | datasette/renderer.py | 33 | CODE | |
| LOW | datasette/database.py | 570 | CODE | |
| LOW | datasette/database.py | 716 | CODE | |
| LOW | datasette/database.py | 840 | CODE | |
| LOW | datasette/database.py | 1212 | CODE | |
| LOW | datasette/database.py | 735 | CODE | |
| LOW | datasette/telemetry.py | 225 | CODE | |
| LOW | datasette/cli.py | 73 | CODE | |
| LOW | datasette/app.py | 410 | CODE | |
| LOW | datasette/app.py | 657 | CODE | |
| LOW | datasette/app.py | 792 | CODE | |
| LOW | datasette/app.py | 1353 | CODE | |
| LOW | datasette/app.py | 1552 | CODE | |
| LOW | datasette/app.py | 3203 | CODE | |
| LOW | datasette/app.py | 3342 | CODE | |
| LOW | datasette/app.py | 3218 | CODE | |
| LOW | datasette/facets.py | 15 | CODE | |
| LOW | datasette/facets.py | 215 | CODE | |
| LOW | datasette/facets.py | 311 | CODE | |
| LOW | datasette/facets.py | 381 | CODE | |
| LOW | datasette/facets.py | 510 | CODE | |
| LOW | datasette/tracer.py | 90 | CODE | |
| LOW | datasette/tracer.py | 101 | CODE | |
| LOW | datasette/filters.py | 47 | CODE | |
| LOW | datasette/filters.py | 49 | CODE | |
| LOW | datasette/filters.py | 453 | CODE | |
| LOW | datasette/default_permissions/config.py | 112 | CODE | |
| LOW | datasette/default_permissions/config.py | 212 | CODE | |
| LOW | datasette/default_permissions/restrictions.py | 142 | CODE | |
| LOW | datasette/utils/multipart.py | 186 | CODE | |
| LOW | datasette/utils/multipart.py | 645 | CODE | |
| LOW | datasette/utils/multipart.py | 368 | CODE | |
| LOW | datasette/utils/multipart.py | 735 | CODE | |
| LOW | datasette/utils/asgi.py | 312 | CODE | |
| LOW | datasette/utils/actions_sql.py | 517 | CODE | |
| LOW | datasette/utils/__init__.py | 1321 | CODE | |
| LOW | datasette/utils/__init__.py | 1660 | CODE | |
| LOW | datasette/utils/__init__.py | 1708 | CODE | |
| LOW | datasette/utils/__init__.py | 1382 | CODE | |
| LOW | datasette/utils/__init__.py | 1669 | CODE | |
| 36 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/conftest.py | 61 | CODE | |
| LOW | tests/conftest.py | 61 | CODE | |
| LOW | tests/conftest.py | 61 | CODE | |
| LOW | tests/conftest.py | 61 | CODE | |
| LOW | tests/conftest.py | 61 | CODE | |
| LOW | tests/conftest.py | 61 | CODE | |
| LOW | tests/conftest.py | 420 | CODE | |
| LOW | tests/conftest.py | 420 | CODE | |
| LOW | tests/conftest.py | 420 | CODE | |
| LOW | tests/conftest.py | 420 | CODE | |
| LOW | tests/conftest.py | 420 | CODE | |
| LOW | tests/conftest.py | 420 | CODE | |
| LOW | tests/conftest.py | 420 | CODE | |
| LOW | tests/conftest.py | 420 | CODE | |
| LOW | tests/conftest.py | 420 | CODE | |
| LOW | tests/conftest.py | 420 | CODE | |
| LOW | tests/conftest.py | 420 | CODE | |
| LOW | tests/conftest.py | 420 | CODE | |
| LOW | tests/conftest.py | 420 | CODE | |
| LOW | tests/conftest.py | 420 | CODE | |
| LOW | tests/conftest.py | 420 | CODE | |
| LOW | tests/conftest.py | 420 | CODE | |
| LOW | tests/conftest.py | 420 | CODE | |
| LOW | tests/test_docs.py | 10 | CODE | |
| LOW | datasette/stored_queries.py | 1 | CODE | |
| LOW | datasette/background_tasks.py | 27 | CODE | |
| LOW | datasette/csrf.py | 10 | CODE | |
| LOW | datasette/_pytest_plugin.py | 15 | CODE | |
| LOW | datasette/jump.py | 1 | CODE | |
| LOW | datasette/__init__.py | 1 | CODE | |
| LOW | datasette/__init__.py | 2 | CODE | |
| LOW | datasette/__init__.py | 2 | CODE | |
| LOW | datasette/__init__.py | 3 | CODE | |
| LOW | datasette/__init__.py | 4 | CODE | |
| LOW | datasette/__init__.py | 4 | CODE | |
| LOW | datasette/__init__.py | 5 | CODE | |
| LOW | datasette/__init__.py | 5 | CODE | |
| LOW | datasette/__init__.py | 5 | CODE | |
| LOW | datasette/__init__.py | 6 | CODE | |
| LOW | datasette/__init__.py | 6 | CODE | |
| LOW | datasette/__init__.py | 6 | CODE | |
| LOW | datasette/__init__.py | 6 | CODE | |
| LOW | datasette/__init__.py | 6 | CODE | |
| LOW | datasette/__init__.py | 13 | CODE | |
| LOW | datasette/__init__.py | 14 | CODE | |
| LOW | datasette/__init__.py | 15 | CODE | |
| LOW | datasette/__init__.py | 16 | CODE | |
| LOW | datasette/tokens.py | 9 | CODE | |
| LOW | datasette/app.py | 1 | CODE | |
| LOW | datasette/write_sql.py | 1 | CODE | |
| LOW | datasette/default_permissions/config.py | 7 | CODE | |
| LOW | datasette/default_permissions/__init__.py | 18 | CODE | |
| LOW | datasette/default_permissions/__init__.py | 20 | CODE | |
| LOW | datasette/default_permissions/__init__.py | 21 | CODE | |
| LOW | datasette/default_permissions/__init__.py | 24 | CODE | |
| LOW | datasette/default_permissions/__init__.py | 27 | CODE | |
| LOW | datasette/default_permissions/__init__.py | 31 | CODE | |
| LOW | datasette/default_permissions/__init__.py | 34 | CODE | |
| LOW | datasette/default_permissions/__init__.py | 39 | CODE | |
| LOW | datasette/default_permissions/__init__.py | 42 | CODE | |
| 11 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | tests/test_write_wrapper.py | 115 | def wrapper(conn): | CODE |
| LOW | tests/test_write_wrapper.py | 118 | except Exception as e: # noqa: BLE001 | CODE |
| LOW | tests/test_api_write.py | 1588 | except Exception: # noqa: BLE001, S110 | STRING |
| LOW | datasette/csrf.py | 164 | except Exception: # noqa: BLE001, S110 | CODE |
| LOW | datasette/_pytest_plugin.py | 92 | except Exception as e: # noqa: BLE001 | CODE |
| MEDIUM | datasette/database.py | 489 | def _dispatch_events_after_write(): | CODE |
| LOW | datasette/database.py | 242 | except Exception: # noqa: BLE001, S110 | CODE |
| LOW | datasette/database.py | 249 | except Exception: # noqa: BLE001, S110 | CODE |
| LOW | datasette/database.py | 261 | except Exception: # noqa: BLE001, S110 | CODE |
| LOW | datasette/database.py | 267 | except Exception: # noqa: BLE001, S110 | CODE |
| LOW | datasette/database.py | 492 | except Exception: # noqa: BLE001 | CODE |
| LOW | datasette/database.py | 580 | except Exception as e: # noqa: BLE001 | CODE |
| LOW | datasette/database.py | 589 | except Exception: # noqa: BLE001, S110 | CODE |
| LOW | datasette/database.py | 637 | except Exception as e: # noqa: BLE001 | CODE |
| LOW | datasette/database.py | 658 | except Exception as e: # noqa: BLE001 | CODE |
| LOW | datasette/database.py | 772 | except Exception as e: | CODE |
| LOW | datasette/database.py | 812 | except Exception as e: | CODE |
| LOW | datasette/database.py | 1115 | except Exception as e: | CODE |
| LOW | datasette/app.py | 990 | except Exception as e: # noqa: BLE001 | CODE |
| LOW | datasette/app.py | 997 | except Exception as e: # noqa: BLE001 | CODE |
| LOW | datasette/app.py | 3151 | except Exception: | CODE |
| LOW | datasette/app.py | 3329 | except Exception as exception: # noqa: BLE001 | CODE |
| LOW | datasette/app.py | 2396 | except Exception: # noqa: BLE001, S110 | STRING |
| LOW | datasette/tracer.py | 54 | except Exception as ex: | CODE |
| LOW | datasette/utils/multipart.py | 82 | except Exception: # noqa: BLE001, S110 | CODE |
| LOW | datasette/utils/multipart.py | 160 | except Exception: # noqa: BLE001, S110 | CODE |
| LOW | datasette/utils/multipart.py | 169 | except Exception: # noqa: BLE001, S110 | CODE |
| LOW | datasette/utils/multipart.py | 235 | except Exception: # noqa: BLE001, S110 | CODE |
| MEDIUM | datasette/utils/multipart.py | 79 | def __del__(self): | CODE |
| LOW | datasette/utils/asgi.py | 320 | except Exception as e: # noqa: BLE001 | CODE |
| LOW | datasette/utils/asgi.py | 330 | except Exception as e: # noqa: BLE001 | CODE |
| LOW | datasette/views/database.py | 672 | except Exception as ex: # noqa: BLE001 | CODE |
| LOW | datasette/views/database.py | 688 | except Exception as ex: # noqa: BLE001 | CODE |
| LOW | datasette/views/table.py | 1159 | except Exception as e: # noqa: BLE001 | CODE |
| MEDIUM | datasette/views/table.py | 1023 | def post(self, request, upsert=False): | CODE |
| MEDIUM | datasette/views/table_create_alter.py | 1068 | def get(self, request): | CODE |
| LOW | datasette/views/table_create_alter.py | 963 | except Exception as e: # noqa: BLE001 | STRING |
| LOW | datasette/views/table_create_alter.py | 1379 | except Exception as e: # noqa: BLE001 | STRING |
| LOW | datasette/views/row.py | 806 | except Exception as e: # noqa: BLE001 | STRING |
| LOW | datasette/views/row.py | 891 | except Exception as e: # noqa: BLE001 | STRING |
| LOW | datasette/views/special.py | 428 | except Exception: # noqa: BLE001 | CODE |
| LOW | datasette/views/base.py | 319 | except Exception as ex: # noqa: BLE001 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | test-in-pyodide-with-shot-scraper.sh | 13 | # Create a blank index page | COMMENT |
| MEDIUM | tests/test_schema_endpoints.py | 30 | # Create a database with restricted access (requires root permission) | COMMENT |
| MEDIUM | tests/test_schema_endpoints.py | 36 | # Create an empty database | COMMENT |
| MEDIUM⚡ | tests/test_plugins.py | 1748 | # Create a token using the hardcoded handler (first registered from plugins dir) | STRING |
| MEDIUM⚡ | tests/test_plugins.py | 1757 | # Create a token by explicitly requesting the hardcoded handler by name | STRING |
| MEDIUM⚡ | tests/test_plugins.py | 1763 | # Create a token by explicitly requesting the signed handler by name | STRING |
| MEDIUM | tests/test_plugins.py | 1860 | # Define a test plugin that registers these actions | STRING |
| MEDIUM | tests/test_multipart.py | 524 | # Create a body larger than the in-memory threshold (1MB) | COMMENT |
| MEDIUM | tests/test_allowed_resources.py | 346 | # Create a database with 105 tables | COMMENT |
| MEDIUM | tests/test_internal_db.py | 204 | # Create a data database file | STRING |
| MEDIUM | docs/conf.py | 5 | # This file is execfile()d with the current directory set to its | COMMENT |
| MEDIUM | datasette/publish/heroku.py | 142 | # Create a new app | COMMENT |
| MEDIUM | demos/plugins/example_js_manager_plugins.py | 7 | # Create a set with view names that qualify for this JS, since plugins won't do anything on other pages | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM⚡ | tests/test_allowed_many.py | 73 | # ---------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/test_allowed_many.py | 75 | # ---------------------------------------------------------------------- | COMMENT |
| MEDIUM | tests/test_allowed_many.py | 206 | # ---------------------------------------------------------------------- | COMMENT |
| MEDIUM | tests/test_allowed_many.py | 208 | # ---------------------------------------------------------------------- | COMMENT |
| MEDIUM | tests/test_allowed_many.py | 583 | # ---------------------------------------------------------------------- | COMMENT |
| MEDIUM | tests/test_allowed_many.py | 585 | # ---------------------------------------------------------------------- | COMMENT |
| MEDIUM | datasette/utils/permissions.py | 87 | # ----------------------------- | COMMENT |
| MEDIUM | datasette/utils/permissions.py | 89 | # ----------------------------- | COMMENT |
| MEDIUM⚡ | datasette/utils/permissions.py | 134 | # ----------------------------------------------- | STRING |
| MEDIUM⚡ | datasette/utils/permissions.py | 136 | # ----------------------------------------------- | STRING |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/test_auth.py | 397 | # Set root_enabled to simulate --root flag | COMMENT |
| LOW | tests/test_docs.py | 197 | # Check if next line is entirely made of a single underline character | COMMENT |
| LOW | tests/test_docs.py | 209 | # Check if this is an overline+underline style heading | COMMENT |
| LOW | tests/plugins/my_plugin.py | 521 | # Check if this is a global action (no resource_class specified) | STRING |
| LOW | .github/workflows/stable-docs.yml | 64 | # Check if the list of files is non-empty | COMMENT |
| LOW | datasette/app.py | 1720 | # Check if actor can see it | COMMENT |
| LOW | datasette/app.py | 1724 | # Check if anonymous user can see it (for "private" flag) | COMMENT |
| LOW | datasette/app.py | 2008 | # Check if truncated (got more than limit rows) | STRING |
| LOW | datasette/permissions.py | 127 | # Check if our parent has a parent - that would create 3 levels | COMMENT |
| LOW | datasette/utils/permissions.py | 29 | # Check if we should skip permission checks BEFORE calling hooks | COMMENT |
| LOW | datasette/views/index.py | 82 | # Check if table is in allowed set | COMMENT |
| LOW | datasette/views/special.py | 321 | # Check if user has permissions-debug (to show sensitive fields) | COMMENT |
| LOW | datasette/views/special.py | 326 | # Check if this is a request for JSON (has .json extension) | COMMENT |
| LOW | datasette/views/special.py | 495 | # Check if this is a request for JSON (has .json extension) | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/fixtures.py | 108 | CODE | |
| LOW | datasette/stored_queries.py | 164 | CODE | |
| LOW | datasette/stored_queries.py | 242 | CODE | |
| LOW | datasette/stored_queries.py | 358 | CODE | |
| LOW | datasette/stored_queries.py | 428 | CODE | |
| LOW | datasette/app.py | 410 | CODE | |
| LOW | datasette/app.py | 1135 | CODE | |
| LOW | datasette/app.py | 1183 | CODE | |
| LOW | datasette/app.py | 1239 | CODE | |
| LOW | datasette/app.py | 1263 | CODE | |
| LOW | datasette/app.py | 1663 | CODE | |
| LOW | datasette/utils/multipart.py | 645 | CODE | |
| LOW | datasette/utils/multipart.py | 297 | CODE | |
| LOW | datasette/utils/asgi.py | 217 | CODE | |
| LOW | datasette/utils/asgi.py | 549 | CODE | |
| LOW | datasette/utils/testing.py | 84 | CODE | |
| LOW | datasette/utils/testing.py | 115 | CODE | |
| LOW | datasette/utils/testing.py | 139 | CODE | |
| LOW | datasette/views/execute_write.py | 223 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | datasette/app.py | 1673 | Create a Resource instance for the given action with parent/child values. Looks up the action's resour | STRING |
| HIGH | datasette/utils/asgi.py | 231 | Parse form data from the request body. Supports both application/x-www-form-urlencoded and multipart/f | STRING |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| CRITICAL | datasette/static/cm-editor-6.0.1.bundle.js | 1 | var cm=function(t){"use strict";class e{constructor(){}lineAt(t){if(t<0||t>this.length)throw new RangeError(`Invalid pos | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | tests/test_internals_database.py | 864 | # via dependency injection. | COMMENT |
| MEDIUM | datasette/database.py | 509 | # switching to keyword dependency injection when the callback | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | docs/conf.py | 1 | # | COMMENT |
| LOW | docs/conf.py | 81 | # | COMMENT |
| LOW | docs/conf.py | 141 | latex_elements = { | COMMENT |
| LOW | datasette/permissions.py | 241 | # This is deliberately undocumented: it's considered an internal | COMMENT |
| LOW | datasette/static/datasette-manager.js | 221 | // Future API ideas | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/test_playwright.py | 796 | dialog.locator(".table-alter-column-name").first.get_attribute("placeholder") | CODE |
| LOW | tests/test_playwright.py | 947 | assert table_name.get_attribute("placeholder") == "table name" | CODE |
| LOW | tests/test_playwright.py | 434 | dialog.locator(".table-create-column-name").nth(0).get_attribute("placeholder") | STRING |
| LOW | datasette/static/sql-formatter-2.3.3.min.js | 4 | !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.am | CODE |
| LOW | datasette/templates/create_token.html | 95 | expireDuration.setAttribute("placeholder", expireType.value.replace("Expires after X ", "")); | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | datasette/app.py | 175 | logger = logging.getLogger(__name__) | CODE |
| LOW | datasette/fixtures.py | 8 | __all__ = [ | CODE |
| LOW | datasette/views/special.py | 24 | logger = logging.getLogger(__name__) | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | datasette/utils/permissions.py | 112 | # No namespacing - just use plugin params as-is | COMMENT |