Skip to content

Commit c25880e

Browse files
authored
feat: Add name string property to dy.Column (#52)
1 parent e0c30b4 commit c25880e

File tree

4 files changed

+36
-16
lines changed

4 files changed

+36
-16
lines changed

dataframely/_base_schema.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,13 @@ def __new__(
130130

131131
return super().__new__(mcs, name, bases, namespace, *args, **kwargs)
132132

133+
def __getattribute__(cls, name: str) -> Any:
134+
val = super().__getattribute__(name)
135+
# Dynamically set the name of the column if it is a `Column` instance.
136+
if isinstance(val, Column):
137+
val._name = val.alias or name
138+
return val
139+
133140
@staticmethod
134141
def _get_metadata_recursively(kls: type[object]) -> Metadata:
135142
result = Metadata()
@@ -145,9 +152,7 @@ def _get_metadata(source: dict[str, Any]) -> Metadata:
145152
k: v for k, v in source.items() if not k.startswith("__")
146153
}.items():
147154
if isinstance(value, Column):
148-
if not value.alias:
149-
value.alias = attr
150-
result.columns[value.alias] = value
155+
result.columns[value.alias or attr] = value
151156
if isinstance(value, Rule):
152157
# We must ensure that custom rules do not clash with internal rules.
153158
if attr == "primary_key":

dataframely/columns/_base.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,7 @@ def __init__(
6868
alias: An overwrite for this column's name which allows for using a column
6969
name that is not a valid Python identifier. Especially note that setting
7070
this option does _not_ allow to refer to the column with two different
71-
names, the specified alias is the only valid name. If unset, dataframely
72-
internally sets the alias to the column's name in the parent schema.
71+
names, the specified alias is the only valid name.
7372
metadata: A dictionary of metadata to attach to the column.
7473
"""
7574

@@ -85,6 +84,8 @@ def __init__(
8584
self.check = check
8685
self.alias = alias
8786
self.metadata = metadata
87+
# The name may be overridden by the schema on column access.
88+
self._name = ""
8889

8990
# ------------------------------------- DTYPE ------------------------------------ #
9091

@@ -225,12 +226,15 @@ def pyarrow_dtype(self) -> pa.DataType:
225226

226227
# ------------------------------------ HELPER ------------------------------------ #
227228

229+
@property
230+
def name(self) -> str:
231+
"""Get the name of the column in a schema."""
232+
return self._name
233+
228234
@property
229235
def col(self) -> pl.Expr:
230236
"""Obtain a Polars column expression for the column."""
231-
if self.alias is None:
232-
raise ValueError("Cannot obtain column expression if alias is ``None``.")
233-
return pl.col(self.alias)
237+
return pl.col(self.name)
234238

235239
# ----------------------------------- SAMPLING ----------------------------------- #
236240

tests/columns/test_alias.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,17 @@ def test_validation() -> None:
2222
def test_create_empty() -> None:
2323
df = AliasSchema.create_empty()
2424
assert AliasSchema.is_valid(df)
25+
26+
27+
def test_alias() -> None:
28+
assert AliasSchema.a.alias == "hello world: col with space!"
29+
30+
31+
def test_alias_name() -> None:
32+
assert AliasSchema.a.name == "hello world: col with space!"
33+
34+
35+
def test_alias_unset() -> None:
36+
no_alias_col = dy.Int32()
37+
assert no_alias_col.alias is None
38+
assert no_alias_col.name == ""

tests/schema/test_base.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,11 @@ def test_col() -> None:
6464
assert MySchema.d.col.__dict__ == pl.col("e").__dict__
6565

6666

67-
def test_col_raise_if_none() -> None:
68-
class InvalidSchema(dy.Schema):
69-
a = dy.Integer()
70-
71-
# Manually override alias to be ``None``.
72-
InvalidSchema.a.alias = None
73-
with pytest.raises(ValueError):
74-
InvalidSchema.a.col
67+
def test_name() -> None:
68+
assert MySchema.a.name == "a"
69+
assert MySchema.b.name == "b"
70+
assert MySchema.c.name == "c"
71+
assert MySchema.d.name == "e"
7572

7673

7774
def test_col_in_polars_expression() -> None:

0 commit comments

Comments
 (0)