Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: Delgan/loguru
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 0.7.0
Choose a base ref
...
head repository: Delgan/loguru
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 0.7.1
Choose a head ref

Commits on Apr 22, 2023

  1. Copy the full SHA
    9faba68 View commit details

Commits on Apr 25, 2023

  1. Copy the full SHA
    20cbb9e View commit details
  2. Fix invalid unit test for stub

    Delgan committed Apr 25, 2023
    Copy the full SHA
    b71a937 View commit details

Commits on Apr 28, 2023

  1. Copy the full SHA
    28749e7 View commit details
  2. Fix unit tests for Python 3.5

    Delgan committed Apr 28, 2023
    Copy the full SHA
    455808b View commit details

Commits on May 5, 2023

  1. Bump tox from 4.4.6 to 4.5.1 (#860)

    Bumps [tox](https://github.com/tox-dev/tox) from 4.4.6 to 4.5.1.
    - [Release notes](https://github.com/tox-dev/tox/releases)
    - [Changelog](https://github.com/tox-dev/tox/blob/main/docs/changelog.rst)
    - [Commits](tox-dev/tox@4.4.6...4.5.1)
    
    ---
    updated-dependencies:
    - dependency-name: tox
      dependency-type: direct:development
      update-type: version-update:semver-minor
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    dependabot[bot] authored May 5, 2023
    Copy the full SHA
    53093ac View commit details
  2. Bump pytest from 7.2.1 to 7.3.1 (#861)

    Bumps [pytest](https://github.com/pytest-dev/pytest) from 7.2.1 to 7.3.1.
    - [Release notes](https://github.com/pytest-dev/pytest/releases)
    - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
    - [Commits](pytest-dev/pytest@7.2.1...7.3.1)
    
    ---
    updated-dependencies:
    - dependency-name: pytest
      dependency-type: direct:development
      update-type: version-update:semver-minor
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    dependabot[bot] authored May 5, 2023
    Copy the full SHA
    18384c0 View commit details
  3. Bump pytest-mypy-plugins from 1.10.1 to 1.11.1 (#866)

    Bumps [pytest-mypy-plugins](https://github.com/TypedDjango/pytest-mypy-plugins) from 1.10.1 to 1.11.1.
    - [Release notes](https://github.com/TypedDjango/pytest-mypy-plugins/releases)
    - [Changelog](https://github.com/typeddjango/pytest-mypy-plugins/blob/master/CHANGELOG.md)
    - [Commits](typeddjango/pytest-mypy-plugins@1.10.1...1.11.1)
    
    ---
    updated-dependencies:
    - dependency-name: pytest-mypy-plugins
      dependency-type: direct:development
      update-type: version-update:semver-minor
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    dependabot[bot] authored May 5, 2023
    Copy the full SHA
    b919b33 View commit details
  4. Bump pre-commit from 3.2.1 to 3.3.1 (#865)

    Bumps [pre-commit](https://github.com/pre-commit/pre-commit) from 3.2.1 to 3.3.1.
    - [Release notes](https://github.com/pre-commit/pre-commit/releases)
    - [Changelog](https://github.com/pre-commit/pre-commit/blob/main/CHANGELOG.md)
    - [Commits](pre-commit/pre-commit@v3.2.1...v3.3.1)
    
    ---
    updated-dependencies:
    - dependency-name: pre-commit
      dependency-type: direct:development
      update-type: version-update:semver-minor
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    dependabot[bot] authored May 5, 2023
    Copy the full SHA
    c0911df View commit details

Commits on Jun 2, 2023

  1. Copy the full SHA
    4eba4bd View commit details
  2. Bump pytest-cov from 4.0.0 to 4.1.0 (#885)

    Bumps [pytest-cov](https://github.com/pytest-dev/pytest-cov) from 4.0.0 to 4.1.0.
    - [Changelog](https://github.com/pytest-dev/pytest-cov/blob/master/CHANGELOG.rst)
    - [Commits](pytest-dev/pytest-cov@v4.0.0...v4.1.0)
    
    ---
    updated-dependencies:
    - dependency-name: pytest-cov
      dependency-type: direct:development
      update-type: version-update:semver-minor
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    dependabot[bot] authored Jun 2, 2023
    Copy the full SHA
    d379fed View commit details

Commits on Jul 1, 2023

  1. Bump tox from 4.5.1 to 4.6.3 (#911)

    Bumps [tox](https://github.com/tox-dev/tox) from 4.5.1 to 4.6.3.
    - [Release notes](https://github.com/tox-dev/tox/releases)
    - [Changelog](https://github.com/tox-dev/tox/blob/main/docs/changelog.rst)
    - [Commits](tox-dev/tox@4.5.1...4.6.3)
    
    ---
    updated-dependencies:
    - dependency-name: tox
      dependency-type: direct:development
      update-type: version-update:semver-minor
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    dependabot[bot] authored Jul 1, 2023
    Copy the full SHA
    e1bb8a8 View commit details
  2. Bump pytest from 7.3.1 to 7.4.0 (#910)

    Bumps [pytest](https://github.com/pytest-dev/pytest) from 7.3.1 to 7.4.0.
    - [Release notes](https://github.com/pytest-dev/pytest/releases)
    - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
    - [Commits](pytest-dev/pytest@7.3.1...7.4.0)
    
    ---
    updated-dependencies:
    - dependency-name: pytest
      dependency-type: direct:development
      update-type: version-update:semver-minor
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    dependabot[bot] authored Jul 1, 2023
    Copy the full SHA
    0b50708 View commit details

Commits on Jul 3, 2023

  1. Copy the full SHA
    b36df95 View commit details

Commits on Jul 9, 2023

  1. Bump Mypy and update tests

    Delgan committed Jul 9, 2023
    Copy the full SHA
    edca423 View commit details
  2. Copy the full SHA
    5afeed8 View commit details
  3. Copy the full SHA
    2a35b87 View commit details

Commits on Jul 10, 2023

  1. Copy the full SHA
    c102e0a View commit details
  2. Copy the full SHA
    493fb2d View commit details

Commits on Jul 15, 2023

  1. Copy the full SHA
    4f5af16 View commit details

Commits on Jul 30, 2023

  1. Copy the full SHA
    0cd82d8 View commit details

Commits on Aug 6, 2023

  1. Bump pytest-mypy-plugins from 2.0.0 to 3.0.0 (#930)

    Bumps [pytest-mypy-plugins](https://github.com/TypedDjango/pytest-mypy-plugins) from 2.0.0 to 3.0.0.
    - [Release notes](https://github.com/TypedDjango/pytest-mypy-plugins/releases)
    - [Changelog](https://github.com/typeddjango/pytest-mypy-plugins/blob/master/CHANGELOG.md)
    - [Commits](typeddjango/pytest-mypy-plugins@2.0.0...3.0.0)
    
    ---
    updated-dependencies:
    - dependency-name: pytest-mypy-plugins
      dependency-type: direct:development
      update-type: version-update:semver-major
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    dependabot[bot] authored Aug 6, 2023
    Copy the full SHA
    d17ae01 View commit details

Commits on Aug 27, 2023

  1. Add note about security considerations in the Readme (#957)

    Co-authored-by: Andrew Edwards <edwards.andrew@heb.com>
    aedwardstx and Andrew Edwards authored Aug 27, 2023
    Copy the full SHA
    3876de0 View commit details

Commits on Aug 28, 2023

  1. Refactor "colorize" unit tests

    Delgan committed Aug 28, 2023
    Copy the full SHA
    857f7a5 View commit details

Commits on Aug 29, 2023

  1. Add support for Windows 10's ANSI/VT console (#935)

    Co-authored-by: Delgan <delgan.py@gmail.com>
    tunaflsh and Delgan authored Aug 29, 2023
    Copy the full SHA
    d37531b View commit details
  2. Copy the full SHA
    3941b78 View commit details
  3. Copy the full SHA
    ab26eb2 View commit details
  4. Copy the full SHA
    c9f7929 View commit details

Commits on Aug 31, 2023

  1. Copy the full SHA
    e49dfa5 View commit details
  2. Copy the full SHA
    2465fca View commit details
  3. Copy the full SHA
    de646c6 View commit details
  4. Copy the full SHA
    4c8ebe2 View commit details
  5. Copy the full SHA
    2718257 View commit details
  6. Copy the full SHA
    565a6f6 View commit details

Commits on Sep 1, 2023

  1. Copy the full SHA
    aeb6044 View commit details
  2. Bump tox from 4.6.3 to 4.11.0 (#965)

    Bumps [tox](https://github.com/tox-dev/tox) from 4.6.3 to 4.11.0.
    - [Release notes](https://github.com/tox-dev/tox/releases)
    - [Changelog](https://github.com/tox-dev/tox/blob/main/docs/changelog.rst)
    - [Commits](tox-dev/tox@4.6.3...4.11.0)
    
    ---
    updated-dependencies:
    - dependency-name: tox
      dependency-type: direct:development
      update-type: version-update:semver-minor
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    dependabot[bot] authored Sep 1, 2023
    Copy the full SHA
    6735db7 View commit details
  3. Bump sphinx-rtd-theme from 1.2.0 to 1.3.0 (#966)

    Bumps [sphinx-rtd-theme](https://github.com/readthedocs/sphinx_rtd_theme) from 1.2.0 to 1.3.0.
    - [Changelog](https://github.com/readthedocs/sphinx_rtd_theme/blob/master/docs/changelog.rst)
    - [Commits](readthedocs/sphinx_rtd_theme@1.2.0...1.3.0)
    
    ---
    updated-dependencies:
    - dependency-name: sphinx-rtd-theme
      dependency-type: direct:development
      update-type: version-update:semver-minor
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    dependabot[bot] authored Sep 1, 2023
    Copy the full SHA
    f5bfaf6 View commit details
  4. Copy the full SHA
    7fa0d15 View commit details

Commits on Sep 2, 2023

  1. Bump sphinx from 5.3.0 to 7.2.5 (#964)

    Bumps [sphinx](https://github.com/sphinx-doc/sphinx) from 5.3.0 to 7.2.5.
    - [Release notes](https://github.com/sphinx-doc/sphinx/releases)
    - [Changelog](https://github.com/sphinx-doc/sphinx/blob/master/CHANGES)
    - [Commits](sphinx-doc/sphinx@v5.3.0...v7.2.5)
    
    ---
    updated-dependencies:
    - dependency-name: sphinx
      dependency-type: direct:development
      update-type: version-update:semver-major
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    dependabot[bot] authored Sep 2, 2023
    Copy the full SHA
    f339282 View commit details

Commits on Sep 3, 2023

  1. Copy the full SHA
    901dc33 View commit details
  2. Copy the full SHA
    2c585a1 View commit details
  3. Copy the full SHA
    8c2044e View commit details
  4. Update "opener" docs to use safe permissions (#953)

    Co-authored-by: Delgan <delgan.py@gmail.com>
    quantumpacket and Delgan authored Sep 3, 2023
    Copy the full SHA
    80bcf4e View commit details

Commits on Sep 4, 2023

  1. Bump version to 0.7.1

    Delgan committed Sep 4, 2023
    Copy the full SHA
    5c7bc8b View commit details
Showing with 1,072 additions and 485 deletions.
  1. +1 −0 .github/workflows/tests.yml
  2. +6 −13 .pre-commit-config.yaml
  3. +16 −1 CHANGELOG.rst
  4. +16 −6 README.rst
  5. +8 −42 docs/resources/recipes.rst
  6. +1 −1 loguru/__init__.py
  7. +24 −20 loguru/__init__.pyi
  8. +13 −2 loguru/_colorama.py
  9. +2 −2 loguru/_colorizer.py
  10. +12 −5 loguru/_datetime.py
  11. +1 −0 loguru/_defaults.py
  12. +8 −11 loguru/_file_sink.py
  13. +16 −10 loguru/_handler.py
  14. +51 −17 loguru/_logger.py
  15. +21 −8 loguru/_recattrs.py
  16. +23 −14 loguru/_simple_sinks.py
  17. +6 −0 ruff.toml
  18. +9 −9 setup.py
  19. +27 −0 tests/conftest.py
  20. +2 −2 tests/test_add_option_backtrace.py
  21. +28 −194 tests/test_add_option_colorize.py
  22. +66 −0 tests/test_add_option_context.py
  23. +2 −2 tests/test_add_option_diagnose.py
  24. +23 −6 tests/test_add_option_enqueue.py
  25. +2 −2 tests/test_add_option_format.py
  26. +27 −9 tests/test_add_option_kwargs.py
  27. +2 −2 tests/test_add_option_serialize.py
  28. +265 −0 tests/test_colorama.py
  29. +1 −1 tests/test_contextualize.py
  30. +65 −6 tests/test_coroutine_sink.py
  31. +32 −1 tests/test_datetime.py
  32. +17 −17 tests/test_exceptions_catch.py
  33. +0 −1 tests/test_filesink_retention.py
  34. +92 −0 tests/test_filesink_rotation.py
  35. +2 −1 tests/test_formatting.py
  36. +4 −4 tests/test_interception.py
  37. +53 −43 tests/test_multiprocessing.py
  38. +4 −4 tests/test_opt.py
  39. +1 −1 tests/test_propagation.py
  40. +1 −1 tests/test_recattr.py
  41. +3 −3 tests/test_standard_handler.py
  42. +119 −9 tests/typesafety/test_logger.yml
  43. +0 −15 tox.ini
1 change: 1 addition & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -48,6 +48,7 @@ jobs:
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
with:
token: ${{ secrets.CODECOV_TOKEN }}
flags: ${{ matrix.os }}_${{ matrix.python-version }}
verbose: true
fail_ci_if_error: true
19 changes: 6 additions & 13 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -6,26 +6,19 @@ repos:
- id: trailing-whitespace
- id: check-added-large-files
- repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks
rev: v2.6.0
rev: v2.10.0
hooks:
- id: pretty-format-ini
args: [--autofix]
- id: pretty-format-yaml
args: [--autofix, --indent, '2']
- repo: https://github.com/pycqa/isort
rev: 5.12.0
hooks:
- id: isort
- repo: https://github.com/ambv/black
rev: 23.1.0
rev: 23.7.0
hooks:
- id: black
args: [-l, '100', --target-version, py35]
- repo: https://github.com/pycqa/flake8
rev: 6.0.0
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.0.286
hooks:
- id: flake8
args: [--exclude, tests/exceptions/source]
additional_dependencies:
- flake8-bugbear==23.1.20
- pep8-naming==0.13.3
- id: ruff
args: [--fix, --exit-non-zero-on-fix]
17 changes: 16 additions & 1 deletion CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
`0.7.1`_ (2023-09-04)
=====================

- Add a new ``context`` optional argument to ``logger.add()`` specifying ``multiprocessing`` context (like ``"spawn"`` or ``"fork"``) to be used internally instead of the default one (`#851 <https://github.com/Delgan/loguru/issues/851>`_).
- Add support for true colors on Windows using ANSI/VT console when available (`#934 <https://github.com/Delgan/loguru/issues/934>`_, thanks `@tunaflsh <https://github.com/tunaflsh>`_).
- Fix possible deadlock when calling ``logger.complete()`` with concurrent logging of an asynchronous sink (`#906 <https://github.com/Delgan/loguru/issues/906>`_).
- Fix file possibly rotating too early or too late when re-starting an application around midnight (`#894 <https://github.com/Delgan/loguru/issues/894>`_).
- Fix inverted ``"<hide>"`` and ``"<strike>"`` color tags (`#943 <https://github.com/Delgan/loguru/pull/943>`_, thanks `@tunaflsh <https://github.com/tunaflsh>`_).
- Fix possible untraceable errors raised when logging non-unpicklable ``Exception`` instances while using ``enqueue=True`` (`#329 <https://github.com/Delgan/loguru/issues/329>`_).
- Fix possible errors raised when logging non-picklable ``Exception`` instances while using ``enqueue=True`` (`#342 <https://github.com/Delgan/loguru/issues/342>`_, thanks `@ncoudene <https://github.com/ncoudene>`_).
- Fix missing seconds and microseconds when formatting timezone offset that requires such accuracy (`#961 <https://github.com/Delgan/loguru/issues/961>`_).
- Raise ``ValueError`` if an attempt to use nanosecond precision for time formatting is detected (`#855 <https://github.com/Delgan/loguru/issues/855>`_).


`0.7.0`_ (2023-04-10)
=====================

@@ -199,7 +213,8 @@
Initial release.


.. _Unreleased: https://github.com/delgan/loguru/compare/0.7.0...master
.. _Unreleased: https://github.com/delgan/loguru/compare/0.7.1...master
.. _0.7.1: https://github.com/delgan/loguru/releases/tag/0.7.1
.. _0.7.0: https://github.com/delgan/loguru/releases/tag/0.7.0
.. _0.6.0: https://github.com/delgan/loguru/releases/tag/0.6.0
.. _0.5.3: https://github.com/delgan/loguru/releases/tag/0.5.3
22 changes: 16 additions & 6 deletions README.rst
Original file line number Diff line number Diff line change
@@ -128,6 +128,9 @@ Take the tour
.. |better_exceptions| replace:: ``better_exceptions``
.. _better_exceptions: https://github.com/Qix-/better-exceptions

.. |loguru-config| replace:: ``loguru-config``
.. _loguru-config: https://github.com/erezinman/loguru-config

.. |notifiers| replace:: ``notifiers``
.. _notifiers: https://github.com/notifiers/notifiers

@@ -236,7 +239,8 @@ Logging exceptions that occur in your code is important to track bugs, but it's

The code::

logger.add("out.log", backtrace=True, diagnose=True) # Caution, may leak sensitive data in prod
# Caution, "diagnose=True" is the default and may leak sensitive data in prod
logger.add("out.log", backtrace=True, diagnose=True)

def func(a, b):
return a / b
@@ -274,6 +278,8 @@ Would result in:
Note that this feature won't work on default Python REPL due to unavailable frame data.

See also: `Security considerations when using Loguru <https://loguru.readthedocs.io/en/stable/resources/recipes.html#security-considerations-when-using-loguru>`_.


Structured logging as needed
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -375,12 +381,15 @@ Using the logger in your scripts is easy, and you can |configure|_ it at start.
}
logger.configure(**config)

# For libraries
# For libraries, should be your library's `__name__`
logger.disable("my_library")
logger.info("No matter added sinks, this message is not displayed")

# In your application, enable the logger in the library
logger.enable("my_library")
logger.info("This message however is propagated to the sinks")

For additional convenience, you can also use the |loguru-config|_ library to setup the ``logger`` directly from a configuration file.

Entirely compatible with standard logging
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -397,7 +406,7 @@ Need to propagate `Loguru` messages to standard `logging`?
::

class PropagateHandler(logging.Handler):
def emit(self, record):
def emit(self, record: logging.LogRecord) -> None:
logging.getLogger(record.name).handle(record)

logger.add(PropagateHandler(), format="{message}")
@@ -407,16 +416,17 @@ Want to intercept standard `logging` messages toward your `Loguru` sinks?
::

class InterceptHandler(logging.Handler):
def emit(self, record):
def emit(self, record: logging.LogRecord) -> None:
# Get corresponding Loguru level if it exists.
level: str | int
try:
level = logger.level(record.levelname).name
except ValueError:
level = record.levelno

# Find caller from where originated the logged message.
frame, depth = sys._getframe(6), 6
while frame and frame.f_code.co_filename == logging.__file__:
frame, depth = inspect.currentframe(), 0
while frame and (depth == 0 or frame.f_code.co_filename == logging.__file__):
frame = frame.f_back
depth += 1

50 changes: 8 additions & 42 deletions docs/resources/recipes.rst
Original file line number Diff line number Diff line change
@@ -14,6 +14,7 @@ Code snippets and recipes for ``loguru``
.. |contextlib.redirect_stdout| replace:: :func:`contextlib.redirect_stdout`
.. |copy.deepcopy| replace:: :func:`copy.deepcopy`
.. |os.fork| replace:: :func:`os.fork`
.. |os.umask| replace:: :func:`os.umask`
.. |multiprocessing| replace:: :mod:`multiprocessing`
.. |pickle| replace:: :mod:`pickle`
.. |traceback| replace:: :mod:`traceback`
@@ -457,15 +458,15 @@ Setting permissions on created log files

To set desired permissions on created log files, use the ``opener`` argument to pass in a custom opener with permissions octal::

os.umask(0) # Update the current umask (it's value is masked out from "os.open()" permissions)

def opener(file, flags):
return os.open(file, flags, 0o777)
return os.open(file, flags, 0o600) # read/write by owner only

logger.add("foo.log", rotation="100 kB", opener=opener)

When using an opener argument, all created log files including ones created during rotation will use the initially provided opener.

Note that the provided mode will be masked out by the OS `umask <https://en.wikipedia.org/wiki/Umask>`_ value (describing which bits are *not* to be set when creating a file or directory). This value is conventionally equals to ``0o022``, which means specifying a ``0o666`` mode will result in a ``0o666 - 0o022 = 0o644`` file permission in this case (which is actually the default). It is possible to change the umask value by first calling |os.umask|, but this needs to be done with careful consideration, as it changes the value globally and can cause security issues.


Preserving an ``opt()`` parameter for the whole module
------------------------------------------------------
@@ -1027,53 +1028,18 @@ The |multiprocessing| library is also commonly used to start a pool of workers u
Independently of the operating system, note that the process in which a handler is added with ``enqueue=True`` is in charge of the queue internally used. This means that you should avoid to ``.remove()`` such handler from the parent process is any child is likely to continue using it. More importantly, note that a |Thread| is started internally to consume the queue. Therefore, it is recommended to call |complete| before leaving |Process| to make sure the queue is left in a stable state.

Another thing to keep in mind when dealing with multiprocessing is the fact that handlers created with ``enqueue=True`` create a queue internally in the current multiprocessing context. If they are passed through to a subprocesses instantiated within a different context (e.g. with :code:`multiprocessing.get_context("spawn")` on linux, where the default context is :code:`"fork"`) it will most likely result in crashing the subprocess. This is also noted in the `python multiprocessing docs <https://docs.python.org/3/library/multiprocessing.html#contexts-and-start-methods>`_.

So, running this on linux where the default context is ``fork`` this will not work since the handler is added in a different context:
Another thing to keep in mind when dealing with multiprocessing is the fact that handlers created with ``enqueue=True`` create a queue internally in the default multiprocessing context. If they are passed through to a subprocesses instantiated within a different context (e.g. with ``multiprocessing.get_context("spawn")`` on linux, where the default context is ``"fork"``) it will most likely result in crashing the subprocess. This is also noted in the `python multiprocessing docs <https://docs.python.org/3/library/multiprocessing.html#contexts-and-start-methods>`_. To prevent any problems, you should specify the context to be used by Loguru while adding the handler. This can be done by passing the ``context`` argument to the ``add()`` method::


.. code::
# main.py
import multiprocessing
from loguru import logger
import workers_a
import workers_b

if __name__ == "__main__":
logger.remove()
logger.add("file.log", enqueue=True)
worker = workers_a.Worker()
with multiprocessing.get_context("spawn").Pool(4, initializer=worker.set_logger, initargs=(logger, )) as pool:
results = pool.map(worker.work, [1, 10, 100])
with multiprocessing.get_context("spawn").Pool(4, initializer=workers_b.set_logger, initargs=(logger, )) as pool:
results = pool.map(workers_b.work, [1, 10, 100])
logger.info("Done")
To fix this you can set the multiprocessing context globally so that the handler is created in the same context as the subprocesses run in:

.. code::
# main.py
import multiprocessing
from loguru import logger
import workers_a
import workers_b
if __name__ == "__main__":
multiprocessing.set_start_method("spawn")
context = multiprocessing.get_context("spawn")

logger.remove()
logger.add("file.log", enqueue=True)
logger.add("file.log", enqueue=True, context=context)

worker = workers_a.Worker()
with multiprocessing.Pool(4, initializer=worker.set_logger, initargs=(logger, )) as pool:
with context.Pool(4, initializer=worker.set_logger, initargs=(logger, )) as pool:
results = pool.map(worker.work, [1, 10, 100])
with multiprocessing.Pool(4, initializer=workers_b.set_logger, initargs=(logger, )) as pool:
results = pool.map(workers_b.work, [1, 10, 100])
logger.info("Done")
2 changes: 1 addition & 1 deletion loguru/__init__.py
Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@
from ._logger import Core as _Core
from ._logger import Logger as _Logger

__version__ = "0.7.0"
__version__ = "0.7.1"

__all__ = ["logger"]

44 changes: 24 additions & 20 deletions loguru/__init__.pyi
Original file line number Diff line number Diff line change
@@ -91,6 +91,7 @@ import sys
from asyncio import AbstractEventLoop
from datetime import datetime, time, timedelta
from logging import Handler
from multiprocessing.context import BaseContext
from types import TracebackType
from typing import (
Any,
@@ -246,6 +247,7 @@ class Logger:
backtrace: bool = ...,
diagnose: bool = ...,
enqueue: bool = ...,
context: Optional[Union[str, BaseContext]] = ...,
catch: bool = ...
) -> int: ...
@overload
@@ -261,6 +263,7 @@ class Logger:
backtrace: bool = ...,
diagnose: bool = ...,
enqueue: bool = ...,
context: Optional[Union[str, BaseContext]] = ...,
catch: bool = ...,
loop: Optional[AbstractEventLoop] = ...
) -> int: ...
@@ -277,6 +280,7 @@ class Logger:
backtrace: bool = ...,
diagnose: bool = ...,
enqueue: bool = ...,
context: Optional[Union[str, BaseContext]] = ...,
catch: bool = ...,
rotation: Optional[Union[str, int, time, timedelta, RotationFunction]] = ...,
retention: Optional[Union[str, int, timedelta, RetentionFunction]] = ...,
@@ -316,8 +320,8 @@ class Logger:
depth: int = ...,
ansi: bool = ...
) -> Logger: ...
def bind(__self, **kwargs: Any) -> Logger: ...
def contextualize(__self, **kwargs: Any) -> Contextualizer: ...
def bind(__self, **kwargs: Any) -> Logger: ... # noqa: N805
def contextualize(__self, **kwargs: Any) -> Contextualizer: ... # noqa: N805
def patch(self, patcher: PatcherFunction) -> Logger: ...
@overload
def level(self, name: str) -> Level: ...
@@ -367,43 +371,43 @@ class Logger:
chunk: int = ...
) -> Generator[Dict[str, Any], None, None]: ...
@overload
def trace(__self, __message: str, *args: Any, **kwargs: Any) -> None: ...
def trace(__self, __message: str, *args: Any, **kwargs: Any) -> None: ... # noqa: N805
@overload
def trace(__self, __message: Any) -> None: ...
def trace(__self, __message: Any) -> None: ... # noqa: N805
@overload
def debug(__self, __message: str, *args: Any, **kwargs: Any) -> None: ...
def debug(__self, __message: str, *args: Any, **kwargs: Any) -> None: ... # noqa: N805
@overload
def debug(__self, __message: Any) -> None: ...
def debug(__self, __message: Any) -> None: ... # noqa: N805
@overload
def info(__self, __message: str, *args: Any, **kwargs: Any) -> None: ...
def info(__self, __message: str, *args: Any, **kwargs: Any) -> None: ... # noqa: N805
@overload
def info(__self, __message: Any) -> None: ...
def info(__self, __message: Any) -> None: ... # noqa: N805
@overload
def success(__self, __message: str, *args: Any, **kwargs: Any) -> None: ...
def success(__self, __message: str, *args: Any, **kwargs: Any) -> None: ... # noqa: N805
@overload
def success(__self, __message: Any) -> None: ...
def success(__self, __message: Any) -> None: ... # noqa: N805
@overload
def warning(__self, __message: str, *args: Any, **kwargs: Any) -> None: ...
def warning(__self, __message: str, *args: Any, **kwargs: Any) -> None: ... # noqa: N805
@overload
def warning(__self, __message: Any) -> None: ...
def warning(__self, __message: Any) -> None: ... # noqa: N805
@overload
def error(__self, __message: str, *args: Any, **kwargs: Any) -> None: ...
def error(__self, __message: str, *args: Any, **kwargs: Any) -> None: ... # noqa: N805
@overload
def error(__self, __message: Any) -> None: ...
def error(__self, __message: Any) -> None: ... # noqa: N805
@overload
def critical(__self, __message: str, *args: Any, **kwargs: Any) -> None: ...
def critical(__self, __message: str, *args: Any, **kwargs: Any) -> None: ... # noqa: N805
@overload
def critical(__self, __message: Any) -> None: ...
def critical(__self, __message: Any) -> None: ... # noqa: N805
@overload
def exception(__self, __message: str, *args: Any, **kwargs: Any) -> None: ...
def exception(__self, __message: str, *args: Any, **kwargs: Any) -> None: ... # noqa: N805
@overload
def exception(__self, __message: Any) -> None: ...
def exception(__self, __message: Any) -> None: ... # noqa: N805
@overload
def log(
__self, __level: Union[int, str], __message: str, *args: Any, **kwargs: Any
__self, __level: Union[int, str], __message: str, *args: Any, **kwargs: Any # noqa: N805
) -> None: ...
@overload
def log(__self, __level: Union[int, str], __message: Any) -> None: ...
def log(__self, __level: Union[int, str], __message: Any) -> None: ... # noqa: N805
def start(self, *args: Any, **kwargs: Any) -> int: ...
def stop(self, *args: Any, **kwargs: Any) -> None: ...

15 changes: 13 additions & 2 deletions loguru/_colorama.py
Original file line number Diff line number Diff line change
@@ -46,10 +46,21 @@ def should_wrap(stream):

from colorama.win32 import winapi_test

return winapi_test()
if not winapi_test():
return False

try:
from colorama.winterm import enable_vt_processing
except ImportError:
return True

try:
return not enable_vt_processing(stream.fileno())
except Exception:
return True


def wrap(stream):
from colorama import AnsiToWin32

return AnsiToWin32(stream, convert=True, strip=False, autoreset=False).stream
return AnsiToWin32(stream, convert=True, strip=True, autoreset=False).stream
4 changes: 2 additions & 2 deletions loguru/_colorizer.py
Original file line number Diff line number Diff line change
@@ -10,8 +10,8 @@ class Style:
UNDERLINE = 4
BLINK = 5
REVERSE = 7
STRIKE = 8
HIDE = 9
HIDE = 8
STRIKE = 9
NORMAL = 22


Loading