[Zope3-dev] Re: adaptation based on class rather than interface
Jean-Marc Orliaguet wrote: but conceptually it is the same mess :-) i.e. a total lack of specification. It only looks nicer with interfaces. So, in other words (and in summary of previous blog posts): - New techniques complement, rather than completely replace, old techniques - New techniques do not absolve you from thinking about design - New techniques used appropriately can bring benefits - New techniques misused where old techniques would be better can cause problems Pearls. I'm not sure anyone argued otherwise, though. :) Martin ___ Zope3-dev mailing list Zope3-dev@zope.org Unsub: http://mail.zope.org/mailman/options/zope3-dev/archive%40mail-archive.com
[Zope3-dev] Re: adapter registration question
Tres Seaver wrote: -BEGIN PGP SIGNED MESSAGE- Hash: SHA1 Philipp von Weitershausen wrote: Tres Seaver wrote: Thnk of cataloguing / indexing use cases: adapting the catalogued object to a string value (or tuple, or whatever) using named adapters is a very "natural" way to make indexing pluggable: what is *unnatural* (or at least a "dead chicken") is the requirement to adapt to an 'IString', when what I really want is a 'str'. Well, part of Python idea is duck typing and requiring that you get a 'str' may be too much. Perhaps you would really only like to get something that quacks like str. OTOH, perhaps you absolutely want a 'str' and that use case should perhaps be allowed... Heh, in this case using 'IString' is really a "trussed duck" (duck typing with B&D) ;) Python's duck typing breaks down with strings, because they can by "quack tested" like sequences, but you almost *never* want to treat them the same way as other sequences, so you end up with 'isinstance(obj, basestr)' tests to prevent handling them that way. hello RuleDispatch... -w ___ Zope3-dev mailing list Zope3-dev@zope.org Unsub: http://mail.zope.org/mailman/options/zope3-dev/archive%40mail-archive.com
[Zope3-dev] Re: adapter registration question
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 Philipp von Weitershausen wrote: > Tres Seaver wrote: >> Thnk of cataloguing / indexing use cases: adapting the catalogued >> object to a string value (or tuple, or whatever) using named adapters is >> a very "natural" way to make indexing pluggable: what is *unnatural* >> (or at least a "dead chicken") is the requirement to adapt to an >> 'IString', when what I really want is a 'str'. > > Well, part of Python idea is duck typing and requiring that you get a > 'str' may be too much. Perhaps you would really only like to get > something that quacks like str. OTOH, perhaps you absolutely want a > 'str' and that use case should perhaps be allowed... Heh, in this case using 'IString' is really a "trussed duck" (duck typing with B&D) ;) Python's duck typing breaks down with strings, because they can by "quack tested" like sequences, but you almost *never* want to treat them the same way as other sequences, so you end up with 'isinstance(obj, basestr)' tests to prevent handling them that way. Tres. - -- === Tres Seaver +1 202-558-7113 [EMAIL PROTECTED] Palladion Software "Excellence by Design"http://palladion.com -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.2.2 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFFWLUf+gerLs4ltQ4RAt/1AKCUvR230iCgNOq7kUpqAcFrSQVp5wCfedXY WI/ty3z7ektpMS/9Mh+l/PI= =IM7g -END PGP SIGNATURE- ___ Zope3-dev mailing list Zope3-dev@zope.org Unsub: http://mail.zope.org/mailman/options/zope3-dev/archive%40mail-archive.com
[Zope3-dev] Re: adapter registration question
Tres Seaver wrote: Philipp von Weitershausen wrote: Chris Withers wrote: Christian Theune wrote: The problem you have is to provide a specification for the 'str' interface. There are a couple of problems here... 1. str is both a "function" and a "class" Nope. It's a class since Python 2.2. 2. I was to register the "function" str as an adapter for, say, the "class" int to the "class" str, so there's not factory for the adapter, since it's a function Let's create a marker interface that promises everything that 'str' does: class IString(zope.interface.Interface): """A marker for the 'str' interface.""" As discussed elsewhere, you shouldn't need the marker interface, as you can adapt classes. Right, as an *input* of the adaption it's ok just to specify a class. But the output obviously always has to be specified by an interface. Otherwise the whole point of using of adaption is perverted... Like adapting to None? Heh, good point. Thnk of cataloguing / indexing use cases: adapting the catalogued object to a string value (or tuple, or whatever) using named adapters is a very "natural" way to make indexing pluggable: what is *unnatural* (or at least a "dead chicken") is the requirement to adapt to an 'IString', when what I really want is a 'str'. Well, part of Python idea is duck typing and requiring that you get a 'str' may be too much. Perhaps you would really only like to get something that quacks like str. OTOH, perhaps you absolutely want a 'str' and that use case should perhaps be allowed... -- http://worldcookery.com -- Professional Zope documentation and training ___ Zope3-dev mailing list Zope3-dev@zope.org Unsub: http://mail.zope.org/mailman/options/zope3-dev/archive%40mail-archive.com
Re: [Zope3-dev] Re: adaptation based on class rather than interface
Lennart Regebro wrote: On 11/13/06, Jean-Marc Orliaguet <[EMAIL PROTECTED]> wrote: Indeed technically yes. Practically not. I couldn't find many examples in the zope3 codebase that adapts classes. The #1 pattern is to adapt from interfaces, it appears as though there is a reason for it. Yes, and I think both you and me mentioned it, but with different wordings. If you specify it for a class, then only that class is adaptable. If you want to use the adapter for yet another class, you have to register it again. This is possible, but it's more flexible to specify the adapter for an interface, and let all adaptable classes implement that interface. yes, but if you register an adapter for a base class you don't have to register it for subclasses, do you? subclasses will pick up the same adapter. Provided that you use classes for typing your objects and not interfaces. otherwise I withdraw what I previously wrote (that classes were adaptable) if that's for individual classes only. The basic force behind adapter registration (based on interfaces) is the principle of inheritance. This is also a matter of specifying things for what they can do, instead of for what they are, which you mentioned. I'm not sure the proliferication (?) of marker interfaces is a big risk. But if we get many of them, it still works better than the options of magic __something__ attributes. :) but conceptually it is the same mess :-) i.e. a total lack of specification. It only looks nicer with interfaces. /JM ___ Zope3-dev mailing list Zope3-dev@zope.org Unsub: http://mail.zope.org/mailman/options/zope3-dev/archive%40mail-archive.com
[Zope3-dev] Re: adapter registration question
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 Philipp von Weitershausen wrote: > Chris Withers wrote: >> Christian Theune wrote: >>> The problem you have is to provide a specification for the 'str' >>> interface. >> There are a couple of problems here... >> >> 1. str is both a "function" and a "class" > > Nope. It's a class since Python 2.2. > >> 2. I was to register the "function" str as an adapter for, say, the >> "class" int to the "class" str, so there's not factory for the adapter, >> since it's a function >> >>> Let's create a marker interface that promises everything that 'str' does: >>> >>> class IString(zope.interface.Interface): >>> """A marker for the 'str' interface.""" >> As discussed elsewhere, you shouldn't need the marker interface, as you >> can adapt classes. > > Right, as an *input* of the adaption it's ok just to specify a class. > But the output obviously always has to be specified by an interface. > Otherwise the whole point of using of adaption is perverted... Like adapting to None? Using adaptation to look up "value factories" is not any weirder than using it to look up event subscribers whose return values are always discarded. Thnk of cataloguing / indexing use cases: adapting the catalogued object to a string value (or tuple, or whatever) using named adapters is a very "natural" way to make indexing pluggable: what is *unnatural* (or at least a "dead chicken") is the requirement to adapt to an 'IString', when what I really want is a 'str'. Tres. - -- === Tres Seaver +1 202-558-7113 [EMAIL PROTECTED] Palladion Software "Excellence by Design"http://palladion.com -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.2.2 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFFWK2o+gerLs4ltQ4RAsNxAJ4uXSOSup8PyQd2lQPm1Fqr/C3fGgCgwmiG PgKweYkpKMpulOK46qtJFx0= =twN/ -END PGP SIGNATURE- ___ Zope3-dev mailing list Zope3-dev@zope.org Unsub: http://mail.zope.org/mailman/options/zope3-dev/archive%40mail-archive.com
[Zope3-dev] Re: adapter registration question
Chris Withers wrote: Christian Theune wrote: The problem you have is to provide a specification for the 'str' interface. There are a couple of problems here... 1. str is both a "function" and a "class" Nope. It's a class since Python 2.2. 2. I was to register the "function" str as an adapter for, say, the "class" int to the "class" str, so there's not factory for the adapter, since it's a function Let's create a marker interface that promises everything that 'str' does: class IString(zope.interface.Interface): """A marker for the 'str' interface.""" As discussed elsewhere, you shouldn't need the marker interface, as you can adapt classes. Right, as an *input* of the adaption it's ok just to specify a class. But the output obviously always has to be specified by an interface. Otherwise the whole point of using of adaption is perverted... However, given the edge-case nature of this, I can believe there might be "bugs" to be found here... Now, you can setup your adapter like this: Well, that's not right ;-) should be: provide="str" Wtf? Then why do you need an adapter? I thought you wanted to say IString(1) instead of str(1) to be more flexible...? ...and factory="str" is wrong for the reasons given above, or, put differently, because str()(1) will tell you that strings aren't callable ;-) Huh? You got that wrong. IString(1) will call str(1) if provideAdapter(str, (int,), IString). -- http://worldcookery.com -- Professional Zope documentation and training ___ Zope3-dev mailing list Zope3-dev@zope.org Unsub: http://mail.zope.org/mailman/options/zope3-dev/archive%40mail-archive.com
Re: [Zope3-dev] Re: adaptation based on class rather than interface
On 11/13/06, Jean-Marc Orliaguet <[EMAIL PROTECTED]> wrote: Indeed technically yes. Practically not. I couldn't find many examples in the zope3 codebase that adapts classes. The #1 pattern is to adapt from interfaces, it appears as though there is a reason for it. Yes, and I think both you and me mentioned it, but with different wordings. If you specify it for a class, then only that class is adaptable. If you want to use the adapter for yet another class, you have to register it again. This is possible, but it's more flexible to specify the adapter for an interface, and let all adaptable classes implement that interface. This is also a matter of specifying things for what they can do, instead of for what they are, which you mentioned. I'm not sure the proliferication (?) of marker interfaces is a big risk. But if we get many of them, it still works better than the options of magic __something__ attributes. :) -- Lennart Regebro, Nuxeo http://www.nuxeo.com/ CPS Content Management http://www.nuxeo.org/ ___ Zope3-dev mailing list Zope3-dev@zope.org Unsub: http://mail.zope.org/mailman/options/zope3-dev/archive%40mail-archive.com
Re: [Zope3-dev] Re: adapter registration question
Christian Theune wrote: The problem you have is to provide a specification for the 'str' interface. There are a couple of problems here... 1. str is both a "function" and a "class" 2. I was to register the "function" str as an adapter for, say, the "class" int to the "class" str, so there's not factory for the adapter, since it's a function Let's create a marker interface that promises everything that 'str' does: class IString(zope.interface.Interface): """A marker for the 'str' interface.""" As discussed elsewhere, you shouldn't need the marker interface, as you can adapt classes. However, given the edge-case nature of this, I can believe there might be "bugs" to be found here... Now, you can setup your adapter like this: Well, that's not right ;-) should be: provide="str" ...and factory="str" is wrong for the reasons given above, or, put differently, because str()(1) will tell you that strings aren't callable ;-) cheers, Chris -- Simplistix - Content Management, Zope & Python Consulting - http://www.simplistix.co.uk ___ Zope3-dev mailing list Zope3-dev@zope.org Unsub: http://mail.zope.org/mailman/options/zope3-dev/archive%40mail-archive.com
Re: [Zope3-dev] adaptation based on class rather than interface
On 11/9/06, Jean-Marc Orliaguet <[EMAIL PROTECTED]> wrote: Lennart Regebro wrote: > On 11/9/06, Chris Withers <[EMAIL PROTECTED]> wrote: >> Why do you say "extra" ZCML registration? You need that ZCML >> registration whether or not you have to write the marker interface... > > Sure, but with the marker interface you need only one. You need one > for each class, in your example, thats two. So the second one is > "extra". :) > I think it is a mistake to use interfaces to specify what object _are_ as opposed to what they can _do_. It is better to use base classes for that. Yeah, but in this example there are no base classes available, as I understand it. So it's perfectly feasible to marl something with a marker interface to say "this can be adapted to X". It is a "can do" marking, not an "is" marking, IMO. -- Lennart Regebro, Nuxeo http://www.nuxeo.com/ CPS Content Management http://www.nuxeo.org/ ___ Zope3-dev mailing list Zope3-dev@zope.org Unsub: http://mail.zope.org/mailman/options/zope3-dev/archive%40mail-archive.com
[Zope3-dev] Re: adaptation based on class rather than interface
Philipp von Weitershausen wrote: Jean-Marc Orliaguet wrote: Lennart Regebro wrote: On 11/9/06, Chris Withers <[EMAIL PROTECTED]> wrote: Why do you say "extra" ZCML registration? You need that ZCML registration whether or not you have to write the marker interface... Sure, but with the marker interface you need only one. You need one for each class, in your example, thats two. So the second one is "extra". :) I think it is a mistake to use interfaces to specify what object _are_ as opposed to what they can _do_. It is better to use base classes for that. I agree with Chris that making classes adaptable would be simpler. Classes *are* adaptable as has been said many times already. Let's please not make it sound like it's not possible. Indeed technically yes. Practically not. I couldn't find many examples in the zope3 codebase that adapts classes. The #1 pattern is to adapt from interfaces, it appears as though there is a reason for it. So the best way to not make it sound so, is to use it so :-) Interfaces were designed to specify what an object can do, e.g. a media player will do: play(), stop(), rewind(), without specifying the actual implementation ... whereas classes tell what objects are (an mp3 player, an LP player, a cassette player, ...), they are more specific to the object. More generally, interfaces were designed to specify the *behaviour* of an object. Three basic types of behaviour have been identified in Zope: * perform an action (method API) * storing data (schema) * assumed behaviour that can't be expressed in an API or schema (persistable, attribute annotatable, etc.) The last use case is the one marker interfaces serve. A marker interface isn't any less of an interface. It just describes a different category of behaviour, one that can't be expressed through method or attribute APIs. It's still behaviour that we would like to express formally, and using interfaces for that seems the most logical solution. Interface docstrings are as much part of the formal interface as method or attribute specifications! (Otherwise an interface could never mandate the type of an argument passed to a method, e.g. IContainer.__setitem__ only takes unicode or string names.) yes, I agree. A perfect use case for interfaces without methods is when the specification cannot be expressed in a programmatic way. For instance persistable, etc. in that case only a natural language is appropriate. FYI, the same discussion has occurred in Java (since there are marker interfaces there too and since there are interfaces too and the language does not prohibit using interfaces without methods). Are they an anti-pattern? An answer which I find perfectly valid is given at: http://www.artima.com/intv/issuesP.html under "Appropriate Use of Marker Interfaces" however my reaction was against using interfaces without specification or interfaces with a very implicit and blurry specification, as in the cases described by Martin, in which he defends the use of marker interfaces basically as a way to tag classes "externally" (on/off switch, ...). A class annotation API would be better in that case, maybe based on the same internals as the interface API. "marker interfaces" have empty specifications, that's the problem: they can't grow into "real" interfaces that have a specification. If you add methods to the marker interface you will have to track down all classes that implement the interface (unless you don't really care whether classes do implement their interface). That's always a problem with interfaces. Whether or not an interface had specifications before or not, when you change an interface by adding a spec, you will *always* have to track down all implementations. That's why changing an existing, public interface isn't such a good idea. This argument has nothing to do with marker interfaces, though. It's a general problem of public interfaces. yes, with the difference that marker interfaces have so little specification that they are almost meant to see their specification increase. That's what happened with all the magic flags and meta-tags in Zope2/CMF (isPrincipiaFolderish, meta_type, portal_type, ...). Using interfaces in that case does not solve the problem, and only shifts the problem to another area of the system. as said in the article mentioned above, the same applies here: [QUOTE] If the object you pass in has this marker interface, I will treat it in the following way. But I think that down that path lies darkness. Nobody knows the behavior of objects when they get their 17th marker interface. What if the object implements this marker interface and not this one, or this one and that one but not that other one? . [END QUOTE] All that said, I don't think we should overdo marker interfaces (like any kind of interface). I'm just saying they're not evil and it's not like they violate the "pure truth" of interfaces. The t
[Zope3-dev] Re: adaptation based on class rather than interface
Jean-Marc Orliaguet wrote: Lennart Regebro wrote: On 11/9/06, Chris Withers <[EMAIL PROTECTED]> wrote: Why do you say "extra" ZCML registration? You need that ZCML registration whether or not you have to write the marker interface... Sure, but with the marker interface you need only one. You need one for each class, in your example, thats two. So the second one is "extra". :) I think it is a mistake to use interfaces to specify what object _are_ as opposed to what they can _do_. It is better to use base classes for that. I agree with Chris that making classes adaptable would be simpler. Classes *are* adaptable as has been said many times already. Let's please not make it sound like it's not possible. Interfaces were designed to specify what an object can do, e.g. a media player will do: play(), stop(), rewind(), without specifying the actual implementation ... whereas classes tell what objects are (an mp3 player, an LP player, a cassette player, ...), they are more specific to the object. More generally, interfaces were designed to specify the *behaviour* of an object. Three basic types of behaviour have been identified in Zope: * perform an action (method API) * storing data (schema) * assumed behaviour that can't be expressed in an API or schema (persistable, attribute annotatable, etc.) The last use case is the one marker interfaces serve. A marker interface isn't any less of an interface. It just describes a different category of behaviour, one that can't be expressed through method or attribute APIs. It's still behaviour that we would like to express formally, and using interfaces for that seems the most logical solution. Interface docstrings are as much part of the formal interface as method or attribute specifications! (Otherwise an interface could never mandate the type of an argument passed to a method, e.g. IContainer.__setitem__ only takes unicode or string names.) "marker interfaces" have empty specifications, that's the problem: they can't grow into "real" interfaces that have a specification. If you add methods to the marker interface you will have to track down all classes that implement the interface (unless you don't really care whether classes do implement their interface). That's always a problem with interfaces. Whether or not an interface had specifications before or not, when you change an interface by adding a spec, you will *always* have to track down all implementations. That's why changing an existing, public interface isn't such a good idea. This argument has nothing to do with marker interfaces, though. It's a general problem of public interfaces. All that said, I don't think we should overdo marker interfaces (like any kind of interface). I'm just saying they're not evil and it's not like they violate the "pure truth" of interfaces. The third category of behaviour may be unique to Zope interfaces, but that doesn't necessarily mean it's a perverted use of interfaces. -- http://worldcookery.com -- Professional Zope documentation and training ___ Zope3-dev mailing list Zope3-dev@zope.org Unsub: http://mail.zope.org/mailman/options/zope3-dev/archive%40mail-archive.com
Re: [Zope3-dev] zc.recipe.zope3instance on windows
Should I report bugs for zc.recipe.zope3instance (I have a possible patch too! ;) in the Zope-3 collector, or in the zc.buildout's lanchpad bug tracker? Well since I'm not sure where to put it, let me attach a patch "that works for me", in case it is useful for someone. kind regards, jw -- Jan-Wijbrand Kolman --- zc.recipe.zope3instance/src/zc/recipe/zope3instance/__init__.py 2006-11-09 15:03:49.0 +0100 +++ zc.recipe.zope3instance-win32/src/zc/recipe/zope3instance/__init__.py 2006-11-13 11:30:50.0 +0100 @@ -1,4 +1,4 @@ -import os, re, shutil +import os, os.path, sys, re, shutil import zc.buildout import zc.recipe.egg @@ -41,18 +41,33 @@ # The working set has changed. Blow away the instance. shutil.rmtree(location) - + # What follows is a bit of a hack because the instance-setup mechanism # is a bit monolithic. We'll run mkzopeinstabce and then we'll # patch the result. A better approach might be to provide independent # instance-creation logic, but this raises lots of issues that # need to be stored out first. -mkzopeinstance = os.path.join(options['zope3-directory'], - 'bin', 'mkzopeinstance') +if sys.platform == 'win32' and \ +os.path.normpath(os.path.dirname(options['executable'])) ==\ +os.path.normpath(options['zope3-directory']): +# If the zope3-directory (as configured using the location directive +# in a [zope3] section in the buildout.cfg) points to the Python +# installation, we assume Zope is installed using the Windows +# installer. We assume a lot here. +mkzopeinstance = os.path.join( +options['zope3-directory'], 'Scripts', 'mkzopeinstance' +) +# We need to escape the backward slashes since it is passed +# as a command line argument. +location = location.replace('\\', '') +else: +mkzopeinstance = os.path.join( +options['zope3-directory'], 'bin', 'mkzopeinstance' +) assert os.spawnl( os.P_WAIT, options['executable'], options['executable'], -mkzopeinstance, '-d', location, '-u', options['user'], +mkzopeinstance, '-d', '"%s"'%location, '-u', options['user'], '--non-interactive', ) == 0 ___ Zope3-dev mailing list Zope3-dev@zope.org Unsub: http://mail.zope.org/mailman/options/zope3-dev/archive%40mail-archive.com
[Zope3-dev] Re: adaptation based on class rather than interface
Jean-Marc Orliaguet wrote: Martin Aspeli wrote: Jean-Marc Orliaguet wrote: And there is nothing wrong with using inheritance when there is a '__IS A __' type of relation (e.g. an ordered folder IS A folder IS AN item, ...), or if there is a HAS_A type of relation (a folder has items, a chair has four legs...). It seems that Zope3 has banned all form of class inheritance, even those that made sense, and that would have simplified the implementation. ... subclassing is not used in zope3 as a method for assembling components, as it was used in zope2. At least it's not encouraged. It's still possible and sometimes it makes sense. In zope2, if you mix a folder with a catalog aware mixin, you'd have a catalog-aware folder because the functionality is expressed in the mixin class, not outside. Right, the idea of components is separation of responsibilities. Content objects that just worry about storage don't have to know about this funky thing called the catalog anymore. Or FTP access. Or WebDAV locking. Or ... You get the idea. In zope3 if you subclass a container you still have a container, it won't make the container more specialized. Well, that depends on what you do in the subclass. I have made "specialized" (whatever that means) containers by subclassing BTreeContainer, for example. -- http://worldcookery.com -- Professional Zope documentation and training ___ Zope3-dev mailing list Zope3-dev@zope.org Unsub: http://mail.zope.org/mailman/options/zope3-dev/archive%40mail-archive.com
RE: Re: [Zope3-dev] Zope 3.3.0 - Why is the minimum generation for'zope.app' 1? What's a good practice to update to generation 5prior to my own evolver?
Hi Jeff > Behalf Of Jeff Shell > Sent: Monday, November 06, 2006 8:19 PM > To: Zope 3 Development > Subject: Re: Re: [Zope3-dev] Zope 3.3.0 - Why is the minimum > generation for'zope.app' 1? What's a good practice to update > to generation 5prior to my own evolver? [...] I fix a bug in generation evolving for generation 3. See the checkin message for revision 71115. It's also backported to Zope 3.3 in revision 71116 Probably this has something to do with our problem. Regards Roger Ineichen _ END OF MESSAGE ___ Zope3-dev mailing list Zope3-dev@zope.org Unsub: http://mail.zope.org/mailman/options/zope3-dev/archive%40mail-archive.com