Skip to content

Commit

Permalink
0.11.0 (#163)
Browse files Browse the repository at this point in the history
* πŸ“ Add testimonials in README.md

* βœ… Fix test coverage

* βœ… Fix test coverage

* πŸ“ Add backend badges in README

* πŸ› Load entrypoint plugins only when APIs are called

* πŸ’₯ Rename `other` module to `misc`

* πŸ”– 0.11.0
  • Loading branch information
pwwang authored Dec 15, 2022
1 parent 326c00b commit f04c67d
Show file tree
Hide file tree
Showing 21 changed files with 92 additions and 59 deletions.
1 change: 1 addition & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ exclude_lines =
if TYPE_CHECKING:
omit =
datar/datasets.py
*/site-packages/*
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@ pip install -U datar[pandas]
# More backends support will be added in the future
```

## Backends

|Repo|Badges|
|-|-|
|[datar-numpy][1]|![3] ![18]|
|[datar-pandas][2]|![4] ![19]|

## Example usage

```python
Expand Down Expand Up @@ -107,6 +114,15 @@ iris >> pull(f.Sepal_Length) >> dist_plot()

![example](./example2.png)

## Testimonials

[@coforfe](https://github.com/coforfe):
> Thanks for your excellent package to port R (`dplyr`) flow of processing to Python. I have been using other alternatives, and yours is the one that offers the most extensive and equivalent to what is possible now with `dplyr`.
[1]: https://github.com/pwwang/datar-numpy
[2]: https://github.com/pwwang/datar-pandas
[3]: https://img.shields.io/codacy/coverage/0a7519dad44246b6bab30576895f6766?style=flat-square
[4]: https://img.shields.io/codacy/coverage/45f4ea84ae024f1a8cf84be54dd144f7?style=flat-square
[5]: https://pwwang.github.io/datar/
[6]: https://img.shields.io/pypi/v/datar?style=flat-square
[7]: https://pypi.org/project/datar/
Expand All @@ -120,3 +136,5 @@ iris >> pull(f.Sepal_Length) >> dist_plot()
[15]: https://pwwang.github.io/datar/reference-maps/ALL/
[16]: https://pwwang.github.io/datar/notebooks/across/
[17]: https://pwwang.github.io/datar/api/datar/
[18]: https://img.shields.io/pypi/v/datar-numpy?style=flat-square
[19]: https://img.shields.io/pypi/v/datar-pandas?style=flat-square
2 changes: 1 addition & 1 deletion datar/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from .core.defaults import f
from .core.options import options, get_option, options_context

__version__ = "0.10.3"
__version__ = "0.11.0"


def get_versions(prnt: bool = True) -> _Mapping[str, str]:
Expand Down
3 changes: 2 additions & 1 deletion datar/all.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

_locs = locals()

from .core import load_plugins as _
from .core.defaults import f
from .core.import_names_conflict import (
handle_import_names_conflict as _handle_import_names_conflict,
Expand All @@ -12,7 +13,7 @@
from .forcats import *
from .tibble import *
from .tidyr import *
from .other import *
from .misc import *

_locs.update(
{
Expand Down
File renamed without changes.
3 changes: 2 additions & 1 deletion datar/base.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from .core.plugin import plugin as _plugin

from .core.load_plugins import plugin as _plugin
from .apis.base import *

locals().update(_plugin.hooks.base_api())
Expand Down
3 changes: 2 additions & 1 deletion datar/core/import_names_conflict.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ def handle_import_names_conflict(imports, conflict_names):
`sum` to `sum_`.
"""
_import_names_conflict = get_option("import_names_conflict")
if _import_names_conflict == "underscore_suffixed":
if _import_names_conflict == "underscore_suffixed": # pragma: no cover
# Test in subprocess.Popen
return [name for name in imports if not name.startswith("_")], None

import sys
Expand Down
23 changes: 23 additions & 0 deletions datar/core/load_plugins.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from pipda import register_array_ufunc

from .options import get_option
from .plugin import plugin


def _array_ufunc_to_register(ufunc, x, *args, **kwargs):
"""Register the array ufunc to pipda"""
from ..apis.misc import array_ufunc

return array_ufunc(
x,
ufunc,
*args,
**kwargs,
__backend=array_ufunc.backend,
)


plugin.load_entrypoints(only=get_option("backends"))

plugin.hooks.setup()
register_array_ufunc(_array_ufunc_to_register)
26 changes: 2 additions & 24 deletions datar/core/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@
from typing import Any, List, Mapping, Tuple, Callable

from simplug import Simplug, SimplugResult, makecall
from pipda import register_array_ufunc

from .options import get_option

plugin = Simplug("datar")

Expand All @@ -19,19 +16,6 @@ def _collect(calls: List[Tuple[Callable, Tuple, Mapping]]) -> Mapping[str, Any]:
return collected


def _array_ufunc_to_register(ufunc, x, *args, **kwargs):
"""Register the array ufunc to pipda"""
from ..apis.other import array_ufunc

return array_ufunc(
x,
ufunc,
*args,
**kwargs,
__backend=array_ufunc.backend,
)


@plugin.spec
def setup():
"""Initialize the backend"""
Expand Down Expand Up @@ -73,8 +57,8 @@ def tidyr_api():


@plugin.spec(result=_collect)
def other_api():
"""What is implemented the other APIs."""
def misc_api():
"""What is implemented the misc APIs."""


@plugin.spec(result=SimplugResult.SINGLE)
Expand All @@ -85,9 +69,3 @@ def c_getitem(item):
@plugin.spec(result=SimplugResult.SINGLE)
def operate(op: str, x: Any, y: Any = None):
"""Operate on x and y"""


plugin.load_entrypoints(only=get_option("backends"))

plugin.hooks.setup()
register_array_ufunc(_array_ufunc_to_register)
2 changes: 1 addition & 1 deletion datar/data/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def load_dataset(name: str, __backend: str = None):

def __getattr__(name: str):
# mkapi accesses quite a lot of attributes starting with _
if not name.isidentifier() or name.startswith("__"):
if not name.isidentifier() or name.startswith("__"): # pragma: no cover
raise AttributeError(name)

return load_dataset(name.lower())
3 changes: 2 additions & 1 deletion datar/dplyr.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from .core.plugin import plugin as _plugin

from .core.load_plugins import plugin as _plugin
from .apis.dplyr import *

locals().update(_plugin.hooks.dplyr_api())
Expand Down
3 changes: 2 additions & 1 deletion datar/forcats.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from .core.plugin import plugin as _plugin

from .core.load_plugins import plugin as _plugin
from .apis.forcats import *

_additional_imports = _plugin.hooks.forcats_api()
Expand Down
4 changes: 4 additions & 0 deletions datar/misc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from .core.load_plugins import plugin as _plugin

_additional_imports = _plugin.hooks.misc_api()
locals().update(_additional_imports)
4 changes: 0 additions & 4 deletions datar/other.py

This file was deleted.

3 changes: 2 additions & 1 deletion datar/tibble.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from .core.plugin import plugin as _plugin

from .core.load_plugins import plugin as _plugin
from .apis.tibble import *

_additional_imports = _plugin.hooks.tibble_api()
Expand Down
3 changes: 2 additions & 1 deletion datar/tidyr.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from .core.plugin import plugin as _plugin

from .core.load_plugins import plugin as _plugin
from .apis.tidyr import *

_additional_imports = _plugin.hooks.tidyr_api()
Expand Down
6 changes: 6 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Change Log

## 0.11.0

- πŸ“ Add testimonials and backend badges in README.md
- πŸ› Load entrypoint plugins only when APIs are called (#162)
- πŸ’₯ Rename `other` module to `misc`

## 0.10.3

- ⬆️ Bump simplug to 0.2.2
Expand Down
14 changes: 7 additions & 7 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "datar"
version = "0.10.3"
version = "0.11.0"
description = "A Grammar of Data Manipulation in python"
authors = ["pwwang <[email protected]>"]
license = "MIT"
Expand All @@ -13,8 +13,8 @@ python = "^3.7.1"
simplug = "^0.2.2"
pipda = "^0.11"
python-simpleconf = {version = "^0.5", extras = ["toml"]}
datar-numpy = {version = "^0.0", optional = true}
datar-pandas = {version = "^0.1", optional = true}
datar-numpy = {version = "^0.1", optional = true}
datar-pandas = {version = "^0.2", optional = true}
# datar-polars = {version = "^0.0.0", optional = true}
# datar-pyarrow = {version = "^0.0.0", optional = true}

Expand Down
4 changes: 2 additions & 2 deletions tests/test_array_ufunc.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
from pipda import Context
from datar import f
from datar.core import plugin as _ # noqa: F401
from datar.apis.other import array_ufunc
from datar.apis.misc import array_ufunc


def test_default():
out = np.sqrt(f)._pipda_eval([1, 4, 9], Context.EVAL)
assert out.tolist() == [1, 2, 3]


def test_other_obj():
def test_misc_obj():
class Foo(list):
pass

Expand Down
20 changes: 10 additions & 10 deletions tests/test_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ def load_dataset(name, metadata):
return name * 2

@plugin.impl
def other_api():
from datar.apis.other import array_ufunc
def misc_api():
from datar.apis.misc import array_ufunc

@array_ufunc.register(object, backend="testplugin1")
def _array_ufunc(x, ufunc, *args, **kwargs):
Expand Down Expand Up @@ -86,23 +86,23 @@ def test_get_versions(with_test_plugin1, capsys):
assert "datar" in capsys.readouterr().out


def test_other_api(with_test_plugin1):
from datar import all, other
plugin.hooks.other_api()
def test_misc_api(with_test_plugin1):
from datar import all, misc
plugin.hooks.misc_api()
from importlib import reload
reload(other)
assert other.other_var == 1
reload(misc)
assert misc.other_var == 1

reload(all)
from datar.all import other_var
assert other_var == 1


def test_other_api_array_ufunc(with_test_plugin1):
def test_misc_api_array_ufunc(with_test_plugin1):
from datar import f
from datar.apis.other import array_ufunc
from datar.apis.misc import array_ufunc

plugin.hooks.other_api()
plugin.hooks.misc_api()

with pytest.warns(MultiImplementationsWarning):
out = np.sqrt(f)._pipda_eval([3, 12, 27], Context.EVAL)
Expand Down

0 comments on commit f04c67d

Please sign in to comment.