reamberPy Help

Type Hinting Pandas Columns

ReamberPy builds on top of Pandas, and as such, it uses Pandas' DataFrame to index and store data. This allows for our object to yield columns via the properties.

E.g. our OsuMap stores bpms as a DataFrame.

from reamber.osu import OsuMap m = OsuMap.read_file("path/to/file.osu") bpms = m.bpms

Normally, we use bpms["bpm"] to access the column, however, we can also use bpms.bpm to access the column. This works too in DataFrames, however, it is never type-hinted.

ReamberPy works around this by performing meta-programming to not only generate the appropriate properties functions, but also create type-hinted .pyi stubs.

Creating Properties via Decorators

We can create properties via decorators.

@generate_funcs class Alpha: ... @generate_funcs class AlphaNew: ...
class Alpha: def to_beta(self): return self._alpha * 1.5 def to_lambda(self): return self._alpha // 3 class AlphaNew: def to_beta(self): return self._alpha * 1.5 def to_lambda(self): return self._alpha // 3

These decorators generates the new functions, however, as a result of decorators, the type-hints get broken. i.e. decorator-generated functions can't type-hint.

Python Stubs .pyi

To force type-hinting, we can create Python Stubs .pyi files.

class Alpha: def alpha(self) -> str: ...
class Alpha: def alpha(self): return self._alpha

Combining Decorators with Python Stubs, you can create a simple code-base with extensive type-hinting.

Templating

Templating reduces the hinting of inheritables.

For example, using Generic

from typing import Generic, TypeVar T = TypeVar('T') class Alpha(Generic[T]): def alpha(self) -> T: return self._alpha class Beta(Alpha[int]): ...

Yields

class Beta(Alpha): def alpha(self) -> int: return self._alpha

This is useful in propagating new types forward.

Last modified: 23 March 2024