[ python-Bugs-1267540 ] _register is not safe

SourceForge.net noreply at sourceforge.net
Wed Aug 24 07:34:43 CEST 2005


Bugs item #1267540, was opened at 2005-08-24 01:29
Message generated for change (Comment added) made by loewis
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1267540&group_id=5470

Please note that this message will contain a full copy of the comment thread,
including the initial issue submission, for this request,
not just the latest update.
Category: Tkinter
Group: Python 2.4
Status: Open
Resolution: None
Priority: 5
Submitted By: Russell Owen (reowen)
Assigned to: Martin v. Löwis (loewis)
Summary: _register is not safe

Initial Comment:
The _register function is not safe. It uses the following code to 
generate a unique string to identify a python callable entity:

 f = CallWrapper(func, subst, self).__call__
 name = repr(id(f))

It then adds the function name if func has a __name__ attribute, but 
bound methods don't have that, and it is bound methods that cause 
the problem because they don't have a constant id number unless 
somebody bothers to keep an explicit reference to the bound 
reference around (keeping a reference to the object itself isn't 
enough).

For example:
class foo:
  def meth1(self):
    pass
  def meth2(self):
    pass

f = foo()
print id(f)
print id(f.meth1)
print id(f.meth2)

Odds are good that the last two printed numbers will be the same 
even though they are for two different bound methods. The id of f 
will persist and remain unique as long as the object exists, but the id 
of its bound methods will not. Even though one can call the bound 
methods as long as the object persists.

I don't know how to best handle this. Possibilities include:
- Use hash(func) instead of id(func).
I don't know enough about the built in hash to know if that is safe. 
Certainly it is the right idea. One wants a function that has the same 
value if the callable entity is the same and a different value 
otherwise.

- Generate a new hash function that is sure to work.
"paolino" suggested the following hash function for bound methods 
(when I first asked about this problem on comp.lang.python):
id(boundMethod.im_self)^id(boundMethod.im_func) this is probably 
the simplest solution if hash itself isn't safe, but it requires a some 
fiddling to figure out what kind of callable entity one has, and thus 
what hash equation is suitable.

- Keep a reference to the callable entity, so its id number cannot be 
reused.
That sounds hard to do safely; it would be all too  easy to introduce 
a memory leak. It can probably be done fairly easily for the case 
cleanup=1, but there is code that uses cleanup=0 (including 
bind_all and bind_class).

-- Russell

----------------------------------------------------------------------

>Comment By: Martin v. Löwis (loewis)
Date: 2005-08-24 07:34

Message:
Logged In: YES 
user_id=21627

Can you provide a test case that demonstrates the problem?

I don't think there is anything wrong with that code. We
don't take the id of func, we take the id of f, where f is
CallWrapper(...).__call__.  f gets then passed to
tk.createcommand, which in turn puts f into
PythonCmd_ClientData. So as long as the Tcl command lives, f
(which is indeed a method) is referenced, which in turn
means that no other method can have the same id.

You are also wrong that the name is not added for bound
methods. It looks at im_func, and then takes the name of the
function in the bound method.

>>> f.meth1.im_func.__name__
'meth1'



----------------------------------------------------------------------

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1267540&group_id=5470


More information about the Python-bugs-list mailing list