Delgan / loguru

Python logging made (stupidly) simple
MIT License
19.99k stars 701 forks source link

What is the recommended way to 'type hint' a loguru logger being passed around or returned by a function? #1110

Open epicwhale opened 7 months ago

epicwhale commented 7 months ago

Wondering, how do you typehint a logger being passed around in code?

def my_function(a, ctx_logger: ????):
     ctx_logger.debug(...)

I tried using :Logger by importing from loguru import Logger but it gives me a "ImportError: cannot import name 'Logger' from 'loguru'" error

Couldn't find a clear answer here either: https://stackoverflow.com/questions/66411218/type-hint-for-returning-loguru-logger

epicwhale commented 7 months ago

the only workaround I figured so far is:

from loguru import logger

Logger = type(logger)

def process_data(data: str, logger: Logger) -> None:
    ...
changchiyou commented 7 months ago
  1. Improvement of your workaround:

    https://github.com/Delgan/loguru/blob/70e9df2d5d8cd86873456cd88cc45411681aefa6/loguru/__init__.py#L12

    image

  2. (Recommand) Please refer to https://loguru.readthedocs.io/en/stable/api/type_hints.html# :

    image
epicwhale commented 7 months ago

good shout, the from loguru._logger import Logger approach seems like the least ugliest of the lot :)

Delgan commented 7 months ago

Actually, you should preferably not use from loguru._logger import Logger. This is an internal type that is not supposed to be exposed publicly. You'll also miss many of the other types listed in the documentation: Type hints.

You're facing ImportError because the Loguru types being defined in a stub file, they're only accessible to type checkers, not at run-time.

See this answer for more details: https://github.com/Delgan/loguru/issues/1101#issuecomment-2027991074

The following solution should work fine:

import loguru

def my_function(a, ctx_logger: "loguru.Logger"):
     ctx_logger.debug(...)

Alternatively:

from __future__ import annotations

from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from loguru import Logger

def my_function(a, ctx_logger: Logger):
     ctx_logger.debug(...)