Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
Empty file modified .github/files/virtualenv-20.29.1.pyz
100644 → 100755
Empty file.
Empty file modified .github/files/virtualenv-20.30.0.pyz
100644 → 100755
Empty file.
Empty file modified .github/workflows/build-and-deploy.yml
100644 → 100755
Empty file.
Empty file modified .github/workflows/build-and-test-with-asan.yml
100644 → 100755
Empty file.
Empty file modified .github/workflows/build-and-test.yml
100644 → 100755
Empty file.
Empty file modified .github/workflows/build-linux-wheel.yml
100644 → 100755
Empty file.
Empty file modified .github/workflows/build-mac-wheel.yml
100644 → 100755
Empty file.
Empty file modified .github/workflows/build-windows-wheel.yml
100644 → 100755
Empty file.
Empty file modified .github/workflows/test-data-validation.yml
100644 → 100755
Empty file.
Empty file modified .github/workflows/test-linux-wheel.yml
100644 → 100755
Empty file.
Empty file modified .github/workflows/test-mac-wheel.yml
100644 → 100755
Empty file.
Empty file modified .github/workflows/test-windows-wheel.yml
100644 → 100755
Empty file.
Empty file modified .gitignore
100644 → 100755
Empty file.
Empty file modified AGENTS.md
100644 → 100755
Empty file.
Empty file modified CLA.md
100644 → 100755
Empty file.
Empty file modified CONTRIBUTING.md
100644 → 100755
Empty file.
Empty file modified LICENSE
100644 → 100755
Empty file.
Empty file modified NOTICE
100644 → 100755
Empty file.
Empty file modified README.md
100644 → 100755
Empty file.
Empty file modified THIRD_PARTY_LICENSES/BOOST_LICENSE_1_0
100644 → 100755
Empty file.
Empty file modified THIRD_PARTY_LICENSES/GOOGLETEST_LICENSE
100644 → 100755
Empty file.
Empty file modified dbzero/LICENSE
100644 → 100755
Empty file.
Empty file modified dbzero/README.md
100644 → 100755
Empty file.
Empty file modified dbzero/dbzero/__init__.py
100644 → 100755
Empty file.
Empty file modified dbzero/dbzero/atomic.py
100644 → 100755
Empty file.
Empty file modified dbzero/dbzero/compare.py
100644 → 100755
Empty file.
Empty file modified dbzero/dbzero/dbzero.py
100644 → 100755
Empty file.
5 changes: 5 additions & 0 deletions dbzero/dbzero/dbzero.pyi
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ def open(prefix_name: str, open_mode: str = "rw", **kwargs: Any) -> None:
* autocommit (bool) to disable automatic commits for this prefix
* restricted (bool) to restrict memo reflection access for this prefix
* restricted_context (ContextVar) to dynamically restrict memo reflection access for this prefix
* no_auto_migrate (bool) to disable automatic tag-field schema migration
* slab_size (int) for memory slab allocation size in bytes
* meta_io_step_size (int) for metadata I/O operation chunk size
* lock_flags (dict) to change locking behavior when opening the prefix for read-write
Expand All @@ -56,6 +57,10 @@ def open(prefix_name: str, open_mode: str = "rw", **kwargs: Any) -> None:
"""
...

def migrate(memo_type: type) -> None:
"""Apply pending schema migration for a memo type."""
...

def set_restricted(*, restricted: Optional[bool] = None, restricted_context: Any = None,
prefix: Optional[str] = None) -> None:
"""Increase memo restricted-access mode globally or for an open prefix.
Expand Down
Empty file modified dbzero/dbzero/dbzero.template
100644 → 100755
Empty file.
Empty file modified dbzero/dbzero/decorators.py
100644 → 100755
Empty file.
Empty file modified dbzero/dbzero/enum.py
100644 → 100755
Empty file.
Empty file modified dbzero/dbzero/fast_query.py
100644 → 100755
Empty file.
5 changes: 4 additions & 1 deletion dbzero/dbzero/initialization.py
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,10 @@ def init(dbzero_root: str, **kwargs: Any) -> None:

init_kwargs = {}

config_keys = ("autocommit", "autocommit_interval", "cache_size", "lang_cache_size")
if "no_auto_migration" in kwargs and "no_auto_migrate" not in kwargs:
kwargs["no_auto_migrate"] = kwargs["no_auto_migration"]

