Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
e0805cf1
Commit
e0805cf1
authored
Apr 10, 2016
by
Serhiy Storchaka
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Issue #26719: More efficient formatting of ints and floats in json.
parent
fc435118
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
14 additions
and
62 deletions
+14
-62
Lib/json/encoder.py
Lib/json/encoder.py
+10
-10
Modules/_json.c
Modules/_json.c
+4
-52
No files found.
Lib/json/encoder.py
View file @
e0805cf1
...
...
@@ -32,7 +32,6 @@ for i in range(0x20):
#ESCAPE_DCT.setdefault(chr(i), '
\\
u
%
04
x
' % (i,))
INFINITY = float('
inf
')
FLOAT_REPR = repr
def py_encode_basestring(s):
"""Return a JSON representation of a Python string
...
...
@@ -221,7 +220,7 @@ class JSONEncoder(object):
_encoder = encode_basestring
def floatstr(o, allow_nan=self.allow_nan,
_repr=
FLOAT_REPR
, _inf=INFINITY, _neginf=-INFINITY):
_repr=
float.__repr__
, _inf=INFINITY, _neginf=-INFINITY):
# Check for specials. Note that this type of test is processor
# and/or platform-specific, so do tests which don't depend on the
# internals.
...
...
@@ -268,6 +267,7 @@ def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
list=list,
str=str,
tuple=tuple,
_intstr=int.__str__,
):
if _indent is not None and not isinstance(_indent, str):
...
...
@@ -309,10 +309,10 @@ def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
# Subclasses of int/float may override __str__, but we still
# want to encode them as integers/floats in JSON. One example
# within the standard library is IntEnum.
yield buf +
str(int(value)
)
yield buf +
_intstr(value
)
elif isinstance(value, float):
# see comment above for int
yield buf + _floatstr(
float(value)
)
yield buf + _floatstr(
value
)
else:
yield buf
if isinstance(value, (list, tuple)):
...
...
@@ -359,7 +359,7 @@ def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
# also allow them. Many encoders seem to do something like this.
elif isinstance(key, float):
# see comment for int/float in _make_iterencode
key = _floatstr(
float(key)
)
key = _floatstr(
key
)
elif key is True:
key = 'true'
elif key is False:
...
...
@@ -368,7 +368,7 @@ def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
key = 'null'
elif isinstance(key, int):
# see comment for int/float in _make_iterencode
key =
str(int(key)
)
key =
_intstr(key
)
elif _skipkeys:
continue
else:
...
...
@@ -389,10 +389,10 @@ def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
yield 'false'
elif isinstance(value, int):
# see comment for int/float in _make_iterencode
yield
str(int(value)
)
yield
_intstr(value
)
elif isinstance(value, float):
# see comment for int/float in _make_iterencode
yield _floatstr(
float(value)
)
yield _floatstr(
value
)
else:
if isinstance(value, (list, tuple)):
chunks = _iterencode_list(value, _current_indent_level)
...
...
@@ -419,10 +419,10 @@ def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
yield 'false'
elif isinstance(o, int):
# see comment for int/float in _make_iterencode
yield
str(int(o)
)
yield
_intstr(o
)
elif isinstance(o, float):
# see comment for int/float in _make_iterencode
yield _floatstr(
float(o)
)
yield _floatstr(
o
)
elif isinstance(o, (list, tuple)):
yield from _iterencode_list(o, _current_indent_level)
elif isinstance(o, dict):
...
...
Modules/_json.c
View file @
e0805cf1
...
...
@@ -116,8 +116,6 @@ raise_errmsg(char *msg, PyObject *s, Py_ssize_t end);
static
PyObject
*
encoder_encode_string
(
PyEncoderObject
*
s
,
PyObject
*
obj
);
static
PyObject
*
encoder_encode_long
(
PyEncoderObject
*
s
UNUSED
,
PyObject
*
obj
);
static
PyObject
*
encoder_encode_float
(
PyEncoderObject
*
s
,
PyObject
*
obj
);
#define S_CHAR(c) (c >= ' ' && c <= '~' && c != '\\' && c != '"')
...
...
@@ -1444,39 +1442,10 @@ _encoded_const(PyObject *obj)
}
}
static
PyObject
*
encoder_encode_long
(
PyEncoderObject
*
s
UNUSED
,
PyObject
*
obj
)
{
/* Return the JSON representation of a PyLong and PyLong subclasses.
Calls int() on PyLong subclasses in case the str() was changed.
Added specifically to deal with IntEnum. See Issue18264. */
PyObject
*
encoded
,
*
longobj
;
if
(
PyLong_CheckExact
(
obj
))
{
encoded
=
PyObject_Str
(
obj
);
}
else
{
longobj
=
PyNumber_Long
(
obj
);
if
(
longobj
==
NULL
)
{
PyErr_SetString
(
PyExc_ValueError
,
"Unable to coerce int subclass to int"
);
return
NULL
;
}
encoded
=
PyObject_Str
(
longobj
);
Py_DECREF
(
longobj
);
}
return
encoded
;
}
static
PyObject
*
encoder_encode_float
(
PyEncoderObject
*
s
,
PyObject
*
obj
)
{
/* Return the JSON representation of a PyFloat.
Modified to call float() on float subclasses in case the subclass
changes the repr. See Issue18264. */
PyObject
*
encoded
,
*
floatobj
;
/* Return the JSON representation of a PyFloat. */
double
i
=
PyFloat_AS_DOUBLE
(
obj
);
if
(
!
Py_IS_FINITE
(
i
))
{
if
(
!
s
->
allow_nan
)
{
...
...
@@ -1496,24 +1465,7 @@ encoder_encode_float(PyEncoderObject *s, PyObject *obj)
return
PyUnicode_FromString
(
"NaN"
);
}
}
/* coerce float subclasses to float (primarily for Enum) */
if
(
PyFloat_CheckExact
(
obj
))
{
/* Use a better float format here? */
encoded
=
PyObject_Repr
(
obj
);
}
else
{
floatobj
=
PyNumber_Float
(
obj
);
if
(
floatobj
==
NULL
)
{
PyErr_SetString
(
PyExc_ValueError
,
"Unable to coerce float subclass to float"
);
return
NULL
;
}
encoded
=
PyObject_Repr
(
floatobj
);
Py_DECREF
(
floatobj
);
}
return
encoded
;
return
PyFloat_Type
.
tp_repr
(
obj
);
}
static
PyObject
*
...
...
@@ -1557,7 +1509,7 @@ encoder_listencode_obj(PyEncoderObject *s, _PyAccu *acc,
return
_steal_accumulate
(
acc
,
encoded
);
}
else
if
(
PyLong_Check
(
obj
))
{
PyObject
*
encoded
=
encoder_encode_long
(
s
,
obj
);
PyObject
*
encoded
=
PyLong_Type
.
tp_str
(
obj
);
if
(
encoded
==
NULL
)
return
-
1
;
return
_steal_accumulate
(
acc
,
encoded
);
...
...
@@ -1722,7 +1674,7 @@ encoder_listencode_dict(PyEncoderObject *s, _PyAccu *acc,
goto
bail
;
}
else
if
(
PyLong_Check
(
key
))
{
kstr
=
encoder_encode_long
(
s
,
key
);
kstr
=
PyLong_Type
.
tp_str
(
key
);
if
(
kstr
==
NULL
)
{
goto
bail
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment