[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 Andrew Koenig
 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.

I seem to recall bringing up the same issue a while ago; at the time, the
answer was that if you need it, you can write your own:

def callable(x):
return hasattr(x, '__call__')

My own preference would be for such queries to be defined abstractly as a
built-in part of the language, but apparently my preference is out of sync
with the community in this particular respect.



___
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 Guido van Rossum
On 4/8/07, Paul Pogonyshev [EMAIL PROTECTED] wrote:
 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.

Why?

 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.

 Please reconsider removal of callable() or provide an adequate
 replacement.

What if someone passes a callable that doesn't have the expected signature?

-- 
--Guido van Rossum (home page: http://www.python.org/~guido/)
___
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 Guido van Rossum
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.

-- 
--Guido van Rossum (home page: http://www.python.org/~guido/)
___
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 Alexey Borzenkov
On 4/8/07, Paul Pogonyshev [EMAIL PROTECTED] wrote:
  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 ;)

I whole-heartedly agree here, because people who start learning python
(like me some time ago) usually learn that it's bad to test for
__call__ (can't remember where I read about that though), and that we
should always use callable() to be on a safe side. When I first heard
that callable() was going to be removed I kinda panicked myself, it's
good to know that at least there's still a way to be sure that object
is callable or not...
___
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 Alexey Borzenkov
On 4/8/07, Guido van Rossum [EMAIL PROTECTED] 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.

But what if you need to do different things based on argument is
callable or not? Take for example Dependency Injection recipe:

http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/413268

It uses callable to differentiate whether it needs to use object as
singleton or to instantiate it on each request. I'm sure there might
be other uses for callable when it's really useful.
___
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


Re: [Python-Dev] concerns regarding callable() method

2007-04-08 Thread Josiah Carlson

Guido van Rossum [EMAIL PROTECTED] 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.

The point of using callable(x), or it's equivalent now of hasattr(x,
'__call__') is to reduce reduce the time/lines of code between when an
error occurs and when it is reported.
Errors should never pass silently.

While we currently cannot verify that some callable takes the proper
arguments, number of arguments, etc., we *can* verify that it is
callable.  I think this is a good thing, as allowing the assignment of a
non-callable to a name that is supposed to be callable is the silent
passing of an error.

With relatively minimal effort in Python 3, one could use a function
signature object (PEPs 3107 and 362) to verify that a callable takes the
proper number of arguments, expected keyword arguments, etc., which
while still not allowing one to verify that the implementation of a
callback is correct (technically impossible), it does get us closer to
being able to know whether a callable is or may not be crap when it
is assigned.

If you still think that these two operations are undesireable (testing
the callability, and that a callable takes certain arguments), that's
fine (I disagree completely).  But unless we mangle callables to not
support these operations, people are probably going to do them anyways;
especially those who are using annotations, function signature objects,
etc., in their various frameworks.

But maybe I'm misreading or reading to much into your statement of 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.


 - Josiah

___
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 Phillip J. Eby
At 08:01 PM 4/8/2007 +0400, Alexey Borzenkov wrote:
On 4/8/07, Guido van Rossum [EMAIL PROTECTED] 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.

But what if you need to do different things based on argument is
callable or not?

Then delegate that behavior to the object using adaptation or a generic 
function.  That is, use *table-driven* code, rather than if-then based code.


Take for example Dependency Injection recipe:

 http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/413268

It uses callable to differentiate whether it needs to use object as
singleton or to instantiate it on each request.

And that's a *bad* thing.  What if I want to have a callable singleton?  Or 
what if I want to have a singleton that gets notified of each request?

With table-driven code (adaptation, generic functions) I can support the 
first case by reregistering an existing handler, and the second by 
registering my own handler.

If-then based introspection is harmful here, because it's an attempt to 
*guess* what should be done with the object.  Explicit is better than 
implicit, and it's better not to guess.

callable(), like hasattr() or any other interface probing is essentially 
an attempt to guess at the callers intent, instead of providing a 
reasonable default that they can override.

___
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 Guido van Rossum
On 4/8/07, Josiah Carlson [EMAIL PROTECTED] wrote:
 Guido van Rossum [EMAIL PROTECTED] 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.

 The point of using callable(x), or it's equivalent now of hasattr(x,
 '__call__') is to reduce reduce the time/lines of code between when an
 error occurs and when it is reported.
 Errors should never pass silently.

I'm not sure if that argument weighs much (taken a bit farther it
would require static typing :-). Two arguments made earlier are
stronger IMO:

