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

Instances bound methods with different memory addresses but sharing same id #77866

Closed
celicoo mannequin opened this issue May 29, 2018 · 2 comments
Closed

Instances bound methods with different memory addresses but sharing same id #77866

celicoo mannequin opened this issue May 29, 2018 · 2 comments
Labels
interpreter-core (Objects, Python, Grammar, and Parser dirs) type-bug An unexpected behavior, bug, or error

Comments

@celicoo
Copy link
Mannequin

celicoo mannequin commented May 29, 2018

BPO 33685
Nosy @stevendaprano, @celicoo

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-29.16:46:29.722>
created_at = <Date 2018-05-29.16:28:20.576>
labels = ['interpreter-core', 'type-bug', 'invalid']
title = 'Instances bound methods with different memory addresses but sharing same id'
updated_at = <Date 2018-05-29.16:46:29.720>
user = 'https://github.com/celicoo'

bugs.python.org fields:

activity = <Date 2018-05-29.16:46:29.720>
actor = 'steven.daprano'
assignee = 'none'
closed = True
closed_date = <Date 2018-05-29.16:46:29.722>
closer = 'steven.daprano'
components = ['Interpreter Core']
creation = <Date 2018-05-29.16:28:20.576>
creator = 'celicoo'
dependencies = []
files = []
hgrepos = []
issue_num = 33685
keywords = []
message_count = 2.0
messages = ['318057', '318058']
nosy_count = 2.0
nosy_names = ['steven.daprano', 'celicoo']
pr_nums = []
priority = 'normal'
resolution = 'not a bug'
stage = 'resolved'
status = 'closed'
superseder = None
type = 'behavior'
url = 'https://bugs.python.org/issue33685'
versions = ['Python 3.6']

@celicoo
Copy link
Mannequin Author

celicoo mannequin commented May 29, 2018

Different instances should have different bound method ids, since they have different memory addresses, isn’t it? Example:

I have a class and two instances:

    class MyClass:
       def something():
          pass
    
    a = MyClass()
    b = MyClass()

If we print a.something and b.something, we can see that they have different memory addresses:

# a.something
<bound method MyClass.something of <main.MyClass object at 0x103438588>>

# b.something
<bound method MyClass.something of <main.MyClass object at 0x10342add8>>

This clear indicates that they aren’t the same, and we can confirm that comparing both using the is operator:

>>> a.something is b.something
False

But the identity of both indicates that they are the same, according with the doc of is and id:

>>> id(a.something)
4350192008

>>> id(b.something)
4350192008

The documentation of is says:

The operators is and is not test for object identity: x is y is true if and only if x and y are the same object. x is not y yields the inverse truth value. [6]

ref: https://docs.python.org/2/reference/expressions.html#is

And the documentation of id says:

Return the “identity” of an object. This is an integer (or long integer) which is guaranteed to be unique and constant for this object during its lifetime. Two objects with non-overlapping lifetimes may have the same id() value.

CPython implementation detail: This is the address of the object in memory.

Thanks!

@celicoo celicoo mannequin added interpreter-core (Objects, Python, Grammar, and Parser dirs) type-bug An unexpected behavior, bug, or error labels May 29, 2018
@stevendaprano
Copy link
Member

ID numbers in Python are only guaranteed to be unique for the lifespan of the object. In CPython they can be re-used. (In other implementations, like Jython and IronPython, IDs are allocated as sequential numbers and won't be reused.)

The other fact you may be missing is that method objects are generated on the fly each time you look them up. So:

py> class X:
... def method(self): pass
...
py> x = X()
py> a = x.method
py> b = x.method
py> a is b
False

So your example is now understandable: you generate a method object, get its ID, and then the method object is garbage collected, allowing the ID to be reused. Which *in this case* it is. Whether it is or isn't re-used is an accident of implementation.

In other words: nothing to see here. Its not a bug, just the normal behaviour of IDs and garbage collection.

@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
interpreter-core (Objects, Python, Grammar, and Parser dirs) type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

No branches or pull requests

1 participant