Skip to content

Commit 11e492b

Browse files
Rename tests to use Codec terminology
File renames: - schema_adapted.py → schema_codecs.py - test_adapted_attributes.py → test_codecs.py - test_type_composition.py → test_codec_chaining.py Content updates: - LOCALS_ADAPTED → LOCALS_CODECS - GraphType → GraphCodec, LayoutToFilepathType → LayoutCodec - Test class names: TestTypeChain* → TestCodecChain* - Test function names: test_adapted_* → test_codec_* - Updated docstrings and comments 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
1 parent 39cd993 commit 11e492b

File tree

3 files changed

+67
-64
lines changed

3 files changed

+67
-64
lines changed

tests/integration/test_type_composition.py renamed to tests/integration/test_codec_chaining.py

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
"""
2-
Tests for type composition (type chain encoding/decoding).
2+
Tests for codec chaining (composition).
33
44
This tests the <blob@> → <hash> → json composition pattern
5-
and similar type chains.
5+
and similar codec chains.
66
"""
77

88
from datajoint.codecs import (
@@ -12,23 +12,23 @@
1212
)
1313

1414

15-
class TestTypeChainResolution:
16-
"""Tests for resolving type chains."""
15+
class TestCodecChainResolution:
16+
"""Tests for resolving codec chains."""
1717

1818
def setup_method(self):
19-
"""Clear test types from registry before each test."""
19+
"""Clear test codecs from registry before each test."""
2020
for name in list(_codec_registry.keys()):
2121
if name.startswith("test_"):
2222
del _codec_registry[name]
2323

2424
def teardown_method(self):
25-
"""Clean up test types after each test."""
25+
"""Clean up test codecs after each test."""
2626
for name in list(_codec_registry.keys()):
2727
if name.startswith("test_"):
2828
del _codec_registry[name]
2929

30-
def test_single_type_chain(self):
31-
"""Test resolving a single-type chain."""
30+
def test_single_codec_chain(self):
31+
"""Test resolving a single-codec chain."""
3232

3333
class TestSingle(Codec):
3434
name = "test_single"
@@ -49,8 +49,8 @@ def decode(self, stored, *, key=None):
4949
assert chain[0].name == "test_single"
5050
assert store is None
5151

52-
def test_two_type_chain(self):
53-
"""Test resolving a two-type chain."""
52+
def test_two_codec_chain(self):
53+
"""Test resolving a two-codec chain."""
5454

5555
class TestInner(Codec):
5656
name = "test_inner"
@@ -83,8 +83,8 @@ def decode(self, stored, *, key=None):
8383
assert chain[0].name == "test_outer"
8484
assert chain[1].name == "test_inner"
8585

86-
def test_three_type_chain(self):
87-
"""Test resolving a three-type chain."""
86+
def test_three_codec_chain(self):
87+
"""Test resolving a three-codec chain."""
8888

8989
class TestBase(Codec):
9090
name = "test_base"
@@ -131,17 +131,17 @@ def decode(self, stored, *, key=None):
131131
assert chain[2].name == "test_base"
132132

133133

134-
class TestTypeChainEncodeDecode:
135-
"""Tests for encode/decode through type chains."""
134+
class TestCodecChainEncodeDecode:
135+
"""Tests for encode/decode through codec chains."""
136136

137137
def setup_method(self):
138-
"""Clear test types from registry before each test."""
138+
"""Clear test codecs from registry before each test."""
139139
for name in list(_codec_registry.keys()):
140140
if name.startswith("test_"):
141141
del _codec_registry[name]
142142

143143
def teardown_method(self):
144-
"""Clean up test types after each test."""
144+
"""Clean up test codecs after each test."""
145145
for name in list(_codec_registry.keys()):
146146
if name.startswith("test_"):
147147
del _codec_registry[name]
@@ -180,8 +180,8 @@ def decode(self, stored, *, key=None):
180180

181181
# Apply encode in order: outer first, then inner
182182
value = b"start"
183-
for attr_type in chain:
184-
value = attr_type.encode(value)
183+
for codec in chain:
184+
value = codec.encode(value)
185185

186186
assert encode_order == ["outer", "inner"]
187187
assert value == b"start_outer_inner"
@@ -220,14 +220,14 @@ def decode(self, stored, *, key=None):
220220

221221
# Apply decode in reverse order: inner first, then outer
222222
value = b"start_outer_inner"
223-
for attr_type in reversed(chain):
224-
value = attr_type.decode(value)
223+
for codec in reversed(chain):
224+
value = codec.decode(value)
225225

