[Python-Dev] PEP-3121 and PyType_Copy
Hi, In the mailing list archive I see a message that this PEP was implemented, dated June 10. However, while everything else PEP describes does seem to be in SVN, I cannot find PyType_Copy(). Is this function still planned for Python 3000, or are there any simple alternatives? Or are modules just supposed to share types across interpreters? Thanks, Paul ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
[Python-Dev] Py_CLEAR and assigning values
Hi, Sorry if this topic was discussed before, but I couldn't find. Py_CLEAR documentation explains why it is better than Py_DECREF and NULL assignment. However, I don't understand why there is no similar macro for the case you want to replace one object with another? I.e. 'naive' way: Py_DECREF (self-x); /* This is prone to the same bug Py_CLEAR prevents. */ self-x = y; Py_INCREF (self-x); Py_CLEAR way: Py_CLEAR (self-x); /* But __del__ can now in principle trigger access to NULL. */ self-x = y; Py_INCREF (self-x); Way I'd think would be possible: Py_ASSIGN (self-x, y) where Py_ASSIGN is defined this way: #define Py_ASSIGN(op, val) \ do {\ PyObject *_py_tmp = (PyObject *)(op); \ (op) = val; \ Py_XINCREF(op); \ Py_XDECREF(_py_tmp);\ } while (0) Do I miss something obvious? Or is there already a standard way to do that which I overlooked? Paul ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Py_CLEAR and assigning values
Daniel Stutzbach wrote: On Tue, Aug 5, 2008 at 3:38 PM, Paul Pogonyshev [EMAIL PROTECTED] wrote: Py_CLEAR way: Py_CLEAR (self-x); /* But __del__ can now in principle trigger access to NULL. */ self-x = y; Py_INCREF (self-x); The Py_DECREF inside the Py_CLEAR may call arbitrary code while self-x points to NULL. This is OK if you write your code to recognize that self-x may be NULL. Yes, this is quite similar to Python code del obj.x obj.x = y though I'm not sure if for Python code x.__del__ will see obj.x as non-set attribute (I guess so, but I'm not sure). However, I'm trying to emulate obj.x = y in C. Without Py_CLEAR, a Py_DECREF may call arbitrary code while self-x points to a deallocated object. This is never OK since it's impossible to detect that self-x is bogus. Yes, this I don't argue. Generally, I end up storing all the objects to be Py_DECREF'd in temporary variables and doing the Py_DECREF's just before returning. That way, self is never in an inconsistent state. Right. But wouldn't it be easier if there was a standard Python macro for this, sort of like proposed Py_ASSIGN? Paul ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] proposed attribute lookup optimization
[I don't know why I didn't receive this mail, presumably spam filter at gmx.net sucks as always] Phillip J. Eby wrote: At 08:23 PM 7/8/2007 +0300, Paul Pogonyshev wrote: I would like to propose an optimization (I think so, anyway) for the way attributes are looked up. [...] [...] Again, though, this has already been proposed, and I believe there's a patch awaiting review for inclusion in 2.6 (and presumably 3.0). OK, good to know. Of course it is better if done by someone familiar with Python internals :) After proposing this I decided it wasn't worthwile, since it would require cache revalidation after any assignment to a new class attribute. But supposedly I just have incorrect picture of what is often in Python :) Paul ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
[Python-Dev] proposed attribute lookup optimization
Hi, I would like to propose an optimization (I think so, anyway) for the way attributes are looked up. Currently, it is done like this: return value of attribute in instance.__dict__ if present for type in instance.__class__.__mro__: return value of attribute in type.__dict__ if present raise AttributeError I propose adding to each type a C-implementation-private dictionary of attribute-name = type-in-which-defined. Then, it will not be necessary to traverse __mro__ on each attribute lookup for names which are present in this lookup dictionary. This optimization will not have any effect for attributes defined on instance. It will, however, for type attributes, most notably for methods. It will most likely cause a slowdown for looking up attributes that are defined directly on self.__class__, not on any of its bases. However, I believe it will be a benefit for all non-extremely shallow inheritance tree. Especially if they involve multiple inheritance. One open question is what to do in case an attribute on a type is set or deleted. Python example: class Current (type): @staticmethod def getattribute (self, name): dict = object.__getattribute__(self, '__dict__') if name in dict: return dict[name] mro = object.__getattribute__ (self, '__class__').__mro__ for type in mro: dict = type.__dict__ if name in dict: return dict[name] raise AttributeError def __init__(self, name, bases, dict): super (Current, self).__init__(name, bases, dict) self.__getattribute__ = Current.getattribute class Optimized (type): @staticmethod def getattribute (self, name): dict = object.__getattribute__(self, '__dict__') if name in dict: return dict[name] # possible optimization lookup = object.__getattribute__ (self, '__class__').__lookup_cache__ if name in lookup: return lookup[name].__dict__[name] # /possible optimization mro = object.__getattribute__ (self, '__class__').__mro__ for type in mro: dict = object.__getattribute__(type, '__dict__') if name in dict: return dict[name] raise AttributeError # possible optimization def build_lookup_cache (self): lookup = {} for type in self.__mro__: for name in type.__dict__: if name not in lookup: lookup[name] = type return lookup # /possible optimization def __init__(self, name, bases, dict): super (Optimized, self).__init__(name, bases, dict) # possible optimization self.__lookup_cache__ = self.build_lookup_cache () # /possible optimization self.__getattribute__ = Optimized.getattribute class A (object): __metaclass__ = Optimized x = 1 class B (A): pass class C (B): pass class D (C): pass class E (D): pass t = E () for k in xrange (10): t.x Try swapping metaclass of A from Optimized to Current and measure execution time. Paul ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
[Python-Dev] concerns regarding callable() method
Hi, I have seen in PEP 3100 that callable() function is planned to be removed in Python 3000 with this replacement: just call the object and catch the exception???. For one, the object (if it is callable) can raise exception itself, so you need to somehow to differentiate between exception raised inside its __call__ and exception raised if object is not callable to begin with. Additionally consider something like something.set_callback (x) Assume that set_callback() wants to check if `x' is callable at all, to raise exception early and make error tracking easier. Currently, you can assert callable (x) But if callable() is removed, there is no apparent replacement. Of course, you cannot call `x' since it might have side-effects or be slow etc. Please reconsider removal of callable() or provide an adequate replacement. Paul ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] concerns regarding callable() method
Guido van Rossum wrote: On 4/8/07, Paul Pogonyshev [EMAIL PROTECTED] wrote: Additionally consider something like something.set_callback (x) Assume that set_callback() wants to check if `x' is callable at all, to raise exception early and make error tracking easier. Currently, you can assert callable (x) But if callable() is removed, there is no apparent replacement. Of course, you cannot call `x' since it might have side-effects or be slow etc. assert hasattr(x, '__call__') I note that callable() was introduced before all callable objects had a __call__ attribute. This is no longer the case, so it's not needed. I just didn't think about that possibility. If that works the same way, callable() is just a sugar and not something unimplementable in other ways. Therefore, my objection is discarded. (But PEP 3100 should probably be update to mention this, otherwise you may get this complaint again ;) Please reconsider removal of callable() or provide an adequate replacement. What if someone passes a callable that doesn't have the expected signature? Well, I don't know a way to catch such situations now, so removing callable() will not make it worse (even if you don't know about hasattr trick above.) Paul ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] concerns regarding callable() method
Guido van Rossum wrote: On 4/8/07, Paul Pogonyshev [EMAIL PROTECTED] wrote: Guido van Rossum wrote: What if someone passes a callable that doesn't have the expected signature? Well, I don't know a way to catch such situations now, so removing callable() will not make it worse (even if you don't know about hasattr trick above.) My point is that it's futile to use callable() -- even if it passes, you have no assurance that you actually have a valid callback. So why bother with it at all? It's counter to the spirit of Python. If someone passes you a bad callback, they will see a traceback when you call it. Then they fix their program. That's how it's supposed to work. I have no problems with Python being untyped. But I want that error stack traces provide some useful information as possible with reasonable effort and that errors happen as early as possible. In particular, stack trace should mention that error occured when you passed something wrong to set_callback() call and not in some obscure place 200 lines later, because otherwise it will only obfuscate error reason. Yes, assert will not catch all errors, but at least it will some. I consider it perfectly acceptable that you cannot test signature, because (since Python is untyped) you could only test number of arguments and even that would probably involve dumb syntax. So, I understand such assert will not catch all errors. But I don't want to remove it, since I find catching at least some errors (e.g. like passing None) an improvement over catching no errors. Paul ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com