Skip to content

Commit 929e83d

Browse files
committed
Fix #56: NameError on expand_attribute_column=False
The else branch in read_gtf passed `result_df` to parse_gtf before `result_df` had been assigned — a guaranteed NameError that survived because the branch was never tested. Replaced with the correct `filepath_or_buffer` argument and also pass `split_attributes=False` so the unexpanded path doesn't emit the helper `attribute_split` column the user didn't ask for. Added tests/test_expand_attribute_column_false.py covering pandas / polars / dict result types, the features filter, and the alias / version-cast kwargs as graceful no-ops when attribute columns aren't expanded. Bumped to 2.7.1.
1 parent 1c66fa0 commit 929e83d

3 files changed

Lines changed: 79 additions & 2 deletions

File tree

gtfparse/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
read_gtf,
2424
)
2525

26-
__version__ = "2.7.0"
26+
__version__ = "2.7.1"
2727

2828
__all__ = [
2929
"GENCODE_BIOTYPE_ALIASES",

gtfparse/read_gtf.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,10 @@ def read_gtf(
354354
features=features,
355355
)
356356
else:
357-
result_df = parse_gtf(result_df, features=features)
357+
# When the caller opts out of attribute expansion they want the raw
358+
# 'attribute' column verbatim — no need to also produce the
359+
# 'attribute_split' helper that parse_gtf adds by default.
360+
result_df = parse_gtf(filepath_or_buffer, features=features, split_attributes=False)
358361

359362
# converting back to pandas here because Polars bugs manifest
360363
# as `pyo3_runtime.PanicException: assertion `left == right` failed: impl error`
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
"""Regression tests for #56: read_gtf(expand_attribute_column=False)
2+
used to raise NameError because the else branch referenced `result_df`
3+
before it had been assigned.
4+
"""
5+
6+
import pandas as pd
7+
8+
from gtfparse import read_gtf
9+
10+
from .data import data_path
11+
12+
GTF_PATH = data_path("ensembl_grch37.head.gtf")
13+
14+
15+
def test_expand_attribute_column_false_returns_raw_attribute_pandas():
16+
df = read_gtf(GTF_PATH, expand_attribute_column=False, result_type="pandas")
17+
assert isinstance(df, pd.DataFrame)
18+
# raw attribute column is preserved verbatim
19+
assert "attribute" in df.columns
20+
# none of the per-key attribute columns are produced
21+
assert "gene_name" not in df.columns
22+
assert "transcript_id" not in df.columns
23+
# the helper 'attribute_split' column from parse_gtf is also suppressed
24+
assert "attribute_split" not in df.columns
25+
# core GTF columns are present and populated
26+
for col in ("seqname", "source", "feature", "start", "end", "strand"):
27+
assert col in df.columns
28+
assert len(df) > 0
29+
# spot-check that the raw attribute string carries the original key/value form
30+
assert any("gene_id" in val for val in df["attribute"].astype(str))
31+
32+
33+
def test_expand_attribute_column_false_returns_polars():
34+
df = read_gtf(GTF_PATH, expand_attribute_column=False, result_type="polars")
35+
# polars dataframe — has columns attribute but no per-key columns
36+
assert "attribute" in df.columns
37+
assert "gene_name" not in df.columns
38+
assert "attribute_split" not in df.columns
39+
40+
41+
def test_expand_attribute_column_false_returns_dict():
42+
result = read_gtf(GTF_PATH, expand_attribute_column=False, result_type="dict")
43+
assert isinstance(result, dict)
44+
assert "attribute" in result
45+
assert "gene_name" not in result
46+
47+
48+
def test_expand_attribute_column_false_with_features_filter():
49+
"""The features filter must still apply when not expanding."""
50+
df = read_gtf(
51+
GTF_PATH,
52+
expand_attribute_column=False,
53+
features={"gene"},
54+
result_type="pandas",
55+
)
56+
assert set(df["feature"]) == {"gene"}
57+
58+
59+
def test_expand_attribute_column_false_skips_alias_and_version_logic():
60+
"""When attribute columns aren't expanded, attribute_aliases has
61+
nothing to rename and cast_version_columns has nothing to cast.
62+
Neither should raise — both must be graceful no-ops on the raw
63+
'attribute'-column-only frame."""
64+
df = read_gtf(
65+
GTF_PATH,
66+
expand_attribute_column=False,
67+
attribute_aliases={"gene_type": "gene_biotype"},
68+
cast_version_columns=True,
69+
result_type="pandas",
70+
)
71+
# alias source wasn't in columns → no rename happened → no canonical added
72+
assert "gene_biotype" not in df.columns
73+
# version columns weren't present → no cast → still nothing
74+
assert "gene_version" not in df.columns

0 commit comments

Comments
 (0)