-
Notifications
You must be signed in to change notification settings - Fork 794
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
**Public API is unchanged** Core changes are to simplify testing and extension: - `_readers.py` -> `_reader.py` - w/ two new support modules `_constraints`, and `_readimpl` - Functions (`BaseImpl`) are declared with what they support (`include`) and restrictions (`exclude`) on that subset - Transforms a lot of the imperative logic into set operations - Greatly improved `pyarrow` support - Utilize schema - Provides additional fallback `.json` implementations - `_stdlib_read_json_to_arrow` finally resolves `"movies.json"` issue
- Loading branch information
1 parent
d3b3ef2
commit b606a7d
Showing
8 changed files
with
1,260 additions
and
686 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
"""Set-like guards for matching metadata to an implementation.""" | ||
|
||
from __future__ import annotations | ||
|
||
from collections.abc import Set | ||
from itertools import chain | ||
from typing import TYPE_CHECKING, Any | ||
|
||
from narwhals.stable import v1 as nw | ||
|
||
if TYPE_CHECKING: | ||
import sys | ||
from collections.abc import Iterable, Iterator | ||
|
||
from altair.datasets._typing import Metadata | ||
|
||
if sys.version_info >= (3, 12): | ||
from typing import Unpack | ||
else: | ||
from typing_extensions import Unpack | ||
if sys.version_info >= (3, 10): | ||
from typing import TypeAlias | ||
else: | ||
from typing_extensions import TypeAlias | ||
|
||
__all__ = [ | ||
"Items", | ||
"MetaIs", | ||
"is_arrow", | ||
"is_csv", | ||
"is_json", | ||
"is_meta", | ||
"is_not_tabular", | ||
"is_parquet", | ||
"is_spatial", | ||
"is_tsv", | ||
] | ||
|
||
Items: TypeAlias = Set[tuple[str, Any]] | ||
|
||
|
||
class MetaIs(Set[tuple[str, Any]]): | ||
_requires: frozenset[tuple[str, Any]] | ||
|
||
def __init__(self, kwds: frozenset[tuple[str, Any]], /) -> None: | ||
object.__setattr__(self, "_requires", kwds) | ||
|
||
@classmethod | ||
def from_metadata(cls, meta: Metadata, /) -> MetaIs: | ||
return cls(frozenset(meta.items())) | ||
|
||
def to_metadata(self) -> Metadata: | ||
if TYPE_CHECKING: | ||
|
||
def collect(**kwds: Unpack[Metadata]) -> Metadata: | ||
return kwds | ||
|
||
return collect(**dict(self)) | ||
return dict(self) | ||
|
||
def to_expr(self) -> nw.Expr: | ||
return nw.all_horizontal(nw.col(name) == val for name, val in self) | ||
|
||
def isdisjoint(self, other: Iterable[Any]) -> bool: | ||
return super().isdisjoint(other) | ||
|
||
def issubset(self, other: Iterable[Any]) -> bool: | ||
return self._requires.issubset(other) | ||
|
||
def __call__(self, meta: Items, /) -> bool: | ||
return self._requires <= meta | ||
|
||
def __hash__(self) -> int: | ||
return hash(self._requires) | ||
|
||
def __contains__(self, x: object) -> bool: | ||
return self._requires.__contains__(x) | ||
|
||
def __iter__(self) -> Iterator[tuple[str, Any]]: | ||
yield from self._requires | ||
|
||
def __len__(self) -> int: | ||
return self._requires.__len__() | ||
|
||
def __setattr__(self, name: str, value: Any): | ||
msg = ( | ||
f"{type(self).__name__!r} is immutable.\n" | ||
f"Could not assign self.{name} = {value}" | ||
) | ||
raise TypeError(msg) | ||
|
||
def __repr__(self) -> str: | ||
items = dict(self) | ||
if not items: | ||
contents = "<placeholder>" | ||
elif suffix := items.pop("suffix", None): | ||
contents = ", ".join( | ||
chain([f"'*{suffix}'"], (f"{k}={v!r}" for k, v in items.items())) | ||
) | ||
else: | ||
contents = ", ".join(f"{k}={v!r}" for k, v in items.items()) | ||
return f"is_meta({contents})" | ||
|
||
|
||
def is_meta(**kwds: Unpack[Metadata]) -> MetaIs: | ||
return MetaIs.from_metadata(kwds) | ||
|
||
|
||
is_csv = is_meta(suffix=".csv") | ||
is_json = is_meta(suffix=".json") | ||
is_tsv = is_meta(suffix=".tsv") | ||
is_arrow = is_meta(suffix=".arrow") | ||
is_parquet = is_meta(suffix=".parquet") | ||
is_spatial = is_meta(is_spatial=True) | ||
is_not_tabular = is_meta(is_tabular=False) |
Oops, something went wrong.