Repository: astropenguin/pandas-dataclasses

Issue:
Update asdata module
- [x] Rename `core.asdata` module to `core.aspandas` (because the former is ambiguous)
- [x] Rename `*dataframe*` to `*frame*` in functions and type hints
- [x] Add aliases for the backward compatibility

Discussion:

Patch:
diff --git a/README.md b/README.md
index 61461ac..f9bf148 100644
--- a/README.md
+++ b/README.md
@@ -17,13 +17,13 @@ pandas-dataclass makes it easy to create [pandas] data (DataFrame and Series) by
 
 ```python
 from dataclasses import dataclass
-from pandas_dataclasses import AsDataFrame, Data, Index
+from pandas_dataclasses import AsFrame, Data, Index
 ```
 </details>
 
 ```python
 @dataclass
-class Weather(AsDataFrame):
+class Weather(AsFrame):
     """Weather information."""
 
     year: Index[int]
@@ -72,7 +72,7 @@ pip install pandas-dataclasses
 pandas-dataclasses provides you the following features:
 
 - Type hints for dataclass fields (`Attr`, `Column`, `Data`, `Index`) to specify the data type and name of each element in pandas data
-- Mix-in classes for dataclasses (`As`, `AsDataFrame`, `AsSeries`) to create pandas data by a classmethod (`new`) that takes the same arguments as dataclass initialization
+- Mix-in classes for dataclasses (`As`, `AsFrame`, `AsSeries`) to create pandas data by a classmethod (`new`) that takes the same arguments as dataclass initialization
 
 When you call `new`, it will first create a dataclass object and then create a Series or DataFrame object from the dataclass object according the type hints and values in it.
 In the example above, `df = Weather.new(...)` is thus equivalent to:
@@ -81,36 +81,36 @@ In the example above, `df = Weather.new(...)` is thus equivalent to:
 <summary>Click to see all imports</summary>
 
 ```python
-from pandas_dataclasses import asdataframe
+from pandas_dataclasses import asframe
 ```
 </details>
 
 ```python
 obj = Weather([2020, ...], [1, ...], [7.1, ...], [2.4, ...])
-df = asdataframe(obj)
+df = asframe(obj)
 ```
 
-where `asdataframe` is a conversion function.
+where `asframe` is a conversion function.
 pandas-dataclasses does not touch the dataclass object creation itself; this allows you to fully customize your dataclass before conversion by the dataclass features (`field`, `__post_init__`, ...).
 
 ## Basic usage
 
 ### DataFrame creation
 
-As shown in the example above, a dataclass that has the `AsDataFrame` mix-in will create DataFrame objects:
+As shown in the example above, a dataclass that has the `AsFrame` mix-in will create DataFrame objects:
 
 <details>
 <summary>Click to see all imports</summary>
 
 ```python
 from dataclasses import dataclass
-from pandas_dataclasses import AsDataFrame, Data, Index
+from pandas_dataclasses import AsFrame, Data, Index
 ```
 </details>
 
 ```python
 @dataclass
-class Weather(AsDataFrame):
+class Weather(AsFrame):
     """Weather information."""
 
     year: Index[int]
@@ -159,7 +159,7 @@ class Weather(AsSeries):
 ser = Weather.new(...)
 ```
 
-Unlike `AsDataFrame`, the second and subsequent data fields are ignored in the Series creation even if they exist.
+Unlike `AsFrame`, the second and subsequent data fields are ignored in the Series creation even if they exist.
 Other rules are the same as for the DataFrame creation.
 
 ## Advanced usage
@@ -173,13 +173,13 @@ Fields typed by `Attr` are *attribute fields*, each value of which will become a
 
 ```python
 from dataclasses import dataclass
-from pandas_dataclasses import AsDataFrame, Attr, Data, Index
+from pandas_dataclasses import AsFrame, Attr, Data, Index
 ```
 </details>
 
 ```python
 @dataclass
-class Weather(AsDataFrame):
+class Weather(AsFrame):
     """Weather information."""
 
     year: Index[int]
@@ -210,13 +210,13 @@ The name of attribute, data, or index can be explicitly specified by adding a ha
 ```python
 from dataclasses import dataclass
 from typing import Annotated as Ann
-from pandas_dataclasses import AsDataFrame, Attr, Data, Index
+from pandas_dataclasses import AsFrame, Attr, Data, Index
 ```
 </details>
 
 ```python
 @dataclass
-class Weather(AsDataFrame):
+class Weather(AsFrame):
     """Weather information."""
 
     year: Ann[Index[int], "Year"]
@@ -255,13 +255,13 @@ If an annotation is a [format string], it will be formatted by a dataclass objec
 ```python
 from dataclasses import dataclass
 from typing import Annotated as Ann
