bpo-1617161: Make the hash and equality of methods not depending on the value of self. by serhiy-storchaka · Pull Request #7848 · python/cpython (original) (raw)

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 andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Conversation5 Commits4 Checks0 Files changed

Conversation

This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters

[ Show hidden characters]({{ revealButtonHref }})

serhiy-storchaka

https://bugs.python.org/issue1617161

@serhiy-storchaka

…he value of self.

pablogsal

return -1;
}
x = _Py_HashPointer(a->m_self);
if (x == -1)

Choose a reason for hiding this comment

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

Does this need braces according to PEP7?

Choose a reason for hiding this comment

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

Right. Although this is an old code, just unindented.

But actually this check is not needed because _Py_HashPointer() never returns -1.

@serhiy-storchaka

ZackerySpytz

y = PyObject_Hash(a->im_func);
if (y == -1)

Choose a reason for hiding this comment

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

PyObject_Hash() can return -1.

Choose a reason for hiding this comment

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

Good catch!

@serhiy-storchaka

@jdemeyer

I find this quite confusing:

The hash of :class:`BuiltinMethodType` instances (methods of built-in
classes) no longer depends on the hash of *self*.

It does depend on the hash of id(self), it would be good to mention this in the NEWS.

@serhiy-storchaka

rco-odoo added a commit to odoo-dev/odoo that referenced this pull request

Sep 1, 2020

@rco-odoo

Python 3.8 changed the equality rules for bound methods to be based on the identity of the receiver (__self__) rather than its equality. This means that in 3.7, methods from different instances will compare (and hash) equal, thereby landing in the same map "slot", but that isn't the case in 3.8.

While it's usually not relevant, it's an issue for GroupCalls which is indexed by a function: in 3.7, that being a method from recordsets comparing equal will deduplicate them, but not anymore in 3.8, leading to duplicated callbacks (exactly the thing GroupCalls aims to avoid).

Also, the API of GroupCalls turned out to be unusual and weird. The bug above is fixed by using a plain list for callbacks, thereby avoiding comparisons between registered functions. The API is now:

callbacks.add(func)     # add func to callbacks
callbacks.run()         # run all callbacks in addition order
callbacks.clear()       # remove all callbacks

In order to handle aggregated data, the callbacks object provides a dictionary callbacks.data that any callback function can freely use. For the sake of consistency, the callbacks.data dict is automatically cleared upon execution of callbacks.

Discovered by @william-andre

Related to odoo#56583

References:

robodoo pushed a commit to odoo/odoo that referenced this pull request

Sep 2, 2020

@rco-odoo

Python 3.8 changed the equality rules for bound methods to be based on the identity of the receiver (__self__) rather than its equality. This means that in 3.7, methods from different instances will compare (and hash) equal, thereby landing in the same map "slot", but that isn't the case in 3.8.

While it's usually not relevant, it's an issue for GroupCalls which is indexed by a function: in 3.7, that being a method from recordsets comparing equal will deduplicate them, but not anymore in 3.8, leading to duplicated callbacks (exactly the thing GroupCalls aims to avoid).

Also, the API of GroupCalls turned out to be unusual and weird. The bug above is fixed by using a plain list for callbacks, thereby avoiding comparisons between registered functions. The API is now:

callbacks.add(func)     # add func to callbacks
callbacks.run()         # run all callbacks in addition order
callbacks.clear()       # remove all callbacks

In order to handle aggregated data, the callbacks object provides a dictionary callbacks.data that any callback function can freely use. For the sake of consistency, the callbacks.data dict is automatically cleared upon execution of callbacks.

Discovered by @william-andre

Related to #56583

References:

closes #56748

Related: odoo/enterprise#12763 Signed-off-by: Raphael Collet (rco) rco@openerp.com

rco-odoo added a commit to odoo-dev/odoo that referenced this pull request

Sep 2, 2020

@rco-odoo

Python 3.8 changed the equality rules for bound methods to be based on the identity of the receiver (__self__) rather than its equality. This means that in 3.7, methods from different instances will compare (and hash) equal, thereby landing in the same map "slot", but that isn't the case in 3.8.

While it's usually not relevant, it's an issue for GroupCalls which is indexed by a function: in 3.7, that being a method from recordsets comparing equal will deduplicate them, but not anymore in 3.8, leading to duplicated callbacks (exactly the thing GroupCalls aims to avoid).

Also, the API of GroupCalls turned out to be unusual and weird. The bug above is fixed by using a plain list for callbacks, thereby avoiding comparisons between registered functions. The API is now:

callbacks.add(func)     # add func to callbacks
callbacks.run()         # run all callbacks in addition order
callbacks.clear()       # remove all callbacks

In order to handle aggregated data, the callbacks object provides a dictionary callbacks.data that any callback function can freely use. For the sake of consistency, the callbacks.data dict is automatically cleared upon execution of callbacks.

Discovered by @william-andre

Related to odoo#56583

References:

X-original-commit: a3a4d14

robodoo pushed a commit to odoo/odoo that referenced this pull request

Sep 3, 2020

@rco-odoo

Python 3.8 changed the equality rules for bound methods to be based on the identity of the receiver (__self__) rather than its equality. This means that in 3.7, methods from different instances will compare (and hash) equal, thereby landing in the same map "slot", but that isn't the case in 3.8.

While it's usually not relevant, it's an issue for GroupCalls which is indexed by a function: in 3.7, that being a method from recordsets comparing equal will deduplicate them, but not anymore in 3.8, leading to duplicated callbacks (exactly the thing GroupCalls aims to avoid).

