Skip to content

Commit

Permalink
Merge branch 'dev' into staging_expand
Browse files Browse the repository at this point in the history
  • Loading branch information
mavaylon1 authored Feb 20, 2025
2 parents 0489257 + bcde246 commit 9b76a1e
Show file tree
Hide file tree
Showing 6 changed files with 410 additions and 2 deletions.
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ repos:
# hooks:
# - id: black
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.9.2
rev: v0.9.6
hooks:
- id: ruff
# - repo: https://github.com/econchick/interrogate
# rev: 1.5.0
# hooks:
# - id: interrogate
- repo: https://github.com/codespell-project/codespell
rev: v2.3.0
rev: v2.4.1
hooks:
- id: codespell
additional_dependencies:
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# HDMF Changelog

## [Unreleased]

### Changed
- `hdmf.monitor` is unused and undocumented. It has been deprecated and will be removed in HDMF 5.0. @rly [#1245](https://github.com/hdmf-dev/hdmf/pull/1245)

## HDMF 4.0.0 (January 22, 2025)

Expand Down
8 changes: 8 additions & 0 deletions src/hdmf/monitor.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
from abc import ABCMeta, abstractmethod
import warnings

from .data_utils import AbstractDataChunkIterator, DataChunkIterator, DataChunk
from .utils import docval, getargs

warnings.warn(
"The hdmf.monitor module is deprecated and will be removed in HDMF 5.0. If you are using this module, "
"please copy this module to your codebase or raise an issue in the HDMF repository: "
"https://github.com/hdmf-dev/hdmf/issues",
DeprecationWarning,
)


class NotYetExhausted(Exception):
pass
Expand Down
163 changes: 163 additions & 0 deletions tests/unit/spec_tests/test_group_spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,91 @@ def test_is_inherited_attribute(self):
with self.assertRaisesWith(ValueError, "Attribute 'attribute4' not found"):
self.inc_group_spec.is_inherited_attribute('attribute4')

def test_is_overridden_spec_nested(self):
"""Test that is_overridden_spec correctly identifies overridden specs in nested structures."""
# Create base spec with a dataset containing an attribute
base_dataset = DatasetSpec('Base dataset',
'int',
name='test_dataset',
attributes=[AttributeSpec('attr1', 'Base attr', 'text')])
base_group = GroupSpec('Base group',
name='test_group',
attributes=[AttributeSpec('attr1', 'Base attr', 'text')])
base_spec = GroupSpec('A base group',
data_type_def='BaseType',
datasets=[base_dataset],
groups=[base_group])

# Create extending spec that overrides both dataset and group with new attribute values
override_dataset = DatasetSpec('Override dataset',
'int',
name='test_dataset',
attributes=[AttributeSpec('attr1', 'Override attr', 'text')])
override_group = GroupSpec('Override group',
name='test_group',
attributes=[AttributeSpec('attr1', 'Override attr', 'text')])
ext_spec = GroupSpec('An extending group',
data_type_inc='BaseType',
data_type_def='ExtType',
datasets=[override_dataset],
groups=[override_group])

# Resolve the extension
ext_spec.resolve_spec(base_spec)

# Test attribute in overridden dataset is marked as overridden
dataset_attr = ext_spec.get_dataset('test_dataset').get_attribute('attr1')
self.assertTrue(ext_spec.is_overridden_spec(dataset_attr))

# Test attribute in overridden group is marked as overridden
group_attr = ext_spec.get_group('test_group').get_attribute('attr1')
self.assertTrue(ext_spec.is_overridden_spec(group_attr))

# Test attributes in base spec are not marked as overridden
base_dataset_attr = base_spec.get_dataset('test_dataset').get_attribute('attr1')
base_group_attr = base_spec.get_group('test_group').get_attribute('attr1')
self.assertFalse(base_spec.is_overridden_spec(base_dataset_attr))
self.assertFalse(base_spec.is_overridden_spec(base_group_attr))

def test_is_overridden_group(self):
"""Test that is_overridden_group correctly identifies overridden groups."""
# Create base spec with a group
base_group = GroupSpec('Base group',
name='test_group',
attributes=[])
base_spec = GroupSpec('A base group',
data_type_def='BaseType',
groups=[base_group])

# Create extending spec that overrides the group
override_group = GroupSpec('Override group',
name='test_group',
attributes=[])
ext_spec = GroupSpec('An extending group',
data_type_inc='BaseType',
data_type_def='ExtType',
groups=[override_group])

# Resolve the extension
ext_spec.resolve_spec(base_spec)

# Test base spec has no overridden groups
self.assertFalse(base_spec.is_overridden_group('test_group'))

# Test extending spec correctly identifies overridden group
self.assertTrue(ext_spec.is_overridden_group('test_group'))

# Test non-existent group raises error
with self.assertRaisesWith(ValueError, "Group 'nonexistent_group' not found in spec"):
ext_spec.is_overridden_group('nonexistent_group')

# Test new group in extending spec is not overridden
new_group = GroupSpec('New group',
name='new_group',
attributes=[])
ext_spec.set_group(new_group)
self.assertFalse(ext_spec.is_overridden_group('new_group'))

def test_is_overridden_attribute(self):
self.assertFalse(self.def_group_spec.is_overridden_attribute('attribute1'))
self.assertFalse(self.def_group_spec.is_overridden_attribute('attribute2'))
Expand All @@ -410,6 +495,84 @@ def test_is_overridden_attribute(self):
with self.assertRaisesWith(ValueError, "Attribute 'attribute4' not found"):
self.inc_group_spec.is_overridden_attribute('attribute4')

def test_resolve_group_inheritance(self):
"""Test resolution of inherited groups in GroupSpec.resolve_spec."""
# Create base group with named and unnamed groups
unnamed_group = GroupSpec('An unnamed group',
data_type_def='UnnamedType',
attributes=[])
named_group = GroupSpec('A named group',
name='named_group',
attributes=[])
base_groups = [unnamed_group, named_group]

base_spec = GroupSpec('A test group',
data_type_def='BaseType',
groups=base_groups)

# Create extending group that overrides the named group and adds a new one
override_group = GroupSpec('Override named group',
name='named_group',
attributes=[])
new_group = GroupSpec('A new group',
name='new_group',
attributes=[])
ext_groups = [override_group, new_group]

ext_spec = GroupSpec('An extending group',
data_type_inc='BaseType',
data_type_def='ExtType',
groups=ext_groups)

# Resolve the extension
ext_spec.resolve_spec(base_spec)

# Test unnamed group is added to data_types
self.assertEqual(ext_spec.get_data_type('UnnamedType'), unnamed_group)

# Test named group is overridden
resolved_group = ext_spec.get_group('named_group')
self.assertEqual(resolved_group.doc, 'Override named group')
self.assertTrue(ext_spec.is_overridden_spec(resolved_group))

# Test new group is added
new_resolved = ext_spec.get_group('new_group')
self.assertEqual(new_resolved.doc, 'A new group')
self.assertFalse(ext_spec.is_overridden_spec(new_resolved))

def test_resolve_group_inheritance_multiple(self):
"""Test resolution of multiple levels of group inheritance."""
# Base spec with a named group
base_group = GroupSpec('Base group',
name='test_group',
attributes=[])
base_spec = GroupSpec('A base group',
data_type_def='BaseType',
groups=[base_group])

# First extension overrides the group
mid_group = GroupSpec('Mid group',
name='test_group',
attributes=[])
mid_spec = GroupSpec('A middle group',
data_type_inc='BaseType',
data_type_def='MidType',
groups=[mid_group])

# Second extension inherits without override
ext_spec = GroupSpec('An extending group',
data_type_inc='MidType',
data_type_def='ExtType')

# Resolve the extensions
mid_spec.resolve_spec(base_spec)
ext_spec.resolve_spec(mid_spec)

# Test group inheritance through multiple levels
resolved_group = ext_spec.get_group('test_group')
self.assertEqual(resolved_group.doc, 'Mid group')
self.assertTrue(ext_spec.is_inherited_spec(resolved_group))


class TestResolveGroupSameAttributeName(TestCase):
# https://github.com/hdmf-dev/hdmf/issues/1121
Expand Down
Loading

0 comments on commit 9b76a1e

Please sign in to comment.