Re: [Zope-dev] A summary of Interfaces vs ZCA concepts

2009-12-22 Thread Martijn Faassen
Hey,

A few points instead of a point by point reply.

* I thought we had agreed to add methods to Interface that support multi 
adapter and utility lookup. We seem to have, but only about the external 
API, not about where the implementation is. (even if in my plugin 
proposal the implementation still lies in zope.component)

* Apparently not even single adapter lookup is supported by you, at 
least as implemented in zope.interface. I had not previously realized 
that the current implementation of __call__ could be considered wrong by 
you.

* You appear to be looking for something that at least in the Python 
language is only accepted as a kind of hack: an ability to extend the 
API of an existing class far away from the definition of that class, 
without there being a subclassing relationship (or I suppose, a class 
decorator). The idea in Python is generally that the API of a class is 
defined by that class or its base classes, not elsewhere.

* There is of course a way to extend what one can do with an object in 
Python. Subclassing is one way, adaptation another, and defining 
functions another. The last is what zope.component does.

* I do not know of a user community that uses zope.interface and does 
not use a component architecture. The Twisted community for instance 
uses zope.interface's adapter registry and __call__ hook. This is an 
argument for making component lookup an integral part of 
zope.interface's responsibilities. I think you could even make an 
argument for folding zope.component's responsibilities into 
zope.interface, though I'm not currently proposing this (also because 
we're are looking to improve the implementation, see below). 
Generalizing what kinds of component lookups one can do using Interface 
seems like a good idea from this perspective.

* I think it is entirely possible that people will plug in alternative 
component lookup strategies to zope.interface in the future, as the long 
discussion also involved changing the way zope.component's internals worked.

* All this questioning of fundamentals makes me inclined to give up on 
this project for the time being. I thought we had reached a conclusion, 
but I was wrong. Too many cooks?

Some more technical points:

* you wonder about a 'context' parameter. Are you talking about the 
lookup context here? We hadn't considered passing through the lookup 
context in previous discussions. We could leave that out for the time being.

* A single plugin seems fine instead of a list of plugin points for 
zope.interface. I think a single plugin, using a global would be the 
most straightforward and readable solution, but perhaps some performance 
measurements would be interesting.

Regards,

Martijn

___
Zope-Dev maillist  -  Zope-Dev@zope.org
https://mail.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 https://mail.zope.org/mailman/listinfo/zope-announce
 https://mail.zope.org/mailman/listinfo/zope )


Re: [Zope-dev] A summary of Interfaces vs ZCA concepts

2009-12-22 Thread Chris McDonough
Thomas Lotze wrote:
 Chris McDonough wrote:
 
 Thomas Lotze wrote:
 Because then, if you use third-party code that uses
 zope.interface.Interface and other code (third-party or your own) that
 uses the subclassed interfaces, you'll have to deal with both types at
 the same time in your client code. You could use the new API on some
 interfaces but not on others, possibly on the same line of code. How
 readable or maintainable would such code be?
 I'm not sure, but if we had it to do all over again, this would be an
 obvious solution.  It would be the work of maybe two days to convert all
 ZTK packages to use a z.c.interface.Interface, and any existing package
 would need to be touched anyway to use .adapt and .utility.  So it bears
 some weight I think, even if it is eventually rejected.
 
 It does certainly bear some weight as one possibility to be considered.
 However, my point wasn't so much about converting a limited existing
 amount of code; you're obviously right about having to touch that anyway
 in order to use the new methods.
 
 My objection is this: If we go to the trouble of implementing basic
 interfaces in zope.interface plus derived ones with component lookup
 capabilities in zope.component and keep both around for their respective
 reasons of existence, then it is expected that there will be code that
 uses both types of interfaces for these very reasons (and maybe other
 types which have other added behaviour). Such code would become a lot less
 maintainable since you'd never know whether a given interface has a
 particular method just because the one next to it does.
 
 OTOH, registering all behaviour an application needs onto the same
 interface type doesn't create that problem. As long as you're familiar
 with the application at large, you will know for every interface that
 occurs in it which methods is has, how they need to be called and what
 their semantics are.
 
 Also, subclassing for adding behaviour introduces the typical problems of
 hierarchies and tight coupling. This isn't a practical problem as long as
 we only ever talk about adaptation as the only use of interfaces, but I'm
 trying to discuss interfaces as a language feature with a greater set of
 possible use cases.
 

Maybe a hook or API extension just isn't the right thing here.  Maybe we 
just give up on the idea that z.component worldview doesn't belong in 
z.interface, for the sake of implementation simplicity.

- Move the Components class from zope.component.registry to
   zope.interface.adapter and leave behind an import alias.

- Move the base registry from zope.component.globalregistry
   into zope.interface.adapter and leave behind an import alias.

- Move the getSiteManager function from zope.component._api into
   zope.interface.adapter and leave behind an import alias.

- Move the hookable implementation from zope.component.hookable
   into zope.interface.hookable and leave behind an import alias.

- Change the zope.interface.interface.InterfaceClass implementation
   directly, adding adapts and utility methods, which would
   use zope.interface.adapter.getSiteManager to find the registry.

z.interface would then become responsible for:

- Providing an implementation of a component registry which has
   a z.c worldview: adapters and utilities, stolen from
   z.c.registry.Components.

- Providing a function that returns the current component registry
   (getSiteManager, which will continue to be hookable;
   although maybe we should take the opportunity to rename it to
   actually mean something).

- Providing the instance that is the default component registry.

All other responsibility (global API functions, a persistent registry 
implementation, security stuff, zcml support, etc), would remain in z.component.

This would also line up conceptually with usage of the ZCA by BFG, which does 
not hook getSiteManager by default, but still uses a ZCA component registry.

- C
___
Zope-Dev maillist  -  Zope-Dev@zope.org
https://mail.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 https://mail.zope.org/mailman/listinfo/zope-announce
 https://mail.zope.org/mailman/listinfo/zope )


Re: [Zope-dev] A summary of Interfaces vs ZCA concepts

2009-12-22 Thread Chris McDonough
Chris McDonough wrote:
 Thomas Lotze wrote:
 Chris McDonough wrote:

 Thomas Lotze wrote:
 Because then, if you use third-party code that uses
 zope.interface.Interface and other code (third-party or your own) that
 uses the subclassed interfaces, you'll have to deal with both types at
 the same time in your client code. You could use the new API on some
 interfaces but not on others, possibly on the same line of code. How
 readable or maintainable would such code be?
 I'm not sure, but if we had it to do all over again, this would be an
 obvious solution.  It would be the work of maybe two days to convert all
 ZTK packages to use a z.c.interface.Interface, and any existing package
 would need to be touched anyway to use .adapt and .utility.  So it bears
 some weight I think, even if it is eventually rejected.
 It does certainly bear some weight as one possibility to be considered.
 However, my point wasn't so much about converting a limited existing
 amount of code; you're obviously right about having to touch that anyway
 in order to use the new methods.

 My objection is this: If we go to the trouble of implementing basic
 interfaces in zope.interface plus derived ones with component lookup
 capabilities in zope.component and keep both around for their respective
 reasons of existence, then it is expected that there will be code that
 uses both types of interfaces for these very reasons (and maybe other
 types which have other added behaviour). Such code would become a lot less
 maintainable since you'd never know whether a given interface has a
 particular method just because the one next to it does.

 OTOH, registering all behaviour an application needs onto the same
 interface type doesn't create that problem. As long as you're familiar
 with the application at large, you will know for every interface that
 occurs in it which methods is has, how they need to be called and what
 their semantics are.

 Also, subclassing for adding behaviour introduces the typical problems of
 hierarchies and tight coupling. This isn't a practical problem as long as
 we only ever talk about adaptation as the only use of interfaces, but I'm
 trying to discuss interfaces as a language feature with a greater set of
 possible use cases.

 
 Maybe a hook or API extension just isn't the right thing here.  Maybe we 
 just give up on the idea that z.component worldview doesn't belong in 
 z.interface, for the sake of implementation simplicity.
 
 - Move the Components class from zope.component.registry to
zope.interface.adapter and leave behind an import alias.
 
 - Move the base registry from zope.component.globalregistry
into zope.interface.adapter and leave behind an import alias.
 
 - Move the getSiteManager function from zope.component._api into
