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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/python-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ on:
jobs:
build:

runs-on: ubuntu-latest
runs-on: ubuntu-20.04
strategy:
fail-fast: false
matrix:
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]
python-version: ["3.6", "3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]

steps:
- uses: actions/checkout@v3
Expand Down
106 changes: 71 additions & 35 deletions src/mavehgvs/variant.py
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ def _process_string_variant( # noqa: max-complexity: 23
positions = VariantPosition(match_dict[f"{pattern_group}_position"])
if self._prefix == "p":
sequences = (positions.amino_acid, match_dict[f"{pattern_group}_new"])
elif self._prefix in tuple("gmo" "cn" "r"):
elif self._prefix in tuple("gmocnr"):
sequences = (
match_dict[f"{pattern_group}_ref"],
match_dict[f"{pattern_group}_new"],
Expand Down Expand Up @@ -479,43 +479,18 @@ def _variant_dictionary_to_string( # noqa: max-complexity: 25
else:
return variant_string

def __eq__(self, other: "Variant") -> bool:
"""Equality comparison operator.
def _format_component_variants(self) -> List[str]: # noqa: max-complexity: 14
"""Format each of the component variants of this variant into a variant string.

Parameters
----------
other : Variant
The other Variant to compare to.
The result is a list of strings, each representing a single variant. If this
variant is a single variant, the list will contain a single element equivalent
to the input string. For multi-variants, the list will contain each component
variant of the variant.

Returns
-------
bool
True if this variant is the same as the other position; else False.

"""
return (
self._target_id,
self.variant_count,
self._prefix,
self._variant_types,
self._positions,
self._sequences,
) == (
other._target_id,
other.variant_count,
other._prefix,
other._variant_types,
other._positions,
other._sequences,
)

def __repr__(self) -> str: # noqa: max-complexity: 14
"""The object representation is equivalent to the input string.

Returns
-------
str
The object representation.
List[str]
List of formatted component variants.

"""

Expand Down Expand Up @@ -569,12 +544,55 @@ def format_variant(
else: # pragma: no cover
raise ValueError("invalid variant type")

return [format_variant(*t) for t in self.variant_tuples()]

def __eq__(self, other: "Variant") -> bool:
"""Equality comparison operator.

Parameters
----------
other : Variant
The other Variant to compare to.

Returns
-------
bool
True if this variant is the same as the other position; else False.

"""
return (
self._target_id,
self.variant_count,
self._prefix,
self._variant_types,
self._positions,
self._sequences,
) == (
other._target_id,
other.variant_count,
other._prefix,
other._variant_types,
other._positions,
other._sequences,
)

def __repr__(self) -> str:
"""The object representation is equivalent to the input string.

Returns
-------
str
The object representation.

"""

elements = self._format_component_variants()

if self._target_id is not None:
prefix = f"{self._target_id}:{self._prefix}"
else:
prefix = f"{self._prefix}"

elements = [format_variant(*t) for t in self.variant_tuples()]
if self.is_multi_variant():
return f"{prefix}.[{';'.join(elements)}]"
else:
Expand Down Expand Up @@ -834,3 +852,21 @@ def target_id(self) -> Optional[str]:

"""
return self._target_id

def components(self) -> Tuple[str, ...]:
"""The component substrings of a variant.

Returns
-------
Tuple[str, ...]
List of component substrings for this variant.

"""
if self.target_id is not None:
prefix = f"{self.target_id}:{self.prefix}"
else:
prefix = f"{self.prefix}"

return tuple(
[f"{prefix}.{component}" for component in self._format_component_variants()]
)
24 changes: 24 additions & 0 deletions tests/test_variant.py
Original file line number Diff line number Diff line change
Expand Up @@ -987,6 +987,30 @@ def test_uses_extended_positions(self):
v = Variant(s)
self.assertTrue(v.uses_extended_positions())

def test_components(self):
variant_strings = [
("p.[Glu27Trp;Ter345Lys]", ("p.Glu27Trp", "p.Ter345Lys")),
("p.[Glu27Trp;Lys212fs]", ("p.Glu27Trp", "p.Lys212fs")),
(
"p.[Gly18del;Glu27Trp;Ter345Lys]",
("p.Gly18del", "p.Glu27Trp", "p.Ter345Lys"),
),
(
"p.[Gln7_Asn19del;Glu27Trp;Ter345Lys]",
("p.Gln7_Asn19del", "p.Glu27Trp", "p.Ter345Lys"),
),
(
"c.[1_35del;78+5_78+10del;122T>A]",
("c.1_35del", "c.78+5_78+10del", "c.122T>A"),
),
("p.Glu27Trp", ("p.Glu27Trp",)),
]

for s, expected_components in variant_strings:
with self.subTest(s=s):
v = Variant(s)
self.assertTrue(all([c in expected_components for c in v.components()]))


# TODO: multi-variant test cases
class TestMiscProperties(unittest.TestCase):
Expand Down