config_keys = ("autocommit", "autocommit_interval", "cache_size", "lang_cache_size", "no_auto_migrate")
config = {}
for key in config_keys:
if key in kwargs:
Expand Down
Empty file modified dbzero/dbzero/interfaces.py
100644 → 100755
Empty file.
Empty file modified dbzero/dbzero/locked.py
100644 → 100755
Empty file.
43 changes: 42 additions & 1 deletion dbzero/dbzero/memo.py
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,44 @@
from .dbzero import _wrap_memo_type, set_prefix


__DBZERO_TAG_FIELDS_ATTR = "__DBZERO_TAG_FIELDS_ATTR"


def _normalize_tag_fields(field_names):
tag_fields = []
seen = set()
for field_name in field_names:
if not isinstance(field_name, str):
raise TypeError("tag_fields arguments must be strings")
if field_name not in seen:
seen.add(field_name)
tag_fields.append(field_name)
return tuple(tag_fields)


def _merge_tag_field_declarations(*declarations):
tag_fields = []
seen = set()
for declaration in declarations:
for field_name in declaration:
if field_name not in seen:
seen.add(field_name)
tag_fields.append(field_name)
return tuple(tag_fields)


def tag_fields(*field_names):
new_fields = _normalize_tag_fields(field_names)

def wrap(cls):
existing_fields = getattr(cls, __DBZERO_TAG_FIELDS_ATTR, ())
merged_fields = _merge_tag_field_declarations(existing_fields, new_fields)
setattr(cls, __DBZERO_TAG_FIELDS_ATTR, merged_fields)
return cls

return wrap


def migration(func: Callable) -> Callable:
"""Decorator for marking a function as a migration function"""
func._db0_migration = None
Expand Down Expand Up @@ -271,9 +309,12 @@ def wrap(cls_):
dyn_prefix = None
init_vars = []

tag_field_names = list(getattr(cls_, __DBZERO_TAG_FIELDS_ATTR, ()))

wrapped = _wrap_memo_type(cls_, py_file = getfile(cls_), py_init_vars = init_vars, py_dyn_prefix = dyn_prefix, \
py_migrations = list(find_migrations(cls_)) if is_singleton else None, **kwargs
py_migrations = list(find_migrations(cls_)) if is_singleton else None, py_tag_fields = tag_field_names, **kwargs
)
setattr(wrapped, __DBZERO_TAG_FIELDS_ATTR, tuple(tag_field_names))

