Skip to content

Commit cdf4a49

Browse files
committed
Replace mutable default arguments with None across public APIs
Switch run_isovar, apply_filters, evaluate_filters, and DataFrameBuilder from mutable module-level defaults to None with fresh copies created inside each function/constructor. Prevents accidental cross-call contamination if a caller mutates the returned defaults. Fixes #136
1 parent 186876e commit cdf4a49

5 files changed

Lines changed: 31 additions & 10 deletions

File tree

.claude/worktrees/agent-a2bf1121

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Subproject commit d7cbc775b76cae1bf9f0455bfe5f5db7a129273f

isovar/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
# See the License for the specific language governing permissions and
1111
# limitations under the License.
1212

13-
__version__ = "1.4.6"
13+
__version__ = "1.4.7"
1414

1515

1616
from .allele_read import AlleleRead

isovar/dataframe_builder.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,10 @@ def __init__(
3232
self,
3333
element_class,
3434
field_names=None,
35-
exclude=set([]),
36-
converters={},
37-
rename_dict={},
38-
extra_column_fns={},
35+
exclude=None,
36+
converters=None,
37+
rename_dict=None,
38+
extra_column_fns=None,
3939
variant_columns=True,
4040
convert_collections_to_size=True):
4141
"""
@@ -77,6 +77,14 @@ def __init__(
7777
then collection values cause a runtime error.
7878
"""
7979
self.element_class = element_class
80+
if exclude is None:
81+
exclude = set()
82+
if converters is None:
83+
converters = {}
84+
if rename_dict is None:
85+
rename_dict = {}
86+
if extra_column_fns is None:
87+
extra_column_fns = {}
8088
self.rename_dict = rename_dict
8189
self.converters = converters
8290
self.variant_columns = variant_columns

isovar/filtering.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ def evaluate_boolean_filters(isovar_result, filter_flags):
103103
def evaluate_filters(
104104
isovar_result,
105105
filter_thresholds,
106-
filter_flags=[]):
106+
filter_flags=None):
107107
"""
108108
Creates a dictionary whose keys are named of different
109109
filter conditions and values are booleans, where True
@@ -133,6 +133,8 @@ def evaluate_filters(
133133
Dictionary of filter names mapped to boolean value indicating
134134
whether this locus passed the filter.
135135
"""
136+
if filter_flags is None:
137+
filter_flags = []
136138
filter_values_dict = evaluate_boolean_filters(isovar_result, filter_flags)
137139
filter_values_dict.update(
138140
evaluate_threshold_filters(isovar_result, filter_thresholds))
@@ -141,8 +143,8 @@ def evaluate_filters(
141143

142144
def apply_filters(
143145
isovar_result,
144-
filter_thresholds={},
145-
filter_flags=[]):
146+
filter_thresholds=None,
147+
filter_flags=None):
146148
"""
147149
Given an IsovarResult object, evaluates given filters
148150
for each object, and returns a copy of the IsovarResult with new fiter
@@ -168,6 +170,10 @@ def apply_filters(
168170
169171
Returns IsovarResult
170172
"""
173+
if filter_thresholds is None:
174+
filter_thresholds = {}
175+
if filter_flags is None:
176+
filter_flags = []
171177
filter_values = OrderedDict(isovar_result.filter_values.items())
172178
new_filter_values = evaluate_filters(
173179
isovar_result,

isovar/main.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,8 @@ def run_isovar(
7777
transcript_id_whitelist=None,
7878
read_collector=None,
7979
protein_sequence_creator=None,
80-
filter_thresholds=DEFAULT_FILTER_THRESHOLDS,
81-
filter_flags=DEFAULT_FILTER_FLAGS,
80+
filter_thresholds=None,
81+
filter_flags=None,
8282
min_shared_fragments_for_phasing=MIN_SHARED_FRAGMENTS_FOR_PHASING,
8383
decompression_threads=1):
8484
"""
@@ -130,6 +130,12 @@ def run_isovar(
130130
`protein_sequences` field of the IsovarVar result will be empty
131131
if no sequences could be determined.
132132
"""
133+
if filter_thresholds is None:
134+
filter_thresholds = OrderedDict(DEFAULT_FILTER_THRESHOLDS)
135+
136+
if filter_flags is None:
137+
filter_flags = list(DEFAULT_FILTER_FLAGS)
138+
133139
if isinstance(variants, str):
134140
variants = load_vcf(variants)
135141

0 commit comments

Comments
 (0)