mirror of
https://github.com/simonw/datasette.git
synced 2026-05-27 12:34:37 +02:00
Move name and description to class attributes on ColumnType
Instead of passing name= and description= as constructor arguments, define them as class attributes on each subclass. This better reflects that they are intrinsic to the type, not configurable per-instance. https://claude.ai/code/session_01SvPEPqHgURTWESRp28pTC3
This commit is contained in:
parent
72c8c71518
commit
8af98c24c2
4 changed files with 40 additions and 27 deletions
|
|
@ -1,19 +1,17 @@
|
|||
from dataclasses import dataclass
|
||||
|
||||
|
||||
@dataclass(frozen=True, kw_only=True)
|
||||
class ColumnType:
|
||||
name: str
|
||||
"""
|
||||
Unique identifier string. Lowercase, no spaces.
|
||||
Examples: "markdown", "file", "email", "url", "point", "image".
|
||||
Base class for column types.
|
||||
|
||||
Subclasses must define ``name`` and ``description`` as class attributes:
|
||||
|
||||
- ``name``: Unique identifier string. Lowercase, no spaces.
|
||||
Examples: "markdown", "file", "email", "url", "point", "image".
|
||||
- ``description``: Human-readable label for admin UI dropdowns.
|
||||
Examples: "Markdown text", "File reference", "Email address".
|
||||
"""
|
||||
|
||||
name: str
|
||||
description: str
|
||||
"""
|
||||
Human-readable label for admin UI dropdowns.
|
||||
Examples: "Markdown text", "File reference", "Email address".
|
||||
"""
|
||||
|
||||
async def render_cell(
|
||||
self, value, column, table, database, datasette, request, config
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ from datasette.column_types import ColumnType
|
|||
|
||||
|
||||
class UrlColumnType(ColumnType):
|
||||
name = "url"
|
||||
description = "URL"
|
||||
|
||||
async def render_cell(
|
||||
self, value, column, table, database, datasette, request, config
|
||||
|
|
@ -28,6 +30,8 @@ class UrlColumnType(ColumnType):
|
|||
|
||||
|
||||
class EmailColumnType(ColumnType):
|
||||
name = "email"
|
||||
description = "Email address"
|
||||
|
||||
async def render_cell(
|
||||
self, value, column, table, database, datasette, request, config
|
||||
|
|
@ -48,6 +52,8 @@ class EmailColumnType(ColumnType):
|
|||
|
||||
|
||||
class JsonColumnType(ColumnType):
|
||||
name = "json"
|
||||
description = "JSON data"
|
||||
|
||||
async def render_cell(
|
||||
self, value, column, table, database, datasette, request, config
|
||||
|
|
@ -76,7 +82,7 @@ class JsonColumnType(ColumnType):
|
|||
@hookimpl
|
||||
def register_column_types(datasette):
|
||||
return [
|
||||
UrlColumnType(name="url", description="URL"),
|
||||
EmailColumnType(name="email", description="Email address"),
|
||||
JsonColumnType(name="json", description="JSON data"),
|
||||
UrlColumnType(),
|
||||
EmailColumnType(),
|
||||
JsonColumnType(),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1012,6 +1012,9 @@ Return a list of :ref:`ColumnType <column_types>` instances to register custom c
|
|||
|
||||
|
||||
class ColorColumnType(ColumnType):
|
||||
name = "color"
|
||||
description = "CSS color value"
|
||||
|
||||
async def render_cell(
|
||||
self,
|
||||
value,
|
||||
|
|
@ -1045,14 +1048,9 @@ Return a list of :ref:`ColumnType <column_types>` instances to register custom c
|
|||
|
||||
@hookimpl
|
||||
def register_column_types(datasette):
|
||||
return [
|
||||
ColorColumnType(
|
||||
name="color",
|
||||
description="CSS color value",
|
||||
)
|
||||
]
|
||||
return [ColorColumnType()]
|
||||
|
||||
Each ``ColumnType`` instance has the following attributes:
|
||||
Each ``ColumnType`` subclass must define the following class attributes:
|
||||
|
||||
``name`` - string
|
||||
Unique identifier for the column type, e.g. ``"color"``. Must be unique across all plugins.
|
||||
|
|
|
|||
|
|
@ -352,7 +352,11 @@ async def test_validation_allows_empty_string(ds_ct):
|
|||
|
||||
@pytest.mark.asyncio
|
||||
async def test_column_type_base_defaults():
|
||||
ct = ColumnType(name="test", description="Test type")
|
||||
class TestType(ColumnType):
|
||||
name = "test"
|
||||
description = "Test type"
|
||||
|
||||
ct = TestType()
|
||||
assert await ct.render_cell("val", "col", "tbl", "db", None, None, None) is None
|
||||
assert await ct.validate("val", None, None) is None
|
||||
assert await ct.transform_value("val", None, None) == "val"
|
||||
|
|
@ -378,6 +382,9 @@ async def test_render_cell_extra_with_column_types(ds_ct):
|
|||
@pytest.mark.asyncio
|
||||
async def test_duplicate_column_type_name_raises_error():
|
||||
class DuplicateUrlType(ColumnType):
|
||||
name = "url"
|
||||
description = "Duplicate URL"
|
||||
|
||||
async def render_cell(
|
||||
self, value, column, table, database, datasette, request, config
|
||||
):
|
||||
|
|
@ -386,7 +393,7 @@ async def test_duplicate_column_type_name_raises_error():
|
|||
class _Plugin:
|
||||
@hookimpl
|
||||
def register_column_types(self, datasette):
|
||||
return [DuplicateUrlType(name="url", description="Duplicate URL")]
|
||||
return [DuplicateUrlType()]
|
||||
|
||||
plugin = _Plugin()
|
||||
pm.register(plugin, name="test_duplicate_ct")
|
||||
|
|
@ -420,6 +427,9 @@ async def test_transform_value_in_json_output(tmp_path_factory):
|
|||
"""A column type with transform_value should modify rows in JSON API."""
|
||||
|
||||
class UpperColumnType(ColumnType):
|
||||
name = "upper"
|
||||
description = "Uppercase"
|
||||
|
||||
async def transform_value(self, value, config, datasette):
|
||||
if isinstance(value, str):
|
||||
return value.upper()
|
||||
|
|
@ -428,7 +438,7 @@ async def test_transform_value_in_json_output(tmp_path_factory):
|
|||
class _Plugin:
|
||||
@hookimpl
|
||||
def register_column_types(self, datasette):
|
||||
return [UpperColumnType(name="upper", description="Uppercase")]
|
||||
return [UpperColumnType()]
|
||||
|
||||
plugin = _Plugin()
|
||||
pm.register(plugin, name="test_transform_ct")
|
||||
|
|
@ -469,6 +479,9 @@ async def test_column_type_render_cell_has_priority_over_plugins(tmp_path_factor
|
|||
"""Column type render_cell should take priority over render_cell plugin hook."""
|
||||
|
||||
class PriorityColumnType(ColumnType):
|
||||
name = "priority_test"
|
||||
description = "Priority test"
|
||||
|
||||
async def render_cell(
|
||||
self, value, column, table, database, datasette, request, config
|
||||
):
|
||||
|
|
@ -481,9 +494,7 @@ async def test_column_type_render_cell_has_priority_over_plugins(tmp_path_factor
|
|||
class _ColumnTypePlugin:
|
||||
@hookimpl
|
||||
def register_column_types(self, datasette):
|
||||
return [
|
||||
PriorityColumnType(name="priority_test", description="Priority test")
|
||||
]
|
||||
return [PriorityColumnType()]
|
||||
|
||||
class _RenderCellPlugin:
|
||||
@hookimpl
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue