Skip to content

TYP: io.pytables annotations #29861

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Nov 29, 2019
65 changes: 36 additions & 29 deletions pandas/io/pytables.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
from pandas.io.formats.printing import adjoin, pprint_thing

if TYPE_CHECKING:
from tables import File # noqa:F401
from tables import File, Node # noqa:F401


# versioning attribute
Expand Down Expand Up @@ -527,7 +527,7 @@ def __getattr__(self, name: str):
f"'{type(self).__name__}' object has no attribute '{name}'"
)

def __contains__(self, key: str):
def __contains__(self, key: str) -> bool:
""" check for existence of this key
can match the exact pathname or the pathnm w/o the leading '/'
"""
Expand Down Expand Up @@ -1269,18 +1269,22 @@ def walk(self, where="/"):

yield (g._v_pathname.rstrip("/"), groups, leaves)

def get_node(self, key: str):
def get_node(self, key: str) -> Optional["Node"]:
""" return the node with the key or None if it does not exist """
self._check_if_open()
if not key.startswith("/"):
key = "/" + key

assert self._handle is not None
try:
return self._handle.get_node(self.root, key)
node = self._handle.get_node(self.root, key)
except _table_mod.exceptions.NoSuchNodeError: # type: ignore
return None

assert _table_mod is not None # for mypy
assert isinstance(node, _table_mod.Node), type(node)
return node

def get_storer(self, key: str) -> Union["GenericFixed", "Table"]:
""" return the storer object for a key, raise if not in the file """
group = self.get_node(key)
Expand Down Expand Up @@ -1389,7 +1393,9 @@ def info(self) -> str:

return output

# private methods ######
# ------------------------------------------------------------------------
# private methods

def _check_if_open(self):
if not self.is_open:
raise ClosedFileError(f"{self._path} file is not open!")
Expand Down Expand Up @@ -1561,7 +1567,7 @@ def _write_to_group(
if isinstance(s, Table) and index:
s.create_index(columns=index)

def _read_group(self, group, **kwargs):
def _read_group(self, group: "Node", **kwargs):
s = self._create_storer(group)
s.infer_axes()
return s.read(**kwargs)
Expand Down Expand Up @@ -1788,7 +1794,7 @@ def copy(self):
new_self = copy.copy(self)
return new_self

def infer(self, handler):
def infer(self, handler: "Table"):
"""infer this column from the table: create and return a new object"""
table = handler.table
new_self = self.copy()
Expand Down Expand Up @@ -2092,7 +2098,7 @@ def __repr__(self) -> str:
)
)

