Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
a4852ad
FEAT: Add to_dict(), keys(), values(), items(), __contains__ to Row (…
jahnvi480 Jun 1, 2026
d21846e
FIX: Deduplicate dict-like methods when _column_map has lowercase ali…
jahnvi480 Jun 2, 2026
757a550
Linting fix
jahnvi480 Jun 2, 2026
a4804ae
Merge branch 'main' into jahnvi/row-dict-api-606
jahnvi480 Jun 2, 2026
9b96304
Merge branch 'main' into jahnvi/row-dict-api-606
jahnvi480 Jun 11, 2026
75998e2
FIX: Move _column_names to cursor for zero per-row cost, fix items() …
jahnvi480 Jun 11, 2026
31f3d47
REFACTOR: Move all Row tests from globals to cursor integration tests
jahnvi480 Jun 11, 2026
89c3b2f
FIX: Correct test_row_case_insensitive_access - normal SELECT has no …
jahnvi480 Jun 11, 2026
b7cb1a8
Merge branch 'main' into jahnvi/row-dict-api-606
jahnvi480 Jun 11, 2026
0917d1f
TEST: Cover _column_names=() and __contains__ lowercase branches (lin…
jahnvi480 Jun 11, 2026
93d9f37
Resolving linting issue
jahnvi480 Jun 11, 2026
c2c6927
PERF: Lazy-compute _column_names, add type annotations, update class …
jahnvi480 Jun 11, 2026
ae22ff8
Merge branch 'main' into jahnvi/row-dict-api-606
jahnvi480 Jun 11, 2026
e6142d0
TEST: Cover _get_column_names dedup fallback (lines 228-232)
jahnvi480 Jun 11, 2026
04111b9
FIX: Remove __contains__ (breaking change), make values() return tupl…
jahnvi480 Jun 11, 2026
10292eb
Merge branch 'main' into jahnvi/row-dict-api-606
jahnvi480 Jun 11, 2026
a4b4ac2
Merge branch 'main' into jahnvi/row-dict-api-606
jahnvi480 Jun 11, 2026
fa3c112
Merge branch 'main' into jahnvi/row-dict-api-606
jahnvi480 Jun 15, 2026
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
25 changes: 25 additions & 0 deletions mssql_python/row.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,31 @@ def __getattr__(self, name: str) -> Any:

raise AttributeError(f"Row has no attribute '{name}'")

def keys(self):
Comment thread
jahnvi480 marked this conversation as resolved.
Outdated
"""Return column names, like dict.keys()."""
return self._column_map.keys()

def values(self):
"""Return column values, like dict.values()."""
return self._values

def items(self):
"""Return (column_name, value) pairs, like dict.items()."""
return ((name, self._values[idx]) for name, idx in self._column_map.items())

def to_dict(self):
"""Return the row as a plain dict mapping column names to values."""
return {name: self._values[idx] for name, idx in self._column_map.items()}
Comment thread
jahnvi480 marked this conversation as resolved.
Outdated

def __contains__(self, key) -> bool:
"""Support 'col_name in row' membership testing."""
if isinstance(key, str):
if key in self._column_map:
return True
if self._column_map_lower is not None:
return key.lower() in self._column_map_lower
return False

def __eq__(self, other: Any) -> bool:
"""
Support comparison with lists for test compatibility.
Expand Down
63 changes: 63 additions & 0 deletions tests/test_001_globals.py
Original file line number Diff line number Diff line change
Expand Up @@ -1059,3 +1059,66 @@ def test_row_string_key_case_insensitive_with_lowercase():
# Non-existent attribute raises AttributeError
with pytest.raises(AttributeError):
row.nonexistent


def test_row_to_dict():
"""Test Row.to_dict() returns a plain dict of column names to values."""
from mssql_python.row import Row

row = Row(
[1, "foo", 3.14],
{"ProductID": 0, "Name": 1, "Price": 2},
cursor=None,
)

d = row.to_dict()
assert d == {"ProductID": 1, "Name": "foo", "Price": 3.14}
assert isinstance(d, dict)


def test_row_keys_values_items():
"""Test Row.keys(), values(), and items() behave like dict counterparts."""
from mssql_python.row import Row

column_map = {"id": 0, "name": 1}
row = Row([42, "Alice"], column_map, cursor=None)

# keys()
assert list(row.keys()) == ["id", "name"]

# values()
assert list(row.values()) == [42, "Alice"]

# items()
assert list(row.items()) == [("id", 42), ("name", "Alice")]


def test_row_contains():
"""Test 'column_name in row' membership testing."""
from mssql_python.row import Row

row = Row(
[1, "foo"],
{"ProductID": 0, "Name": 1},
cursor=None,
)

assert "ProductID" in row
assert "Name" in row
assert "nonexistent" not in row
# Integer is not a column name
assert 0 not in row


def test_row_contains_case_insensitive():
"""Test 'in' operator is case-insensitive when column_map_lower is provided."""
from mssql_python.row import Row

column_map = {"productid": 0, "name": 1}
column_map_lower = {k.lower(): v for k, v in column_map.items()}
row = Row([1, "bar"], column_map, cursor=None, column_map_lower=column_map_lower)

assert "productid" in row
assert "ProductID" in row
assert "NAME" in row
assert "missing" not in row
Loading