226226
assert decode_order == ["inner", "outer"]
227227
assert value == b"start"
228228

229229
def test_roundtrip(self):
230-
"""Test encode/decode roundtrip through a type chain."""
230+
"""Test encode/decode roundtrip through a codec chain."""
231231

232232
class TestInnerRt(Codec):
233233
name = "test_inner_rt"
@@ -264,21 +264,21 @@ def decode(self, stored, *, key=None):
264264

265265
# Encode: outer → inner
266266
encoded = original
267-
for attr_type in chain:
268-
encoded = attr_type.encode(encoded)
267+
for codec in chain:
268+
encoded = codec.encode(encoded)
269269

270270
assert encoded == b"COMPRESSED:test data"
271271

272272
# Decode: inner → outer (reversed)
273273
decoded = encoded
274-
for attr_type in reversed(chain):
275-
decoded = attr_type.decode(decoded)
274+
for codec in reversed(chain):
275+
decoded = codec.decode(decoded)
276276

277277
assert decoded == original
278278

279279

280-
class TestBuiltinTypeComposition:
281-
"""Tests for built-in type composition."""
280+
class TestBuiltinCodecChains:
281+
"""Tests for built-in codec chains."""
282282

283283
def test_blob_internal_resolves_to_bytes(self):
284284
"""Test that <blob> (internal) → bytes."""
@@ -345,17 +345,17 @@ def test_filepath_external_resolves_to_json(self):
345345

346346

347347
class TestStoreNameParsing:
348-
"""Tests for store name parsing in type specs."""
348+
"""Tests for store name parsing in codec specs."""
349349

350-
def test_type_with_store(self):
351-
"""Test parsing type with store name."""
350+
def test_codec_with_store(self):
351+
"""Test parsing codec with store name."""
352352
final_dtype, chain, store = resolve_dtype("<blob@mystore>")
353353

354354
assert final_dtype == "json"
355355
assert store == "mystore"
356356

357-
def test_type_without_store(self):
358-
"""Test parsing type without store name."""
357+
def test_codec_without_store(self):
358+
"""Test parsing codec without store name."""
359359
final_dtype, chain, store = resolve_dtype("<blob>")
360360

361361
assert store is None

tests/integration/test_adapted_attributes.py renamed to tests/integration/test_codecs.py

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"""
2-
Tests for adapted/custom attribute types.
2+
Tests for custom codecs.
33
44
These tests verify the Codec system for custom data types.
55
"""
@@ -11,50 +11,51 @@
1111

1212
import datajoint as dj
1313

14-
from tests import schema_adapted
15-
from tests.schema_adapted import Connectivity, Layout
14+
from tests import schema_codecs
15+
from tests.schema_codecs import Connectivity, Layout
1616

1717

1818
@pytest.fixture
1919
def schema_name(prefix):
20-
return prefix + "_test_custom_datatype"
20+
return prefix + "_test_codecs"
2121

2222