def __eq__(self, other):
def __eq__(self, other) -> bool:
""" compare 2 col items """
return all(
getattr(self, a, None) == getattr(other, a, None)
Expand Down Expand Up @@ -2504,9 +2510,16 @@ class Fixed:
pandas_kind: str
obj_type: Type[Union[DataFrame, Series]]
ndim: int
parent: HDFStore
group: "Node"
is_table = False

def __init__(self, parent, group, encoding=None, errors="strict", **kwargs):
def __init__(
self, parent: HDFStore, group: "Node", encoding=None, errors="strict", **kwargs
):
assert isinstance(parent, HDFStore), type(parent)
assert _table_mod is not None # needed for mypy
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this not have any impact on runtime? The global state management here is a little nuanced so just want to double check that it is valid to add to the constructor here, as on first glance it may not be set until methods are called by design

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does not, we wouldn't get here if _table_mod were not initialized

assert isinstance(group, _table_mod.Node), type(group)
self.parent = parent
self.group = group
self.encoding = _ensure_encoding(encoding)
Expand Down Expand Up @@ -2770,7 +2783,7 @@ def read_array(
else:
return ret

def read_index(self, key, **kwargs):
def read_index(self, key: str, **kwargs):
variety = _ensure_decoded(getattr(self.attrs, f"{key}_variety"))

if variety == "multi":
Expand All @@ -2785,7 +2798,7 @@ def read_index(self, key, **kwargs):
else: # pragma: no cover
raise TypeError(f"unrecognized index variety: {variety}")

def write_index(self, key, index):
def write_index(self, key: str, index):
if isinstance(index, MultiIndex):
setattr(self.attrs, f"{key}_variety", "multi")
self.write_multi_index(key, index)
Expand All @@ -2797,9 +2810,7 @@ def write_index(self, key, index):
self.write_sparse_intindex(key, index)
else:
setattr(self.attrs, f"{key}_variety", "regular")
converted = _convert_index(
"index", index, self.encoding, self.errors, self.format_type
)
converted = _convert_index("index", index, self.encoding, self.errors)

self.write_array(key, converted.values)

Expand All @@ -2816,18 +2827,18 @@ def write_index(self, key, index):
if hasattr(index, "tz") and index.tz is not None:
node._v_attrs.tz = _get_tz(index.tz)

def write_block_index(self, key, index):
def write_block_index(self, key: str, index):
self.write_array(f"{key}_blocs", index.blocs)
self.write_array(f"{key}_blengths", index.blengths)
setattr(self.attrs, f"{key}_length", index.length)

def read_block_index(self, key, **kwargs) -> BlockIndex:
def read_block_index(self, key: str, **kwargs) -> BlockIndex:
length = getattr(self.attrs, f"{key}_length")
blocs = self.read_array(f"{key}_blocs", **kwargs)
blengths = self.read_array(f"{key}_blengths", **kwargs)
return BlockIndex(length, blocs, blengths)

def write_sparse_intindex(self, key, index):
def write_sparse_intindex(self, key: str, index):
self.write_array(f"{key}_indices", index.indices)
setattr(self.attrs, f"{key}_length", index.length)

Expand All @@ -2836,7 +2847,7 @@ def read_sparse_intindex(self, key, **kwargs) -> IntIndex:
indices = self.read_array(f"{key}_indices", **kwargs)
return IntIndex(length, indices)

def write_multi_index(self, key, index):
def write_multi_index(self, key: str, index):
setattr(self.attrs, f"{key}_nlevels", index.nlevels)

for i, (lev, level_codes, name) in enumerate(
Expand All @@ -2848,9 +2859,7 @@ def write_multi_index(self, key, index):
"Saving a MultiIndex with an extension dtype is not supported."
)
level_key = f"{key}_level{i}"
conv_level = _convert_index(
level_key, lev, self.encoding, self.errors, self.format_type
)
conv_level = _convert_index(level_key, lev, self.encoding, self.errors)
self.write_array(level_key, conv_level.values)
node = getattr(self.group, level_key)
node._v_attrs.kind = conv_level.kind
Expand All @@ -2863,7 +2872,7 @@ def write_multi_index(self, key, index):
label_key = f"{key}_label{i}"
self.write_array(label_key, level_codes)

def read_multi_index(self, key, **kwargs) -> MultiIndex:
def read_multi_index(self, key: str, **kwargs) -> MultiIndex:
nlevels = getattr(self.attrs, f"{key}_nlevels")

levels = []
Expand All @@ -2884,7 +2893,7 @@ def read_multi_index(self, key, **kwargs) -> MultiIndex:
)

def read_index_node(
self, node, start: Optional[int] = None, stop: Optional[int] = None
self, node: "Node", start: Optional[int] = None, stop: Optional[int] = None
):
data = node[start:stop]
# If the index was an empty array write_array_empty() will
Expand Down Expand Up @@ -3349,7 +3358,7 @@ def values_cols(self) -> List[str]:
""" return a list of my values cols """
return [i.cname for i in self.values_axes]

def _get_metadata_path(self, key) -> str:
def _get_metadata_path(self, key: str) -> str:
""" return the metadata pathname for this key """
group = self.group._v_pathname
return f"{group}/meta/{key}/meta"
Expand Down Expand Up @@ -3706,9 +3715,7 @@ def create_axes(

if i in axes:
name = obj._AXIS_NAMES[i]
new_index = _convert_index(
name, a, self.encoding, self.errors, self.format_type
)
new_index = _convert_index(name, a, self.encoding, self.errors)
new_index.axis = i
index_axes_map[i] = new_index

Expand Down Expand Up @@ -4573,10 +4580,10 @@ def _set_tz(values, tz, preserve_UTC: bool = False, coerce: bool = False):
return values


def _convert_index(name: str, index, encoding=None, errors="strict", format_type=None):
def _convert_index(name: str, index: Index, encoding=None, errors="strict"):
assert isinstance(name, str)

index_name = getattr(index, "name", None)
index_name = index.name

if isinstance(index, DatetimeIndex):
converted = index.asi8
Expand Down