"warning: mpd_setminalloc" caused by importing toml locally (in TomlConfigParser.read() method) · Issue #1084 · nedbat/coveragepy (original) (raw)

Describe the bug

This is an extremely corner case with a very simple solution --I think.

Under edge circumstances, I got this warning "_opt_bblocal_var_buildworker_ports_build_ports_lang_python38/python38/work/Python-3.8.7/Modules/_decimal/libmpdec/context.c:55: warning: mpd_setminalloc: ignoring request to set MPD_MINALLOC a second time".

This warning ultimately causes an exception:

Traceback (most recent call last):
  ...
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/coverage/control.py", line 195, in __init__
    self.config = read_coverage_config(
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/coverage/config.py", line 530, in read_coverage_config
    config_read = config.from_file(fname, our_file=our_file)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/coverage/config.py", line 275, in from_file
    files_read = cp.read(filename)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/coverage/tomlconfig.py", line 32, in read
    from coverage.optional import toml
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/coverage/optional.py", line 51, in <module>
    import toml
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/toml/__init__.py", line 6, in <module>
    from toml import encoder
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/toml/encoder.py", line 4, in <module>
    from decimal import Decimal
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/decimal.py", line 3, in <module>
    from _decimal import *
KeyError: 'numbers'

I do not really understand which is the cause of this warning (and the subsequent exception) in my code.

But I traced it to this piece of code in tomlconfig.py, line 32 (coverage 5.3.1): from coverage.optional import toml.

The issue is solved by removing this line and import coverage.optional.toml in the module scope --that is, moving from coverage.optional import toml out of the TomlConfigParser.read() method.

To Reproduce

This is a very extreme corner case. I really try to write a simple example to reproduce it, but I am not able to re-create the bug. Sorry about this.

Basically, I am try to test an invoke task --http://www.pyinvoke.org/-- that runs tests itself. Part of running tests via the invoke task is checking their coverage and print it out. The issue emerges when coverage.Coverage() is called in the invoke task method.

To make things even worse, the warning only appears when all project's tests --including the test that checks the invoke tasks-- are run via python -m unittest discover .... (Indeed, not proper unittest but a module that customises unittest for sub-tests counting).

I should mention that there is a pyproject.toml in the project.

Quite complicated to reproduce.

Normally, I do not submit such kind of almost-impossible-to-reproduce bug. But I find that solution is quite simple in this case, so I feel that it is fine to share it with you. Sorry for burdening you.

What version of Python are you using?
Python 3.8.7 - macOS-10.14.6-x86_64-i386-64bit

What version of coverage.py are you using?
coverage 5.3.1

What versions of what packages do you have installed?
(Some relevant packages)
coverage==5.3.1
invoke==1.4.1
toml==0.10.2

Expected behavior

Do not raise any warning or exception related to toml configuration.

Additional context

Thank you.