zope.interface.adapter and leave behind an import alias.
 
 - Move the hookable implementation from zope.component.hookable
into zope.interface.hookable and leave behind an import alias.
 
 - Change the zope.interface.interface.InterfaceClass implementation
directly, adding adapts and utility methods, which would
use zope.interface.adapter.getSiteManager to find the registry.
 
 z.interface would then become responsible for:
 
 - Providing an implementation of a component registry which has
a z.c worldview: adapters and utilities, stolen from
z.c.registry.Components.
 
 - Providing a function that returns the current component registry
(getSiteManager, which will continue to be hookable;
although maybe we should take the opportunity to rename it to
actually mean something).
 
 - Providing the instance that is the default component registry.
 
 All other responsibility (global API functions, a persistent registry 
 implementation, security stuff, zcml support, etc), would remain in 
 z.component.
 
 This would also line up conceptually with usage of the ZCA by BFG, which 
 does 
 not hook getSiteManager by default, but still uses a ZCA component registry.
 
 - C

OK, I just tried this.  It's maybe 2 days worth of effort to untangle this as 
it also effectively means:

- Moving the majority of interfaces and exceptions
   from zope.component.interfaces to zope.interface.interfaces

- Folding zope.event into zope.interface (this turns out to make sense when
   you're down the rabbit hole some of the way).

- Untangling the tests.

I thought maybe it might be a bit easier (I thought maybe I could get it done 
today) so I'm going to give up the idea of doing it on spec without some 
positive feedback about the idea.

- C
___
Zope-Dev maillist  -  Zope-Dev@zope.org
https://mail.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 https://mail.zope.org/mailman/listinfo/zope-announce
 https://mail.zope.org/mailman/listinfo/zope )


Re: [Zope-dev] A summary of Interfaces vs ZCA concepts

2009-12-22 Thread Martijn Faassen
Hey,

Chris McDonough wrote:
[snip experiment folding zope.component bits into zope.interface]
 I thought maybe it might be a bit easier (I thought maybe I could get it done 
 today) so I'm going to give up the idea of doing it on spec without some 
 positive feedback about the idea.

Thanks for trying this! I do think it's an interesting direction to 
explore. We really need to involve Gary into this, though, to see 
whether it fits his thoughts. I've cc-ed him on this so he knows to look 
in this thread again.

Regards,

Martijn

___
Zope-Dev maillist  -  Zope-Dev@zope.org
https://mail.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 https://mail.zope.org/mailman/listinfo/zope-announce
 https://mail.zope.org/mailman/listinfo/zope )


Re: [Zope-dev] A summary of Interfaces vs ZCA concepts

2009-12-21 Thread Thomas Lotze
Hi,

this is a long message with a lot of replies to things that I don't agree
with. Since I realize that making those points over and over again doesn't
get us anywhere, I'd like to point out first that I'm going to implement
Martijn's suggestions anyway on one of my branches, hoping that seeing
more actual code to talk about might help getting to more consensus.

Martijn Faassen wrote:

 * It'd be nice if __call__ came back with a LookupError instead of a
 TypeError, but how to get from A to B without breakage?
 
 It's not possible without breakage.
 
 Unless we create a zope.interface specific LookupError which subclasses
 both the built-in LookupError and TypeError. zope.component's
 ComponentLookupError should subclass this special LookupError then.

Technically true, so my statement was admittedly too strong. I just don't
feel comfortable with the idea, which may well be just because it's the
let's make both exceptions work sowmehow solution to me instead of the
clear change I thought we were considering. OTOH, it's not that big an
issue either, so I guess I'd be fine with it.

 * the methods can be on zope.interface even if zope.component isn't
 installed. They will behave as if the component registry is empty.
 
 This isn't covered by the consensus you mentioned above as far as I'm
 concerned.
 
 Yeah, I put that in so we can reach consensus on it. I thought Tres had a
 good idea going on there that makes the plugin behavior a lot cleaner.

Hm, I can't help feeling pushed into this. While this plugin stuff is
indeed nice *assuming* that we want all the zope.component concepts in
zope.interface, it doesn't contribute to the decision about *whether* we
want that in the first place.

 IFoo.adapt(context) raises LookupError, unless the context provides
 IFoo, in which case it returns context.

 IFoo.adapt(context, default=default) returns default unless context
 provides IFoo, in which case it returns context.

 IFoo.utility() raises LookupError.

 IFoo.utility(default=default) returns default
 
 I think looking at that API explains why we have trouble with having
 stub methods defined by zope.interface: these methods contain enough
 information about component concepts to blur the distinction between
 zope.interface and zope.component, but they still lie about the actual
 method signature.

 I don't understand you: why do you say they lie about their method
 signature? They should have the same signature and have a well-defined
 behavior if zope.component is not installed: there is nothing registered
 at all. zope.interface provides a plugin point that allows one to plug
 lookup behavior into it.

When I wrote that, I was assuming that we were talking about patching
interfaces with methods that have zope.component's full lookup semantics,
including `name` and `context` parameters - which abviously would change
the signatures. If we're talking about something that doesn't add those
parameters, there's no lie involved but I don't see how our lookup methods
could then access the full feature set of zope.component's lookups.

 In that case, I want the real contract to be in zope.interface. That's
 where the methods are, after all. We need to talk about the concept of an
 adapter and a utility briefly in zope.interface and defer to
 zope.component as the most common implementation. We already have this
 kind of behavior going on anyway with __call__() (even though not
 documented!).

Well, we obviously disagree completely about this. The existing __call__
method is neither a good example of a zope.component lookup API, nor do I
think that it was fortunate to wire up the adaptation concept in
zope.interface through __call__ in the first place. I'd rather try to
loosen this reference to component concepts than use it as a reason for
adding more.

 You'll have to go into more detail. Why does it feel wrong to you?

Because it is just another way of encoding the zope.component details
within zope.interface. I would love to add a plugin API that is generic
enough to apply equally to other uses of interfaces than component lookup,
and that would allow implementations of component lookup with different
concepts and different lookup methods than those of zope.component.

 Why is it a problem that the zope.interface package gains knowledge about
 adaptation (which it always had, anyway)

(and which, IMO, it shouldn't have in the first place)

 and utility lookup?

Because if we're serious about making interfaces more of a language
feature, they should at their core be reduced to *being* mostly
information (maybe with a bit of verification code) instead of extended to
*doing* things that derive mainly from *our* particular ways of using them.

 Because to
 the user of those methods on Interface, it looks exactly like the
 packa
 does have such knowledge. We shouldn't lie.ge

I don't think that we lie as long as we state that we have a plugin system
of any kind (including monkey-patching, for the sake of 

Re: [Zope-dev] A summary of Interfaces vs ZCA concepts

2009-12-21 Thread Chris McDonough
Thomas Lotze wrote:
 Chris McDonough wrote:
 
 I'll throw out the obvious...

 Why not subclass Interface in zope.component and make the required API
 additions there?  If it were anybody but us thinking about doing this,
 they'd probably just subclass.
 
 Because then, if you use third-party code that uses
 zope.interface.Interface and other code (third-party or your own) that
 uses the subclassed interfaces, you'll have to deal with both types at the
 same time in your client code. You could use the new API on some
 interfaces but not on others, possibly on the same line of code. How
 readable or maintainable would such code be?

I'm not sure, but if we had it to do all over again, this would be an obvious 
solution.  It would be the work of maybe two days to convert all ZTK packages 
to use a z.c.interface.Interface, and any existing package would need to be 
touched anyway to use .adapt and .utility.  So it bears some weight I think, 
even if it is eventually rejected.

- C

___
Zope-Dev maillist  -  Zope-Dev@zope.org
https://mail.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 https://mail.zope.org/mailman/listinfo/zope-announce
 https://mail.zope.org/mailman/listinfo/zope )


Re: [Zope-dev] A summary of Interfaces vs ZCA concepts

2009-12-21 Thread Thomas Lotze
Chris McDonough wrote:

 Thomas Lotze wrote:
 Because then, if you use third-party code that uses
 zope.interface.Interface and other code (third-party or your own) that
 uses the subclassed interfaces, you'll have to deal with both types at
 the same time in your client code. You could use the new API on some
 interfaces but not on others, possibly on the same line of code. How
 readable or maintainable would such code be?
 
 I'm not sure, but if we had it to do all over again, this would be an
 obvious solution.  It would be the work of maybe two days to convert all
 ZTK packages to use a z.c.interface.Interface, and any existing package
 would need to be touched anyway to use .adapt and .utility.  So it bears
 some weight I think, even if it is eventually rejected.

It does certainly bear some weight as one possibility to be considered.
However, my point wasn't so much about converting a limited existing
amount of code; you're obviously right about having to touch that anyway
in order to use the new methods.

My objection is this: If we go to the trouble of implementing basic
interfaces in zope.interface plus derived ones with component lookup
capabilities in zope.component and keep both around for their respective
reasons of existence, then it is expected that there will be code that
uses both types of interfaces for these very reasons (and maybe other
types which have other added behaviour). Such code would become a lot less
maintainable since you'd never know whether a given interface has a
particular method just because the one next to it does.

OTOH, registering all behaviour an application needs onto the same
interface type doesn't create that problem. As long as you're familiar
with the application at large, you will know for every interface that
occurs in it which methods is has, how they need to be called and what
their semantics are.

Also, subclassing for adding behaviour introduces the typical problems of
hierarchies and tight coupling. This isn't a practical problem as long as
we only ever talk about adaptation as the only use of interfaces, but I'm
trying to discuss interfaces as a language feature with a greater set of
possible use cases.

-- 
Thomas



___
Zope-Dev maillist  -  Zope-Dev@zope.org
https://mail.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 https://mail.zope.org/mailman/listinfo/zope-announce
 https://mail.zope.org/mailman/listinfo/zope )


Re: [Zope-dev] A summary of Interfaces vs ZCA concepts

2009-12-20 Thread Thomas Lotze
Chris McDonough wrote:

 I'll throw out the obvious...
 
 Why not subclass Interface in zope.component and make the required API
 additions there?  If it were anybody but us thinking about doing this,
 they'd probably just subclass.

Because then, if you use third-party code that uses
zope.interface.Interface and other code (third-party or your own) that
uses the subclassed interfaces, you'll have to deal with both types at the
same time in your client code. You could use the new API on some
interfaces but not on others, possibly on the same line of code. How
readable or maintainable would such code be?

-- 
Thomas



___
Zope-Dev maillist  -  Zope-Dev@zope.org
https://mail.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 https://mail.zope.org/mailman/listinfo/zope-announce
 https://mail.zope.org/mailman/listinfo/zope )


Re: [Zope-dev] A summary of Interfaces vs ZCA concepts

2009-12-18 Thread Wolfgang Schnerring
* Martijn Faassen faas...@startifact.com [2009-12-17 17:48]:
 * Thomas Lotze t...@gocept.com:
  zope.interface [should be] completely unaware of any particular uses
  of interfaces

 Why is it a problem that the zope.interface package gains knowledge 
 about adaptation (which it always had, anyway) and utility lookup? 

This is the key issue, I think.
(And I'd like to ask you not to argue it has always been that way,
since what we're trying to do here precisely is to improve the status
quo.)

The question is, which concepts belong into zope.interface and which don't?
One might also phrase that as, what is the responsibility and purpose of
zope.interface (drawing upon the software engineering terms of cohesion
and coupling).

My opinion is that

 [__call__ introduces] the following notion into zope.interface:
 please look up an object that provides this interface, somehow. (with 
 zero or more context objects)

might well belong into zope.interface, but that anything of these:

 adapters, utilities, null-adapters or contextual utilities

absolutely do not.

I think there is a clear distinction between what interfaces are about
and what component architecture is about, and I think it is worthwile
to maintain and clarify that distinction.

For me, a notion of looking up something that provides an interface
belongs to what interfaces are about.
But notions of utilities which might or might not be singletons, of
adapters which might or might not take additional parameters such as a
name to look them up, or notions of a context or a registry (which
for me comes up immediately when thinking about global vs. local
utilities) that influences the lookup, for me emphatically do *not* belong
to what interfaces are about.

By putting method stubs into zope.interface which are exclusively about
concepts of zope.component we would be
a) On a conceptual level: blurring the distinction between the two
packages and concepts, which I think is a Bad Thing(tm)
b) On a more practical level: coupling zope.interface to zope.component.
Given all the recent efforts of untangling the dependency structure
between our packages, I think doing that would be a step in the exact
opposite direction.

Wolfgang

___
Zope-Dev maillist  -  Zope-Dev@zope.org
https://mail.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 https://mail.zope.org/mailman/listinfo/zope-announce
 https://mail.zope.org/mailman/listinfo/zope )


Re: [Zope-dev] A summary of Interfaces vs ZCA concepts

2009-12-18 Thread Martijn Faassen
Wolfgang Schnerring wrote:
 * Martijn Faassen faas...@startifact.com [2009-12-17 17:48]:
 * Thomas Lotze t...@gocept.com:
 zope.interface [should be] completely unaware of any particular uses
 of interfaces
 Why is it a problem that the zope.interface package gains knowledge 
 about adaptation (which it always had, anyway) and utility lookup? 
 
 This is the key issue, I think.
 (And I'd like to ask you not to argue it has always been that way,
 since what we're trying to do here precisely is to improve the status
 quo.)

I'm saying that because I don't recall people arguing against this 
before. Since the __call__ logic is only about adapter lookup, does this 
mean that your argument is expanded against this as well or does it fall 
under the notion of looking up anything by interface? I think from the 
rest of your mail that you mean the latter. At least it's a strict 
subset of an expanded notion of lookup.

[snip]
 By putting method stubs into zope.interface which are exclusively about
 concepts of zope.component we would be

I would say that to be consistent in that position, you would need to 
argue not just against method stubs but against the presence of these 
methods at all, no matter where they come from. The rest is just an 
implementation detail.

Reasoning from your position that zope.interface shouldn't have notions 
of adapter and utility lookup, it hardly matters what package implements 
these methods. To the user of Interface it will look the same, except 
that zope.component monkey-patching things in would be harder to 
understand and debug.

To be consistent we have the following options:

* only provide a general notion of looking up something by interface 
in zope.interface. This general notion unfortunately clearly doesn't 
have support from a large number of people so sadly I had to let that go.

* not change anything at all. Looking up these things remains the task 
of zope.component and we better use zope.component APIs.

Monkey-patching methods in from another package to me looks like it 
doesn't improve the conceptual story at all. Conceptually Interface ends 
up as messed up as before and it becomes more difficult to understand 
what's going on for the code reader or debugger.

  which might or might not take additional parameters such as a
  name to look them up ...
  for me emphatically do *not* belong to what interfaces are about.

I think you can see a name as another context in a multi-adaptation, 
where this context is special in that:

* it needs to be human-readable text

* it cannot extend another name, unlike interfaces, which can extend 
each other

It's just a handy shortcut. :)

  By putting method stubs into zope.interface which are exclusively
  about concepts of zope.component we would be
  a) On a conceptual level: blurring the distinction between the two
  packages and concepts, which I think is a Bad Thing(tm)
  b) On a more practical level: coupling zope.interface to
  zope.component.
  Given all the recent efforts of untangling the dependency structure
  between our packages, I think doing that would be a step in the exact
  opposite direction.

