Skip to content
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

TypeError: unhashable type: 'instancemethod' #77576

Closed
siming85 mannequin opened this issue Apr 30, 2018 · 6 comments
Closed

TypeError: unhashable type: 'instancemethod' #77576

siming85 mannequin opened this issue Apr 30, 2018 · 6 comments
Labels
3.7 (EOL) end of life 3.8 only security fixes type-bug An unexpected behavior, bug, or error

Comments

@siming85
Copy link
Mannequin

siming85 mannequin commented Apr 30, 2018

BPO 33395
Nosy @tiran, @bitdancer, @siming85

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields:

assignee = None
closed_at = <Date 2018-05-01.16:42:17.869>
created_at = <Date 2018-04-30.20:39:51.085>
labels = ['3.8', 'type-bug', '3.7']
title = "TypeError: unhashable type: 'instancemethod'"
updated_at = <Date 2018-05-01.16:42:17.868>
user = 'https://github.com/siming85'

bugs.python.org fields:

activity = <Date 2018-05-01.16:42:17.868>
actor = 'r.david.murray'
assignee = 'none'
closed = True
closed_date = <Date 2018-05-01.16:42:17.869>
closer = 'r.david.murray'
components = []
creation = <Date 2018-04-30.20:39:51.085>
creator = 'siming85'
dependencies = []
files = []
hgrepos = []
issue_num = 33395
keywords = []
message_count = 6.0
messages = ['315964', '315975', '315979', '315996', '316003', '316004']
nosy_count = 3.0
nosy_names = ['christian.heimes', 'r.david.murray', 'siming85']
pr_nums = []
priority = 'normal'
resolution = 'third party'
stage = 'resolved'
status = 'closed'
superseder = None
type = 'behavior'
url = 'https://bugs.python.org/issue33395'
versions = ['Python 3.5', 'Python 3.6', 'Python 3.7', 'Python 3.8']

@siming85
Copy link
Mannequin Author

siming85 mannequin commented Apr 30, 2018

in Python 3.5 it the pprint.PrettyPrinter mechanism got an overhaul, relying on PrettyPrinter._dispatch dict-lookup based on obj.__repr__ type.

This breaks any Cythonized 3rd party libraries that used to be pretty-printable in Python3.4.

type(object).__repr__
<instancemethod __repr__ at 0x10cf2a618>

since instancemethod_hash function has been commented out:

oddly the behavior is different between Linux and Mac.

The same object in Linux returns cyfunction, and is hashable,
where as under the same CPython version in Mac, it returns instancemethod, rendering it unhashable.
(based on Cython 0.27.3)

note that this isn't exactly something related directly to the implementation of Cython.

the old logic in Python <3.4 pprint was not pretty (pun not intended), but relied solely on type checking,
where as the new implementation depends on hashing, which introduces this bug.

@siming85 siming85 mannequin added type-crash A hard crash of the interpreter, possibly with a core dump 3.7 (EOL) end of life 3.8 only security fixes labels Apr 30, 2018
@bitdancer
Copy link
Member

The non-hashable case should be handled by a default function, I would think. It should be fairly straightforward to come up with a reproducer that does not involve cython, which I think would be the first step.

@siming85
Copy link
Mannequin Author

siming85 mannequin commented May 1, 2018

having a tough time trying to reproduce this issue in pure python.

any clue as to how to create a __repr__ that's unhashable?

class UnhashableRepr(dict):
    __repr__ = _testcapi.instancemethod(dict.__repr__)

doesn't work because that turns into a <slot wrapper '__repr__' of 'dict' objects> which becomes hashable.

i'd love to provide a patch, seems trivial to fix, but wouldn't want to do so without some tests.

@bitdancer
Copy link
Member

Ah, in the absence of a traceback I think I misunderstood the problem (I failed to actually look at the code :)

Given what you say about the slotwrapper, I'm not sure, but I'm guessing that that means cython isn't using the PyInstanceMethod_Type as intended. That doesn't mean it can't be fixed (though if true it makes it less likely that we'll fix it, unfortunately), but you'll have to figure out what the difference is between how it is used by cython and cpython. I've nosied Christian, maybe he'll remember why the hash is commented out.

@siming85
Copy link
Mannequin Author

siming85 mannequin commented May 1, 2018

i just discovered cython v0.28 no longer creates instancemethod, so this bug should technically no longer show up after upgrading cython.
(related cython bug cython/cython#2105)

so the question remains - is it a good idea to assume all type(obj).__repr__ is hashable?

if so, we can close this bug.

@bitdancer
Copy link
Member

Functions/methods should be immutable, so yes, I think it is a safe assumption that they should be hashable, and a bug if they are not. I seem to vaguely recall that there is some other part of the cpython machinery that depend on being able to test function/method equality and assumes that they are immutable, which implies they should be hashable.

I'll close this; Christian can reopen it if he thinks there is an actual bug lurking here.

@bitdancer bitdancer added type-bug An unexpected behavior, bug, or error and removed type-crash A hard crash of the interpreter, possibly with a core dump labels May 1, 2018
@ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.7 (EOL) end of life 3.8 only security fixes type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

No branches or pull requests

1 participant