Skip to content

Conversation

@orenmn
Copy link
Contributor

@orenmn orenmn commented Sep 18, 2017

  • in _json.c: add a check whether encoder() hasn't returned a string.
  • in test_json/test_speedups.py: add a test to verify that the assertion failure is no more, and that the patch doesn't break anything when encoder() fails.

https://bugs.python.org/issue31505

None)

@test.support.cpython_only
def test_issue31505(self):
Copy link
Member

Choose a reason for hiding this comment

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

I think this can be named test_bad_str_encoder.

b"\xCD\x7D\x3D\x4E\x12\x4C\xF9\x79\xD7\x52\xBA\x82\xF2\x27\x4A\x7D\xA0\xCA\x75",
None)

@test.support.cpython_only
Copy link
Member

Choose a reason for hiding this comment

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

I think this test should be passed on other implementations that have compatible c_make_encoder.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

i thought about using test.support.get_attribute() to check whether c_make_encoder() is available, but test_make_encoder() just uses it, and would have failed if it hadn't existed.

maybe we can assume that every other C implementations implements test_make_encoder()?

Copy link
Member

Choose a reason for hiding this comment

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

I think that if other C implementation doesn't implement test_make_encoder() we should get a request for making this test optional.

def test_make_encoder(self):
self.assertRaises(TypeError, self.json.encoder.c_make_encoder,
(True, False),
b"\xCD\x7D\x3D\x4E\x12\x4C\xF9\x79\xD7\x52\xBA\x82\xF2\x27\x4A\x7D\xA0\xCA\x75",
Copy link
Member

Choose a reason for hiding this comment

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

This isn't related to this issue, but it seems to me that TypeError is raised for different cause than was originally in this test. This test doesn't work as intended.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

IIUC, Victor wrote this test to verify that the interpreter doesn't crash (as part of https://bugs.python.org/issue6986, as originally PyArg_ParseTupleAndKeywords() was given actual fields of the new PyEncoderObject, instead of temp vars), so raising a TypeError is the wanted outcome here.
maybe we can just change the name of the test to 'test_issue6986' (as it tests only this specific issue)?
and maybe do the same for test_make_scanner()?
anyway, I guess any such change should be in a PR referring to bpo-6986..

Copy link
Member

Choose a reason for hiding this comment

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

Seems your are right. Thank you for a reference.

# receives a bad encoder() argument.
def _bad_encoder1(*args):
return None
enc = self.json.encoder.c_make_encoder(None, None, _bad_encoder1, None,
Copy link
Member

Choose a reason for hiding this comment

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

Use more meaningful arguments. Otherwise TypeError could be raised for different reason (for example if default is not a callable).

c_make_encoder(None, default, _bad_encoder1, None, ': ', ', ', False, False, False)

def test_issue31505(self):
# There shouldn't be an assertion failure in case c_make_encoder()
# receives a bad encoder() argument.
def _bad_encoder1(*args):
Copy link
Member

Choose a reason for hiding this comment

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

No need to use starting underscore. This is a local name.

enc = self.json.encoder.c_make_encoder(None, None, _bad_encoder1, None,
'foo', 'bar', None, None, None)
with self.assertRaises(TypeError):
enc(obj='spam', _current_indent_level=4)
Copy link
Member

Choose a reason for hiding this comment

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

Why keyword arguments are used? In the code an encoder is called with positional arguments.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

no reason, my bad.

return s->fast_encode(NULL, obj);
else
return PyObject_CallFunctionObjArgs(s->encoder, obj, NULL);
encoded = PyObject_CallFunctionObjArgs(s->encoder, obj, NULL);
Copy link
Member

Choose a reason for hiding this comment

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

Add braces around return above.

Copy link
Member

@serhiy-storchaka serhiy-storchaka left a comment

Choose a reason for hiding this comment

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

LGTM.

I prefer different form for assertions, but will merge the PR in any case.

bad_encoder1, None, ': ', ', ',
False, False, False)
with self.assertRaises(TypeError):
enc('spam', 4)
Copy link
Member

Choose a reason for hiding this comment

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

This can be written without context manager:

self.assertRaises(TypeError, enc, 'spam', 4)

I prefer this form for simple function calls.

@serhiy-storchaka serhiy-storchaka added needs backport to 2.7 type-bug An unexpected behavior, bug, or error labels Sep 24, 2017
@serhiy-storchaka serhiy-storchaka merged commit 2b382dd into python:master Sep 24, 2017
@miss-islington
Copy link
Contributor

Thanks @orenmn for the PR, and @serhiy-storchaka for merging it 🌮🎉.. I'm working now to backport this PR to: 2.7, 3.6.
🐍🍒⛏🤖

@miss-islington
Copy link
Contributor

Thanks @orenmn for the PR, and @serhiy-storchaka for merging it 🌮🎉.. I'm working now to backport this PR to: 2.7, 3.6.
🐍🍒⛏🤖 I'm not a witch! I'm not a witch!

@miss-islington
Copy link
Contributor

Thanks @orenmn for the PR, and @serhiy-storchaka for merging it 🌮🎉.. I'm working now to backport this PR to: 2.7, 3.6.
🐍🍒⛏🤖

@miss-islington
Copy link
Contributor

Thanks @orenmn for the PR, and @serhiy-storchaka for merging it 🌮🎉.. I'm working now to backport this PR to: 2.7, 3.6.
🐍🍒⛏🤖

@miss-islington
Copy link
Contributor

Sorry @orenmn and @serhiy-storchaka, I had trouble checking out the 2.7 backport branch.
Please backport using cherry_picker on command line.
cherry_picker 2b382dd6121bb1e4b75470fb3ef8555665df3eb6 2.7

@bedevere-bot
Copy link

GH-3777 is a backport of this pull request to the 3.6 branch.

miss-islington pushed a commit to miss-islington/cpython that referenced this pull request Sep 27, 2017
…_encoder() received a bad encoder() argument. (pythonGH-3643)

(cherry picked from commit 2b382dd)
serhiy-storchaka pushed a commit that referenced this pull request Sep 27, 2017
…_encoder() received a bad encoder() argument. (GH-3643) (#3777)

(cherry picked from commit 2b382dd)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type-bug An unexpected behavior, bug, or error

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants