Re: implementing zope.component 4.0

Marius Gedminas <[email protected]>
Newsgroups gmane.comp.web.zope.devel
Message-ID <[email protected]>
On Fri, Nov 27, 2009 at 12:32:52PM +0100, Martijn Faassen wrote:
> Hi there,
> 
> Introduction
> ------------
> 
> So now that we've had some discussion and to exit the "bikeshed" phase, 
> let's see about getting some volunteers to work on this.
> 
> The goal here is to make interfaces disappear into the language as much 
> as possible. This means that I'll ignore backwards compatibility while 
> sketching out the "ideal semantics" below - I have the impression we can 
> get consensus on the following behavior:
> 
> Simple adaptation:
> 
>    IFoo(adapted)
> 
> Named adaptation:
> 
>    IFoo(adapted, name="foo")
> 
> Adaptation with a default
> 
>    IFoo(adapted, default=bar)
> 
> Multi-adaptation:
> 
>    IFoo(one, two)
> 
> Named multi adaptation:
> 
>    IFoo(one, two, name="foo")
> 
> Multi-adaptation with a default:
> 
>    IFoo(one, two, default=bar)
> 
> Utility lookup:
> 
>    IFoo()
> 
> Named utility lookup:
> 
>    IFoo(name="foo")
> 
> Utility lookup with a default:
> 
>    IFoo(default=bar)
> 
> Where "name" and "default" can be combined. The name and default keyword 
> parameters have to be used explicitly - *args is interpreted as what to 
> adapt only. Any other keyword parameters should be rejected.

+0.5 --- I can live with it.  Backwards incompatibility with IFoo(one,
default) will be a slight inconvenience.  There were proposals I liked
more (IFoo.adapt(), IFoo.utility()) and proposals I liked less
(IFoo((one, two, we_like_parentheses, and_screw_people_adapting_tuples))).

> Utility lookups versus adapter lookups
> --------------------------------------
> 
> There was some discussion on whether utility lookups are really 
> something fundamentally different than adaptation as adaptation 
> *creates* a new instance while utility lookup uses a registered 
> instance. I think the essential part here is however: "give me an 
> instance that implements IFoo", and utility lookup fits there. We could 
> even envision a way to create utilities that *does* instantiate them on 
> the fly - it shouldn't affect the semantics for the user of the utility.

+1

I've often had the need to "give me an instance that implements IFoo"
where that instance is not a singleton.  I can write the code to find
the right IFoo, but since utilities are so limited, I had to resort to
adapting None.

> Features off the table for now
> -------------------------------
> 
> Saying an interface is implemented by a class (Python 2.6 and up) with a 
> decorator we'll leave out of the discussion for now.

Personally, I prefer Zope's syntax ("decorators" inside the class block)
to Python's (decorators above the class block), aesthetically.

> It would also be come up with an improved API to look up the adapter 
> *before* it is called, but I'd also like to take this off the table for 
> this discussion.
> 
> Backwards compatibility
> -----------------------
> 
> Now let's get back to my favorite topic in this discussion: backwards 
> compatibility. The ideal semantics unfortunately break backwards 
> compatibility for the single adapter lookup case, as this supports a 
> second argument, the default.
> 
> The challenge is therefore to come up with a way to support the new 
> semantics without breaking the old.

Can't be done.

> We could introduce the following upgrade pattern:
> 
> zope.component 3.8.0: old semantics
> 
> zope.component 3.9: old semantics is the default. new semantics 
> supported too somehow but explicitly triggered.

How?

from zope.__future__ import new_adapter_lookup?

> zope.component 4.0: new semantics is the default. Old semantics is not
> supported anymore.
> 
> We could, if needed, maintain zope.component 3.x in parallel with the 
> new-semantics 4.0 line for a while.
> 
> A per-module triggering of the new semantics might be done like this:
> 
> from zope.component.__future__ import __new_lookup__

Whoa, great minds think alike ;)

> Is that implementable at all however?

I think so, with some caveats.  E.g. something like

    class Interface(...):

        def __call__(...):
            new_semantics = (sys._getframe(1).f_globals.get('__new_lookup__')
                             is zope.component.__future__.__new_lookup__)

> Someone needs to experiment.
> 
> Alternatively we could do something special when we see this: IFoo(foo, 
> bar). This is ambiguous - is the new semantics in use or the old one? If 
> the adapter cannot be looked up using multi adaptation we *could* fall 
> back on single adaptation under the assumption that the old semantics 
> are desired. But this will lead to a problem if the new semantics *was* 
> desired but the component simply could not be found.

Which is why I'd maybe slightly prefer IFoo.adapt(foo, bar) as the explicit
syntax for multiadaptation.  Or live with the status quo.

> I think it's important not to do a "big bang" upgrade but instead allow 
> people to upgrade bit by bit. It should be possible to compose an 
> application that mixes code that expects the old semantics with code 
> that expects the new semantics. A bit by bit upgrade I think would 
> ideally be on a per-module basis. I think it's important to make sure we 
> can support such an upgrade *before* we release any of this.

+1

> Conclusions
> -----------
> 
> Are people okay with the proposed semantics?

+0.5

> Would people be okay with such an upgrade path? Any better ideas?

IFoo(one, default), IFoo.adapt(one, two, default=default),
IFoo.utility(default=default).

> Most importantly, any volunteers?

Ah.  Um.  Maybe, but only if I get to choose my preferred syntax, and
am allowed to give up after a couple of days declaring the task too
hard.

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

_______________________________________________
Zope-Dev maillist  -  [email protected]
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 )
signature.asc (application/pgp-signature, 191 B)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2.2 (GNU/Linux)

iD8DBQFLD8HkkVdEXeem148RAsIOAKCTSYJRTAj/LdN/RqQqRdUVS6Y57gCdHjuc
6eMiPudgr4voggv7kiL4yz4=
=0E/J
-----END PGP SIGNATURE-----
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.