I don't think the dependency refactoring argument holds. We were 
untangling physical dependencies. This wouldn't change physical 
dependencies one bit: zope.component would still depend on 
zope.interface. There are likely tons of places where package A depends 
on package B and also configures package B, changing its behavior. This 
would be no different: zope.component depends on zope.interface and 
plugs into it as well to configure some of its behavior. That's what it 
does today with the adapter hook.

Putting notions of conceptual purity aside, I was arguing for a 
pragmatic solution that results in code that is as unsurprising as possible.

I don't think .adapt and .utility are perfect, and I would have gone for 
another solution myself (a more generalized lookup method), but they 
seem to have consensus support. I don't think they do much in the way of 
active harm by being there in zope.interface. They help readability of 
the code that uses them. Moreover, this pragmatic solution would make 
code that looks up multi adapters and utilities more convenient to write.

So, zope.interface needs to gain these methods, and open up a plugin 
point so that these methods can be fully implemented by another package. 
I think this can be constructed so that the only new notions to 
zope.interface are:

* multi-adaptation, an extension of adaptation

* look up by name, a conceptual extension of multi-adaptation :)

* utility lookup

Too many for my tastes when there's such an elegant general lookup 
method available, but I can't convince enough people of that.

If we are going to make Interface support these methods for pragmatic 
considerations, we should just face it and implement them on Interface 
(delegating to a plugin). Anything else just helps to obfuscate what is 
going on.

Regards,

Martijn


Re: [Zope-dev] A summary of Interfaces vs ZCA concepts

2009-12-18 Thread Lennart Regebro
On Fri, Dec 18, 2009 at 08:51, Brian Sutherland br...@vanguardistas.net wrote:
 I like things to fail noisily and loudly unconfigured and give good
 information about what's wrong.

+1

  So my preferred implementation of a
 stub utility function on Interface is:

    def utility(default=None):
        Lookup a utility for this interface.

        A utility is a ${long explanation of utility concept}.

        This method behaves like ${explanation of utility method contract}.
        
        raise NotImplementedError(No Utility lookup mechanism has been 
 configured.
            If you wish to use utility lookups on interfaces, please configure 
 a
            package that contains this mechanism. Packages known to
            implement this are:
                zope.component
            )

 I agree that this encodes in the zope.interface package concepts from
 zope.component.


I think that is stretching the encoding concepts a bit too far. Yes,
we make zope.interface aware that such a thing as utility-registries
exist, but say we don't implement it. I don't think that's a problem.
The error message also gives an example of an implementation. That's
probably not a problem either.

 I feel uncomfortable about that.

I don't. :-)

-- 
Lennart Regebro: http://regebro.wordpress.com/
Python 3 Porting: http://python-incompatibility.googlecode.com/
+33 661 58 14 64
___
Zope-Dev maillist  -  Zope-Dev@zope.org
https://mail.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 https://mail.zope.org/mailman/listinfo/zope-announce
 https://mail.zope.org/mailman/listinfo/zope )


Re: [Zope-dev] A summary of Interfaces vs ZCA concepts

2009-12-18 Thread Ethan Jucovy
Hi,

On Fri, Dec 18, 2009 at 9:47 AM, Lennart Regebro rege...@gmail.com wrote:
 On Fri, Dec 18, 2009 at 08:51, Brian Sutherland br...@vanguardistas.net 
 wrote:
 I like things to fail noisily and loudly unconfigured and give good
 information about what's wrong.

 +1
[snip]
 we make zope.interface aware that such a thing as utility-registries
 exist, but say we don't implement it. I don't think that's a problem.
 The error message also gives an example of an implementation. That's
 probably not a problem either.

 I feel uncomfortable about that.

 I don't. :-)

+1 from my perspective of I don't know or understand the core ZCA
codebase very well (and don't understand all the implications in this
discussion) but often read or trace through the code.  A
well-documented NotImplementedError seems much more human-useful than
a default implementation that fulfills the contract, because it
assertively announces the expectation for the most common case by far:
you probably want to plug in a real implementation here.  Then if
there is a need for the proposed default implementation, it can be
provided as a plugin by some other package, right?

-Ethan
___
Zope-Dev maillist  -  Zope-Dev@zope.org
https://mail.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 https://mail.zope.org/mailman/listinfo/zope-announce
 https://mail.zope.org/mailman/listinfo/zope )


Re: [Zope-dev] A summary of Interfaces vs ZCA concepts

2009-12-18 Thread Martijn Faassen
Ethan Jucovy wrote:
 +1 from my perspective of I don't know or understand the core ZCA
 codebase very well (and don't understand all the implications in this
 discussion) but often read or trace through the code.  A
 well-documented NotImplementedError seems much more human-useful than
 a default implementation that fulfills the contract, because it
 assertively announces the expectation for the most common case by far:
 you probably want to plug in a real implementation here.  Then if
 there is a need for the proposed default implementation, it can be
 provided as a plugin by some other package, right?

I'm now convinced people want to see a clear NotImplementedError.

I think if we went with a plugin structure, we could do something like this:

class Interface:
 ...
 def utility(...):
return lookup_plugin.utility(...)

class NotImplementedLookupPlugin(object):
 def utility(...):
 raise NotImplementedError(
this is the not implemented lookup plugin. You need to install another 
one. Blah blah zope.component blah blah)

lookup_plugin = NotImplementedLookupPlugin()

def set_lookup_plugin(plugin):
 global lookup_plugin
 lookup_plugin = plugin

As long as external packages do not register a proper plugin, it'll 
raise NotImplementedErrors. Both the actual error as well as the name of 
the default lookup plugin signal something hasn't been installed.

We could also easily provide *another* plugin in zope.interface that 
does the as if the registry is empty behavior, if that turns out to be 
useful (perhaps for testing). But to use it someone would need to 
explicitly enable it. Tests could also define fake lookup plugins with 
other behavior so we can test these methods properly.

Regards,

Martijn

___
Zope-Dev maillist  -  Zope-Dev@zope.org
https://mail.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 https://mail.zope.org/mailman/listinfo/zope-announce
 https://mail.zope.org/mailman/listinfo/zope )


Re: [Zope-dev] A summary of Interfaces vs ZCA concepts

2009-12-18 Thread Tres Seaver
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

Ethan Jucovy wrote:
 Hi,
 
 On Fri, Dec 18, 2009 at 9:47 AM, Lennart Regebro rege...@gmail.com wrote:
 On Fri, Dec 18, 2009 at 08:51, Brian Sutherland br...@vanguardistas.net 
 wrote:
 I like things to fail noisily and loudly unconfigured and give good
 information about what's wrong.
 +1
 [snip]
 we make zope.interface aware that such a thing as utility-registries
 exist, but say we don't implement it. I don't think that's a problem.
 The error message also gives an example of an implementation. That's
 probably not a problem either.

 I feel uncomfortable about that.
 I don't. :-)
 
 +1 from my perspective of I don't know or understand the core ZCA
 codebase very well (and don't understand all the implications in this
 discussion) but often read or trace through the code.  A
 well-documented NotImplementedError seems much more human-useful than
 a default implementation that fulfills the contract, because it
 assertively announces the expectation for the most common case by far:
 you probably want to plug in a real implementation here.  Then if
 there is a need for the proposed default implementation, it can be
 provided as a plugin by some other package, right?

The same argument applies in your case:  you could plug in your own
wrapper implementation which raised errors if not replaced.

- -1 to raising NotImplementedError.


Tres.
- --
===
Tres Seaver  +1 540-429-0999  tsea...@palladion.com
Palladion Software   Excellence by Designhttp://palladion.com
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkssANoACgkQ+gerLs4ltQ57XgCdGN8W4q4IevSbQX+XgaRaUXA4
rNkAn1ART1odK+s576b8GbjGX6JIJh6u
=VJnE
-END PGP SIGNATURE-
___
Zope-Dev maillist  -  Zope-Dev@zope.org
https://mail.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 https://mail.zope.org/mailman/listinfo/zope-announce
 https://mail.zope.org/mailman/listinfo/zope )


[Zope-dev] A summary of Interfaces vs ZCA concepts

2009-12-17 Thread Martijn Faassen
Hi there,

Here's a summary of what has been going on in this thread with some 
attempts at conclusions that have support of the consensus so that 
Thomas can proceed

* We want to implement .adapter(), .utility() and .__call__() in 
zope.component as much as possible.

* we want a similar mechanism for each of them to plug in.

* It'd be nice if __call__ came back with a LookupError instead of a 
TypeError, but how to get from A to B without breakage?

* there was some discussion about general plugin points on Interface. 
Those have a complexity cost compared to simply poking the methods into 
the class.

* the methods can be on zope.interface even if zope.component isn't 
installed. They will behave as if the component registry is empty. Their 
behavior should be:

IFoo.adapt(context) raises LookupError, unless the context
provides IFoo, in which case it returns context.

IFoo.adapt(context, default=default) returns default unless context 
provides IFoo, in which case it returns context.

IFoo.utility() raises LookupError.

IFoo.utility(default=default) returns default

What's the behavior of __call__ now if zope.component isn't around?

* Tres brought up that we can come up with a clean plugin interface 
instead, and now I'm tempted to go for that instead of monkey-ing around.

What if there's some global object that zope.component can register into 
that has this API?

class ILookupPlugin(Interface):
def singleAdapt(interface, context):
Look up an adapter that provides interface in the adapter
   registry for context.