Also, the API of GroupCalls turned out to be unusual and weird. The bug above is fixed by using a plain list for callbacks, thereby avoiding comparisons between registered functions. The API is now:

callbacks.add(func)     # add func to callbacks
callbacks.run()         # run all callbacks in addition order
callbacks.clear()       # remove all callbacks

In order to handle aggregated data, the callbacks object provides a dictionary callbacks.data that any callback function can freely use. For the sake of consistency, the callbacks.data dict is automatically cleared upon execution of callbacks.

Discovered by @william-andre

Related to #56583

References:

closes #56960

X-original-commit: a3a4d14 Related: odoo/enterprise#12899 Signed-off-by: Raphael Collet (rco) rco@openerp.com

rco-odoo added a commit to odoo-dev/odoo that referenced this pull request

Sep 3, 2020

@rco-odoo

Python 3.8 changed the equality rules for bound methods to be based on the identity of the receiver (__self__) rather than its equality. This means that in 3.7, methods from different instances will compare (and hash) equal, thereby landing in the same map "slot", but that isn't the case in 3.8.

While it's usually not relevant, it's an issue for GroupCalls which is indexed by a function: in 3.7, that being a method from recordsets comparing equal will deduplicate them, but not anymore in 3.8, leading to duplicated callbacks (exactly the thing GroupCalls aims to avoid).

Also, the API of GroupCalls turned out to be unusual and weird. The bug above is fixed by using a plain list for callbacks, thereby avoiding comparisons between registered functions. The API is now:

callbacks.add(func)     # add func to callbacks
callbacks.run()         # run all callbacks in addition order
callbacks.clear()       # remove all callbacks

In order to handle aggregated data, the callbacks object provides a dictionary callbacks.data that any callback function can freely use. For the sake of consistency, the callbacks.data dict is automatically cleared upon execution of callbacks.

Discovered by @william-andre

Related to odoo#56583

References:

X-original-commit: a986f49

robodoo pushed a commit to odoo/odoo that referenced this pull request

Sep 3, 2020

@rco-odoo

Python 3.8 changed the equality rules for bound methods to be based on the identity of the receiver (__self__) rather than its equality. This means that in 3.7, methods from different instances will compare (and hash) equal, thereby landing in the same map "slot", but that isn't the case in 3.8.

While it's usually not relevant, it's an issue for GroupCalls which is indexed by a function: in 3.7, that being a method from recordsets comparing equal will deduplicate them, but not anymore in 3.8, leading to duplicated callbacks (exactly the thing GroupCalls aims to avoid).

Also, the API of GroupCalls turned out to be unusual and weird. The bug above is fixed by using a plain list for callbacks, thereby avoiding comparisons between registered functions. The API is now:

callbacks.add(func)     # add func to callbacks
callbacks.run()         # run all callbacks in addition order
callbacks.clear()       # remove all callbacks

In order to handle aggregated data, the callbacks object provides a dictionary callbacks.data that any callback function can freely use. For the sake of consistency, the callbacks.data dict is automatically cleared upon execution of callbacks.

Discovered by @william-andre

Related to #56583

References:

X-original-commit: a986f49

fw-bot pushed a commit to odoo-dev/odoo that referenced this pull request

Sep 3, 2020

@rco-odoo

Python 3.8 changed the equality rules for bound methods to be based on the identity of the receiver (__self__) rather than its equality. This means that in 3.7, methods from different instances will compare (and hash) equal, thereby landing in the same map "slot", but that isn't the case in 3.8.

While it's usually not relevant, it's an issue for GroupCalls which is indexed by a function: in 3.7, that being a method from recordsets comparing equal will deduplicate them, but not anymore in 3.8, leading to duplicated callbacks (exactly the thing GroupCalls aims to avoid).

Also, the API of GroupCalls turned out to be unusual and weird. The bug above is fixed by using a plain list for callbacks, thereby avoiding comparisons between registered functions. The API is now:

callbacks.add(func)     # add func to callbacks
callbacks.run()         # run all callbacks in addition order
callbacks.clear()       # remove all callbacks

In order to handle aggregated data, the callbacks object provides a dictionary callbacks.data that any callback function can freely use. For the sake of consistency, the callbacks.data dict is automatically cleared upon execution of callbacks.

Discovered by @william-andre

Related to odoo#56583

References:

X-original-commit: d4b2e92

robodoo pushed a commit to odoo/odoo that referenced this pull request

Sep 3, 2020

@rco-odoo

Python 3.8 changed the equality rules for bound methods to be based on the identity of the receiver (__self__) rather than its equality. This means that in 3.7, methods from different instances will compare (and hash) equal, thereby landing in the same map "slot", but that isn't the case in 3.8.

While it's usually not relevant, it's an issue for GroupCalls which is indexed by a function: in 3.7, that being a method from recordsets comparing equal will deduplicate them, but not anymore in 3.8, leading to duplicated callbacks (exactly the thing GroupCalls aims to avoid).

Also, the API of GroupCalls turned out to be unusual and weird. The bug above is fixed by using a plain list for callbacks, thereby avoiding comparisons between registered functions. The API is now:

callbacks.add(func)     # add func to callbacks
callbacks.run()         # run all callbacks in addition order
callbacks.clear()       # remove all callbacks

In order to handle aggregated data, the callbacks object provides a dictionary callbacks.data that any callback function can freely use. For the sake of consistency, the callbacks.data dict is automatically cleared upon execution of callbacks.

Discovered by @william-andre

Related to #56583

References:

X-original-commit: d4b2e92