Skip to content
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

mypy error in the logger.configure(**config) example from the documentation #920

Closed
DeadNews opened this issue Jul 13, 2023 · 1 comment
Closed
Labels
upstream This is not our bug

Comments

@DeadNews
Copy link

DeadNews commented Jul 13, 2023

Looks like mypy issue.
But I'll leave it here just in case.


loguru/README.rst

Lines 368 to 376 in 493fb2d

# For scripts
config = {
"handlers": [
{"sink": sys.stdout, "format": "{time} - {message}"},
{"sink": "file.log", "serialize": True},
],
"extra": {"user": "someone"}
}
logger.configure(**config)

or

def test_dict_unpacking(writer):
config = {
"handlers": [{"sink": writer, "format": "{level.no} - {extra[x]} {extra[z]} - {message}"}],
"levels": [{"name": "test", "no": 30}],
"extra": {"x": 1, "y": 2, "z": 3},
}
logger.debug("NOPE")
logger.configure(**config)

Causing the following mypy error:

test.py:15:20: error: Argument 1 to "configure" of "Logger" has incompatible type "**dict[str, Collection[object]]"; expected "Sequence[dict[str, Any]]"  [arg-type]
test.py:15:20: error: Argument 1 to "configure" of "Logger" has incompatible type "**dict[str, Collection[object]]"; expected "Sequence[LevelConfig] | None"  [arg-type]
test.py:15:20: error: Argument 1 to "configure" of "Logger" has incompatible type "**dict[str, Collection[object]]"; expected "dict[Any, Any] | None"  [arg-type]
test.py:15:20: error: Argument 1 to "configure" of "Logger" has incompatible type "**dict[str, Collection[object]]"; expected "Callable[[Record], None] | None"  [arg-type]
test.py:15:20: error: Argument 1 to "configure" of "Logger" has incompatible type "**dict[str, Collection[object]]"; expected "Sequence[tuple[str | None, bool]] | None"  [arg-type]

This code does not cause any mypy errors:

import sys
from typing import Any

from loguru import logger

# For scripts
config: dict[str, Any] = {
    "handlers": [
        {"sink": sys.stdout, "format": "{time} - {message}"},
        {"sink": "file.log", "serialize": True},
    ],
    "extra": {"user": "someone"},
}
logger.configure(**config)

or

import sys
from collections.abc import Sequence
from typing import Any, TypedDict

from loguru import logger


class Config(TypedDict):
    """Loguru config."""

    handlers: Sequence[dict[str, Any]]
    extra: dict[Any, Any] | None


# For scripts
config: Config = {
    "handlers": [
        {"sink": sys.stdout, "format": "{time} - {message}"},
        {"sink": "file.log", "serialize": True},
    ],
    "extra": {"user": "someone"},
}
logger.configure(**config)

ref: python/mypy#14073, python/mypy#5382

@Delgan
Copy link
Owner

Delgan commented Jul 15, 2023

Thanks for the report and the Mypy references.

From what I understand there's not much we can do on the Loguru side unfortunately.

We could add a ConfigDict type publicly available. However, that doesn't solve the underlying problem. By default, an error will still be raised if the user does not explicitly add type-annotation to the config dictionary. Most importantly, this would only apply to configure(). If the user decides to use dict unpacking to call let's say logger.add(), they will face the same issue.
This implies that each method would need to define an associated TypedDict in case the user wanted to use dict unpacking, which becomes very cumbersome and not desirable.

We could also add a @overload to logger.configure() type hints but that means that some invalid configurations will no longer be detected.

It looks like Mypy should extract Literal from these dict when possible, and map them to the method signature (which is not trivial as Mypy can't guess the dict is immutable and not generic). At least, the config type should be infered as dict[str, Any] instead of current dict[str, Collection[object]]. Pyright seems to handle that correctly.

@Delgan Delgan added the upstream This is not our bug label Jul 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
upstream This is not our bug
Projects
None yet
Development

No branches or pull requests

2 participants