# Call __init_subclass__ on the wrapped class for any base that defines it.
# Python normally calls __init_subclass__ before the decorator runs, so the
Expand Down
Empty file modified dbzero/dbzero/reflection_api.py
100644 → 100755
Empty file.
Empty file modified dbzero/dbzero/select.py
100644 → 100755
Empty file.
Empty file modified dbzero/dbzero/storage_api.py
100644 → 100755
Empty file.
Empty file modified dbzero/dbzero/utilities.py
100644 → 100755
Empty file.
Empty file modified dbzero/setup.py
100644 → 100755
Empty file.
Empty file modified design/OVERLAID_TYPES_NOTES.md
100644 → 100755
Empty file.
Empty file modified docker/Dockerfile
100644 → 100755
Empty file.
Empty file modified docker/Dockerfile-dev
100644 → 100755
Empty file.
Empty file modified docker/Dockerfile-dev-12
100644 → 100755
Empty file.
Empty file modified docker/Dockerfile-dev-13
100644 → 100755
Empty file.
Empty file modified docker/Dockerfile-dev-14
100644 → 100755
Empty file.
Empty file modified docker/Dockerfile-dev-15
100644 → 100755
Empty file.
Empty file modified docker/Dockerfile-package
100644 → 100755
Empty file.
Empty file modified docker/Dockerfile-python-308
100644 → 100755
Empty file.
Empty file modified docker/Dockerfile-python-309
100644 → 100755
Empty file.
Empty file modified docker/Dockerfile-python-310
100644 → 100755
Empty file.
Empty file modified docker/Dockerfile-python-311-debug
100644 → 100755
Empty file.
Empty file modified docker/Dockerfile-python-312
100644 → 100755
Empty file.
Empty file modified docker/Dockerfile-python-313
100644 → 100755
Empty file.
Empty file modified docker/claude-settings.json
100644 → 100755
Empty file.
Empty file modified docker/claude-shell-init.sh
100644 → 100755
Empty file.
Empty file modified meson.build
100644 → 100755
Empty file.
Empty file modified meson_options.txt
100644 → 100755
Empty file.
Empty file modified notebooks/CRDT_Allocator/db0-allocator-1-poc.ipynb
100644 → 100755
Empty file.
Empty file modified notebooks/CRDT_Allocator/db0-allocator-2-poc.ipynb
100644 → 100755
Empty file.
Empty file modified notebooks/hello/hello-db0-1_pl.ipynb
100644 → 100755
Empty file.
Empty file modified notebooks/hello/hello-db0-2_pl.ipynb
100644 → 100755
Empty file.
Empty file modified notebooks/hello/hello-db0-3_pl.ipynb
100644 → 100755
Empty file.
Empty file modified notebooks/hello/hello.db0_1.ipynb
100644 → 100755
Empty file.
Empty file modified notebooks/hello/hello.db0_2.ipynb
100644 → 100755
Empty file.
Empty file modified notebooks/hello/hello.db0_3.ipynb
100644 → 100755
Empty file.
Empty file modified notebooks/hello/hello.db0_4.ipynb
100644 → 100755
Empty file.
Empty file modified notebooks/hello/hello.db0_5.ipynb
100644 → 100755
Empty file.
Empty file modified notebooks/hello/mem_charts.py
100644 → 100755
Empty file.
Empty file modified notebooks/hello/ram-utilization-chart.ipynb
100644 → 100755
Empty file.
Empty file.
Empty file.
Empty file.
Empty file modified notebooks/issues/.ipynb_checkpoints/test-parse-checkpoint.ipynb
100644 → 100755
Empty file.
Empty file modified notebooks/issues/db0-test-data/my-test-prefix2.db0
100644 → 100755
Empty file.
Empty file modified notebooks/issues/import_tests.ipynb
100644 → 100755
Empty file.
Empty file modified notebooks/issues/issues/add_tag_in_init.ipynb
100644 → 100755
Empty file.
Empty file modified notebooks/issues/issues/attribute_error.ipynb
100644 → 100755
Empty file.
Empty file modified notebooks/issues/issues/import_tests.ipynb
100644 → 100755
Empty file.
Empty file modified notebooks/issues/issues/test-parse.ipynb
100644 → 100755
Empty file.
Empty file modified notebooks/issues/test-parse.ipynb
100644 → 100755
Empty file.
Empty file modified pyproject.toml
100644 → 100755
Empty file.
Empty file modified pytest.ini
100644 → 100755
Empty file.
Empty file modified python_tests/__init__.py
100644 → 100755
Empty file.
Empty file modified python_tests/conftest.py
100644 → 100755
Empty file.
Empty file modified python_tests/data_for_tests.py
100644 → 100755
Empty file.
Empty file modified python_tests/memo_test_types.py
100644 → 100755
Empty file.
Empty file modified python_tests/migration2_init.py
100644 → 100755
Empty file.
Empty file modified python_tests/migration2_test.py
100644 → 100755
Empty file.
Empty file modified python_tests/migration_init.py
100644 → 100755
Empty file.
Empty file modified python_tests/migration_test_1.py
100644 → 100755
Empty file.
Empty file modified python_tests/migration_test_2.py
100644 → 100755
Empty file.
Empty file modified python_tests/scripts/create_test_data.py
100644 → 100755
Empty file.
Empty file modified python_tests/scripts/validate_test_data.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_allocator.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_assign.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_atomic.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_atomic_lifecycle.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_auto_weak_proxy.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_autocommit.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_bool.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_bytearray.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_bytes.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_cache.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_callable.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_commit.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_compare.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_composite_tags.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_copy_prefix.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_crash_recovery.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_datetime.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_decimal.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_decorators.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_dict.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_diff_storage.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_durability.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_dyn_scope.py
100644 → 100755
Empty file.
20 changes: 20 additions & 0 deletions python_tests/test_enum.py
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,26 @@ def test_enum_tags_are_distinguished_from_string_values(db0_fixture):
assert set([x.value for x in db0.find(Colors.RED)]) == set([1])


def test_enum_tags_are_not_treated_as_passive_tags(db0_fixture):
Colors = db0.enum("Colors", ["RED", "GREEN", "BLUE"])
db0.tags(MemoTestClass(1)).add(Colors.RED)
db0.tags(MemoTestClass(2), passive=True).add("passive-tag")

assert set([x.value for x in db0.find(Colors.RED)]) == {1}
with pytest.raises(Exception):
list(db0.find("passive-tag"))


def test_enum_tag_can_anchor_passive_tag_query(db0_fixture):
Colors = db0.enum("Colors", ["RED", "GREEN", "BLUE"])
obj = MemoTestClass(1)
db0.tags(obj).add(Colors.RED)
db0.tags(obj, passive=True).add("passive-tag")
db0.tags(MemoTestClass(2), passive=True).add("passive-tag")

