[Python-Dev] PEP-3121 and PyType_Copy

2008-08-17 Thread Paul Pogonyshev
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

2008-08-05 Thread Paul Pogonyshev
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

2008-08-05 Thread Paul Pogonyshev
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

2007-07-11 Thread Paul Pogonyshev
[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

2007-07-08 Thread Paul Pogonyshev
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

2007-04-08 Thread Paul Pogonyshev
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

2007-04-08 Thread Paul Pogonyshev
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

2007-04-08 Thread Paul Pogonyshev
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