[issue12657] Cannot override JSON encoding of basic type subclasses
Samuel Freilich added the comment: A fully general solution for this might require a separate way to override the behavior for serializing dict keys (since those have to be serialized as strings). -- ___ Python tracker <https://bugs.python.org/issue12657> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue12657] Cannot override JSON encoding of basic type subclasses
Samuel Freilich added the comment: > A modern solution for this is to define a singledispatch function (with > implementations for your custom types) and pass it as the `default` parameter > to the dump functions. Does that work? I thought the default function only got called for non-serializable types. I'm running into the same issue with some code that would like to do round-trip serialization of a datastructure (which doesn't need 100% generality of supported values but would like to deal with the existing structure of types). Dealing with set is easy, for example: def default(obj): # pass to default parameter of json.dumps if isinstance(obj, frozenset): return {'_class': 'set', 'items': list(obj)} ... def object_hook(obj): # pass to object_hook parameter of json.loads if obj.get('_class') == 'set': return set(decoded_dict['items']) ... But you can't do the equivalent thing for tuple, even if you override encode/iterencode. It seems like the JSON module is making performance versus generality tradeoffs, it doesn't make a fresh call to encode/iterencode for every dict key/value for example. Which is fine, but it would be nice if there was a mode that allowed getting custom behavior for every type, taking the performance cost. -- nosy: +sfreilich ___ Python tracker <https://bugs.python.org/issue12657> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue31466] No easy way to change float formatting when subclassing encoder.JSONEncoder
Samuel Freilich added the comment: I think the less-minor issue, of which this is a small subset, is that JSONEncoder doesn't allow changing the behavior for default-serializable types at all. That means you can't choose to lose less information in round-trip serialization/deserialization, if that's what you want (e.g. there's no way to round-trip serialize a tuple with JSONEncoder, though it's trivial to do that for a set). -- nosy: +sfreilich ___ Python tracker <https://bugs.python.org/issue31466> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue41114] "TypeError: unhashable type" could often be more clear
Samuel Freilich added the comment: python-ideas thread: https://mail.python.org/archives/list/python-id...@python.org/thread/B6OMGYIM47OVGOCZLEY3MEUJDFURJRDV/ The most minimal ideas from that seem to be: 1. Maybe link to the glossary from the error message (if links to documentation in error messages are permissible). 2. Add a glossary entry for "unhashable" for the sake of completeness (similar to how there are entries for both "immutable" and "mutable"). -- ___ Python tracker <https://bugs.python.org/issue41114> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue41114] "TypeError: unhashable type" could often be more clear
Samuel Freilich added the comment: > I think it's reasonable to discuss the problem on python-ideas rather than on > a bugs issue, when it's not obvious what the right solution is. I did start a thread there. Don't object to that, if that's a better forum for this sort of thing. -- ___ Python tracker <https://bugs.python.org/issue41114> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue41114] "TypeError: unhashable type" could often be more clear
Samuel Freilich added the comment: > No minor tweak to the exception message will make this go away. For > understanding to occur, the only way to forward is to learn a bit about > hashability. That is a step that every beginner must take. This is a derisive and beginner-hostile response that ignores half of what's been said by other participants in this thread. > Also the error message itself is easily Googled Yeah, the first thing that comes up is ~4k Stack Overflow entries where people are really confused by the error message. -- ___ Python tracker <https://bugs.python.org/issue41114> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue41114] "TypeError: unhashable type" could often be more clear
Samuel Freilich added the comment: > The user already knows The example I link to in the initial description appears to be one case where the user does not in fact know. I do think context that this restriction applies to dict key in particular is very relevant. The line could use the same type for both the key and the value in a dict assignment, for example. > TypeError: unhashable type: 'dict'. Consider using an int, str, tuple, or > frozenset. That seems like a pretty reasonable wording, though I think mentioning "dictionary key" or "set item" specifically still helps. It could also link to the documentation directly: https://docs.python.org/3/glossary.html#term-hashable Though other error messages don't generally follow that pattern. > Saying it twice doesn't help. As the comment you were responding to noted, putting it in the type implies there might be additional information in documentation (or at least provides a place in documentation to put that information). TypeError is too general to say something about that specifically: https://docs.python.org/3/library/exceptions.html#TypeError -- ___ Python tracker <https://bugs.python.org/issue41114> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue41114] "TypeError: unhashable type" could often be more clear
New submission from Samuel Freilich : Currently, if you (for example) put a dict as a value in a set or key in a dict, you get: TypeError: unhashable type: 'dict' I'm pretty sure this wording goes back a long time, but I've noticed that Python beginners tend to find this really confusing. It fits into a pattern of error messages where you have to explain why the error message is worded the way it is after you explain why the error message occurs at all. There are many instances of: https://stackoverflow.com/questions/13264511/typeerror-unhashable-type-dict It would be clearer if the message was something like: TypeError: 'dict' can not be used as a set value because it is an unhashable type. (Or "dict key" instead of "set value".) The exception is raised in PyObject_Hash, so that doesn't have some of the context about how/why hash was called. That's called in a lot of places. Possibly, PyObject_Hash and PyObject_HashNotImplemented could take the format string passed to PyErr_Format as an optional second argument, defaulting to the current behavior? Then certain callers (in particular, the set and dict constructor, set and dict methods that add set values or add/modify dict keys) could provide clearer error messages. -- messages: 372366 nosy: sfreilich priority: normal severity: normal status: open title: "TypeError: unhashable type" could often be more clear type: behavior ___ Python tracker <https://bugs.python.org/issue41114> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue36871] Misleading error from unittest.mock's assert_has_calls
Change by Samuel Freilich : -- keywords: +patch pull_requests: +15942 stage: test needed -> patch review pull_request: https://github.com/python/cpython/pull/16361 ___ Python tracker <https://bugs.python.org/issue36871> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue36871] Misleading error from unittest.mock's assert_has_calls
Samuel Freilich added the comment: Check out my PR, which solves a much smaller issue: It fixes a bug in the exception raising logic in assert_has_calls (and _awaits) which makes complicated problems like the one you mention much harder to debug. Also it has tests! -- ___ Python tracker <https://bugs.python.org/issue36871> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue36871] Misleading error from unittest.mock's assert_has_calls
Samuel Freilich added the comment: Sure, but the bug in error-handling should still be fixed. Currently, if _call_matcher returns an exception, that's ignored by assert_has_calls, and the error message generated as a result is extremely misleading! -- ___ Python tracker <https://bugs.python.org/issue36871> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue36871] Misleading error from unittest.mock's assert_has_calls
Change by Samuel Freilich : -- pull_requests: +15630 pull_request: https://github.com/python/cpython/pull/16005 ___ Python tracker <https://bugs.python.org/issue36871> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue36871] Misleading error from unittest.mock's assert_has_calls
Samuel Freilich added the comment: This is still not totally fixed. This solves the underlying error with method specs, but not the bug that was causing the error-swallowing in assert_has_calls: https://github.com/python/cpython/blob/ee536b2020b1f0baad1286dbd4345e13870324af/Lib/unittest/mock.py#L2216 expected = [self._call_matcher(c) for c in calls] cause = expected if isinstance(expected, Exception) else None isinstance(expected, Exception) is never true, because expected is always a list. It should instead be: cause = next((e for e in expected if isinstance(e, Exception)), None) -- nosy: +sfreilich ___ Python tracker <https://bugs.python.org/issue36871> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue36366] Patcher stop method should be idempotent
New submission from Samuel Freilich : Currently, it's an error to call the stop() method of a patcher object created by mock.patch repeatedly: >>> patch = mock.patch.object(Foo, 'BAR', 'x') >>> patch.start() 'x' >>> patch.stop() >>> patch.stop() RuntimeError: stop called on unstarted patcher This causes unnecessary problems when test classes using mock.patch.stopall for cleanup are mixed with those cleaning up patches individually: class TestA(unittest.TestCase): def setUp(): patcher = mock.patch.object(...) self.mock_a = patcher.start() self.addCleanup(patcher.stop) ... class TestB(TestA): def setUp(): super().setUp() self.addCleanup(mock.patch.stopall) self.mock_b = mock.patch.object(...).start() ... This fails because mock.patch.stopall stops the patch set up in TestA.setUp(), then that raises an exception when it's stopped again. But why does patcher.stop() enforce that precondition? Wouldn't it be sufficient for it to just enforce the postcondition, that after stop() is called the patch is stopped()? That would make it easier to write test code which makes use of mock.patch.stopall, which allows the proper cleanup of patches to be configured much more concisely. -- messages: 338371 nosy: sfreilich priority: normal severity: normal status: open title: Patcher stop method should be idempotent ___ Python tracker <https://bugs.python.org/issue36366> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue35711] Print information about an unexpectedly pending error before crashing
New submission from Samuel Freilich : _PyObject_FastCallDict and _PyObject_FastCallKeywords assert that there is no pending exception before calling functions that might otherwise clobber the exception state. However, that doesn't produce very clear output for debugging, since the assert failure doesn't say anything about what the pending exception actually was. It would be better to print the pending exception first. -- messages: 333418 nosy: Samuel Freilich priority: normal severity: normal status: open title: Print information about an unexpectedly pending error before crashing ___ Python tracker <https://bugs.python.org/issue35711> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com