-from pandas_dataclasses import AsDataFrame, Data, Index
+from pandas_dataclasses import AsFrame, Data, Index
 ```
 </details>
 
 ```python
 @dataclass
-class Weather(AsDataFrame):
+class Weather(AsFrame):
     """Weather information."""
 
     year: Ann[Index[int], "Year"]
@@ -287,13 +287,13 @@ Adding tuple annotations to data fields will create DataFrame objects with hiera
 ```python
 from dataclasses import dataclass
 from typing import Annotated as Ann
-from pandas_dataclasses import AsDataFrame, Data, Index
+from pandas_dataclasses import AsFrame, Data, Index
 ```
 </details>
 
 ```python
 @dataclass
-class Weather(AsDataFrame):
+class Weather(AsFrame):
     """Weather information."""
 
     year: Ann[Index[int], "Year"]
@@ -328,13 +328,13 @@ Column names can be (explicitly) specified by *column fields* (with hashable ann
 ```python
 from dataclasses import dataclass
 from typing import Annotated as Ann
-from pandas_dataclasses import AsDataFrame, Column, Data, Index
+from pandas_dataclasses import AsFrame, Column, Data, Index
 ```
 </details>
 
 ```python
 @dataclass
-class Weather(AsDataFrame):
+class Weather(AsFrame):
     """Weather information."""
 
     year: Ann[Index[int], "Year"]
@@ -368,7 +368,7 @@ If a tuple annotation has [format string]s, they will also be formatted by a dat
 
 ### Custom pandas factory
 
-A custom class can be specified as a factory for the Series or DataFrame creation by `As`, the generic version of `AsDataFrame` and `AsSeries`.
+A custom class can be specified as a factory for the Series or DataFrame creation by `As`, the generic version of `AsFrame` and `AsSeries`.
 Note that the custom class must be a subclass of either `pandas.Series` or `pandas.DataFrame`:
 
 <details>
