Skip to content

Commit 6fa0106

Browse files
Raise explicit error on call_ fields
1 parent cb89ed5 commit 6fa0106

File tree

2 files changed

+24
-9
lines changed

2 files changed

+24
-9
lines changed

tests/test_filter.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,18 @@ def test_evaluate(self, expression, data, expected):
120120
result = fee.evaluate(numpify_values(data))
121121
nt.assert_array_equal(result, expected)
122122

123+
@pytest.mark.parametrize(
124+
"expression",
125+
[
126+
"FORMAT/AD > 30",
127+
"FMT/AD > 30",
128+
"GT > 30",
129+
],
130+
)
131+
def test_sample_evaluation_unsupported(self, expression):
132+
with pytest.raises(filter_mod.UnsupportedSampleFilteringError):
133+
filter_mod.FilterExpression(include=expression)
134+
123135
@pytest.mark.parametrize(
124136
("expr", "expected"),
125137
[

vcztools/filter.py

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ class UnsupportedFileReferenceError(UnsupportedFilteringFeatureError):
4747
feature = "File references"
4848

4949

50+
class UnsupportedSampleFilteringError(UnsupportedFilteringFeatureError):
51+
issue = "180"
52+
feature = "Per-sample filter expressions"
53+
54+
5055
# The parser and evaluation model here are based on the eval_arith example
5156
# in the pyparsing docs:
5257
# https://github.com/pyparsing/pyparsing/blob/master/examples/eval_arith.py
@@ -90,6 +95,8 @@ def __init__(self, tokens):
9095
class Identifier(EvaluationNode):
9196
def __init__(self, mapper, tokens):
9297
self.field_name = mapper(tokens[0])
98+
if self.field_name.startswith("call_"):
99+
raise UnsupportedSampleFilteringError()
93100
logger.debug(f"Mapped {tokens[0]} to {self.field_name}")
94101
# TODO add errors for unsupported things like call_ fields etc.
95102

@@ -103,12 +110,10 @@ def referenced_fields(self):
103110
return frozenset([self.field_name])
104111

105112

106-
class IndexedIdentifier(Identifier):
107-
def __init__(self, mapper, tokens):
108-
super().__init__(mapper, tokens[0])
109-
# Only literal integers are supported as indexes in bcftools
110-
# assert isinstance(self.index, str)
111-
self.index = tokens[0][1]
113+
class IndexedIdentifier(EvaluationNode):
114+
def __init__(self, tokens):
115+
# The tokens here are the already resolved idenfitier
116+
# and the index
112117
raise UnsupportedArraySubscriptError()
113118

114119

@@ -244,9 +249,7 @@ def make_bcftools_filter_parser(all_fields=None, map_vcf_identifiers=True):
244249
identifier = vcf_identifier.set_parse_action(
245250
functools.partial(Identifier, name_mapper)
246251
)
247-
indexed_identifier = indexed_identifier.set_parse_action(
248-
functools.partial(IndexedIdentifier, name_mapper)
249-
)
252+
indexed_identifier = indexed_identifier.set_parse_action(IndexedIdentifier)
250253
comp_op = pp.oneOf("< = == > >= <= !=")
251254
filter_expression = pp.infix_notation(
252255
constant | indexed_identifier | identifier | file_expr,

0 commit comments

Comments
 (0)