assert set([x.value for x in db0.find(Colors.RED, "passive-tag")]) == {1}


def test_enum_type_defines_values_method(db0_fixture):
Colors = db0.enum("Colors", ["RED", "GREEN", "BLUE"])
assert len(Colors.values()) == 3
Expand Down
Empty file modified python_tests/test_enum_class.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_enum_comparison.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_exists.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_fast_query.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_fetch.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_field_layout.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_filter.py
100644 → 100755
Empty file.
48 changes: 30 additions & 18 deletions python_tests/test_find.py
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -237,31 +237,43 @@ def test_remove_tags_then_find_typed(db0_fixture):
assert len(list(db0.find(MemoTestClass, "one"))) == 0


def test_query_result_cannot_be_used_as_tag_target(db0_fixture):
objects = [MemoTestClass(i) for i in range(4)]
db0.tags(objects[0]).add("source")
db0.tags(objects[1]).add("source")
def test_add_tags_to_query_result(db0_fixture):
objects = [MemoTestClass(i) for i in range(6)]
db0.tags(objects[0]).add(["token-a", "token-b"])
db0.tags(objects[1]).add("token-a")
db0.tags(objects[2]).add(["token-a", "token-b"])
db0.tags(objects[3]).add("token-b")

with pytest.raises(RuntimeError, match="memo objects"):
db0.tags(db0.find("source"))
db0.tags(db0.find("token-a", "token-b")).add("token-c")

with pytest.raises(RuntimeError, match="memo objects"):
db0.tags(objects[2], db0.find("source"))
assert {item.value for item in db0.find("token-c")} == {0, 2}

db0.tags(objects[2]).add("batch")
assert {item.value for item in db0.find("batch")} == {2}

def test_remove_tags_from_query_result(db0_fixture):
objects = [MemoTestClass(i) for i in range(5)]
db0.tags(objects[0]).add(["token-a", "keep"])
db0.tags(objects[1]).add("token-a")
db0.tags(objects[2]).add(["token-a", "other"])
db0.tags(objects[3]).add("other")

def test_snapshot_query_cannot_be_used_as_tag_target(db0_fixture):
obj = MemoTestClass(1)
db0.tags(obj).add("source")
db0.commit()
db0.tags(db0.find("token-a")).remove("token-a")

with db0.snapshot() as snap:
with pytest.raises(RuntimeError, match="memo objects"):
db0.tags(snap.find("source"))
assert list(db0.find("token-a")) == []
assert {item.value for item in db0.find("keep")} == {0}
assert {item.value for item in db0.find("other")} == {2, 3}


def test_query_tag_target_can_be_empty_or_mixed_with_memo_target(db0_fixture):
objects = [MemoTestClass(i) for i in range(4)]
db0.tags(objects[0]).add("source")
db0.tags(objects[1]).add("source")

db0.tags(db0.find("missing")).add("batch")
assert list(db0.find("batch")) == []

assert list(db0.find("source")) == [obj]
db0.tags(objects[2], db0.find("source")).add(["batch", "extra"])
assert {item.value for item in db0.find("batch")} == {0, 1, 2}
assert {item.value for item in db0.find("extra")} == {0, 1, 2}


def test_query_by_non_existing_tag(db0_fixture):
Expand Down
Empty file modified python_tests/test_foreign_tags.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_index.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_inheritance.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_init.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_issues_1.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_issues_10.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_issues_11.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_issues_12.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_issues_13.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_issues_14.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_issues_15.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_issues_16.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_issues_18.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_issues_2.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_issues_3.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_issues_4.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_issues_5.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_issues_6.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_issues_7.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_issues_8.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_issues_9.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_join.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_list.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_load.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_locked.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_memo.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_memo_dataclass.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_memo_dir_vars.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_memo_init.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_memo_lofi.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_memo_np_members.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_memo_singleton.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_meta_io.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_migration.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_multi_index.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_multi_prefix.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_multiple_inheritance.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_multiprocess.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_object.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_object_lifecycle.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_object_stress.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_page_io.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_prefix_api.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_query_compare.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_query_serialization.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_query_signature.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_reflection_api.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_refresh.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_refresh_stress_tests.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_restricted_memo_access.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_restricted_statek_repros.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_schema.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_scoped_enums.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_scoped_types.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_select.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_set.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_slice.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_snapshot.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_split_by.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_storage.py
100644 → 100755
Empty file.
Empty file modified python_tests/test_storage_stats.py
100644 → 100755
Empty file.
Loading
Loading