ABC: what about the method arguments ?
Hello, ABC __subclasshook__ implementations will only check that the method is present in the class. That's the case for example in collections.Container. It will check that the __contains__ method is present but that's it. It won't check that the method has only one argument. e.g. __contains__(self, x) The problem is that the implemented method could have a different list of arguments and will eventually fail. Using inspect, we could check in __subclasshook__ that the arguments defined are the same than the ones defined in the abstractmethod.-- the name and the ordering. I can even think of a small function in ABC for that: same_signature(method1, method2) => True or False Regards Tarek -- Tarek Ziadé | http://ziade.org
That is not a new idea. So far I have always rejected it because I worry about both false positives and false negatives. Trying to enforce that the method *behaves* as it should (or even its return type) is hopeless; there can be a variety of reasons to modify the argument list while still conforming to (the intent of) the interface. I also worry that it will slow everything down. That said, if you want to provide a standard mechanism that can *optionally* be turned on to check argument conformance, e.g. by using a class or method decorator on the subclass, I would be fine with that (as long as it runs purely at class-definition time; it shouldn't slow down class instantiation or method calls). It will probably even find some bugs. It will also surely have to be tuned to avoid certain classes false positives. --Guido On Thu, Sep 23, 2010 at 7:37 AM, Tarek Ziadé <ziade.tarek@gmail.com> wrote:
Hello,
ABC __subclasshook__ implementations will only check that the method is present in the class. That's the case for example in collections.Container. It will check that the __contains__ method is present but that's it. It won't check that the method has only one argument. e.g. __contains__(self, x)
The problem is that the implemented method could have a different list of arguments and will eventually fail.
Using inspect, we could check in __subclasshook__ that the arguments defined are the same than the ones defined in the abstractmethod.-- the name and the ordering.
I can even think of a small function in ABC for that: same_signature(method1, method2) => True or False
Regards Tarek
-- Tarek Ziadé | http://ziade.org _______________________________________________ Python-ideas mailing list Python-ideas@python.org http://mail.python.org/mailman/listinfo/python-ideas
-- --Guido van Rossum (python.org/~guido)
On Thu, Sep 23, 2010 at 4:53 PM, Guido van Rossum <guido@python.org> wrote:
That is not a new idea. So far I have always rejected it because I worry about both false positives and false negatives. Trying to enforce that the method *behaves* as it should (or even its return type) is hopeless; there can be a variety of reasons to modify the argument list while still conforming to (the intent of) the interface. I also worry that it will slow everything down.
Right
That said, if you want to provide a standard mechanism that can *optionally* be turned on to check argument conformance, e.g. by using a class or method decorator on the subclass, I would be fine with that (as long as it runs purely at class-definition time; it shouldn't slow down class instantiation or method calls). It will probably even find some bugs. It will also surely have to be tuned to avoid certain classes false positives.
I'll experiment on this and come back :) Regards Tarek
On Thu, Sep 23, 2010 at 9:37 AM, Tarek Ziadé <ziade.tarek@gmail.com> wrote:
The problem is that the implemented method could have a different list of arguments and will eventually fail.
A slightly different argument list is okay if it is more permissive. For example, the collections.Sequence ABC defines a count method with one parameter. However, the list implementation's count method takes one mandatory parameter plus two optional parameters. I'm not sure how easy it would be to detect a valid but more general signature. You might be interested in the related Issue 9731 ("Add ABCMeta.has_methods and tests that use it"). -- Daniel Stutzbach, Ph.D. President, Stutzbach Enterprises, LLC <http://stutzbachenterprises.com/>
On Thu, Sep 23, 2010 at 4:54 PM, Daniel Stutzbach <daniel@stutzbachenterprises.com> wrote:
On Thu, Sep 23, 2010 at 9:37 AM, Tarek Ziadé <ziade.tarek@gmail.com> wrote:
The problem is that the implemented method could have a different list of arguments and will eventually fail.
A slightly different argument list is okay if it is more permissive. For example, the collections.Sequence ABC defines a count method with one parameter. However, the list implementation's count method takes one mandatory parameter plus two optional parameters. I'm not sure how easy it would be to detect a valid but more general signature.
Well, with inspect it's possible to see if the extra parameters have defaults values, thus making calls without them still working.
You might be interested in the related Issue 9731 ("Add ABCMeta.has_methods and tests that use it").
Ah... interesting.. has_methods could possibly have an option to check for the signature --will hack on that when I find some time--
-- Daniel Stutzbach, Ph.D. President, Stutzbach Enterprises, LLC
-- Tarek Ziadé | http://ziade.org
On Thu, 23 Sep 2010 16:37:21 +0200 Tarek Ziadé <ziade.tarek@gmail.com> wrote:
The problem is that the implemented method could have a different list of arguments and will eventually fail.
Using inspect, we could check in __subclasshook__ that the arguments defined are the same than the ones defined in the abstractmethod.-- the name and the ordering.
I don't think we should steer in the type checking direction. After all, the Python philosophy of dynamicity (dynamism?) is articulated around the idea that checking types "ahead of time" is useless. IMO, ABCs should be used more as a convention for documenting what capabilities a class claims to expose, than for type checking. (also, you'll have a hard time checking methods with *args or **kwargs parameters) Regards Antoine.
On Thu, Sep 23, 2010 at 5:39 PM, Antoine Pitrou <solipsis@pitrou.net> wrote:
On Thu, 23 Sep 2010 16:37:21 +0200 Tarek Ziadé <ziade.tarek@gmail.com> wrote:
The problem is that the implemented method could have a different list of arguments and will eventually fail.
Using inspect, we could check in __subclasshook__ that the arguments defined are the same than the ones defined in the abstractmethod.-- the name and the ordering.
I don't think we should steer in the type checking direction. After all, the Python philosophy of dynamicity (dynamism?) is articulated around the idea that checking types "ahead of time" is useless. IMO, ABCs should be used more as a convention for documenting what capabilities a class claims to expose, than for type checking.
I think it goes further than documentation at this point. ABC is present and used in the stdlib, not the doc. So asking a class about its capabilities is a feature we provide for third-party code. Also, not sure what you mean about the "ahead of time", but ABCs can be used with issubclass() to check that an object quacks like it should. This is not opposed to dynamicity.
(also, you'll have a hard time checking methods with *args or **kwargs parameters)
True, but I don't expect the ABC to define abstract methods with vague arguments. And if it is so, there's no point checking them in that case. So it should definitely be something optional. Regards, Tarek
Regards
Antoine.
_______________________________________________ Python-ideas mailing list Python-ideas@python.org http://mail.python.org/mailman/listinfo/python-ideas
-- Tarek Ziadé | http://ziade.org
Le jeudi 23 septembre 2010 à 18:18 +0200, Tarek Ziadé a écrit :
Using inspect, we could check in __subclasshook__ that the arguments defined are the same than the ones defined in the abstractmethod.-- the name and the ordering.
I don't think we should steer in the type checking direction. After all, the Python philosophy of dynamicity (dynamism?) is articulated around the idea that checking types "ahead of time" is useless. IMO, ABCs should be used more as a convention for documenting what capabilities a class claims to expose, than for type checking.
I think it goes further than documentation at this point. ABC is present and used in the stdlib, not the doc. So asking a class about its capabilities is a feature we provide for third-party code.
This feature already exists, as you mention, using issubclass() or isinstance(). What you are asking for is a different feature: check that a class has an appropriate implementation of the advertised capabilities. Traditionally, this is best left to unit testing (or other forms of test-based checking). Do you have an use case where unit testing would not be appropriate for this?
(also, you'll have a hard time checking methods with *args or **kwargs parameters)
True, but I don't expect the ABC to define abstract methods with vague arguments.
It depends on the arguments. And the implementation could definitely use *args or **kwargs arguments, especially if it acts as a proxy. Regards Antoine.
On Thu, Sep 23, 2010 at 6:32 PM, Antoine Pitrou <solipsis@pitrou.net> wrote: ...
This feature already exists, as you mention, using issubclass() or isinstance(). What you are asking for is a different feature: check that a class has an appropriate implementation of the advertised capabilities. Traditionally, this is best left to unit testing (or other forms of test-based checking).
Do you have an use case where unit testing would not be appropriate for this?
Why are you thinking about unit tests ? Don't you ever use issubclass/isinstance in your programs ? Checking signatures using ABC when you create a plugin system is one use case for instance.
(also, you'll have a hard time checking methods with *args or **kwargs parameters)
True, but I don't expect the ABC to define abstract methods with vague arguments.
It depends on the arguments. And the implementation could definitely use *args or **kwargs arguments, especially if it acts as a proxy.
Sure but ISTM that most of the time signatures are well defined, and proxies lives in an upper layer. Regards Tarek
Le jeudi 23 septembre 2010 à 19:51 +0200, Tarek Ziadé a écrit :
On Thu, Sep 23, 2010 at 6:32 PM, Antoine Pitrou <solipsis@pitrou.net> wrote: ...
This feature already exists, as you mention, using issubclass() or isinstance(). What you are asking for is a different feature: check that a class has an appropriate implementation of the advertised capabilities. Traditionally, this is best left to unit testing (or other forms of test-based checking).
Do you have an use case where unit testing would not be appropriate for this?
Why are you thinking about unit tests ? Don't you ever use issubclass/isinstance in your programs ?
Sorry, you don't seem to be answering the question. Why wouldn't the implementor of the class use unit tests to check that his/her class implements the desired ABC?
Checking signatures using ABC when you create a plugin system is one use case for instance.
Again, why do you want to check signatures? Do you not trust plugin authors to write plugins? Also, why do you think checking signatures is actually useful? It only checks that the signature is right, not that the expected semantics are observed. The argument for checking method signature in advance is as weak as the argument for checking types at compile time.
It depends on the arguments. And the implementation could definitely use *args or **kwargs arguments, especially if it acts as a proxy.
Sure but ISTM that most of the time signatures are well defined, and proxies lives in an upper layer.
Not really. If I write a file object wrapper that proxies some methods to an other file object, I don't want to re-type all method signatures (including default args) by hand. Regards Antoine.
On Thu, Sep 23, 2010 at 8:01 PM, Antoine Pitrou <solipsis@pitrou.net> wrote:
Le jeudi 23 septembre 2010 à 19:51 +0200, Tarek Ziadé a écrit :
On Thu, Sep 23, 2010 at 6:32 PM, Antoine Pitrou <solipsis@pitrou.net> wrote: ...
This feature already exists, as you mention, using issubclass() or isinstance(). What you are asking for is a different feature: check that a class has an appropriate implementation of the advertised capabilities. Traditionally, this is best left to unit testing (or other forms of test-based checking).
Do you have an use case where unit testing would not be appropriate for this?
Why are you thinking about unit tests ? Don't you ever use issubclass/isinstance in your programs ?
Sorry, you don't seem to be answering the question. Why wouldn't the implementor of the class use unit tests to check that his/her class implements the desired ABC?
That's fine indeed. Now, why wouldn't the implementor of an application use ABC to check that the third party class he's about to load in his app implements the desired ABC?
Checking signatures using ABC when you create a plugin system is one use case for instance.
Again, why do you want to check signatures? Do you not trust plugin authors to write plugins?
Also, why do you think checking signatures is actually useful? It only checks that the signature is right, not that the expected semantics are observed. The argument for checking method signature in advance is as weak as the argument for checking types at compile time.
Sorry but it seems that you are now advocating against ABC altogether. Checking the methods, and optionally their attributes is just a deeper operation on something that already exists. It's fine to use those only in your tests, but why do you object that someone would want to use them in their app. This is completely orthogonal to the discussion which is: extend a method checker to check attributes.
It depends on the arguments. And the implementation could definitely use *args or **kwargs arguments, especially if it acts as a proxy.
Sure but ISTM that most of the time signatures are well defined, and proxies lives in an upper layer.
Not really. If I write a file object wrapper that proxies some methods to an other file object, I don't want to re-type all method signatures (including default args) by hand.
In that case I am curious to see why you would have file I/O method with extra *args/**kwargs. You should handle this kind of set up in the constructor and keep the methods similar. (and avoid extra re-type actually) Regards Tarek
Regards
Antoine.
_______________________________________________ Python-ideas mailing list Python-ideas@python.org http://mail.python.org/mailman/listinfo/python-ideas
-- Tarek Ziadé | http://ziade.org
Le jeudi 23 septembre 2010 à 20:59 +0200, Tarek Ziadé a écrit :
That's fine indeed. Now, why wouldn't the implementor of an application use ABC to check that the third party class he's about to load in his app implements the desired ABC?
Why would he? What does it provide him exactly? A false sense of security / robustness?
Also, why do you think checking signatures is actually useful? It only checks that the signature is right, not that the expected semantics are observed. The argument for checking method signature in advance is as weak as the argument for checking types at compile time.
Sorry but it seems that you are now advocating against ABC altogether.
As I said, I believe ABCs are useful mainly for documentation purposes; that is, for conveying an /intent/. Thinking that ABCs guarantee anything about quality or conformity of the implementation sounds wrong to me. (the other reason for using ABCs is to provide default implementations of some methods, like the io ABCs do)
This is completely orthogonal to the discussion which is: extend a method checker to check attributes.
It's not really orthogonal. I'm opposing the idea that programmatically checking the conformity of method signatures is useful; I also think it's *not* a good thing to advocate to Python programmers coming from other languages.
In that case I am curious to see why you would have file I/O method with extra *args/**kwargs.
def seek(self, *args): return self.realfileobj.seek(*args)
So are you in favor of the removal of all kind of type checking mechanism in Python ?
"Type" checking is simply done when necessary. It is duck typing. Even in the case of ABCs, method calls are still duck-typed. For example, if you look at the io ABCs and concrete classes, a BufferedReader won't check that you are giving it a RawIOBase to wrap access to. Regards Antoine.
If I were writing a class intended to implement an particular ABC, I would be happy to have an automated check function that might catch errors. 100% testing is hard to achieve. -- Terry Jan Reedy
On Thu, 23 Sep 2010 14:39:01 -0400 Terry Reedy <tjreedy@udel.edu> wrote:
If I were writing a class intended to implement an particular ABC, I would be happy to have an automated check function that might catch errors. 100% testing is hard to achieve.
How would an automatic check function solve anything, if you don't test that the class does what is expected? Again, this is exactly the argument for compile-time type checking, and it is routinely pointed out that it is mostly useless.
On Thu, Sep 23, 2010 at 8:52 PM, Antoine Pitrou <solipsis@pitrou.net> wrote:
On Thu, 23 Sep 2010 14:39:01 -0400 Terry Reedy <tjreedy@udel.edu> wrote:
If I were writing a class intended to implement an particular ABC, I would be happy to have an automated check function that might catch errors. 100% testing is hard to achieve.
How would an automatic check function solve anything, if you don't test that the class does what is expected?
Again, this is exactly the argument for compile-time type checking, and it is routinely pointed out that it is mostly useless.
So are you in favor of the removal of all kind of type checking mechanism in Python ?
_______________________________________________ Python-ideas mailing list Python-ideas@python.org http://mail.python.org/mailman/listinfo/python-ideas
-- Tarek Ziadé | http://ziade.org
On Thu, Sep 23, 2010 at 1:52 PM, Antoine Pitrou <solipsis@pitrou.net> wrote:
How would an automatic check function solve anything, if you don't test that the class does what is expected?
Automated checks are a good way to help ensure that your test coverage is good. If the automated check fails and all the other tests pass, it means there's been an oversight in both functionality and tests. This isn't a purely theoretical concern. See Issues 9212 and 9213 for cases where a class purported to support an ABC but wasn't actually supplying all the methods. -- Daniel Stutzbach, Ph.D. President, Stutzbach Enterprises, LLC <http://stutzbachenterprises.com/>
On Thu, Sep 23, 2010 at 11:52 AM, Antoine Pitrou <solipsis@pitrou.net> wrote:
On Thu, 23 Sep 2010 14:39:01 -0400 Terry Reedy <tjreedy@udel.edu> wrote:
If I were writing a class intended to implement an particular ABC, I would be happy to have an automated check function that might catch errors. 100% testing is hard to achieve.
How would an automatic check function solve anything, if you don't test that the class does what is expected?
Again, this is exactly the argument for compile-time type checking, and it is routinely pointed out that it is mostly useless.
That may be the party line of dynamic-language diehards, but that doesn't make it true. There are plenty of times when compile-time checking can save the day, and typically, the larger a system, the more useful it becomes. Antoine, can you back off your attempts to prove that the proposed feature is useless and instead help designing the details of the feature (or if you can't or don't want to help there, just stay out of the discussion)? -- --Guido van Rossum (python.org/~guido)
On 9/23/2010 3:26 PM, Guido van Rossum wrote:
On Thu, Sep 23, 2010 at 11:52 AM, Antoine Pitrou<solipsis@pitrou.net> wrote:
On Thu, 23 Sep 2010 14:39:01 -0400 Terry Reedy<tjreedy@udel.edu> wrote:
If I were writing a class intended to implement an particular ABC, I would be happy to have an automated check function that might catch errors. 100% testing is hard to achieve.
How would an automatic check function solve anything, if you don't test that the class does what is expected?
Again, this is exactly the argument for compile-time type checking, and it is routinely pointed out that it is mostly useless.
That may be the party line of dynamic-language diehards, but that doesn't make it true. There are plenty of times when compile-time checking can save the day, and typically, the larger a system, the more useful it becomes.
Sometimes you surprise me with your non-dogmatic practicality. I do hope, though, that you continue to reject C-like braces {;-}.
Antoine, can you back off your attempts to prove that the proposed feature is useless and instead help designing the details of the feature (or if you can't or don't want to help there, just stay out of the discussion)?
Yes, let the cat scratch his itch and see what he produces. Since unittests have been brought up, I have a idea and question. Can this work? Split the current test suite for a concrete class that implements one of the ABCs into concrete-specific and ABC-general portions, with the abstract part parameterized by concrete class. For instance, split test/test_dict.py into test_dict.py and test_Mapping.py, where the latter has all tests that test compliance with the Mapping ABC (or whatever it is called) and the former keeps all the dict-specific extension tests. Rewrite test_Mapping so it is not dict specific, so one could write something like class MyMapping(): "Implement exactly the Mapping ABC with no extras." ... if __name__ == '__main__': from test import test_Mapping as tM tM.concrete = MyMapping tM.runtests() This is similar to but not the same as splitting tests into generic and CPython parts, the latter for reuse by other implementations of the interpreter. (For dicts, test_dict.py could still be so split, or a portion of it made conditional on the platform.) This idea is for reuse of tests by other implementations of ABCs, whatever interpreter implementation they run under. The underlying question is whether ABCs are intended to be an integral part of Python3 or just an optional extra tucked away in a corner (which is how many, including me, still tend to view them)? If the former, then to me they should, if possible, be supported by a semantic validation test suite. In a way, I am agreeing with Antoine's objection that signature validation is not enough, but with the opposite suggestion of extend rather than reject Tarek's idea of providing auto test tools that make writing and using ABCs easier. -- Terry Jan Reedy
Terry Reedy wrote: [...]
Since unittests have been brought up, I have a idea and question. Can this work? Split the current test suite for a concrete class that implements one of the ABCs into concrete-specific and ABC-general portions, with the abstract part parameterized by concrete class.
FWIW, bzr's test suite has this facility, and bzr plugins that implement various bzr interfaces will have tests for those interfaces automatically applied. (Being a Python 2.4+ project, bzr doesn't actually use the ABCs feature, but we certainly use the concept of "interface with many implemenations".) E.g. if you define a new Transport (in bzr terms, a thing like FTP, HTTP, etc) you probably want to make sure it complies with bzrlib's expectations for Transports. So you can include a get_test_permutations function in your module that returns a list of (transport_class, server_class) pairs. [Unsurprisingly you need a test server to run against, although for transports like LocalTransport (local filesystem access) they can be very simple.] It works very well, and is very useful both for bzrlib itself and plugins. We have “per-implementation” tests for: branch, bzrdir, repository, interrepository, merger, transport, tree, workingtree, uifactory, and more. Look for bzrlib/tests/per_*. It's not necessarily easy to write all those tests. The more complex an interface, the more likely it is you'll have many tests for that interface that don't really apply to all implementations — for instance some Transports are read-only, or don't support list_dir, etc. So tests that involve those need to specifically check for that capability and raise NotApplicable, and finding the exact right way to do that can be tricky. It's often easier to say “if isinstance(thing, ParticularImplementation): ...”, but that quickly erodes the applicability of those tests for new implementations. Also tricky is when the setup or even assertions for some tests needs to vary considerably by implementation: how complicated is your parameterisation interface going to have to be? bzr has found it worthwhile, so I do encourage trying it. I'd use Robert Collins' http://launchpad.net/testscenarios library if I were providing this infrastructure in a suite that doesn't already have this approach; it's basically a distillation of the infrastructure developed in bzrlib.tests. -Andrew.
On Thu, Sep 23, 2010 at 7:24 PM, Terry Reedy <tjreedy@udel.edu> wrote:
Can this work? Split the current test suite for a concrete class that implements one of the ABCs into concrete-specific and ABC-general portions, with the abstract part parameterized by concrete class.
For instance, split test/test_dict.py into test_dict.py and test_Mapping.py, where the latter has all tests that test compliance with the Mapping ABC (or whatever it is called) and the former keeps all the dict-specific extension tests. Rewrite test_Mapping so it is not dict specific, so one could write something like
As a heavy user of the ABCs in the collections module, that would be awesome. :-) It would make my life a lot easier when I'm writing tests to go along with an ABC-derived class. I have 8 such classes on PyPi (heapdict.heapdict and blist.*), plus more in private repositories. There is some code vaguely along those lines in the existing unit tests. For example, Lib/test/seq_tests.py contains tests common to sequences. However, that was written before collections.Sequence came along and the pre-2.6 definition of "sequence" only loosely correlates with a collections.Sequence. -- Daniel Stutzbach, Ph.D. President, Stutzbach Enterprises, LLC <http://stutzbachenterprises.com/>
On 9/24/2010 10:17 AM, Daniel Stutzbach wrote:
On Thu, Sep 23, 2010 at 7:24 PM, Terry Reedy <tjreedy@udel.edu <mailto:tjreedy@udel.edu>> wrote:
Can this work? Split the current test suite for a concrete class that implements one of the ABCs into concrete-specific and ABC-general portions, with the abstract part parameterized by concrete class.
For instance, split test/test_dict.py into test_dict.py and test_Mapping.py, where the latter has all tests that test compliance with the Mapping ABC (or whatever it is called) and the former keeps all the dict-specific extension tests. Rewrite test_Mapping so it is not dict specific, so one could write something like
Reading the responses, I realized that I am already doing a simplified version of my suggestion for functions rather than classes. For didactic purposes, I am writing multiple implementations of multiple abstract functions. I embody a test for a particular function in an iterable of input-output pairs (where the 'output' can also be an exception class). I use that with a custom super test function that tests one or more callables against the pairs. It works great and it is easy to add another implementation or more pairs.
As a heavy user of the ABCs in the collections module, that would be awesome. :-) It would make my life a lot easier when I'm writing tests to go along with an ABC-derived class. I have 8 such classes on PyPi (heapdict.heapdict and blist.*), plus more in private repositories.
There is some code vaguely along those lines in the existing unit tests. For example, Lib/test/seq_tests.py contains tests common to sequences. However, that was written before collections.Sequence came along and the pre-2.6 definition of "sequence" only loosely correlates with a collections.Sequence.
Well, pick one existing test file, revise and extend and perhaps split, start a tracker issue with proposed patch, get comments, and perhaps commit it. If you do, add terry.reedy as nosy. -- Terry Jan Reedy
On 9/23/2010 2:52 PM, Antoine Pitrou wrote:
On Thu, 23 Sep 2010 14:39:01 -0400 Terry Reedy<tjreedy@udel.edu> wrote:
If I were writing a class intended to implement an particular ABC, I would be happy to have an automated check function that might catch errors. 100% testing is hard to achieve.
How would an automatic check function solve anything, if you don't test that the class does what is expected?
If all tests are written with calls by position, as is my habit and general preference, they will not catch argument name mismatches that would trip up someone who prefers call by keyword or any introspection-by-name process. -- Terry Jan Reedy
On Thu, Sep 23, 2010 at 1:51 PM, Tarek Ziadé <ziade.tarek@gmail.com> wrote:
Why are you thinking about unit tests ? Don't you ever use issubclass/isinstance in your programs ?
Checking signatures using ABC when you create a plugin system is one use case for instance.
This is something that I have implemented (before ABCs) in plugin systems I use. When loading the plugin I validate all methods exist and that each method has the correct number of required arguments, I generally dont check argument name as my plugin systems all pass by position instead of keyword. If the signature I am checking contains *args it automatically passes the check. If the plugin fails the check I dont load it. On Thu, Sep 23, 2010 at 2:01 PM, Antoine Pitrou <solipsis@pitrou.net> wrote:
Again, why do you want to check signatures? Do you not trust plugin authors to write plugins?
No, no I dont. I have had several plugin authors come to me complaining that the plugin system is broken because it wont load their plugin (even with a fairly detailed error message). Dj Gilcrease ____ ( | \ o () | o |`| | | /`\_/| | | ,__ ,_, ,_, __, , ,_, _| | | / | | |/ / / | |_/ / | / \_|_/ (/\___/ |/ /(__,/ |_/|__/\___/ |_/|__/\__/|_/\,/ |__/ /| \|
On Fri, Sep 24, 2010 at 2:18 AM, Tarek Ziadé <ziade.tarek@gmail.com> wrote:
I think it goes further than documentation at this point. ABC is present and used in the stdlib, not the doc. So asking a class about its capabilities is a feature we provide for third-party code.
Minor nit - we can only ask a fairly limited subset of questions along these lines (i.e. does *this* class/instance implement *this* ABC?). More interesting questions like "which ABCs does this class/instance explicitly implement?" are currently impossible (see http://bugs.python.org/issue5405). Back on topic - I like Guido's approach. While we can debate the merits of LBYL signature checking forever without reaching agreement (for the record, my opinion is that static checks should be thought of as a bunch of implicit unit tests that you get "for free"), providing a way to explicitly request ABC signature checks in the abc module probably isn't a bad idea. If nothing else, invoking that check can become a recommended part of the unit test suite for classes that claim to implement ABCs. Is getting the method signatures right *sufficient* for ABC compliance? No. Is it *necessary*? Yes. It's the latter point that makes this feature potentially worth standardising. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia
Am 23.09.2010 16:37, schrieb Tarek Ziadé:
Hello,
ABC __subclasshook__ implementations will only check that the method is present in the class. That's the case for example in collections.Container. It will check that the __contains__ method is present but that's it. It won't check that the method has only one argument. e.g. __contains__(self, x)
The problem is that the implemented method could have a different list of arguments and will eventually fail.
I'm not concerned about this in the least. Whoever implements a special method with the wrong signature has more pressing problems than a false- positive ABC subclass check. And AFAIK, our ABCs only check for special methods.
Using inspect, we could check in __subclasshook__ that the arguments defined are the same than the ones defined in the abstractmethod.-- the name and the ordering.
"ordering"? Georg -- Thus spake the Lord: Thou shalt indent with four spaces. No more, no less. Four shall be the number of spaces thou shalt indent, and the number of thy indenting shall be four. Eight shalt thou not indent, nor either indent thou two, excepting that thou then proceed to four. Tabs are right out.
participants (9)
-
Andrew Bennetts
-
Antoine Pitrou
-
Daniel Stutzbach
-
Dj Gilcrease
-
Georg Brandl
-
Guido van Rossum
-
Nick Coghlan
-
Tarek Ziadé
-
Terry Reedy