relocating Zope 2 core interfaces - a proposal
Hi again! As discussed two days ago, I started working on integrating Five interfaces closer into Zope 2.8. I believe I understand the problem better now and like to propose a different way to resolve it: Current State ============= Five (now part of Zope 2.8) ships with one big interfaces.py file that contains z3 interfaces for Zope 2 core classes. (There are also some five specific interfaces in that file, but they are not subject of this proposal.) interfaces.zcml states that Zope 2 implements these interfaces, but there are no tests to verify that and in fact many of these interfaces are broken in Five 1.0. (Yesterday I checked in some fixes to the Five trunk.) So if they are used at all in Five products, they are only used as marker interfaces, not to verify implementations. I grepped through CMFonFive, SilvaDocBook and SilvaFlexibleXML: None of them use these interfaces. Goals ===== Step by step, Zope 2 should move to z3 interfaces. Where z2 interfaces exist, these should be improved and bridged to z3 interfaces. Missing interfaces should be added as z3 interfaces. Instead of maintaining competing interfaces, Five should support that process. Interface locations are identifiers, so first of all I want to get these locations right before Zope 2.8 is released. Z3 interfaces should be located in an 'interfaces' module of the corresponding package. In the Five package they are unmaintainable. So e.g. instead of Products.Five.interfaces.IObjectManager Products.Five.interfaces.IWriteLock we would have OFS.interfaces.IObjectManager webdav.interfaces.IWriteLock Proposed Solution ================= 1.) Adding ZCML that bridges existing z2 interfaces into the 'interfaces' module of their package. [Zope 2.8.0] 2.) Copying z3 interfaces from Five.interfaces to the 'interfaces' module of the corresponding package. Marking those in Five as Zope 2.7 backwards compatibility cruft. [Zope 2.8.0] 3.) Doing the same for Zope 2.7 with monkey patching code. [Five 1.0+] 4.) Making interfaces.zcml point to the new locations. [Five 1.0+] 5.) Adding unit tests that verify interfaces and implementations. [Zope 2.8.0] Risks ===== I can't see a way to provide backwards compatibility for Products.Five.interfaces.*, but as explained above I'm hopeful this doesn't break many Five products. Any comments? Cheers, Yuppie
--On Freitag, 6. Mai 2005 13:07 Uhr +0200 yuppie <y.2005-@wcm-solutions.de> wrote:
Proposed Solution =================
1.) Adding ZCML that bridges existing z2 interfaces into the 'interfaces' module of their package. [Zope 2.8.0]
2.) Copying z3 interfaces from Five.interfaces to the 'interfaces' module of the corresponding package. Marking those in Five as Zope 2.7 backwards compatibility cruft. [Zope 2.8.0]
3.) Doing the same for Zope 2.7 with monkey patching code. [Five 1.0+]
4.) Making interfaces.zcml point to the new locations. [Five 1.0+]
5.) Adding unit tests that verify interfaces and implementations. [Zope 2.8.0]
-1. Such changes are not much acceptable *now*. 2.b2 will be released this week and 2.8 final in about two weeks. Such changes should have been proposed during alpha phase...but I am against such change in this late release phase. Andreas
Andreas Jung wrote: [snip]
-1. Such changes are not much acceptable *now*. 2.b2 will be released this week and 2.8 final in about two weeks. Such changes should have been proposed during alpha phase...but I am against such change in this late release phase.
That's a good point. Let's amend the plan and say we start executing this *after* Zope 2.8, possibly for Zope 2.9. I hope we can make that release cycle relatively short anyway, and driven by Five changes; this would be a good example of such. Jim may have bigger plans for deeper Zope 3 integration (such as merging the security system), but if that is going to take time then we could defer that until Zope 2.10. This way, all the work that remains for me is to merge in Five 1.0 into Zope 2.8. Regards, Martijn
Hi! Martijn Faassen wrote:
Andreas Jung wrote: [snip]
-1. Such changes are not much acceptable *now*. 2.b2 will be released this week and 2.8 final in about two weeks. Such changes should have been proposed during alpha phase...but I am against such change in this late release phase.
For Zope 2.8 it is a low risk change and I can work on it within the next days. The problem was introduced by adding Five and the beta phase is for finding issues with new code and fixing them.
That's a good point. Let's amend the plan and say we start executing this *after* Zope 2.8, possibly for Zope 2.9. I hope we can make that release cycle relatively short anyway, and driven by Five changes; this would be a good example of such. Jim may have bigger plans for deeper Zope 3 integration (such as merging the security system), but if that is going to take time then we could defer that until Zope 2.10.
This way, all the work that remains for me is to merge in Five 1.0 into Zope 2.8.
My point is: Doing that in a backward compatible way is impossible. So we have to do it now or never. Cheers, Yuppie
yuppie wrote: [snip]
This way, all the work that remains for me is to merge in Five 1.0 into Zope 2.8. My point is:
Doing that in a backward compatible way is impossible. So we have to do it now or never.
That's true, but it's not that difficult to ask people to change their ZCML files to point to new interfaces at some point in the future. I think the importance of doing the release on time weighs against any improvements in Five. By the way, I've just merged in Five 1.0 into Zope 2.8 (which was a significant amount of work, due to all kinds of copyright headers being different). Regards, Martijn
Martijn Faassen wrote:
yuppie wrote: [snip]
This way, all the work that remains for me is to merge in Five 1.0 into Zope 2.8.
My point is:
Doing that in a backward compatible way is impossible. So we have to do it now or never.
That's true, but it's not that difficult to ask people to change their ZCML files to point to new interfaces at some point in the future. I think the importance of doing the release on time weighs against any improvements in Five.
Yes. I still don't see where the need for incompatability is. Maybe I'm just blind. Can someone explain?
By the way, I've just merged in Five 1.0 into Zope 2.8 (which was a significant amount of work, due to all kinds of copyright headers being different).
Cool. I can imagine that it was quite dificult. By the way, I think we should have yuppie's r11978 in it (which means we need it on Five-1.0 branch and a Five 1.0.1 release, probably). Gee, I would do the merge myself my laptop wasn't broken. I'm on a Windoze machine right now on which I quickly installed Thunderbird to be at least a little communicative :). Philipp
Philipp von Weitershausen wrote:
Martijn Faassen wrote:
Yes. I still don't see where the need for incompatability is. Maybe I'm just blind. Can someone explain?
I no longer see a problem. If we make sure the Five interfaces and those in the Zope tree are the same, there are no incompatibilities.
By the way, I've just merged in Five 1.0 into Zope 2.8 (which was a significant amount of work, due to all kinds of copyright headers being different).
Can't we use the same headers for Five 1.0 and Zope 2.8? Both releases are ZPL 2.1, aren't they? Are there other things you did have to change?
Cool. I can imagine that it was quite dificult. By the way, I think we should have yuppie's r11978 in it (which means we need it on Five-1.0 branch and a Five 1.0.1 release, probably).
Gee, I would do the merge myself my laptop wasn't broken. I'm on a Windoze machine right now on which I quickly installed Thunderbird to be at least a little communicative :).
Sorry. I didn't think Martijn would merge in Five today. Please let me know if can help to put things straight. Cheers, Yuppie
yuppie wrote:
Yes. I still don't see where the need for incompatability is. Maybe I'm just blind. Can someone explain?
I no longer see a problem. If we make sure the Five interfaces and those in the Zope tree are the same, there are no incompatibilities.
By the way, I've just merged in Five 1.0 into Zope 2.8 (which was a significant amount of work, due to all kinds of copyright headers being different).
Can't we use the same headers for Five 1.0 and Zope 2.8? Both releases are ZPL 2.1, aren't they? Are there other things you did have to change?
They're both ZPL 2.1, but the copyright statement is a different one. Bare Five is Copyright (c) Five contributors, code in the Zope repository is Copyright (c) Zope Corporation and contributors. Maybe we should just switch all of Five to the ZC header to make things easier? It wouldn't change much of legal impact, would it?
Cool. I can imagine that it was quite dificult. By the way, I think we should have yuppie's r11978 in it (which means we need it on Five-1.0 branch and a Five 1.0.1 release, probably).
Gee, I would do the merge myself my laptop wasn't broken. I'm on a Windoze machine right now on which I quickly installed Thunderbird to be at least a little communicative :).
Sorry. I didn't think Martijn would merge in Five today. Please let me know if can help to put things straight.
You just need to merge the revision to the Five-1.0 branch (using svn merge) and apply the diff (output of svn diff -r11977:11978) to the Zope repository (2.8 branch) using the Unix 'patch' program. Philipp
yuppie wrote:
By the way, I've just merged in Five 1.0 into Zope 2.8 (which was a significant amount of work, due to all kinds of copyright headers being different).
Can't we use the same headers for Five 1.0 and Zope 2.8? Both releases are ZPL 2.1, aren't they? Are there other things you did have to change?
Yes, some other things like taking out the monkey.py module, and some documentation differences. I want to get the headers in synch inside Five eventually, just didn't want to do it for Five 1.0.
Cool. I can imagine that it was quite dificult. By the way, I think we should have yuppie's r11978 in it (which means we need it on Five-1.0 branch and a Five 1.0.1 release, probably).
Gee, I would do the merge myself my laptop wasn't broken. I'm on a Windoze machine right now on which I quickly installed Thunderbird to be at least a little communicative :).
Sorry. I didn't think Martijn would merge in Five today. Please let me know if can help to put things straight.
I'd been putting it off, and all this, especially Andreas' note, reminded me I should do it. If you can get your fixes checked into the Zope 2.8 trunk (as well as in the Five-1.0 branch) then we should be fine (assuming you can check into svn.zope.org? Otherwise just put it in the branch and I'll port it into Zope 2.8). Regards, Martijn
Martijn Faassen wrote:
Can't we use the same headers for Five 1.0 and Zope 2.8? Both releases are ZPL 2.1, aren't they? Are there other things you did have to change?
Yes, some other things like taking out the monkey.py module, and some documentation differences.
I want to get the headers in synch inside Five eventually, just didn't want to do it for Five 1.0.
There is a lot of cruft in Zope 2.8. As long as the monkey patchs are disabled in Zope 2.8, I would not mind if they are shipped with 2.8. That would make it easier to update the Zope repository frequently.
I'd been putting it off, and all this, especially Andreas' note, reminded me I should do it. If you can get your fixes checked into the Zope 2.8 trunk (as well as in the Five-1.0 branch) then we should be fine (assuming you can check into svn.zope.org? Otherwise just put it in the branch and I'll port it into Zope 2.8).
Done. Five-1.0 and Zope trunk. Cheers, Yuppie
Martijn Faassen wrote:
yuppie wrote:
By the way, I've just merged in Five 1.0 into Zope 2.8 (which was a significant amount of work, due to all kinds of copyright headers being different).
Can't we use the same headers for Five 1.0 and Zope 2.8? Both releases are ZPL 2.1, aren't they? Are there other things you did have to change?
Yes, some other things like taking out the monkey.py module, and some documentation differences.
Did you tag Five when you merged? It would probably a good idea, that way continuous merging will be easier (since you can ...
I want to get the headers in synch inside Five eventually, just didn't want to do it for Five 1.0.
Yeah, I woudln't mind using the ZC header (I'm personally not too fond of it in its contents, but the advantages outweigh the disadvantages). We could do such change on the trunk at least. Philipp
Philipp von Weitershausen wrote:
Martijn Faassen wrote:
yuppie wrote:
By the way, I've just merged in Five 1.0 into Zope 2.8 (which was a significant amount of work, due to all kinds of copyright headers being different).
Can't we use the same headers for Five 1.0 and Zope 2.8? Both releases are ZPL 2.1, aren't they? Are there other things you did have to change?
Yes, some other things like taking out the monkey.py module, and some documentation differences.
Did you tag Five when you merged? It would probably a good idea, that way continuous merging will be easier (since you can ...
Yes, as I merged Five 1.0. :) Regards, Martijn
yuppie wrote: [snip]
Current State =============
Five (now part of Zope 2.8) ships with one big interfaces.py file that contains z3 interfaces for Zope 2 core classes. (There are also some five specific interfaces in that file, but they are not subject of this proposal.)
interfaces.zcml states that Zope 2 implements these interfaces, but there are no tests to verify that and in fact many of these interfaces are broken in Five 1.0. (Yesterday I checked in some fixes to the Five trunk.)
Note that they also need to be in the 1.0 branch, if this is to be in Zope 2.8.
So if they are used at all in Five products, they are only used as marker interfaces, not to verify implementations.
True; Five hasn't worked with verifying implementations at all yet as far as I know.
I grepped through CMFonFive, SilvaDocBook and SilvaFlexibleXML: None of them use these interfaces.
I think there's some code inside the Five tests that might use them. There's also a chance someone else is using them, but admittedly the risk of breaking something doesn't seem too big. This does deserve to be called 1.1 though if we're breaking APIs (this would then derive from the 1.0 branch, not the Five trunk).
Goals =====
Step by step, Zope 2 should move to z3 interfaces. Where z2 interfaces exist, these should be improved and bridged to z3 interfaces. Missing interfaces should be added as z3 interfaces. Instead of maintaining competing interfaces, Five should support that process.
Agreed.
Interface locations are identifiers, so first of all I want to get these locations right before Zope 2.8 is released. Z3 interfaces should be located in an 'interfaces' module of the corresponding package. In the Five package they are unmaintainable.
[snip example] Agreed again.
Proposed Solution =================
1.) Adding ZCML that bridges existing z2 interfaces into the 'interfaces' module of their package. [Zope 2.8.0]
2.) Copying z3 interfaces from Five.interfaces to the 'interfaces' module of the corresponding package. Marking those in Five as Zope 2.7 backwards compatibility cruft. [Zope 2.8.0]
3.) Doing the same for Zope 2.7 with monkey patching code. [Five 1.0+]
I don't understand this step; what are you proposing?
4.) Making interfaces.zcml point to the new locations. [Five 1.0+]
While in Zope 2.8, we could add 'implements' in the Zope 2 code directly, we don't need to do this from ZCML anymore.
5.) Adding unit tests that verify interfaces and implementations. [Zope 2.8.0]
Risks =====
I can't see a way to provide backwards compatibility for Products.Five.interfaces.*, but as explained above I'm hopeful this doesn't break many Five products.
I'm okay with giving up backwards compatibility here. Another potential risk is Five doing five:implements to a class that already has a Zope 3 style 'implements()'. I don't know what happens in such a case... Regards, Martijn
Hi! Martijn Faassen wrote:
yuppie wrote: [snip]
Current State =============
Five (now part of Zope 2.8) ships with one big interfaces.py file that contains z3 interfaces for Zope 2 core classes. (There are also some five specific interfaces in that file, but they are not subject of this proposal.)
interfaces.zcml states that Zope 2 implements these interfaces, but there are no tests to verify that and in fact many of these interfaces are broken in Five 1.0. (Yesterday I checked in some fixes to the Five trunk.)
Note that they also need to be in the 1.0 branch, if this is to be in Zope 2.8.
<sarcasm>Maybe it's better the interfaces are broken. That makes sure people don't use them extensively and might give us a chance to relocate them at a later point.</sarcasm>
I grepped through CMFonFive, SilvaDocBook and SilvaFlexibleXML: None of them use these interfaces.
I think there's some code inside the Five tests that might use them. There's also a chance someone else is using them, but admittedly the risk of breaking something doesn't seem too big. This does deserve to be called 1.1 though if we're breaking APIs (this would then derive from the 1.0 branch, not the Five trunk).
Ok.
Proposed Solution =================
1.) Adding ZCML that bridges existing z2 interfaces into the 'interfaces' module of their package. [Zope 2.8.0]
2.) Copying z3 interfaces from Five.interfaces to the 'interfaces' module of the corresponding package. Marking those in Five as Zope 2.7 backwards compatibility cruft. [Zope 2.8.0]
3.) Doing the same for Zope 2.7 with monkey patching code. [Five 1.0+]
I don't understand this step; what are you proposing?
It might be better to use the new locations also for Zope 2.7. But the interfaces don't exist in Zope 2.7, so we would have to inject them into Zope 2.7.
4.) Making interfaces.zcml point to the new locations. [Five 1.0+]
While in Zope 2.8, we could add 'implements' in the Zope 2 code directly, we don't need to do this from ZCML anymore.
As you state below, there might be issues with mixing five:implements and implements(). But if there are no issues, I agree that using implements() would be better.
Another potential risk is Five doing five:implements to a class that already has a Zope 3 style 'implements()'. I don't know what happens in such a case...
Cheers, Yuppie
yuppie wrote:
Current State =============
Five (now part of Zope 2.8) ships with one big interfaces.py file that contains z3 interfaces for Zope 2 core classes. (There are also some five specific interfaces in that file, but they are not subject of this proposal.)
interfaces.zcml states that Zope 2 implements these interfaces, but there are no tests to verify that and in fact many of these interfaces are broken in Five 1.0. (Yesterday I checked in some fixes to the Five trunk.)
Note that they also need to be in the 1.0 branch, if this is to be in Zope 2.8.
<sarcasm>Maybe it's better the interfaces are broken. That makes sure people don't use them extensively and might give us a chance to relocate them at a later point.</sarcasm>
Seriously, you should merge your r11978 to the Five-1.0 branch.0
I grepped through CMFonFive, SilvaDocBook and SilvaFlexibleXML: None of them use these interfaces.
I think there's some code inside the Five tests that might use them. There's also a chance someone else is using them, but admittedly the risk of breaking something doesn't seem too big. This does deserve to be called 1.1 though if we're breaking APIs (this would then derive from the 1.0 branch, not the Five trunk).
Ok.
I don't think we need to break backward compatability. We would just need to deprecate the Five.interfaces location. Basically, the goals are: * The solution needs to work with Zope 2.7 * Preferrably, the interface import spelling should be equal on both systems (which means a monkey on 2.7 is probably inevitable). * On 2.8 we want to have definitions of the z3-style interfaces in the Zope tree. * Five.interfaces and OFS.interfaces.*, etc. need to contain the exact *same* interfaces (same, not equal) on both systems at all times. * Five.interfaces should be deprecated as an import location in the long term.
Proposed Solution =================
1.) Adding ZCML that bridges existing z2 interfaces into the 'interfaces' module of their package. [Zope 2.8.0]
2.) Copying z3 interfaces from Five.interfaces to the 'interfaces' module of the corresponding package. Marking those in Five as Zope 2.7 backwards compatibility cruft. [Zope 2.8.0]
3.) Doing the same for Zope 2.7 with monkey patching code. [Five 1.0+]
I don't understand this step; what are you proposing?
It might be better to use the new locations also for Zope 2.7. But the interfaces don't exist in Zope 2.7, so we would have to inject them into Zope 2.7.
Yup. In Zope 2.7, the OFS.interfaces, etc. modules would have to be injected and be filled with the definitions from Five.interfaces. This is why Five.interfaces needs to be kept around anyway. It would probably be a sharade to Five._interfaces which is only imported on demand...
4.) Making interfaces.zcml point to the new locations. [Five 1.0+]
While in Zope 2.8, we could add 'implements' in the Zope 2 code directly, we don't need to do this from ZCML anymore.
As you state below, there might be issues with mixing five:implements and implements(). But if there are no issues, I agree that using implements() would be better.
five:implements (which is equal to using zope.interface.classImplements) and implements() can be mixed. The class will in the end implement both definitions. Philipp
Hi Philipp! Philipp von Weitershausen wrote:
yuppie wrote:
Seriously, you should merge your r11978 to the Five-1.0 branch.0
Martijn was faster than I thought :( I'll follow up to this in an other mail.
I don't think we need to break backward compatability. We would just need to deprecate the Five.interfaces location.
Basically, the goals are:
* The solution needs to work with Zope 2.7 * Preferrably, the interface import spelling should be equal on both systems (which means a monkey on 2.7 is probably inevitable). * On 2.8 we want to have definitions of the z3-style interfaces in the Zope tree. * Five.interfaces and OFS.interfaces.*, etc. need to contain the exact *same* interfaces (same, not equal) on both systems at all times.
That's the point I missed! So we just need code like this at the end of Five.interfaces: try: # override IObjectManager with Zope 2.8 interface from OFS.interfaces import IObjectManager except ImportError: # monkey patch Zope 2.7 OFS ... Right?
* Five.interfaces should be deprecated as an import location in the long term.
Fine. I no longer think we need to break backward compatibility. Cheers, Yuppie
yuppie wrote:
I don't think we need to break backward compatability. We would just need to deprecate the Five.interfaces location.
Basically, the goals are:
* The solution needs to work with Zope 2.7 * Preferrably, the interface import spelling should be equal on both systems (which means a monkey on 2.7 is probably inevitable). * On 2.8 we want to have definitions of the z3-style interfaces in the Zope tree. * Five.interfaces and OFS.interfaces.*, etc. need to contain the exact *same* interfaces (same, not equal) on both systems at all times.
That's the point I missed!
It's important because if someone registers a view for Five.interfaces.IObjectManager and OFS.ObjectManager.ObjectManager implements OFS.interfaces.IObjectManager, you'd want these to be the same...
So we just need code like this at the end of Five.interfaces:
try: # override IObjectManager with Zope 2.8 interface from OFS.interfaces import IObjectManager except ImportError: # monkey patch Zope 2.7 OFS ...
Right?
Yup, something like that. I'd prefer something like this, though:: try: # override IObjectManager with Zope 2.8 interface from OFS.interfaces import IObjectManager def monkey(): pass except ImportError: def monkey(): # monkey patch Zope 2.7 OFS and in Five.monkey, we do:: from Products.Five.interfaces import monkey as interfaceMonkey interfaceMonkey() That way all monkey are effectively executed from Five.monkey which is the convention. I do it like that on the philikon-i18n branch, too, if you want to see another example.
* Five.interfaces should be deprecated as an import location in the long term.
Fine. I no longer think we need to break backward compatibility.
Good :). Philipp
yuppie wrote:
Proposed Solution =================
1.) Adding ZCML that bridges existing z2 interfaces into the 'interfaces' module of their package. [Zope 2.8.0]
+1
2.) Copying z3 interfaces from Five.interfaces to the 'interfaces' module of the corresponding package. Marking those in Five as Zope 2.7 backwards compatibility cruft. [Zope 2.8.0]
+1
3.) Doing the same for Zope 2.7 with monkey patching code. [Five 1.0+]
I assume here you mean patching in OFS.interfaces, webdav.interfaces etc...
4.) Making interfaces.zcml point to the new locations. [Five 1.0+]
5.) Adding unit tests that verify interfaces and implementations. [Zope 2.8.0]
IMHO that's yagni. We actually don't use interfaces that much for verifying implementations anymore. I think their most common use in Zope 3/Five is documentation, API/schema specification, and easier spelling for security declarations.
Risks =====
I can't see a way to provide backwards compatibility for Products.Five.interfaces.*, but as explained above I'm hopeful this doesn't break many Five products.
How and where would we be backward incompatible? I assume that Five.interfaces would remain where it is, since its definitions are needed for your point 3) above. Philipp
Philipp von Weitershausen wrote:
yuppie wrote:
Proposed Solution ================= [...] 3.) Doing the same for Zope 2.7 with monkey patching code. [Five 1.0+]
I assume here you mean patching in OFS.interfaces, webdav.interfaces etc...
Yes.
4.) Making interfaces.zcml point to the new locations. [Five 1.0+]
5.) Adding unit tests that verify interfaces and implementations. [Zope 2.8.0]
IMHO that's yagni. We actually don't use interfaces that much for verifying implementations anymore. I think their most common use in Zope 3/Five is documentation, API/schema specification, and easier spelling for security declarations.
??? Who is 'we'? How do you make sure documentation and specification are in sync with the implementation? AFAICT verifyClass() is quite useful for that. Cheers, Yuppie
yuppie wrote:
4.) Making interfaces.zcml point to the new locations. [Five 1.0+]
5.) Adding unit tests that verify interfaces and implementations. [Zope 2.8.0]
IMHO that's yagni. We actually don't use interfaces that much for verifying implementations anymore. I think their most common use in Zope 3/Five is documentation, API/schema specification, and easier spelling for security declarations.
???
Who is 'we'?
The Zope 3 developers.
How do you make sure documentation and specification are in sync with the implementation? AFAICT verifyClass() is quite useful for that.
Your unit test should exercise the whole API promised by an implementation anyway, so often an explicit interface check is redudant (of course, it can't hurt). verifyClass() per se isn't bad, it's in fact a useful indicator, but having that it as a *sole* measure whether a class fulfills an interface or not is not sufficient (plus, in many Zope cases, verifyObject is better because attributes may only be initialized in __init__). The point why I think it's YAGNI is that we know the Zope 2 implementations do implement the interfaces. After all, I derived the interfaces from the implementations by gutting out the code. And it's unlikely they'll change (although I might be wrong on this one, in which case you win :)). Philipp
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Philipp von Weitershausen wrote:
yuppie wrote:
4.) Making interfaces.zcml point to the new locations. [Five 1.0+]
5.) Adding unit tests that verify interfaces and implementations. [Zope 2.8.0]
IMHO that's yagni. We actually don't use interfaces that much for verifying implementations anymore. I think their most common use in Zope 3/Five is documentation, API/schema specification, and easier spelling for security declarations.
???
Who is 'we'?
The Zope 3 developers.
How do you make sure documentation and specification are in sync with the implementation? AFAICT verifyClass() is quite useful for that.
Your unit test should exercise the whole API promised by an implementation anyway, so often an explicit interface check is redudant (of course, it can't hurt). verifyClass() per se isn't bad, it's in fact a useful indicator, but having that it as a *sole* measure whether a class fulfills an interface or not is not sufficient (plus, in many Zope cases, verifyObject is better because attributes may only be initialized in __init__).
The point why I think it's YAGNI is that we know the Zope 2 implementations do implement the interfaces. After all, I derived the interfaces from the implementations by gutting out the code. And it's unlikely they'll change (although I might be wrong on this one, in which case you win :)).
When writing "test-first", I often start with only the 'verifyClass' test, and an empty interface. Then as I flesh out the interface, the test fails, reminding me to add the method / attribute. Yes, you still need tests for the semantics, but the conformance test is still valuable, because it "tests the tests" (an extra safety belt). Tres. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.5 (GNU/Linux) Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org iD8DBQFCe6AZ+gerLs4ltQ4RAhmqAJsHMI0T4V+p+RIcOBE4stCgxWBDgACfTAHG vrqWMXOBPVH98hheB4Ao0r8= =c00Z -----END PGP SIGNATURE-----
Tres Seaver wrote:
Your unit test should exercise the whole API promised by an implementation anyway, so often an explicit interface check is redudant (of course, it can't hurt). verifyClass() per se isn't bad, it's in fact a useful indicator, but having that it as a *sole* measure whether a class fulfills an interface or not is not sufficient (plus, in many Zope cases, verifyObject is better because attributes may only be initialized in __init__).
The point why I think it's YAGNI is that we know the Zope 2 implementations do implement the interfaces. After all, I derived the interfaces from the implementations by gutting out the code. And it's unlikely they'll change (although I might be wrong on this one, in which case you win :)).
When writing "test-first", I often start with only the 'verifyClass' test, and an empty interface. Then as I flesh out the interface, the test fails, reminding me to add the method / attribute. Yes, you still need tests for the semantics, but the conformance test is still valuable, because it "tests the tests" (an extra safety belt).
Fair enough. Note the "extra": it shouldn't be your only one. Philipp
Philipp von Weitershausen wrote:
Tres Seaver wrote:
Your unit test should exercise the whole API promised by an implementation anyway, so often an explicit interface check is redudant (of course, it can't hurt). verifyClass() per se isn't bad, it's in fact a useful indicator, but having that it as a *sole* measure whether a class fulfills an interface or not is not sufficient (plus, in many Zope cases, verifyObject is better because attributes may only be initialized in __init__).
The point why I think it's YAGNI is that we know the Zope 2 implementations do implement the interfaces. After all, I derived the interfaces from the implementations by gutting out the code. And it's unlikely they'll change (although I might be wrong on this one, in which case you win :)).
When writing "test-first", I often start with only the 'verifyClass' test, and an empty interface. Then as I flesh out the interface, the test fails, reminding me to add the method / attribute. Yes, you still need tests for the semantics, but the conformance test is still valuable, because it "tests the tests" (an extra safety belt).
Fair enough. Note the "extra": it shouldn't be your only one.
Right. The time recently when it paid off was after PyCon, when the ZODB interfaces had been fleshed out. When the merging Five and Zope3 into Zope 2.8, one of the Zope3 classes had such a test, and blew up becuase the interface had previously been incomplete. Fixing it was easy, I think, but we would not have known about the problem without the conformance test. Tres.
participants (5)
-
Andreas Jung -
Martijn Faassen -
Philipp von Weitershausen -
Tres Seaver -
yuppie