- The traceback can be much clearer if it comes from setcallback(x)
rather than from the actual call, much later.

- The pragmatic ability (which often occurs in DWIM-ish behavior in
template systems) to do different things depending on whether
something is callable or not. (While in theory I agree with Phillip's
objection that this should be dealt with in a more systematic way, in
practice, at least for Python 2.x, I think it's an okay thing to
do.)

But the same thing can be said for properties like iterable, or
hashable, and other primitive operations.

FWIW, I haven't given up on doing something with abstract base classes
here. I think they (or interfaces or generic functions, for that
matter :-) provide a more systematic approach than either callable()
or hasattr(x, __call__).

TBC,

--Guido

 While we currently cannot verify that some callable takes the proper
 arguments, number of arguments, etc., we *can* verify that it is
 callable.  I think this is a good thing, as allowing the assignment of a
 non-callable to a name that is supposed to be callable is the silent
 passing of an error.

 With relatively minimal effort in Python 3, one could use a function
 signature object (PEPs 3107 and 362) to verify that a callable takes the
 proper number of arguments, expected keyword arguments, etc., which
 while still not allowing one to verify that the implementation of a
 callback is correct (technically impossible), it does get us closer to
 being able to know whether a callable is or may not be crap when it
 is assigned.

 If you still think that these two operations are undesireable (testing
 the callability, and that a callable takes certain arguments), that's
 fine (I disagree completely).  But unless we mangle callables to not
 support these operations, people are probably going to do them anyways;
 especially those who are using annotations, function signature objects,
 etc., in their various frameworks.

 But maybe I'm misreading or reading to much into your statement of 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.


  - Josiah




-- 
--Guido van Rossum (home page: http://www.python.org/~guido/)
___
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 BJörn Lindqvist
On 4/8/07, Paul Pogonyshev [EMAIL PROTECTED] wrote:
 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.

Using the duck typing philosophy; if it quacks like a duck and walks
like a duck, then it probably is a duck. But how can you be so sure
it is NOT a duck if you have never seen it walk or heard it quack?
What if you are passing in an object that is not callable but later on
becomes callable? Is it really an error? I think the plan is that in
py3k, you will be able to do type-checking using function annotations
(bleach). Like this:

def set_callback(self, callback : CallableType):
self.callback = callback

You probably also need to add some more gunk to make it work. I
believe it should be able to replace most uses of callable().

-- 
mvh Björn
___
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 skip

Guido My point is that it's futile to use callable() -- even if it
Guido passes, you have no assurance that you actually have a valid
Guido callback. So why bother with it at all? It's counter to the
Guido spirit of Python. If someone passes you a bad callback, they will
Guido see a traceback when you call it. Then they fix their
Guido program. That's how it's supposed to work.

There's one place where I find the traceback somewhat unhelpful.  Consider
calling a method of a class with incorrect arguments:

 class C:
...   def __init__(self):
... pass
... 
 C(1)
Traceback (most recent call last):
  File stdin, line 1, in module
TypeError: __init__() takes exactly 1 argument (2 given)

While in this example it's clear what method wasn't called correctly, a
callback called with the wrong number of arguments yields a fairly useless
stack trace.  I'm thinking in particular of callbacks called from C code
(e.g. Gtk signal handlers).  I think it would be helpful to check to see if
the function being called had an im_class attribute.  If so, then resolve
the class name and include it in the TypeError message:

TypeError: C.__init__() takes exactly 1 argument (2 given)

Skip
___
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