If no adapter can be found, raise LookupError. (
(or return None or another sentinel? See below for an argument
 in favor of LookupError)
   

def multiAdapt(interface, contexts):
   Look up an adapter that provides interface for contexts.
   

def utility(interface):
   Lookup an utility that provides interface.
   

And a way to register this into zope.interface (globally):

def registerLookupPlugin(plugin):
 ...

The default plugin provided by zope.interface always raises 
ComponentLookupError (or returns the sentinel). The plugin is not 
responsible for handling defaults, just registry lookups.

Then the code in __call__, adapt and utility can:

* check whether the context (if available) already provides interface, 
return that.

* look up in the plugin

* if the plugin raises (or returns sentinel) and there is a default,
   return default

* if there no default, raise LookupError. I think we can turn the 
message from ComponentLookupError into a LookupError fairly safely, so I 
think having the plugin raise exceptions is better as it retains more 
information. In fact it'd be entirely safe to just reraise 
ComponentLookupError as we only specify LookupError in the API and the 
ComponentLookupError *is* a LookupError

I realize that the proposal for a plugin API gives zope.interface some 
knowledge about adaption and utility lookups, which is what Thomas and 
Wolfgang had trouble with. But after all that's what we're doing anyway 
by putting those methods on the API, one way or another. And we can 
define sensible enough behavior even if zope.component is not installed. 
If someone comes up with *another* implementation besides 
zope.component, say, zope.component2, zope.interface could cleanly deal 
with that too.

[Philosophically from my own perspective I think we'd have much less 
conceptual difficulty with this if we just made __call__ do all lookups, 
as that hides the whole set of concepts of utility versus adapter a bit, 
but we can't get consensus for that unfortunately. But I'm biding my time..]

Regards,

Martijn

___
Zope-Dev maillist  -  Zope-Dev@zope.org
https://mail.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 https://mail.zope.org/mailman/listinfo/zope-announce
 https://mail.zope.org/mailman/listinfo/zope )


Re: [Zope-dev] A summary of Interfaces vs ZCA concepts

2009-12-17 Thread Ethan Jucovy
Hi,

On Thu, Dec 17, 2009 at 10:15 AM, Martijn Faassen
faas...@startifact.com wrote:
 * It'd be nice if __call__ came back with a LookupError instead of a
 TypeError, but how to get from A to B without breakage?

Maybe I've misunderstanding, but what's the advantage of making
IFoo(x) raise a LookupError instead of a TypeError?  I've tried to
follow the thread but I've been confused about this.  I do rely on
catching TypeErrors quite often in my code -- I had thought it was
intended as part of the API.

I like that treating it as typecasting instead of lookup blurs the
conceptual distinction between adapting x to IFoo and asserting x
implements IFoo directly -- when I actually want to know one or the
other I can use explicit adaptation or check providedBy.  In other
words I use IFoo(x) when I don't care whether IFoo(x) == x.

I suppose it's not a big deal but catching LookupErrors instead would
feel somewhat less semantic for the way I think about this.  But from
what I've caught of the larger thread it sounds like I'm in the
minority here.

-Ethan
___
Zope-Dev maillist  -  Zope-Dev@zope.org
https://mail.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 https://mail.zope.org/mailman/listinfo/zope-announce
 https://mail.zope.org/mailman/listinfo/zope )


Re: [Zope-dev] A summary of Interfaces vs ZCA concepts

2009-12-17 Thread Wichert Akkerman
On 12/17/09 16:36 , Ethan Jucovy wrote:
 Hi,

 On Thu, Dec 17, 2009 at 10:15 AM, Martijn Faassen
 faas...@startifact.com  wrote:
 * It'd be nice if __call__ came back with a LookupError instead of a
 TypeError, but how to get from A to B without breakage?

 Maybe I've misunderstanding, but what's the advantage of making
 IFoo(x) raise a LookupError instead of a TypeError?  I've tried to
 follow the thread but I've been confused about this.  I do rely on
 catching TypeErrors quite often in my code -- I had thought it was
 intended as part of the API.

 I like that treating it as typecasting instead of lookup blurs the
 conceptual distinction between adapting x to IFoo and asserting x
 implements IFoo directly -- when I actually want to know one or the
 other I can use explicit adaptation or check providedBy.  In other
 words I use IFoo(x) when I don't care whether IFoo(x) == x.

 I suppose it's not a big deal but catching LookupErrors instead would
 feel somewhat less semantic for the way I think about this.  But from
 what I've caught of the larger thread it sounds like I'm in the
 minority here.

Perhapse LookupError should be a subclass of TypeError.

Wichert.
___
Zope-Dev maillist  -  Zope-Dev@zope.org
https://mail.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 https://mail.zope.org/mailman/listinfo/zope-announce
 https://mail.zope.org/mailman/listinfo/zope )


Re: [Zope-dev] A summary of Interfaces vs ZCA concepts

2009-12-17 Thread Martijn Faassen
Hey,

Ethan Jucovy wrote:
 On Thu, Dec 17, 2009 at 10:15 AM, Martijn Faassen 
 faas...@startifact.com wrote:
 * It'd be nice if __call__ came back with a LookupError instead of
 a TypeError, but how to get from A to B without breakage?
 
 Maybe I've misunderstanding, but what's the advantage of making 
 IFoo(x) raise a LookupError instead of a TypeError?  I've tried to 
 follow the thread but I've been confused about this.  I do rely on 
 catching TypeErrors quite often in my code -- I had thought it was 
 intended as part of the API.

Consistency. The other lookup APIs in zope.component raise
ComponentLookupError, which is a kind of LookupError.

Good data point about catching TypeError though - I don't think we can
just make a release that breaks this.

 I like that treating it as typecasting instead of lookup blurs the 
 conceptual distinction between adapting x to IFoo and asserting x 
 implements IFoo directly -- when I actually want to know one or the 
 other I can use explicit adaptation or check providedBy.  In other 
 words I use IFoo(x) when I don't care whether IFoo(x) == x.

Yeah, TypeError makes sense from the type casting perspective.

Perhaps my earlier idea about a new Error that subclasses both TypeError 
and LookupError isn't so ugly after all.. After all a failure to look up 
an adapter can easily be interpreted as both.

Regards,

Martijn


___
Zope-Dev maillist  -  Zope-Dev@zope.org
https://mail.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 https://mail.zope.org/mailman/listinfo/zope-announce
 https://mail.zope.org/mailman/listinfo/zope )


Re: [Zope-dev] A summary of Interfaces vs ZCA concepts

2009-12-17 Thread Thomas Lotze
Martijn Faassen wrote:

 Here's a summary of what has been going on in this thread with some
 attempts at conclusions that have support of the consensus so that Thomas
 can proceed

Thank you, half an hour later and I'd have written the summary ;o)

 * We want to implement .adapter(), .utility() and .__call__() in
 zope.component as much as possible.

The method's name is `adapt`, JFTR.

 * we want a similar mechanism for each of them to plug in.

Agreed, even though (AFAICT) we haven't been talking about moving the
implementation of __call__ to zope.component so far.

 * It'd be nice if __call__ came back with a LookupError instead of a
 TypeError, but how to get from A to B without breakage?

It's not possible without breakage. I'd say changing the error is worth a
4.0 release, but we might want to postpone this change and see whether
there's anything else we want to change about zope.interface in a
backwards-incompatible way, and if so, put that in the 4.0 release as
well. I guess we don't want too many backwards-incompatible releases of
such a central package.

One thing I start questioning is an adapter registry being implemented by
zope.interface. Moving it to zope.component seems to me to be related to
keeping the implementations of the new method within zope.component.

 * there was some discussion about general plugin points on Interface.
 Those have a complexity cost compared to simply poking the methods into
 the class.

As for poking the methods into the class, see the new
tlotze-patching-interfaces branches of zope.interface and zope.component
for the minimum change this would take IMO. The change to zope.interface
is really just about documentation.

 * the methods can be on zope.interface even if zope.component isn't
 installed. They will behave as if the component registry is empty.

This isn't covered by the consensus you mentioned above as far as I'm
concerned.

 Their behavior should be:
 
 IFoo.adapt(context) raises LookupError, unless the context provides IFoo,
 in which case it returns context.
 
 IFoo.adapt(context, default=default) returns default unless context
 provides IFoo, in which case it returns context.
 
 IFoo.utility() raises LookupError.
 
 IFoo.utility(default=default) returns default

I think looking at that API explains why we have trouble with having stub
methods defined by zope.interface: these methods contain enough
information about component concepts to blur the distinction between
zope.interface and zope.component, but they still lie about the actual
method signature. In that sense, these stubs would be worse than
zope.interface not documenting the methods at all.

In my and Wolfgang's opinion, we can either have zope.interface implement
methods with the real contract, which would mean defining the full
concepts of the ZCA within zope.interface (if not their implementation),
or not even have method stubs in zope.interface and leave the whole
business of defining specialised uses of interfaces to other packages such
as zope.component.

 What's the behavior of __call__ now if zope.component isn't around?

Similar to what you've just described of your `adapt` method, up to the
name of the `default` parameter and the exception raised.

 * Tres brought up that we can come up with a clean plugin interface
 instead, and now I'm tempted to go for that instead of monkey-ing around.
[...]

I'd have to think about that some more, but while reading it the first
time, it feels quite wrong to me.

 I realize that the proposal for a plugin API gives zope.interface some
 knowledge about adaption and utility lookups, which is what Thomas and
 Wolfgang had trouble with. But after all that's what we're doing anyway by
 putting those methods on the API, one way or another.

No: the zope.interface package doesn't have any knowledge about the
particulars of any of the uses of interfaces. One might claim that
interfaces do after they've been patched by other code, but then, that's
after some application has made its choice about plugin certain packages
together. It's not baked into zope.interface, and that's what we're trying
so hard to achieve.

 [Philosophically from my own perspective I think we'd have much less
 conceptual difficulty with this if we just made __call__ do all lookups,
 as that hides the whole set of concepts of utility versus adapter a bit,
 but we can't get consensus for that unfortunately. But I'm biding my
 time..]

Implementing __call__ within zope.interface in that way would get the
package rid of the method names `adapt` and `utility`, but the technical
problem with the method signatures and the more philosophical one about
whether zope.interface should really make adaptation stand out as a use of
interfaces remains.

Which brings me back to the question I asked earlier, and which nobody has
replied to so far: Do we want to make zope.interface completely unaware of
any particular uses of interfaces, or do we want to treat component lookup
and in particular 

Re: [Zope-dev] A summary of Interfaces vs ZCA concepts

2009-12-17 Thread Martijn Faassen
Wichert Akkerman wrote:
[knip]
 Perhapse LookupError should be a subclass of TypeError.

It's a Python built-in. :)

Regards,

Martijn

___
Zope-Dev maillist  -  Zope-Dev@zope.org
https://mail.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 https://mail.zope.org/mailman/listinfo/zope-announce
 https://mail.zope.org/mailman/listinfo/zope )


Re: [Zope-dev] A summary of Interfaces vs ZCA concepts

2009-12-17 Thread Martijn Faassen
Hey,

Thomas Lotze wrote:
[snip]
 * We want to implement .adapter(), .utility() and .__call__() in
 zope.component as much as possible.
 
 The method's name is `adapt`, JFTR.

Whoops, yes, I prefer 'adapt' actually anyway. :)

 * we want a similar mechanism for each of them to plug in.
 
 Agreed, even though (AFAICT) we haven't been talking about moving the
 implementation of __call__ to zope.component so far.

