Skip to content

BUG: pd.show_versions: json.decoder.JSONDecodeError #39766

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

Merged
merged 7 commits into from
Feb 22, 2021
Merged
1 change: 1 addition & 0 deletions doc/source/whatsnew/v1.3.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,7 @@ Other
- :class:`Styler` rendered HTML output minor alterations to support w3 good code standard (:issue:`39626`)
- Bug in :class:`Styler` where rendered HTML was missing a column class identifier for certain header cells (:issue:`39716`)
- Bug in :meth:`DataFrame.equals`, :meth:`Series.equals`, :meth:`Index.equals` with object-dtype containing ``np.datetime64("NaT")`` or ``np.timedelta64("NaT")`` (:issue:`39650`)
- Bug in :func:`pandas.util.show_versions` where console JSON output was not proper JSON (:issue:`39701`)


.. ---------------------------------------------------------------------------
Expand Down
64 changes: 60 additions & 4 deletions pandas/tests/util/test_show_versions.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
import json
import os
import re

import pytest

from pandas.util._print_versions import (
_get_dependency_info,
_get_sys_info,
)

import pandas as pd


Expand All @@ -26,11 +33,47 @@
"ignore:Distutils:UserWarning"
)
@pytest.mark.filterwarnings("ignore:Setuptools is replacing distutils:UserWarning")
def test_show_versions(capsys):
def test_show_versions(tmpdir):
# GH39701
as_json = os.path.join(tmpdir, "test_output.json")

pd.show_versions(as_json=as_json)

with open(as_json) as fd:
# check if file output is valid JSON, will raise an exception if not
result = json.load(fd)

# Basic check that each version element is found in output
expected = {
"system": _get_sys_info(),
"dependencies": _get_dependency_info(),
}

assert result == expected


def test_show_versions_console_json(capsys):
# GH39701
pd.show_versions(as_json=True)
stdout = capsys.readouterr().out

# check valid json is printed to the console if as_json is True
result = json.loads(stdout)

# Basic check that each version element is found in output
expected = {
"system": _get_sys_info(),
"dependencies": _get_dependency_info(),
}

assert result == expected


def test_show_versions_console(capsys):
# gh-32041
pd.show_versions()
captured = capsys.readouterr()
result = captured.out
# GH39701
pd.show_versions(as_json=False)
result = capsys.readouterr().out

# check header
assert "INSTALLED VERSIONS" in result
Expand All @@ -44,3 +87,16 @@ def test_show_versions(capsys):

# check optional dependency
assert re.search(r"pyarrow\s*:\s([0-9\.]+|None)\n", result)


def test_json_output_match(capsys, tmpdir):
# GH39701
pd.show_versions(as_json=True)
result_console = capsys.readouterr().out

out_path = os.path.join(tmpdir, "test_json.json")
pd.show_versions(as_json=out_path)
with open(out_path) as out_fd:
result_file = out_fd.read()

assert result_console == result_file
2 changes: 1 addition & 1 deletion pandas/util/_print_versions.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ def show_versions(as_json: Union[str, bool] = False) -> None:
j = {"system": sys_info, "dependencies": deps}

if as_json is True:
print(j)
sys.stdout.writelines(json.dumps(j, indent=2))
else:
assert isinstance(as_json, str) # needed for mypy
with codecs.open(as_json, "wb", encoding="utf8") as f:
Expand Down