Skip to content

Commit

Permalink
fix(project): Make project.put work when called with keyword argume…
Browse files Browse the repository at this point in the history
…nts (#549)

Remove use of `singledispatchmethod`, which does not play well with
keyword arguments. Instead, manually check the type of argument `key`
and dispatch to `put_several` or to `put_one`, a new method which
contains the logic formerly in `put`.

Closes #539

- **Add failing test**
- **Add Project.put_one**
- **Make `put` point either to `put_one` or to `put_several`**

---------

Co-authored-by: Thomas S. <[email protected]>
  • Loading branch information
augustebaum and thomass-dev authored Oct 21, 2024
1 parent 4dafe41 commit 1527a1b
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 7 deletions.
52 changes: 45 additions & 7 deletions skore/src/skore/project.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
"""Define a Project."""

import logging
from functools import singledispatchmethod
from pathlib import Path
from typing import Any, Literal, Union
from typing import Any, Literal, Optional, Union

from skore.item import (
CrossValidationItem,
Expand Down Expand Up @@ -39,9 +38,49 @@ def __init__(
self.item_repository = item_repository
self.view_repository = view_repository

@singledispatchmethod
def put(self, key: str, value: Any, on_error: Literal["warn", "raise"] = "warn"):
"""Add a value to the Project.
def put(
self,
key: Union[str, dict[str, Any]],
value: Optional[Any] = None,
on_error: Literal["warn", "raise"] = "warn",
):
"""Add one or more key-value pairs to the Project.
If `key` is a string, then `put` adds the single `key`-`value` pair mapping to
the Project.
If `key` is a dict, it is interpreted as multiple key-value pairs to add to
the Project.
If `on_error` is "raise", any error stops the execution. If `on_error`
is "warn" (or anything other than "raise"), a warning is shown instead.
Parameters
----------
key : str | dict[str, Any]
The key to associate with `value` in the Project,
or dict of key-value pairs to add to the Project.
value : Any | None
The value to associate with `key` in the Project.
If `key` is a dict, this argument is ignored.
on_error : "warn" or "raise", optional
Upon error (e.g. if the key is not a string), whether to raise an error or
to print a warning. Default is "warn".
Raises
------
ProjectPutError
If the key-value pair(s) cannot be saved properly,
and `on_error` is "raise".
"""
if isinstance(key, dict):
self.put_several(key, on_error=on_error)
else:
self.put_one(key, value, on_error=on_error)

def put_one(
self, key: str, value: Any, on_error: Literal["warn", "raise"] = "warn"
):
"""Add a key-value pair to the Project.
If `on_error` is "raise", any error stops the execution. If `on_error`
is "warn" (or anything other than "raise"), a warning is shown instead.
Expand Down Expand Up @@ -75,7 +114,6 @@ def put(self, key: str, value: Any, on_error: Literal["warn", "raise"] = "warn")
f"due to the following error: {e}"
)

@put.register
def put_several(
self, key_to_value: dict, on_error: Literal["warn", "raise"] = "warn"
):
Expand All @@ -101,7 +139,7 @@ def put_several(
and `on_error` is "raise".
"""
for key, value in key_to_value.items():
self.put(key, value, on_error=on_error)
self.put_one(key, value, on_error=on_error)

def put_item(self, key: str, item: Item):
"""Add an Item to the Project."""
Expand Down
11 changes: 11 additions & 0 deletions skore/tests/unit/test_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,17 @@ def test_put(in_memory_project):
assert in_memory_project.list_item_keys() == ["key1", "key2", "key3", "key4"]


def test_put_kwargs(in_memory_project):
in_memory_project.put(key="key1", value=1)
assert in_memory_project.list_item_keys() == ["key1"]


def test_put_wrong_key_type(in_memory_project):
with pytest.raises(ProjectPutError):
in_memory_project.put(key=2, value=1, on_error="raise")
assert in_memory_project.list_item_keys() == []


def test_put_twice(in_memory_project):
in_memory_project.put("key2", 2)
in_memory_project.put("key2", 5)
Expand Down

0 comments on commit 1527a1b

Please sign in to comment.