I figured we'd want to treat each of them in the same way.

 * It'd be nice if __call__ came back with a LookupError instead of a
 TypeError, but how to get from A to B without breakage?
 
 It's not possible without breakage.

Unless we create a zope.interface specific LookupError which subclasses 
both the built-in LookupError and TypeError. zope.component's 
ComponentLookupError should subclass this special LookupError then.

 One thing I start questioning is an adapter registry being implemented by
 zope.interface. Moving it to zope.component seems to me to be related to
 keeping the implementations of the new method within zope.component.

I'm not sure where that stuff should be. I'll defer some of this to Gary 
again, who is interested in working on this topic. :)

[snip]
 * the methods can be on zope.interface even if zope.component isn't
 installed. They will behave as if the component registry is empty.
 
 This isn't covered by the consensus you mentioned above as far as I'm
 concerned.

Yeah, I put that in so we can reach consensus on it. I thought Tres had 
a good idea going on there that makes the plugin behavior a lot cleaner.

 Their behavior should be:

 IFoo.adapt(context) raises LookupError, unless the context provides IFoo,
 in which case it returns context.

 IFoo.adapt(context, default=default) returns default unless context
 provides IFoo, in which case it returns context.

 IFoo.utility() raises LookupError.

 IFoo.utility(default=default) returns default
 
 I think looking at that API explains why we have trouble with having stub
 methods defined by zope.interface: these methods contain enough
 information about component concepts to blur the distinction between
 zope.interface and zope.component, but they still lie about the actual
 method signature.

I don't understand you: why do you say they lie about their method 
signature? They should have the same signature and have a well-defined 
behavior if zope.component is not installed: there is nothing registered 
at all. zope.interface provides a plugin point that allows one to plug 
lookup behavior into it.

 In that sense, these stubs would be worse than
 zope.interface not documenting the methods at all.

I strongly disagree. We want to define a bunch of methods on Interface 
that we want everybody to have access to. We can't then turn around and 
say we really actually don't want to implement those methods on Interface.

That Interface *delegates* the implementation to something else is fine, 
but the methods are conceptually on Interface, and delegation is 
normally implemented by just calling the code we delegate to.

 In my and Wolfgang's opinion, we can either have zope.interface implement
 methods with the real contract, which would mean defining the full
 concepts of the ZCA within zope.interface (if not their implementation),
 or not even have method stubs in zope.interface and leave the whole
 business of defining specialised uses of interfaces to other packages such
 as zope.component.

In that case, I want the real contract to be in zope.interface. That's 
where the methods are, after all. We need to talk about the concept of 
an adapter and a utility briefly in zope.interface and defer to 
zope.component as the most common implementation. We already have this 
kind of behavior going on anyway with __call__() (even though not 
documented!).

 What's the behavior of __call__ now if zope.component isn't around?
 
 Similar to what you've just described of your `adapt` method, up to the
 name of the `default` parameter and the exception raised.

So if no registry is available (zope.component not installed), you can 
still call it and it'll just behave as if the registry is empty? That's 
good..

 * Tres brought up that we can come up with a clean plugin interface
 instead, and now I'm tempted to go for that instead of monkey-ing around.
 [...]
 
 I'd have to think about that some more, but while reading it the first
 time, it feels quite wrong to me.

You'll have to go into more detail. Why does it feel wrong to you? It's 
the way plugin APIs generally tend to work. You could even look up this 
API as a utility - but that's probably a chicken and egg problem. :)

[see below for a possible improvement on this API]

 I realize that the proposal for a plugin API gives zope.interface some
 knowledge about adaption and utility lookups, which is what Thomas and
 Wolfgang had trouble with. But after all that's what we're doing anyway by
 putting those methods on the API, one way or another.
 
 No: the zope.interface package 

Re: [Zope-dev] A summary of Interfaces vs ZCA concepts

2009-12-17 Thread Chris McDonough
I'll throw out the obvious...

Why not subclass Interface in zope.component and make the required API 
additions there?  If it were anybody but us thinking about doing this, they'd 
probably just subclass.

- C