2323
@pytest.fixture
24-
def schema_ad(
24+
def schema_codec(
2525
connection_test,
2626
s3_creds,
2727
tmpdir,
2828
schema_name,
2929
):
30-
dj.config["stores"] = {"repo-s3": dict(s3_creds, protocol="s3", location="adapted/repo", stage=str(tmpdir))}
31-
# Codecs are auto-registered via __init_subclass__ in schema_adapted
32-
context = {**schema_adapted.LOCALS_ADAPTED}
30+
dj.config["stores"] = {"repo-s3": dict(s3_creds, protocol="s3", location="codecs/repo", stage=str(tmpdir))}
31+
# Codecs are auto-registered via __init_subclass__ in schema_codecs
32+
context = {**schema_codecs.LOCALS_CODECS}
3333
schema = dj.schema(schema_name, context=context, connection=connection_test)
34-
schema(schema_adapted.Connectivity)
35-
schema(schema_adapted.Layout)
34+
schema(schema_codecs.Connectivity)
35+
schema(schema_codecs.Layout)
3636
yield schema
3737
schema.drop()
3838

3939

4040
@pytest.fixture
41-
def local_schema(schema_ad, schema_name):
41+
def local_schema(schema_codec, schema_name):
4242
"""Fixture for testing spawned classes"""
43-
local_schema = dj.Schema(schema_name, connection=schema_ad.connection)
43+
local_schema = dj.Schema(schema_name, connection=schema_codec.connection)
4444
local_schema.spawn_missing_classes()
4545
yield local_schema
46-
# Don't drop - schema_ad fixture handles cleanup
46+
# Don't drop - schema_codec fixture handles cleanup
4747

4848

4949
@pytest.fixture
50-
def schema_virtual_module(schema_ad, schema_name):
50+
def schema_virtual_module(schema_codec, schema_name):
5151
"""Fixture for testing virtual modules"""
52-
# Types are registered globally, no need to add_objects for codecs
53-
schema_virtual_module = dj.VirtualModule("virtual_module", schema_name, connection=schema_ad.connection)
52+
# Codecs are registered globally, no need to add_objects
53+
schema_virtual_module = dj.VirtualModule("virtual_module", schema_name, connection=schema_codec.connection)
5454
return schema_virtual_module
5555

5656

57-
def test_adapted_type(schema_ad):
57+
def test_codec_graph(schema_codec):
58+
"""Test basic codec encode/decode with graph type."""
5859
c = Connectivity()
5960
graphs = [
6061
nx.lollipop_graph(4, 2),
@@ -71,8 +72,8 @@ def test_adapted_type(schema_ad):
7172
c.delete()
7273

7374

74-
def test_adapted_filepath_type(schema_ad, minio_client):
75-
"""https://github.com/datajoint/datajoint-python/issues/684"""
75+
def test_codec_chained(schema_codec, minio_client):
76+
"""Test codec chaining (layout -> blob)."""
7677
c = Connectivity()
7778
c.delete()
7879
c.insert1((0, nx.lollipop_graph(4, 2)))
@@ -88,7 +89,8 @@ def test_adapted_filepath_type(schema_ad, minio_client):
8889
c.delete()
8990

9091

91-
def test_adapted_spawned(local_schema):
92+
def test_codec_spawned(local_schema):
93+
"""Test codecs work with spawned classes."""
9294
c = Connectivity() # a spawned class
9395
graphs = [
9496
nx.lollipop_graph(4, 2),
@@ -105,7 +107,8 @@ def test_adapted_spawned(local_schema):
105107
c.delete()
106108

107109

108-
def test_adapted_virtual(schema_virtual_module):
110+
def test_codec_virtual_module(schema_virtual_module):
111+
"""Test codecs work with virtual modules."""
109112
c = schema_virtual_module.Connectivity()
110113
graphs = [
111114
nx.lollipop_graph(4, 2),
Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@
55
import datajoint as dj
66

77

8-
class GraphType(dj.Codec):
8+
class GraphCodec(dj.Codec):
99
"""Custom codec for storing NetworkX graphs as edge lists."""
1010

1111
name = "graph"
1212

1313
def get_dtype(self, is_external: bool) -> str:
14-
"""Chain to djblob for serialization."""
14+
"""Chain to blob for serialization."""
1515
return "<blob>"
1616

1717
def encode(self, obj, *, key=None, store_name=None):
@@ -24,22 +24,22 @@ def decode(self, stored, *, key=None):
2424
return nx.Graph(stored)
2525

2626

27-
class LayoutToFilepathType(dj.Codec):
28-
"""Custom codec that saves a graph layout as serialized JSON blob."""
27+
class LayoutCodec(dj.Codec):
28+
"""Custom codec that saves a graph layout as serialized blob."""
2929

30-
name = "layout_to_filepath"
30+
name = "layout"
3131

3232
def get_dtype(self, is_external: bool) -> str:
33-
"""Chain to djblob for serialization."""
33+
"""Chain to blob for serialization."""
3434
return "<blob>"
3535

3636
def encode(self, layout, *, key=None, store_name=None):
3737
"""Serialize layout dict."""
38-
return layout # djblob handles serialization
38+
return layout # blob handles serialization
3939

4040
def decode(self, stored, *, key=None):
4141
"""Deserialize layout dict."""
42-
return stored # djblob handles deserialization
42+
return stored # blob handles deserialization
4343

4444

4545
class Connectivity(dj.Manual):
@@ -55,9 +55,9 @@ class Layout(dj.Manual):
5555
# stores graph layout
5656
-> Connectivity
5757
---
58-
layout: <layout_to_filepath>
58+
layout: <layout>
5959
"""
6060

6161

62-
LOCALS_ADAPTED = {k: v for k, v in locals().items() if inspect.isclass(v)}
63-
__all__ = list(LOCALS_ADAPTED)
62+
LOCALS_CODECS = {k: v for k, v in locals().items() if inspect.isclass(v)}
63+
__all__ = list(LOCALS_CODECS)

0 commit comments

Comments
 (0)