Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion doc/source/whatsnew/v3.0.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ Other enhancements
- :class:`pandas.api.typing.FrozenList` is available for typing the outputs of :attr:`MultiIndex.names`, :attr:`MultiIndex.codes` and :attr:`MultiIndex.levels` (:issue:`58237`)
- :class:`pandas.api.typing.SASReader` is available for typing the output of :func:`read_sas` (:issue:`55689`)
- Added :meth:`.Styler.to_typst` to write Styler objects to file, buffer or string in Typst format (:issue:`57617`)
- Added functionality to support saving json without escaping forward slashes by adding to :meth:`DataFrame.to_json` (:issue:`61442`)
- Added missing :meth:`pandas.Series.info` to API reference (:issue:`60926`)
- :class:`pandas.api.typing.NoDefault` is available for typing ``no_default``
- :func:`DataFrame.to_excel` now raises an ``UserWarning`` when the character count in a cell exceeds Excel's limitation of 32767 characters (:issue:`56954`)
Expand Down Expand Up @@ -228,7 +229,6 @@ Other enhancements
- Support reading Stata 102-format (Stata 1) dta files (:issue:`58978`)
- Support reading Stata 110-format (Stata 7) dta files (:issue:`47176`)
- Switched wheel upload to **PyPI Trusted Publishing** (OIDC) for release-tag pushes in ``wheels.yml``. (:issue:`61718`)
-

.. ---------------------------------------------------------------------------
.. _whatsnew_300.notable_bug_fixes:
Expand Down
5 changes: 5 additions & 0 deletions pandas/core/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -2342,6 +2342,7 @@ def to_json(
indent: int | None = None,
storage_options: StorageOptions | None = None,
mode: Literal["a", "w"] = "w",
escape_forward_slashes: bool = True,
) -> str | None:
"""
Convert the object to a JSON string.
Expand Down Expand Up @@ -2429,6 +2430,9 @@ def to_json(
Accepted args are 'w' (writing) and 'a' (append) only.
mode='a' is only supported when lines is True and orient is 'records'.

escape_forward_slashes : bool, optional, default True
Remove backward slashes that get added in conversion to json.

Returns
-------
None or str
Expand Down Expand Up @@ -2629,6 +2633,7 @@ def to_json(
indent=indent,
storage_options=storage_options,
mode=mode,
escape_forward_slashes=escape_forward_slashes,
)

@final
Expand Down
20 changes: 20 additions & 0 deletions pandas/io/json/_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ def to_json(
indent: int = ...,
storage_options: StorageOptions = ...,
mode: Literal["a", "w"] = ...,
escape_forward_slashes: Literal[True, False] = ...,
) -> None: ...


Expand All @@ -133,6 +134,7 @@ def to_json(
indent: int = ...,
storage_options: StorageOptions = ...,
mode: Literal["a", "w"] = ...,
escape_forward_slashes: Literal[True, False] = ...,
) -> str: ...


Expand All @@ -151,6 +153,7 @@ def to_json(
indent: int = 0,
storage_options: StorageOptions | None = None,
mode: Literal["a", "w"] = "w",
escape_forward_slashes: Literal[True, False] = True,
) -> str | None:
if orient in ["records", "values"] and index is True:
raise ValueError(
Expand Down Expand Up @@ -218,6 +221,23 @@ def to_json(
) as handles:
handles.handle.write(s)
else:
if not escape_forward_slashes:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will only apply if you are not writing to a file.

pattern = r"\/"
i = 1
new_s = ""
skip = False
for letter in s:
if skip is False:
if letter + s[i] == pattern:
new_s = new_s + r"/"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For me, this shouldn't be done in python as a post-processing step. Ideally, you should change the behavior on the C implementation.

skip = True
else:
new_s = new_s + letter
else:
skip = False
if i < len(s) - 1:
i = i + 1
return new_s
return s
return None

Expand Down
19 changes: 19 additions & 0 deletions pandas/tests/io/json/test_pandas.py
Original file line number Diff line number Diff line change
Expand Up @@ -2286,6 +2286,25 @@ def test_to_json_ea_null():
assert result == expected


def test_to_json_escape_forward_slashes():
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you create a test that also escapes forward slash?

df = DataFrame(
{
"path1": Series(["/escape/three/slashes"], dtype="str"),
"path2": Series(["/"], dtype="str"),
"path3": Series(["ending/"], dtype="str"),
"path4": Series(["/beginning"], dtype="str"),
"path5": Series(["/multiples//multiple"], dtype="str"),
"path6": Series(["//"], dtype="str"),
}
)
result = df.to_json(orient="records", escape_forward_slashes=False)
expected1 = '[{"path1":"/escape/three/slashes","path2":"/","path3":"ending/"'
expected2 = ',"path4":"/beginning","path5":"/multiples//multiple","path6":"//"}]'
expected = expected1 + expected2

assert result == expected


def test_read_json_lines_rangeindex():
# GH 57429
data = """
Expand Down
Loading