diff --git a/pandas_dataclasses/__init__.py b/pandas_dataclasses/__init__.py
index fe0a274..18a5d75 100644
--- a/pandas_dataclasses/__init__.py
+++ b/pandas_dataclasses/__init__.py
@@ -1,6 +1,7 @@
 __all__ = [
     "As",
     "AsDataFrame",
+    "AsFrame",
     "AsSeries",
     "Attr",
     "Column",
@@ -9,13 +10,14 @@ __all__ = [
     "Other",
     "Spec",
     "asdataframe",
+    "asframe",
     "asseries",
     "core",
 ]
 
 
 from . import core
-from .core.asdata import *
+from .core.aspandas import *
 from .core.mixins import *
 from .core.specs import *
 from .core.typing import *
@@ -23,3 +25,12 @@ from .core.typing import *
 
 # metadata
 __version__ = "0.8.0"
+
+
+# aliases
+AsDataFrame = AsFrame
+"""Alias of ``core.mixins.AsFrame``."""
+
+
+asdataframe = asframe
+"""Alias of ``core.aspandas.asframe``."""
diff --git a/pandas_dataclasses/core/__init__.py b/pandas_dataclasses/core/__init__.py
index cd94a78..b44c4f9 100644
--- a/pandas_dataclasses/core/__init__.py
+++ b/pandas_dataclasses/core/__init__.py
@@ -1,7 +1,7 @@
-__all__ = ["asdata", "mixins", "specs", "typing"]
+__all__ = ["aspandas", "mixins", "specs", "typing"]
 
 
-from . import asdata
+from . import aspandas
 from . import mixins
 from . import specs
 from . import typing
diff --git a/pandas_dataclasses/core/asdata.py b/pandas_dataclasses/core/aspandas.py
similarity index 88%
rename from pandas_dataclasses/core/asdata.py
rename to pandas_dataclasses/core/aspandas.py
index 29265a5..b7003c4 100644
--- a/pandas_dataclasses/core/asdata.py
+++ b/pandas_dataclasses/core/aspandas.py
@@ -1,4 +1,4 @@
-__all__ = ["asdataframe", "asseries"]
+__all__ = ["asframe", "asseries"]
 
 
 # standard library
@@ -12,26 +12,26 @@ import pandas as pd
 
 # submodules
 from .specs import Spec
-from .typing import P, DataClass, PandasClass, TDataFrame, TSeries
+from .typing import P, DataClass, PandasClass, TFrame, TSeries
 
 
 # runtime functions
 @overload
-def asdataframe(obj: PandasClass[P, TDataFrame], *, factory: None = None) -> TDataFrame:
+def asframe(obj: PandasClass[P, TFrame], *, factory: None = None) -> TFrame:
     ...
 
 
 @overload
-def asdataframe(obj: DataClass[P], *, factory: Callable[..., TDataFrame]) -> TDataFrame:
+def asframe(obj: DataClass[P], *, factory: Callable[..., TFrame]) -> TFrame:
     ...
 
 
 @overload
-def asdataframe(obj: DataClass[P], *, factory: None = None) -> pd.DataFrame:
+def asframe(obj: DataClass[P], *, factory: None = None) -> pd.DataFrame:
     ...
 
 
-def asdataframe(obj: Any, *, factory: Any = None) -> Any:
+def asframe(obj: Any, *, factory: Any = None) -> Any:
     """Create a DataFrame object from a dataclass object."""
     spec = Spec.from_dataclass(type(obj)) @ obj
 
diff --git a/pandas_dataclasses/core/mixins.py b/pandas_dataclasses/core/mixins.py
index 74b32f7..f1cfad1 100644
--- a/pandas_dataclasses/core/mixins.py
+++ b/pandas_dataclasses/core/mixins.py
@@ -1,4 +1,4 @@
-__all__ = ["As", "AsDataFrame", "AsSeries"]
+__all__ = ["As", "AsFrame", "AsSeries"]
 
 
 # standard library
@@ -14,7 +14,7 @@ from typing_extensions import get_args, get_origin
 
 
 # submodules
-from .asdata import asdataframe, asseries
+from .aspandas import asframe, asseries
 from .typing import P, T, Pandas, PandasClass, TPandas
 
 
@@ -51,7 +51,7 @@ class As(Generic[TPandas]):
         return MethodType(get_creator(cls), cls)
 
 
-AsDataFrame = As[pd.DataFrame]
+AsFrame = As[pd.DataFrame]
 """Alias of ``As[pandas.DataFrame]``."""
 
 
@@ -72,7 +72,7 @@ def get_creator(cls: Any) -> Callable[..., Pandas]:
     origin = get_origin(return_) or return_
 
     if issubclass(origin, pd.DataFrame):
-        converter: Any = asdataframe
+        converter: Any = asframe
     elif issubclass(origin, pd.Series):
         converter = asseries
     else:
diff --git a/pandas_dataclasses/core/typing.py b/pandas_dataclasses/core/typing.py
index dc0704a..4275ff7 100644
--- a/pandas_dataclasses/core/typing.py
+++ b/pandas_dataclasses/core/typing.py
@@ -38,7 +38,7 @@ Pandas = Union[pd.DataFrame, "pd.Series[Any]"]
 P = ParamSpec("P")
 T = TypeVar("T")
 TPandas = TypeVar("TPandas", bound=Pandas)
-TDataFrame = TypeVar("TDataFrame", bound=pd.DataFrame)
+TFrame = TypeVar("TFrame", bound=pd.DataFrame)
 TSeries = TypeVar("TSeries", bound="pd.Series[Any]")
 
 


Test patch:
diff --git a/tests/test_asdata.py b/tests/test_aspandas.py
similarity index 86%
rename from tests/test_asdata.py
rename to tests/test_aspandas.py
index d71000e..ea9b088 100644
--- a/tests/test_asdata.py
+++ b/tests/test_aspandas.py
@@ -6,8 +6,8 @@ from typing import cast
 import pandas as pd
 from pandas.testing import assert_frame_equal, assert_series_equal
 from data import Weather, weather, df_weather_true, ser_weather_true
-from pandas_dataclasses import Spec, asdataframe, asseries
-from pandas_dataclasses.core.asdata import get_attrs, get_columns, get_data, get_index
+from pandas_dataclasses import Spec, asframe, asseries
+from pandas_dataclasses.core.aspandas import get_attrs, get_columns, get_data, get_index
 
 
 # test data
@@ -15,12 +15,12 @@ spec = Spec.from_dataclass(Weather) @ weather
 
 
 # test functions
-def test_asseries() -> None:
-    assert_series_equal(asseries(weather), ser_weather_true)
+def test_asframe() -> None:
+    assert_frame_equal(asframe(weather), df_weather_true)
 
 
-def test_asdataframe() -> None:
-    assert_frame_equal(asdataframe(weather), df_weather_true)
+def test_asseries() -> None:
+    assert_series_equal(asseries(weather), ser_weather_true)
 
 
 def test_get_attrs() -> None:
diff --git a/tests/test_mixins.py b/tests/test_mixins.py
index 7aed087..a6e39da 100644
--- a/tests/test_mixins.py
+++ b/tests/test_mixins.py
@@ -7,7 +7,7 @@ from typing import Any
 import pandas as pd
 from pandas.testing import assert_frame_equal, assert_series_equal
 from data import Weather, weather, df_weather_true, ser_weather_true
-from pandas_dataclasses import As, AsDataFrame, AsSeries
+from pandas_dataclasses import As, AsFrame, AsSeries
 
 
 # test data
@@ -15,47 +15,47 @@ def factory(*args: Any, **kwargs: Any) -> pd.Series:  # type: ignore
     return pd.Series(*args, **kwargs)  # type: ignore
 
 
-class CustomDataFrame(pd.DataFrame):
+class UserFrame(pd.DataFrame):
     pass
 
 
-class CustomSeries(pd.Series):  # type: ignore
+class UserSeries(pd.Series):  # type: ignore
     pass
 
 
 @dataclass
-class DataFrameWeather(Weather, AsDataFrame):
+class Frame(Weather, AsFrame):
     pass
 
 
 @dataclass
-class CustomDataFrameWeather(Weather, As[CustomDataFrame]):
+class CustomFrame(Weather, As[UserFrame]):
     pass
 
 
 @dataclass
-class SeriesWeather(Weather, AsSeries):
+class Series(Weather, AsSeries):
     pass
 
 
 @dataclass
-class FactorySeriesWeather(Weather, AsSeries, factory=factory):
+class CustomSeries(Weather, As[UserSeries]):
     pass
 
 
 @dataclass
-class CustomSeriesWeather(Weather, As[CustomSeries]):
+class FactorySeries(Weather, AsSeries, factory=factory):
     pass
 
 
 @dataclass
-class FloatSeriesWeather(Weather, As["pd.Series[float]"], factory=pd.Series):
+class FloatSeries(Weather, As["pd.Series[float]"], factory=pd.Series):
     pass
 
 
 # test functions
-def test_dataframe_weather() -> None:
-    df_weather = DataFrameWeather.new(
+def test_frame() -> None:
+    df_weather = Frame.new(
         year=weather.year,
         month=weather.month,
         temp_avg=weather.temp_avg,
@@ -68,8 +68,8 @@ def test_dataframe_weather() -> None:
     assert_frame_equal(df_weather, df_weather_true)
 
 
-def test_custom_dataframe_weather() -> None:
-    df_weather = CustomDataFrameWeather.new(
+def test_custom_frame() -> None:
+    df_weather = CustomFrame.new(
         year=weather.year,
         month=weather.month,
         temp_avg=weather.temp_avg,
@@ -78,12 +78,12 @@ def test_custom_dataframe_weather() -> None:
         wind_max=weather.wind_max,
     )
 
-    assert isinstance(df_weather, CustomDataFrame)
+    assert isinstance(df_weather, UserFrame)
     assert_frame_equal(df_weather, df_weather_true, check_frame_type=False)
 
 
-def test_series_weather() -> None:
-    ser_weather = SeriesWeather.new(
+def test_series() -> None:
+    ser_weather = Series.new(
         year=weather.year,
         month=weather.month,
         temp_avg=weather.temp_avg,
@@ -96,8 +96,8 @@ def test_series_weather() -> None:
     assert_series_equal(ser_weather, ser_weather_true)
 
 
-def test_factory_series_weather() -> None:
-    ser_weather = FactorySeriesWeather.new(
+def test_custom_series() -> None:
+    ser_weather = CustomSeries.new(
         year=weather.year,
         month=weather.month,
         temp_avg=weather.temp_avg,
@@ -106,12 +106,12 @@ def test_factory_series_weather() -> None:
         wind_max=weather.wind_max,
     )
 
-    assert isinstance(ser_weather, pd.Series)
-    assert_series_equal(ser_weather, ser_weather_true)
+    assert isinstance(ser_weather, UserSeries)
+    assert_series_equal(ser_weather, ser_weather_true, check_series_type=False)
 
 
-def test_custom_series_weather() -> None:
-    ser_weather = CustomSeriesWeather.new(
+def test_factory_series() -> None:
+    ser_weather = FactorySeries.new(
         year=weather.year,
         month=weather.month,
         temp_avg=weather.temp_avg,
@@ -120,12 +120,12 @@ def test_custom_series_weather() -> None:
         wind_max=weather.wind_max,
     )
 
-    assert isinstance(ser_weather, CustomSeries)
-    assert_series_equal(ser_weather, ser_weather_true, check_series_type=False)
+    assert isinstance(ser_weather, pd.Series)
+    assert_series_equal(ser_weather, ser_weather_true)
 
 
-def test_float_series_weather() -> None:
-    ser_weather = FloatSeriesWeather.new(
+def test_float_series() -> None:
+    ser_weather = FloatSeries.new(
         year=weather.year,
         month=weather.month,
         temp_avg=weather.temp_avg,