Martijn Faassen wrote:
 Wichert Akkerman wrote:
 [knip]
 Perhapse LookupError should be a subclass of TypeError.
 
 It's a Python built-in. :)
 
 Regards,
 
 Martijn
 
 ___
 Zope-Dev maillist  -  Zope-Dev@zope.org
 https://mail.zope.org/mailman/listinfo/zope-dev
 **  No cross posts or HTML encoding!  **
 (Related lists - 
  https://mail.zope.org/mailman/listinfo/zope-announce
  https://mail.zope.org/mailman/listinfo/zope )
 

___
Zope-Dev maillist  -  Zope-Dev@zope.org
https://mail.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 https://mail.zope.org/mailman/listinfo/zope-announce
 https://mail.zope.org/mailman/listinfo/zope )


Re: [Zope-dev] A summary of Interfaces vs ZCA concepts

2009-12-17 Thread Gary Poster
Yeah, I was thinking that too, as a I don't have time to think hard about 
this little daydream.  

Actually I believe you would want to subclass InterfaceClass and make your new 
zope.component.Interface an instance of the new InterfaceClass and specify 
zope.interface's Interface as something it extends.

Then packages in the Zope world would start to use that Interface, I'd guess.

I don't know how I feel about it.

Gary


On Dec 17, 2009, at 11:51 AM, Chris McDonough wrote:

 I'll throw out the obvious...
 
 Why not subclass Interface in zope.component and make the required API 
 additions there?  If it were anybody but us thinking about doing this, they'd 
 probably just subclass.
 
 - C
 
 Martijn Faassen wrote:
 Wichert Akkerman wrote:
 [knip]
 Perhapse LookupError should be a subclass of TypeError.
 
 It's a Python built-in. :)
 
 Regards,
 
 Martijn
 
 ___
 Zope-Dev maillist  -  Zope-Dev@zope.org
 https://mail.zope.org/mailman/listinfo/zope-dev
 **  No cross posts or HTML encoding!  **
 (Related lists - 
 https://mail.zope.org/mailman/listinfo/zope-announce
 https://mail.zope.org/mailman/listinfo/zope )
 
 
 ___
 Zope-Dev maillist  -  Zope-Dev@zope.org
 https://mail.zope.org/mailman/listinfo/zope-dev
 **  No cross posts or HTML encoding!  **
 (Related lists - 
 https://mail.zope.org/mailman/listinfo/zope-announce
 https://mail.zope.org/mailman/listinfo/zope )

___
Zope-Dev maillist  -  Zope-Dev@zope.org
https://mail.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 https://mail.zope.org/mailman/listinfo/zope-announce
 https://mail.zope.org/mailman/listinfo/zope )


Re: [Zope-dev] A summary of Interfaces vs ZCA concepts

2009-12-17 Thread Leonardo Rochael Almeida
We've been through this option recently already. It has been quickly
shot down by those who want interfaces to get the new behaviour
immediately available in existing interfaces, instead of having to
rewrite already existing interfaces to support the new API.

Painful memories of a time when we had 2 interface implementations
come to mind. Though in this case, with z.c.Interface extending
z.i.Interface, we probably wouldn't have so much backward
compatibility issues as we had before: the new API would just not be
available in non migrated code, and old code could treat
z.c.Interfaces just like z.i.Interfaces.

On Thu, Dec 17, 2009 at 15:07, Gary Poster gary.pos...@gmail.com wrote:
 Yeah, I was thinking that too, as a I don't have time to think hard about 
 this little daydream.

 Actually I believe you would want to subclass InterfaceClass and make your 
 new zope.component.Interface an instance of the new InterfaceClass and 
 specify zope.interface's Interface as something it extends.

 Then packages in the Zope world would start to use that Interface, I'd guess.

 I don't know how I feel about it.

 Gary


 On Dec 17, 2009, at 11:51 AM, Chris McDonough wrote:

 I'll throw out the obvious...

 Why not subclass Interface in zope.component and make the required API
 additions there?  If it were anybody but us thinking about doing this, they'd
 probably just subclass.

 - C

 Martijn Faassen wrote:
 Wichert Akkerman wrote:
 [knip]
 Perhapse LookupError should be a subclass of TypeError.

 It's a Python built-in. :)

 Regards,

 Martijn

 ___
 Zope-Dev maillist  -  zope-...@zope.org
 https://mail.zope.org/mailman/listinfo/zope-dev
 **  No cross posts or HTML encoding!  **
 (Related lists -
 https://mail.zope.org/mailman/listinfo/zope-announce
 https://mail.zope.org/mailman/listinfo/zope )


 ___
 Zope-Dev maillist  -  zope-...@zope.org
 https://mail.zope.org/mailman/listinfo/zope-dev
 **  No cross posts or HTML encoding!  **
 (Related lists -
 https://mail.zope.org/mailman/listinfo/zope-announce
 https://mail.zope.org/mailman/listinfo/zope )

 ___
 Zope-Dev maillist  -  zope-...@zope.org
 https://mail.zope.org/mailman/listinfo/zope-dev
 **  No cross posts or HTML encoding!  **
 (Related lists -
  https://mail.zope.org/mailman/listinfo/zope-announce
  https://mail.zope.org/mailman/listinfo/zope )

___
Zope-Dev maillist  -  Zope-Dev@zope.org
https://mail.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 https://mail.zope.org/mailman/listinfo/zope-announce
 https://mail.zope.org/mailman/listinfo/zope )


Re: [Zope-dev] A summary of Interfaces vs ZCA concepts

2009-12-17 Thread Martijn Faassen
Chris McDonough wrote:
 I'll throw out the obvious...
 
 Why not subclass Interface in zope.component and make the required API 
 additions there?  If it were anybody but us thinking about doing this, they'd 
 probably just subclass.

Because then we'd need to rebase all our interfaces to be able to use 
the new feature, making it pretty useless as a handy shortcut.

regards,

Martijn

___
Zope-Dev maillist  -  Zope-Dev@zope.org
https://mail.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 https://mail.zope.org/mailman/listinfo/zope-announce
 https://mail.zope.org/mailman/listinfo/zope )


Re: [Zope-dev] A summary of Interfaces vs ZCA concepts

2009-12-17 Thread Chris McDonough
Martijn Faassen wrote:
 Chris McDonough wrote:
 I'll throw out the obvious...

 Why not subclass Interface in zope.component and make the required API 
 additions there?  If it were anybody but us thinking about doing this, 
 they'd 
 probably just subclass.
 
 Because then we'd need to rebase all our interfaces to be able to use 
 the new feature, making it pretty useless as a handy shortcut.

I guess the counterargument is that you need to change your code anyway to make 
use of the new feature.  So what's the difference?

- C


___
Zope-Dev maillist  -  Zope-Dev@zope.org
https://mail.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 https://mail.zope.org/mailman/listinfo/zope-announce
 https://mail.zope.org/mailman/listinfo/zope )


Re: [Zope-dev] A summary of Interfaces vs ZCA concepts

2009-12-17 Thread Martijn Faassen
Chris McDonough wrote:
 Martijn Faassen wrote:
 Chris McDonough wrote:
 I'll throw out the obvious...

 Why not subclass Interface in zope.component and make the required API 
 additions there?  If it were anybody but us thinking about doing this, 
 they'd 
 probably just subclass.
 Because then we'd need to rebase all our interfaces to be able to use 
 the new feature, making it pretty useless as a handy shortcut.
 
 I guess the counterargument is that you need to change your code anyway to 
 make 
 use of the new feature.  So what's the difference?

I'm a bit surprised I need to spell it out, so perhaps I am missing 
something.

With your subclass proposal, if I use package a.b.c that defines an 
interface, and I import that interface and want to use the new feature, 
I'd need to change package a.b.c to make use of the new feature. That's 
a code change (changing the interface import), and a dependency change 
(making sure the new version of zope.component is in use), and a release.

I need to do that for all packages I import interfaces from. I need to 
*know* which packages have been updated or have things blow up on me. 
That's quite a hassle.

The end result would be that everybody ends up inheriting from the new 
zope.component Interface just to get access to the new methods 
everywhere, or that the new methods don't get uptake from users as 
nobody bothers to use the new API because it is too much work changing 
your dependencies.

If we change the Interface base class, I could use the new feature with 
any interface coming from anywhere. I'd only need to make sure that my 
own package depends on a newer version of zope.interface (or possibly a 
newer version of zope.component, depending on the way these methods are 
implemented).

Regards,

Martijn

___
Zope-Dev maillist  -  Zope-Dev@zope.org
https://mail.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 https://mail.zope.org/mailman/listinfo/zope-announce
 https://mail.zope.org/mailman/listinfo/zope )


Re: [Zope-dev] A summary of Interfaces vs ZCA concepts

2009-12-17 Thread Marius Gedminas
On Thu, Dec 17, 2009 at 05:48:04PM +0100, Martijn Faassen wrote:
 Thomas Lotze wrote:
  I think looking at that API explains why we have trouble with having stub
  methods defined by zope.interface: these methods contain enough
  information about component concepts to blur the distinction between
  zope.interface and zope.component, but they still lie about the actual
  method signature.
 
 I don't understand you: why do you say they lie about their method 
 signature? They should have the same signature and have a well-defined 
 behavior if zope.component is not installed: there is nothing registered 
 at all. zope.interface provides a plugin point that allows one to plug 
 lookup behavior into it.
 
  In that sense, these stubs would be worse than
  zope.interface not documenting the methods at all.
 
 I strongly disagree. We want to define a bunch of methods on Interface 
 that we want everybody to have access to. We can't then turn around and 
 say we really actually don't want to implement those methods on Interface.
 
 That Interface *delegates* the implementation to something else is fine, 
 but the methods are conceptually on Interface, and delegation is 
 normally implemented by just calling the code we delegate to.

I'd like to advance the following argument that I haven't seen yet in
this thread: discoverability.  Specifically, letting the developer
figure out what's happening.

When I see code like this:

formatter = IHTMLFormatter(widget).to_html()

I can look up the definition of IHTMLFormatter, see that it's a class
inheriting from Interface, look up zope.interface.Interface, see that
it's an InterfaceClass instance, look up InterfaceClass.__call__ to
see what it does -- checks for widget.__conform__, checks if widget
provides IHTMLFormatter directly, loops through adapter_hooks.  Then I
can grep for adapter_hooks in my buildout omelette tree and find that
zope.component hooks into it.  And so on.

If there's only monkey-patching going on, I'd get stuck in step 4:
InterfaceClass has no __call__.  Where does it come from?
Monkey-patching is sufficiently frowned-upon in the Python world that it
wouldn't occur for me to recursively grep InterfaceClass.__call__ =;
I'd assume I missed something and run in circles.



The main point of my email completed, I still cannot force myself to
desist from further comments.

  In my and Wolfgang's opinion, we can either have zope.interface implement
  methods with the real contract, which would mean defining the full
  concepts of the ZCA within zope.interface (if not their implementation),
  or not even have method stubs in zope.interface and leave the whole
  business of defining specialised uses of interfaces to other packages such
  as zope.component.
 
 In that case, I want the real contract to be in zope.interface. That's 
 where the methods are, after all. We need to talk about the concept of 
 an adapter and a utility briefly in zope.interface and defer to 
 zope.component as the most common implementation. We already have this 
 kind of behavior going on anyway with __call__() (even though not 
 documented!).

It'd be simpler if utilities didn't exist as a concept in
zope.interface, but y'all have decided that's too ambitious.

(Personally I kinda think redesigning zope.component/zope.interface APIs
is too ambitious; the Zope community would be better served by having a
website with up-to-date documentation of everything, launchpad bug
trackers for every package in the ZTK and KGS, stable and regular ZTK
and KGS releases, etc.  But I know that I have no right to tell anyone
what they should work on instead of their chosen pet project.)

  What's the behavior of __call__ now if zope.component isn't around?
  
  Similar to what you've just described of your `adapt` method, up to the
  name of the `default` parameter and the exception raised.
 
 So if no registry is available (zope.component not installed), you can 
 still call it and it'll just behave as if the registry is empty? That's 
 good..

(Unless it trips people up leading them to assume they made a mistake in
their adapter/utility registrations, when they instead forgot to
register the hook.  But that's unlikely, as I've already said
elsewhere.)

Marius Gedminas
-- 
http://pov.lt/ -- Zope 3 consulting and development


signature.asc
Description: Digital signature
___
Zope-Dev maillist  -  Zope-Dev@zope.org
https://mail.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 https://mail.zope.org/mailman/listinfo/zope-announce
 https://mail.zope.org/mailman/listinfo/zope )


Re: [Zope-dev] A summary of Interfaces vs ZCA concepts

2009-12-17 Thread Martijn Faassen
Hey,

Marius Gedminas wrote:

 I'd like to advance the following argument that I haven't seen yet in
 this thread: discoverability.  

I was actually thinking very much about people who read the code all the 
time, but apparently I wasn't very clear. That's also why I moved away 
from a position of monkey patching to a plugin API.

[snip]
 If there's only monkey-patching going on, I'd get stuck in step 4:
 InterfaceClass has no __call__.  Where does it come from?
 Monkey-patching is sufficiently frowned-upon in the Python world that it
 wouldn't occur for me to recursively grep InterfaceClass.__call__ =;
 I'd assume I missed something and run in circles.

I agree. I think therefore we should put implementations in 
zope.interface, that can defer to a plugin registered by zope.component, 
just as we have for the adapter hook. (though I think we can come up 
with a more straightforward pattern than the whole hookable stuff, which 
I think I understood once but have since forgotten :)

[snip]
 It'd be simpler if utilities didn't exist as a concept in
 zope.interface, but y'all have decided that's too ambitious.
 
 (Personally I kinda think redesigning zope.component/zope.interface APIs
 is too ambitious; the Zope community would be better served by having a
 website with up-to-date documentation of everything, launchpad bug
 trackers for every package in the ZTK and KGS, stable and regular ZTK
 and KGS releases, etc.  But I know that I have no right to tell anyone
 what they should work on instead of their chosen pet project.)

I think the Zope community needs to be able to do all these things 
(which I've personally invested quite a bit of time on improving as 
well) *and* improve the ZCA APIs. Some people ask why explore the solar 
system when world hunger isn't yet solved?. Lots of people have lots of 
cogent answers to that question.

We need project infrastructure, yes, but we also need a community:

* where ideas arise that when implemented affect a lot of people

* where we can discuss such ideas

* where we have people and mechanisms to reach such discussions to a 
*conclusion*

* where we have volunteers who actually implement the conclusion

If we don't have that, we don't have a functional community *either*. 
We'll always be in maintenance mode.

 What's the behavior of __call__ now if zope.component isn't around?
 Similar to what you've just described of your `adapt` method, up to the
 name of the `default` parameter and the exception raised.
 So if no registry is available (zope.component not installed), you can 
 still call it and it'll just behave as if the registry is empty? That's 
 good..
 
 (Unless it trips people up leading them to assume they made a mistake in
 their adapter/utility registrations, when they instead forgot to
 register the hook.  But that's unlikely, as I've already said
 elsewhere.)

Yeah, I sympathise. I believe this is an unfortunate consequence of any 
plugin system. To mitigate that issue, I think clear warning signs are 
needed in zope.interface's dummy plugin so that people who step into it 
get a clear clue something didn't get registered right.

Regards,

Martijn

___
Zope-Dev maillist  -  Zope-Dev@zope.org
https://mail.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 https://mail.zope.org/mailman/listinfo/zope-announce
 https://mail.zope.org/mailman/listinfo/zope )


Re: [Zope-dev] A summary of Interfaces vs ZCA concepts

2009-12-17 Thread Brian Sutherland
On Thu, Dec 17, 2009 at 04:59:12PM +0100, Thomas Lotze wrote:
 Martijn Faassen wrote:
  Their behavior should be:
  
  IFoo.adapt(context) raises LookupError, unless the context provides IFoo,
  in which case it returns context.
  
  IFoo.adapt(context, default=default) returns default unless context
  provides IFoo, in which case it returns context.
  
  IFoo.utility() raises LookupError.
  
  IFoo.utility(default=default) returns default
 
 I think looking at that API explains why we have trouble with having stub
 methods defined by zope.interface: these methods contain enough
 information about component concepts to blur the distinction between
 zope.interface and zope.component, but they still lie about the actual
 method signature. In that sense, these stubs would be worse than
 zope.interface not documenting the methods at all.
 
 In my and Wolfgang's opinion, we can either have zope.interface implement
 methods with the real contract, which would mean defining the full
 concepts of the ZCA within zope.interface (if not their implementation),
 or not even have method stubs in zope.interface and leave the whole
 business of defining specialised uses of interfaces to other packages such
 as zope.component.

I like things to fail noisily and loudly unconfigured and give good
information about what's wrong.  So my preferred implementation of a
stub utility function on Interface is:

def utility(default=None):
Lookup a utility for this interface.

A utility is a ${long explanation of utility concept}.

This method behaves like ${explanation of utility method contract}. 

raise NotImplementedError(No Utility lookup mechanism has been 
configured.
If you wish to use utility lookups on interfaces, please configure a
package that contains this mechanism. Packages known to
implement this are:
zope.component
)

I agree that this encodes in the zope.interface package concepts from
zope.component. I feel uncomfortable about that. But I feel more
uncomfortable with magic where it is impossible to find out what is
going on by reading the code.

-- 
Brian Sutherland
___
Zope-Dev maillist  -  Zope-Dev@zope.org
https://mail.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 https://mail.zope.org/mailman/listinfo/zope-announce
 https://mail.zope.org/mailman/listinfo/zope )