Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support in recurring group name in files. #45

Merged
merged 9 commits into from
Mar 20, 2022
31 changes: 25 additions & 6 deletions c3d/c3d.py
Original file line number Diff line number Diff line change
Expand Up @@ -1084,17 +1084,25 @@ def check_parameters(params):
else:
warnings.warn('No analog data found in file.')

def add_group(self, group_id, name, desc):
def add_group(self, group_id, name, desc, rename_duplicated_groups=False):
'''Add a new parameter group.

Parameters
----------
group_id : int
The numeric ID for a group to check or create.
name : str, optional
name : str
If a group is created, assign this name to the group.
The name will be turned to upper case letters.
desc : str, optional
If a group is created, assign this description to the group.
rename_duplicated_groups : bool
If True, when adding a group with a name that already exists, the group will be renamed to
`{name}{group_id}`.
The original group will not be renamed.
In general, having multiple groups with the same name is against the c3d specification.
This option only exists to handle edge cases where files are not created according to the spec and still
need to be imported.

Returns
-------
Expand All @@ -1108,14 +1116,23 @@ def add_group(self, group_id, name, desc):
'''
if not is_integer(group_id):
raise ValueError('Expected Group numerical key to be integer, was %s.' % type(group_id))
if not (isinstance(name, str) or name is None):
if not isinstance(name, str):
raise ValueError('Expected Group name key to be string, was %s.' % type(name))
group_id = int(group_id) # Assert python int
if group_id in self._groups:
raise KeyError(group_id)
raise KeyError('Group with numerical key {} already exists'.format(group_id))
name = name.upper()
if name in self._groups:
raise KeyError(name)
if rename_duplicated_groups is True:
# In some cases group name is not unique (though c3d spec requires that).
# To allow using such files we auto-generate new name.
# Notice that referring to this group's parameters later with the original name will fail.
new_name = name + str(group_id)
warnings.warn(f'Repeated group name {name} modified to {new_name}')
name = new_name
else:
raise KeyError(f'A group with the name {name} already exists.')

group = self._groups[name] = self._groups[group_id] = Group(self._dtypes, name, desc)
return group

Expand Down Expand Up @@ -1437,7 +1454,9 @@ def seek_param_section_header():
self.rename_group(group, name)
group.desc = desc
else:
self.add_group(group_id, name, desc)
# We allow duplicated group names here, even though it is against the c3d spec.
# The groups will be renamed.
self.add_group(group_id, name, desc, rename_duplicated_groups=True)

self._check_metadata()

Expand Down
16 changes: 16 additions & 0 deletions test/test_group_accessors.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,22 @@ def test_Manager_add_group(self):
ref.verify_add_group(100)
ref.verify_remove_all_using_numeric()

def test_Manager_add_group_duplicated_names(self):
'''Check that groups with the same name can be added if the option is enabled.'''
reader = c3d.Reader(Zipload._get(self.ZIP, self.INTEL_REAL))
ref = GroupSample(reader)
test_name = "TEST_NAME"
ref.manager.add_group(ref.max_key + 1, test_name, '')

# Test default
with self.assertRaises(KeyError):
ref.manager.add_group(ref.max_key + 2, test_name, '')

# Test with option on
new_id = ref.max_key + 2
ref.manager.add_group(new_id, test_name, '', rename_duplicated_groups=True)
self.assertEqual(ref.manager._groups[new_id].name, test_name.upper() + str(new_id))

def test_Manager_removing_group_from_numeric(self):
'''Test if removing groups acts as intended.'''
reader = c3d.Reader(Zipload._get(self.ZIP, self.INTEL_REAL))
Expand Down