Re: [Zope-dev] make zope.component.registry.Components inherit from dict?

2009-11-28 Thread Chris McDonough
Charlie Clark wrote:
> Am 24.11.2009, 04:24 Uhr, schrieb Chris McDonough :
> 
>> We've been handling some constructive criticisms from repoze.bfg  
>> developers
>> with respect to verbosity resulting from use of unnamed utility  
>> registrations
>> in a component architecture registry.
>> These criticisms, and our ameliorations are detailed here:
>> 
> 
> An interesting document and discussion. Having struggled initially and in  
> some ways still struggling to grasp the ZCA I can understand the  
> temptation to try and hide it from developers "because they don't need it  
> to get their job done". But my own take on the ZCA is that the component  
> registry is nothing wildly complicated just significantly different from  
> what many people are used to. But once you know it's there and that it  
> just looks after components it's just like having a DBMS manage your data  
> for you: throw stuff into it and it will manage your stuff for you.
> 
> I recently gave a presentation on the ZCA to non-Zopers and the concepts  
> weren't too difficult for the audience (I find it helps to jazz up the  
> metaphors). Conceptually the biggest problems are probably the multi-key  
> (nature of component, interface, name) nature of the registry and the  
> function of an interface as the token or smartcard required to get the  
> desired component.
> 
> In the example
> 
>  from repoze.bfg.interfaces import ISettings
>  from zope.component import getUtility
> settings = getUtility(ISettings)
> 
> the biggest leap of faith is getUtility which makes a behind the scenes  
> call to which registry is present. 

Right.

> I can imagine a clearer implementation  
> that would do the same but be explicitly dependent upon a particular  
> registration.
> 
> registry.get((utility, ISettings, u''))

In a Zope app, you can use this pattern today to make that true:

   from zope.component import getSiteManager
   registry = getSiteManager()
   settings = registry.getUtility(ISettings)

In a BFG app the same thing would be best done as:

   from repoze.bfg.threadlocal import get_current_registry
   registry = get_current_registry()
   settings = registry.getUtility(ISettings)

(This is a little clearer maybe than using the "site manager" terminology.)

If a "request" object was available in that BFG app, it would be better done as:

   registry = request.registry
   settings = registry.getUtility(ISettings)

I agree that the extra verbosity of explicitly obtaining the registry and 
calling methods on it improves readability.  It's the API of the registry 
object I'd like to make better.  I'm not as concerned about the global ZCA API.

- 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] make zope.component.registry.Components inherit from dict?

2009-11-28 Thread Charlie Clark
Am 24.11.2009, 04:24 Uhr, schrieb Chris McDonough :

> We've been handling some constructive criticisms from repoze.bfg  
> developers
> with respect to verbosity resulting from use of unnamed utility  
> registrations
> in a component architecture registry.
> These criticisms, and our ameliorations are detailed here:
> 

An interesting document and discussion. Having struggled initially and in  
some ways still struggling to grasp the ZCA I can understand the  
temptation to try and hide it from developers "because they don't need it  
to get their job done". But my own take on the ZCA is that the component  
registry is nothing wildly complicated just significantly different from  
what many people are used to. But once you know it's there and that it  
just looks after components it's just like having a DBMS manage your data  
for you: throw stuff into it and it will manage your stuff for you.

I recently gave a presentation on the ZCA to non-Zopers and the concepts  
weren't too difficult for the audience (I find it helps to jazz up the  
metaphors). Conceptually the biggest problems are probably the multi-key  
(nature of component, interface, name) nature of the registry and the  
function of an interface as the token or smartcard required to get the  
desired component.

In the example

 from repoze.bfg.interfaces import ISettings
 from zope.component import getUtility
settings = getUtility(ISettings)

the biggest leap of faith is getUtility which makes a behind the scenes  
call to which registry is present. I can imagine a clearer implementation  
that would do the same but be explicitly dependent upon a particular  
registration.

registry.get((utility, ISettings, u''))

This would, of course, be available as a dictionary call, although I'm not  
sure I'd see great advantage in that. All assuming, of course, the  
implemntation didn't clash with a localSiteManager but I think from other  
posts that it does.

Charlie
-- 
Charlie Clark
Managing Director
Clark Consulting & Research
German Office
Helmholtzstr. 20
Düsseldorf
D- 40215
Tel: +49-211-600-3657
Mobile: +49-178-782-6226
___
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] make zope.component.registry.Components inherit from dict?

2009-11-27 Thread Chris McDonough
Christian Theune wrote:
> Hi,
> 
> On 11/25/2009 02:35 AM, Chris McDonough wrote:
>> Chris McDonough wrote:
>>> I think it makes sense.  If we can relax the "utility name must be a string"
>>> restriction it would be the best solution I think.
>>>
>>> I'll see what I can do.
>> I've decided to keep the components subclass which inherits from dict.
> 
> Just for clarification as I'm confused now from reading the 
> back-and-forth-maybe-lets-not-play-together stuff all at once: that 
> means you're going down an incompatible route rolling your own 
> convenience mechanism?

Yes, unfortunately.  At least that's the current plan.

- 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] make zope.component.registry.Components inherit from dict?

2009-11-26 Thread Christian Theune
Hi,

On 11/25/2009 02:35 AM, Chris McDonough wrote:
> Chris McDonough wrote:
>>
>> I think it makes sense.  If we can relax the "utility name must be a string"
>> restriction it would be the best solution I think.
>>
>> I'll see what I can do.
>
> I've decided to keep the components subclass which inherits from dict.

Just for clarification as I'm confused now from reading the 
back-and-forth-maybe-lets-not-play-together stuff all at once: that 
means you're going down an incompatible route rolling your own 
convenience mechanism?

Christian

-- 
Christian Theune · c...@gocept.com
gocept gmbh & co. kg · forsterstraße 29 · 06112 halle (saale) · germany
http://gocept.com · tel +49 345 1229889 0 · fax +49 345 1229889 1
Zope and Plone consulting and development

___
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] make zope.component.registry.Components inherit from dict?

2009-11-24 Thread Chris McDonough
Martin Aspeli wrote:
> Chris McDonough wrote:
> 
>> I fear it was for naught, sorry.
>>
>> Adding an attribute is unsightly and turning this into a component problem 
>> doesn't have enough immediate gain.  The BFG registry will just continue to 
>> be 
>> a dict subclass.
>>
>> If Zope folks later want to use libraries that come from BFG-land 
>> (particularly 
>> libraries that have ZCML directives), they'll just need to deal with code 
>> that 
>> wants to use the dict API against the component registry.
> 
> If you're going down this route, my suggestion would be to not (ab)use 
> the ZCA site manager object for this at all. I'd have it be something 
> separate you access via a getConfigRegistry() or whatever. Threadlocals 
> are easy enough to set up.

Any app using more than one thread local for objects that have the same "scope" 
tends to make for a pretty rotten testing experience (see Pylons).  We already 
have the right number of objects to hold app config: one; it's the ZCA 
registry.  Making the registry into a dict is the simplest solution to the 
problem defined in the "defending design" document.

If some BFG-centric library becomes a runaway success, and some Zope user wants 
to use it in Zope, Zope will need to deal with it, or he will need to change 
the library to not use the feature.  That's fine.

- 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] make zope.component.registry.Components inherit from dict?

2009-11-24 Thread Martin Aspeli
Chris McDonough wrote:

> I fear it was for naught, sorry.
> 
> Adding an attribute is unsightly and turning this into a component problem 
> doesn't have enough immediate gain.  The BFG registry will just continue to 
> be 
> a dict subclass.
> 
> If Zope folks later want to use libraries that come from BFG-land 
> (particularly 
> libraries that have ZCML directives), they'll just need to deal with code 
> that 
> wants to use the dict API against the component registry.

If you're going down this route, my suggestion would be to not (ab)use 
the ZCA site manager object for this at all. I'd have it be something 
separate you access via a getConfigRegistry() or whatever. Threadlocals 
are easy enough to set up.

If we're not doing any consistency with the ZCA notion of a utility, 
then it seems wrong to conflate the two. ZCA utilities are still usable 
(and used?) in BFG.

If that is in a separate package (repoze.configregistry or whatever), 
it's re-usable in Zope as well. Everyone wins. :)

Martin

-- 
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
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] make zope.component.registry.Components inherit from dict?

2009-11-24 Thread Chris McDonough
Martin Aspeli wrote:
> Chris McDonough wrote:
> 
>> I think we have to divorce the requirement from "the ZCA".
>>
>> The requirement:
>>
>> - an attribute of an instance of the class
>>"zope.component.registry.Components" which is dictionarylike
>>(accepts any key type, any value type).
>>
>> If I can get that, I'd be happy, regardless of what's happening under the 
>> hood. 
>> If you want to turn this into a component lookup, that'd be fine; if 
>> not, 
>> that'd be fine too.
>>
>> That said, if I had just added a separate attribute ithat is a dict inside 
>> the 
>> Components constructor (instead of subclassing Components from dict) and 
>> checked it in, would anyone have cared? This isn't a feature that any Zope 
>> developer really *has* to use, it's just a feature that provides 
>> compatibility 
>> between future BFG apps and Zope.  It'd also be possible to change its 
>> implementation in the future if we thought it should use utility 
>> registrations.
> 
> ...
> 
>> We already have this situation.  The Components class is already a wrapper 
>> that 
>> has an "adapters" attribute (an instance of a zope.interface 
>> AdapterRegistry) 
>> and a  "utilities" attribute (an instance of something else).  All adapter 
>> and 
>> utility state is kept in these substructures.
>>
>> While maybe it would be wrong to refer to the things manipulated via a 
>> dictlike 
>> object as an additional attribute of the class as "utilities", adding 
>> another 
>> attribute and exposing a wrapper API is a pattern that is already embraced 
>> by 
>> the class.
> 
> If it were just another attribute analogous to .utilities and .adapters, 
> calling it "utils" or "utilities" would be misleading, because it's not 
> actually a utility. You could call it "settings" or something.
> 
> However, you'd still need to implement support for __bases__ and all 
> that: getSiteManager() will return the nearest site manager, so if it 
> was just a "dumb" dictionary you'd get a KeyError as soon as you'd 
> traversed over a site (e.g. into a Plone site), thus setting a local 
> site manager. You *could* use getGlobalSiteManager() every time, but 
> then people have to know that .settings is only on the global site manager.
> 
> And you'd still have to do all the wiring in Python, or invent a new 
> ZCML directive. Wiring at module import time is not ideal.
> 
> Conversely, if you implement it so that it's backed by named utilities 
> providing Interface, then it's just a convenience and we still have the 
> same override and introspection mechanisms we've always had for 
> utilities. That sounds like a good bit of "internal consistency" to me.

I fear it was for naught, sorry.

Adding an attribute is unsightly and turning this into a component problem 
doesn't have enough immediate gain.  The BFG registry will just continue to be 
a dict subclass.

If Zope folks later want to use libraries that come from BFG-land (particularly 
libraries that have ZCML directives), they'll just need to deal with code that 
wants to use the dict API against the 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] make zope.component.registry.Components inherit from dict?

2009-11-24 Thread Martin Aspeli
Chris McDonough wrote:

> I think we have to divorce the requirement from "the ZCA".
> 
> The requirement:
> 
> - an attribute of an instance of the class
>"zope.component.registry.Components" which is dictionarylike
>(accepts any key type, any value type).
> 
> If I can get that, I'd be happy, regardless of what's happening under the 
> hood. 
> If you want to turn this into a component lookup, that'd be fine; if not, 
> that'd be fine too.
> 
> That said, if I had just added a separate attribute ithat is a dict inside 
> the 
> Components constructor (instead of subclassing Components from dict) and 
> checked it in, would anyone have cared? This isn't a feature that any Zope 
> developer really *has* to use, it's just a feature that provides 
> compatibility 
> between future BFG apps and Zope.  It'd also be possible to change its 
> implementation in the future if we thought it should use utility 
> registrations.

...

> We already have this situation.  The Components class is already a wrapper 
> that 
> has an "adapters" attribute (an instance of a zope.interface AdapterRegistry) 
> and a  "utilities" attribute (an instance of something else).  All adapter 
> and 
> utility state is kept in these substructures.
> 
> While maybe it would be wrong to refer to the things manipulated via a 
> dictlike 
> object as an additional attribute of the class as "utilities", adding another 
> attribute and exposing a wrapper API is a pattern that is already embraced by 
> the class.

If it were just another attribute analogous to .utilities and .adapters, 
calling it "utils" or "utilities" would be misleading, because it's not 
actually a utility. You could call it "settings" or something.

However, you'd still need to implement support for __bases__ and all 
that: getSiteManager() will return the nearest site manager, so if it 
was just a "dumb" dictionary you'd get a KeyError as soon as you'd 
traversed over a site (e.g. into a Plone site), thus setting a local 
site manager. You *could* use getGlobalSiteManager() every time, but 
then people have to know that .settings is only on the global site manager.

And you'd still have to do all the wiring in Python, or invent a new 
ZCML directive. Wiring at module import time is not ideal.

Conversely, if you implement it so that it's backed by named utilities 
providing Interface, then it's just a convenience and we still have the 
same override and introspection mechanisms we've always had for 
utilities. That sounds like a good bit of "internal consistency" to me.

Martin

-- 
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
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] make zope.component.registry.Components inherit from dict?

2009-11-24 Thread Chris McDonough
Chris McDonough wrote:
> 
> I think it makes sense.  If we can relax the "utility name must be a string" 
> restriction it would be the best solution I think.
> 
> I'll see what I can do.

I've decided to keep the components subclass which inherits from dict.

- 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] make zope.component.registry.Components inherit from dict?

2009-11-24 Thread Chris McDonough
Stephan Richter wrote:
> On Tuesday 24 November 2009, Chris McDonough wrote:
>>> Off the top of my head, another way to think of this might be to say
>>> that the 'dict access' is basically looking up a named utility
>>> providing a very generic marker interface, e.g.
>>> zope.component.interfaces.IUtility or even just
>>> zope.interface.Interface. That way reg['foo'] == getUtility(IUtility,
>>> name='foo'). Obviously, assignment would register in the same way.
>>>
>>> I'm not sure it's "better", though. :)
>> That would also be fine, and it would normalize things a bit, although the
>> implementation would be harder and it would result in slower lookups.  But
>> if it made folks feel better than inheriting from dict, I'd be +1 on it.
> 
> I have not read the entire thread, but Martin's suggestion using 
> zope.interface.Interface makes a lot to sense to me as the dict syntax 
> becomes 
> syntactic sugar and a simplification when desired.

I think it makes sense.  If we can relax the "utility name must be a string" 
restriction it would be the best solution I think.

I'll see what I can do.

- 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] make zope.component.registry.Components inherit from dict?

2009-11-24 Thread Wichert Akkerman
On 2009-11-24 17:26, Tres Seaver wrote:
> -BEGIN PGP SIGNED MESSAGE-
> Hash: SHA1
>
> Wichert Akkerman wrote:
>> On 2009-11-24 05:57, Martin Aspeli wrote:
>>> I whole-heartedly agree, and I think it's important that we use the
>>> momentum behind BFG (and other consumers of the ZTK) to drive the ZTK
>>> forward. Anything else would be stupid.
>>
>> I don't think BFG can be considered to be a 'consumer of the ZTK'. It
>> uses the ZCA (and zope.i18n currently), but that's about it. The ZTK as
>> it currently is implies a whole lot of Zopisms that BFG does not
>> subscribe to.
>
> BFG uses the "under the bicycle seat" subset of the toolkit. ;)

Doesn't that hurt? ;)

Wichert.


-- 
Wichert AkkermanIt is simple to make things.
http://www.wiggy.net/  It is hard to make things simple.
___
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] make zope.component.registry.Components inherit from dict?

2009-11-24 Thread Tres Seaver
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

Wichert Akkerman wrote:
> On 2009-11-24 05:57, Martin Aspeli wrote:
>> I whole-heartedly agree, and I think it's important that we use the
>> momentum behind BFG (and other consumers of the ZTK) to drive the ZTK
>> forward. Anything else would be stupid.
> 
> I don't think BFG can be considered to be a 'consumer of the ZTK'. It 
> uses the ZCA (and zope.i18n currently), but that's about it. The ZTK as 
> it currently is implies a whole lot of Zopisms that BFG does not 
> subscribe to.

BFG uses the "under the bicycle seat" subset of the toolkit. ;)


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

iEYEARECAAYFAksMCVMACgkQ+gerLs4ltQ5EnQCg2qh2k4WVl6uoNKFVu+p2Gmt0
PlMAn20AMYINmJOUraq0N2K52l+8px99
=OWPe
-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 )


Re: [Zope-dev] make zope.component.registry.Components inherit from dict?

2009-11-24 Thread Tres Seaver
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

Martin Aspeli wrote:
> Martin Aspeli wrote:
> 
>> I *do* actually like the "named IAnonymousUtility" thing as a 
>> convenience, because it retains some consistency. Maybe it's slower, 
>> which would be a negative. But it also allows all the other ZCA stuff 
>> (overriding, introspection, global/local variants, etc) and API: we're 
>> just introducing a convenience.
> 
> Oh, and here's another reason: this allows registration at ZCML 
> configuration time rather than import time (since we're not setting it 
> up in Python) without inventing new directives:
> 
>  name="root"
>  object=".roots.myRoot"
>  provides="zope.component.IAnonymousUtility"
>  />
> 
> Or in Grok speak:
> 
>  grok.global_utility(myRoot, IAnonymousUtility, name="root")
> 
> I think we'd want a less icky name than IAnonymousUtility, though.

Just use 'Interface'.


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

iEYEARECAAYFAksMB9kACgkQ+gerLs4ltQ40UgCgyYBAKKKkwg0oAadLlpDkVefi
5KYAoKaPLUNyDhN8opoF5YWN33kdx3lw
=0dsx
-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 )


Re: [Zope-dev] make zope.component.registry.Components inherit from dict?

2009-11-24 Thread Stephan Richter
On Tuesday 24 November 2009, Chris McDonough wrote:
> > Off the top of my head, another way to think of this might be to say
> > that the 'dict access' is basically looking up a named utility
> > providing a very generic marker interface, e.g.
> > zope.component.interfaces.IUtility or even just
> > zope.interface.Interface. That way reg['foo'] == getUtility(IUtility,
> > name='foo'). Obviously, assignment would register in the same way.
> >
> > I'm not sure it's "better", though. :)
>
> That would also be fine, and it would normalize things a bit, although the
> implementation would be harder and it would result in slower lookups.  But
> if it made folks feel better than inheriting from dict, I'd be +1 on it.

I have not read the entire thread, but Martin's suggestion using 
zope.interface.Interface makes a lot to sense to me as the dict syntax becomes 
syntactic sugar and a simplification when desired.

Regards,
Stephan
-- 
Entrepreneur and Software Geek
Google me. "Zope Stephan Richter"
___
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] make zope.component.registry.Components inherit from dict?

2009-11-24 Thread Benji York
On Tue, Nov 24, 2009 at 6:22 AM, Chris McDonough  wrote:
> I think we have to divorce the requirement from "the ZCA".
>
> The requirement:
>
> - an attribute of an instance of the class
>   "zope.component.registry.Components" which is dictionarylike
>   (accepts any key type, any value type).

As far as I can tell you don't want any of the ZCA functionality (named
utilities, overriding, etc.), so divorcing this from the ZCA seems
appropriate.  I still don't quite see why a module global dictionary
doesn't meet your needs.
-- 
Benji York
___
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] make zope.component.registry.Components inherit from dict?

2009-11-24 Thread Chris McDonough
Martin Aspeli wrote:
> Chris McDonough wrote:
> 
>>> Except at this point we've lost all the other ZCA stuff. You can't 
>>> override with a local utility, for example.
>> I see.  I didn't understand that this was a use case, because I don't use 
>> any 
>> persistent registries.  If you say this is a use case, I believe it.
> 
> Note that you can also have "local" registries that are not persistent. 
> It's just a chain of lookups, where each registry knows its bases. Some 
> unholy code in KSS turns a view into a component site, I think. But 
> let's not go there.

OK.


>> Sure, I could have another dictionary laying around as a thread local.  I 
>> already effectively do that now; the particular thread local dictionary I 
>> use 
>> just happens to *be* the registry.  Libraries written that make use of that 
>> feature in BFG are not usable within Zope, however, which is suboptimal.
> 
> I agree. However, if we're starting down the path of making a totally 
> different registry keyed in a totally different way, I wonder why we're 
> even thinking of doing this with the concept of the ZCA at all.
> I *do* actually like the "named IAnonymousUtility" thing as a 
> convenience, because it retains some consistency. Maybe it's slower, 
> which would be a negative. But it also allows all the other ZCA stuff 
> (overriding, introspection, global/local variants, etc) and API: we're 
> just introducing a convenience.

I think we have to divorce the requirement from "the ZCA".

The requirement:

- an attribute of an instance of the class
   "zope.component.registry.Components" which is dictionarylike
   (accepts any key type, any value type).

If I can get that, I'd be happy, regardless of what's happening under the hood. 
If you want to turn this into a component lookup, that'd be fine; if not, 
that'd be fine too.

That said, if I had just added a separate attribute ithat is a dict inside the 
Components constructor (instead of subclassing Components from dict) and 
checked it in, would anyone have cared? This isn't a feature that any Zope 
developer really *has* to use, it's just a feature that provides compatibility 
between future BFG apps and Zope.  It'd also be possible to change its 
implementation in the future if we thought it should use utility registrations.

> Conversely, *if* we're not using any other "ZCA stuff", then it probably 
> belongs elsewhere.
> 
>> The types of data contained by both the dictionary I want and the ZCA are 
>> the 
>> same types of things (statements about application configuration, expressed 
>> conceptually as "utilities").  We only need one thread local to hold 
>> application configuration; having N of them is an anti-use-case, and having 
>> multiple of them implies balkanization.
> 
> This I agree with, but in effect, if we have a self.utils = {} in 
> __init__, then we actually have two registries that have nothing to do 
> with each other. :)

We already have this situation.  The Components class is already a wrapper that 
has an "adapters" attribute (an instance of a zope.interface AdapterRegistry) 
and a  "utilities" attribute (an instance of something else).  All adapter and 
utility state is kept in these substructures.

While maybe it would be wrong to refer to the things manipulated via a dictlike 
object as an additional attribute of the class as "utilities", adding another 
attribute and exposing a wrapper API is a pattern that is already embraced by 
the class.

>> So if you say that you must be able to override registrations made via 
>> "reg['foo']" or "reg.utils['foo']" with a local utility via 
>> "localreg.registerUtility(someoverride, IAnonymousUtility, name='foo')", and 
>> that the local utility registry can't handle "localreg['foo']" sensibly by 
>> falling back to "globalreg['foo']", I'd believe you, even though I don't 
>> understand why not.  It's not that important, really.
> 
> Sure, we could implement the same type of fallback in __getitem__ or 
> whatever. But now we're building the same thing twice, are we not?

If it didn't exist, what's the worst thing that could happen?

- 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] make zope.component.registry.Components inherit from dict?

2009-11-24 Thread Martin Aspeli
Martin Aspeli wrote:

> I *do* actually like the "named IAnonymousUtility" thing as a 
> convenience, because it retains some consistency. Maybe it's slower, 
> which would be a negative. But it also allows all the other ZCA stuff 
> (overriding, introspection, global/local variants, etc) and API: we're 
> just introducing a convenience.

Oh, and here's another reason: this allows registration at ZCML 
configuration time rather than import time (since we're not setting it 
up in Python) without inventing new directives:

   

Or in Grok speak:

 grok.global_utility(myRoot, IAnonymousUtility, name="root")

I think we'd want a less icky name than IAnonymousUtility, though.

Martin

-- 
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
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] make zope.component.registry.Components inherit from dict?

2009-11-24 Thread Martin Aspeli
Chris McDonough wrote:

>> Except at this point we've lost all the other ZCA stuff. You can't 
>> override with a local utility, for example.
> 
> I see.  I didn't understand that this was a use case, because I don't use any 
> persistent registries.  If you say this is a use case, I believe it.

Note that you can also have "local" registries that are not persistent. 
It's just a chain of lookups, where each registry knows its bases. Some 
unholy code in KSS turns a view into a component site, I think. But 
let's not go there.

> Sure, I could have another dictionary laying around as a thread local.  I 
> already effectively do that now; the particular thread local dictionary I use 
> just happens to *be* the registry.  Libraries written that make use of that 
> feature in BFG are not usable within Zope, however, which is suboptimal.

I agree. However, if we're starting down the path of making a totally 
different registry keyed in a totally different way, I wonder why we're 
even thinking of doing this with the concept of the ZCA at all.

I *do* actually like the "named IAnonymousUtility" thing as a 
convenience, because it retains some consistency. Maybe it's slower, 
which would be a negative. But it also allows all the other ZCA stuff 
(overriding, introspection, global/local variants, etc) and API: we're 
just introducing a convenience.

Conversely, *if* we're not using any other "ZCA stuff", then it probably 
belongs elsewhere.

> The types of data contained by both the dictionary I want and the ZCA are the 
> same types of things (statements about application configuration, expressed 
> conceptually as "utilities").  We only need one thread local to hold 
> application configuration; having N of them is an anti-use-case, and having 
> multiple of them implies balkanization.

This I agree with, but in effect, if we have a self.utils = {} in 
__init__, then we actually have two registries that have nothing to do 
with each other. :)

> So if you say that you must be able to override registrations made via 
> "reg['foo']" or "reg.utils['foo']" with a local utility via 
> "localreg.registerUtility(someoverride, IAnonymousUtility, name='foo')", and 
> that the local utility registry can't handle "localreg['foo']" sensibly by 
> falling back to "globalreg['foo']", I'd believe you, even though I don't 
> understand why not.  It's not that important, really.

Sure, we could implement the same type of fallback in __getitem__ or 
whatever. But now we're building the same thing twice, are we not?

>> Maybe it's better to 
>> look into the stacked variables that Pylons uses for some of its 
>> configuration stuff?
> 
> Hell no.  That particular implementation is a holy mess.

Well, I didn't know that. ;-)

Martin

-- 
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
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] make zope.component.registry.Components inherit from dict?

2009-11-24 Thread Chris McDonough
Hanno Schlichting wrote:
> 
> I'm not sure how this affects Chris proposal. But we already have a
> commonly used subclass of the component registry that uses the dict
> API in a somewhat different way here.

Thanks for the explanation Hanno, fair enough.  five.localsitemanager peed in 
this API pool first. ;-)

- 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] make zope.component.registry.Components inherit from dict?

2009-11-24 Thread Hanno Schlichting
On Tue, Nov 24, 2009 at 5:53 AM, Matthew Wilkes
 wrote:
> But, here is where the ZCA eyes come back into play, I wouldn't add
> this to the ZCA itself.  One reason being that Hanno's been working on
> a more useful persistent component root for Zope that brings in bits
> of OFS, hooking a dict in there would just be confusing.

Just to be clear here. The "five.localsitemanager" package
representing the canonical implementation of a persistent local
component registry in all Zope2 based projects does this since it's
beginning. When using the registry on your own, you are free to ignore
it's container API, but when using GenericSetup to populate such a
component registry, this is what essentially happens (leaving out the
GS parsing methods and helpers):

from zope.component import getSiteManager
from zope.ramcache.interfaces.ram import IRAMCache
from zope.ramcache.ram import RAMCache

sm = getSiteManager()
name = 'zope.ramcache.interfaces.ram.IRAMCache'
sm[name] = RAMCache()
ram = sm[name]
ram.__name__ = name
ram.__parent__ = sm
sm.registerUtility(ram, IRAMCache, name)

One explicit goal of this approach is to keep the data object and it's
registration as an utility separate, so you can unregister a
persistent utility without implicitly removing the only persistent
reference that exists to it. In this view you have a data object that
is persisted itself and you can give it a function by registering it
as a utility.

I'm not sure how this affects Chris proposal. But we already have a
commonly used subclass of the component registry that uses the dict
API in a somewhat different way here.

Hanno
___
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] make zope.component.registry.Components inherit from dict?

2009-11-24 Thread Wichert Akkerman
On 2009-11-24 05:57, Martin Aspeli wrote:
> I whole-heartedly agree, and I think it's important that we use the
> momentum behind BFG (and other consumers of the ZTK) to drive the ZTK
> forward. Anything else would be stupid.

I don't think BFG can be considered to be a 'consumer of the ZTK'. It 
uses the ZCA (and zope.i18n currently), but that's about it. The ZTK as 
it currently is implies a whole lot of Zopisms that BFG does not 
subscribe to.

Wichert.

-- 
Wichert AkkermanIt is simple to make things.
http://www.wiggy.net/  It is hard to make things simple.
___
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] make zope.component.registry.Components inherit from dict?

2009-11-23 Thread Chris McDonough
Martin Aspeli wrote:
>> Could maybe we instead just do:
>>
>>   class Components(object):
>>def __init__(self, name='', bases=()):
>>self.utils = {}
>>
>>
>> This would be faster, simpler to document, and would require exactly one 
>> line 
>> of code.
> 
> Except at this point we've lost all the other ZCA stuff. You can't 
> override with a local utility, for example.

I see.  I didn't understand that this was a use case, because I don't use any 
persistent registries.  If you say this is a use case, I believe it.

> In fact, this is not a ZCA 
> "utility" at all, it's just a key-value pair in a threadlocal. It 
> doesn't have any consistency with named utilities or adapters or any 
> other aspect of the ZCA.
> 
> I'm not saying having "just" a thread-local dictionary is a bad idea, 
> but maybe it's not a ZCA responsibility at all. Why would you really 
> expect it on getSiteManager().utils or whatever?

Sure, I could have another dictionary laying around as a thread local.  I 
already effectively do that now; the particular thread local dictionary I use 
just happens to *be* the registry.  Libraries written that make use of that 
feature in BFG are not usable within Zope, however, which is suboptimal.

The types of data contained by both the dictionary I want and the ZCA are the 
same types of things (statements about application configuration, expressed 
conceptually as "utilities").  We only need one thread local to hold 
application configuration; having N of them is an anti-use-case, and having 
multiple of them implies balkanization.

So if you say that you must be able to override registrations made via 
"reg['foo']" or "reg.utils['foo']" with a local utility via 
"localreg.registerUtility(someoverride, IAnonymousUtility, name='foo')", and 
that the local utility registry can't handle "localreg['foo']" sensibly by 
falling back to "globalreg['foo']", I'd believe you, even though I don't 
understand why not.  It's not that important, really.

> Maybe it's better to 
> look into the stacked variables that Pylons uses for some of its 
> configuration stuff?

Hell no.  That particular implementation is a holy mess.

- 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] make zope.component.registry.Components inherit from dict?

2009-11-23 Thread Martin Aspeli
Chris McDonough wrote:

> OK after rereading this, I think we may be massively overthinking this.  The 
> above is getting kinda silly.  I can't think of a use case where being able 
> to 
> alternate between:
> 
>reg.utils['root_factory']
> 
> and
> 
>reg.getUtility(IAnonymousUtility, name='root_factory')
> 
> ... is at all useful.  I may be wrong.  Can you think of one?
> 
> If not, it's a lot easier to document:
> 
> "The utils attribute of a registry is a dictionary that may contain arbitrary 
> key/value pairs."
> 
> Than it is to document:
> 
> "The utils attribute of a registry is a DictInterface which exposes the 
> Python 
> dictionary API which does unnamed utility registrations using the 
> IAnonymousUtility interface as the utility interface and the key value passed 
> to the various API methods as the utility name.. "
> 
> 
> Could maybe we instead just do:
> 
>   class Components(object):
>def __init__(self, name='', bases=()):
>self.utils = {}
> 
> 
> This would be faster, simpler to document, and would require exactly one line 
> of code.

Except at this point we've lost all the other ZCA stuff. You can't 
override with a local utility, for example. In fact, this is not a ZCA 
"utility" at all, it's just a key-value pair in a threadlocal. It 
doesn't have any consistency with named utilities or adapters or any 
other aspect of the ZCA.

I'm not saying having "just" a thread-local dictionary is a bad idea, 
but maybe it's not a ZCA responsibility at all. Why would you really 
expect it on getSiteManager().utils or whatever? Maybe it's better to 
look into the stacked variables that Pylons uses for some of its 
configuration stuff?

Martin

-- 
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
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] make zope.component.registry.Components inherit from dict?

2009-11-23 Thread Chris McDonough
Chris McDonough wrote:
> Thanks.  Yup. I would be +1 on this if the registry itself implemented 
> IDictInterface.
> 
> If that was untenable, if all the above code lived in the zope.component 
> package itself, and you had an API that manifested an IDictInterface object 
> when you asked for a "utilities" attribute, that would also be acceptable, as 
> long as you could do:
> 
> reg.utils['root_factory'] = RootFactory
> 
> Where the registry implementation would implement a propery for "utils":
> 
> class Components(object):
>  @property
>  def utils(self, name):
>  api = self.queryAdapter(IDictInterface, None)
>  if api is None:
>  api = DictInterface(self)
>  return api
> 
> In reality, this will be slow, and nobody is going to override 
> IDictInterface, 
> so it would probably be better as:
> 
> class Components(object):
>  def __init__(self, name='', bases=()):
>  self.utils = DictInterface(self)

OK after rereading this, I think we may be massively overthinking this.  The 
above is getting kinda silly.  I can't think of a use case where being able to 
alternate between:

   reg.utils['root_factory']

and

   reg.getUtility(IAnonymousUtility, name='root_factory')

... is at all useful.  I may be wrong.  Can you think of one?

If not, it's a lot easier to document:

"The utils attribute of a registry is a dictionary that may contain arbitrary 
key/value pairs."

Than it is to document:

"The utils attribute of a registry is a DictInterface which exposes the Python 
dictionary API which does unnamed utility registrations using the 
IAnonymousUtility interface as the utility interface and the key value passed 
to the various API methods as the utility name.. "


Could maybe we instead just do:

  class Components(object):
   def __init__(self, name='', bases=()):
   self.utils = {}


This would be faster, simpler to document, and would require exactly one line 
of code.

- 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] make zope.component.registry.Components inherit from dict?

2009-11-23 Thread Chris McDonough
Martin Aspeli wrote:
>> Meh, I just remembered that I tried this.  The current implementation 
>> requires 
>> that the "name" value be a literal string object (or at least something 
>> convertable to Unicode).  I think we could relax this requirement; it really 
>> only needs to be hashable.  I wouldn't want to deploy the API if the keys 
>> were 
>> required to only be strings.
> 
> Should be easy to fix, I'm sure. Why would you want something other than 
> strings, though?

For the same reasons that dictionaries accept keys other than strings.  In this 
case, more specifically, we're trying to give Python programmers a familiar API 
without any special restrictions that require "homina homina" documentation.

- 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] make zope.component.registry.Components inherit from dict?

2009-11-23 Thread Chris McDonough
Matthew Wilkes wrote:
> 
> On 2009-11-24, at 0521, Chris McDonough wrote:
> 
>> I don't think I understand.  Could you provide an example?
> 
> Sure!
> 
> I think this is the same thing that Martin suggested, but here's some 
> code which should make it clearer.
> 
> First, we create an object that we want to be accessible from this lookup:
> 
> class Root(dict):
> pass
> 
> Then, we register that as a utility in the global site manager
> 
> manager = zope.component.getGlobalSiteManager()
> manager.registerUtility(Root(),
> zope.interface.Interface,
> name="root")
> 
> This can then be found with:
> 
> manager.getUtility(zope.interface.Interface, name="root")
> 
> As you can see, the special interface code has disappeared, leaving 
> things only keyed on a string, the utility name.
> 
> We can then set up an adapter, something like this:
> 
> from zope.interface import Interface, implements
> from zope.component import adapts
> from zope.component.interfaces import IComponentRegistry
> 
> class IDictInterface(Interface):
> 
> def __getitem__(key):
> pass
> 
> def __setitem__(key, value):
> pass
> 
> def __delitem__(key):
> pass
> 
> class DictInterface(object):
> 
> implements(IDictInterface)
> adapts(IComponentRegistry)
> 
> def __init__(self, manager):
> self.manager = manager
> 
> def __getitem__(self, key):
> return self.manager.getUtility(Interface, name=key)
> 
> def __setitem__(self, key, value):
> self.manager.registerUtility(value,
> Interface,
> name=key)
> 
> def __delitem__(self, key):
> self.manager.unregisterUtility(provided=Interface, name=key)
> 
> manager.registerAdapter(DictInterface)
> 
> (N.B: rough sample code)
> 
> Once you have one of these objects instantiated your example code will 
> work fine:
> 
>  >>> def root_factory(environ):
> ...  return {}
> ...
>  >>> reg=IDictInterface(zope.component.getGlobalSiteManager())
>  >>> reg['root_factory'] = root_factory
>  >>> print reg['root_factory']
> 
>  >>> print zope.component.getUtility(zope.interface.Interface, 
> name="root_factory")
> 

Thanks.  Yup. I would be +1 on this if the registry itself implemented 
IDictInterface.

If that was untenable, if all the above code lived in the zope.component 
package itself, and you had an API that manifested an IDictInterface object 
when you asked for a "utilities" attribute, that would also be acceptable, as 
long as you could do:

reg.utils['root_factory'] = RootFactory

Where the registry implementation would implement a propery for "utils":

class Components(object):
 @property
 def utils(self, name):
 api = self.queryAdapter(IDictInterface, None)
 if api is None:
 api = DictInterface(self)
 return api

In reality, this will be slow, and nobody is going to override IDictInterface, 
so it would probably be better as:

class Components(object):
 def __init__(self, name='', bases=()):
 self.utils = DictInterface(self)

- 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] make zope.component.registry.Components inherit from dict?

2009-11-23 Thread Chris McDonough
Martin Aspeli wrote:
> Hi Chris,
> 
> Chris McDonough wrote:
>> Martin Aspeli wrote:
>>> We need to make sure that we're not inventing a different way to achieve 
>>> something which is already possible. This will lead to confusion, 
>>> because people will have to know "which way" is applicable in a given 
>>> situation, and the distinction will seem arbitrary.
>> I fear we are indeed inventing a different way to achieve something which is 
>> already possible.  We aren't doing it arbitrarily, though: the current way 
>> just 
>> requires the use of an interface instead of a string.  Interface usage for 
>> such 
>> a simple pattern implies a cognitive load that appears to exceed the pain 
>> point 
>> of most Python developers who are not already familiar with Zope.  So we'd 
>> like 
>> to ameliorate that as best we can.
> 
> I wish I knew what "ameliorate" meant, but I'm sure I agree.

Ha, sorry, I've been writing documentation and trying to sound smart.  "fix". 
;-)

> My concern is that we also have a pretty large existing user base to 
> worry about, and we wouldn't want to confuse them. Or, indeed, new users 
> confronted with code that has been written up to this point.

Right.

I don't think there's any way we could further confuse existing users: there 
aren't really any existing docs for the``zope.component.registry.Component`` 
object which would reinforce a set of expectations that would exclude use of a 
dict API against it.  As far as I can tell, existing user-consumable 
documentation documents the threadlocal API only.  (I am beginning to think the 
broadness of the threadlocal API is itself a problem, but that's another issue 
entirely.)

New users confronted with old code: well, we already have this problem, and at 
least if we make incremental improvements like this one, we have a shot at 
making existing code more readable.

> I think it would be nicer, because we could tell a story like this:
> 
>   - if you just want a place to store things by name...
>   - ... which can be overridden at runtime or customised with local 
> components ...
>   - ... and you don't care too much about the notion of an interface ...
>   - ... then here's the ZCA way to look up a component by name only
> 
> To register:
> 
>reg = getSiteManager()
>reg['rootfactory'] = MyRoot()
> 
> To retrieve:
> 
>reg['rootfactory']
> 
> To delete:
> 
>del reg['rootfactory']
> 
> 
> The equivalent ideas would be:
> 
>reg.registerUtility(MyRoot(), provides=Interface, name='rootfactory')
>getUtility(Interface, name='rootfactory')
>reg.unregisterUtility(provides=Interface, name='rootfactory')
> 
> Although I suspect we want a marker interface that's a bit more specific 
> than just 'Interface' since we already have some things that register 
> interfaces as utility, I think. So maybe:
> 
>class IAnonymousUtility(Interface):
>pass

Yup, +1 on all that if it would mean the registry object got a complete dict 
API (although I think we'll need to fix the "name must be a string" issue I 
sent earlier).

To be honest, I'm not really sure that this pattern has much practical benefit 
over inheriting from dict, because it just means more (missing ;-) ) 
documentation, but I recognize the desire for "internal consistency".

- 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] make zope.component.registry.Components inherit from dict?

2009-11-23 Thread Martin Aspeli
Chris McDonough wrote:
> Chris McDonough wrote:
>>> Off the top of my head, another way to think of this *might* be to say 
>>> that the 'dict access' is basically looking up a *named* utility 
>>> providing a very generic marker interface, e.g. 
>>> zope.component.interfaces.IUtility or even just 
>>> zope.interface.Interface. That way reg['foo'] == getUtility(IUtility, 
>>> name='foo'). Obviously, assignment would register in the same way.
>>>
>>> I'm not sure it's "better", though. :)
>> That would also be fine, and it would normalize things a bit, although the 
>> implementation would be harder and it would result in slower lookups.  But 
>> if 
>> it made folks feel better than inheriting from dict, I'd be +1 on it.
> 
> Meh, I just remembered that I tried this.  The current implementation 
> requires 
> that the "name" value be a literal string object (or at least something 
> convertable to Unicode).  I think we could relax this requirement; it really 
> only needs to be hashable.  I wouldn't want to deploy the API if the keys 
> were 
> required to only be strings.

Should be easy to fix, I'm sure. Why would you want something other than 
strings, though?

Martin

-- 
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
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] make zope.component.registry.Components inherit from dict?

2009-11-23 Thread Matthew Wilkes

On 2009-11-24, at 0521, Chris McDonough wrote:

> I don't think I understand.  Could you provide an example?

Sure!

I think this is the same thing that Martin suggested, but here's some  
code which should make it clearer.

First, we create an object that we want to be accessible from this  
lookup:

class Root(dict):
 pass

Then, we register that as a utility in the global site manager

manager = zope.component.getGlobalSiteManager()
manager.registerUtility(Root(),
zope.interface.Interface,
name="root")

This can then be found with:

manager.getUtility(zope.interface.Interface, name="root")

As you can see, the special interface code has disappeared, leaving  
things only keyed on a string, the utility name.

We can then set up an adapter, something like this:

from zope.interface import Interface, implements
from zope.component import adapts
from zope.component.interfaces import IComponentRegistry

class IDictInterface(Interface):

 def __getitem__(key):
 pass

 def __setitem__(key, value):
 pass

 def __delitem__(key):
 pass

class DictInterface(object):

 implements(IDictInterface)
 adapts(IComponentRegistry)

 def __init__(self, manager):
 self.manager = manager

 def __getitem__(self, key):
 return self.manager.getUtility(Interface, name=key)

 def __setitem__(self, key, value):
 self.manager.registerUtility(value,
Interface,
name=key)

 def __delitem__(self, key):
 self.manager.unregisterUtility(provided=Interface, name=key)

manager.registerAdapter(DictInterface)

(N.B: rough sample code)

Once you have one of these objects instantiated your example code will  
work fine:

 >>> def root_factory(environ):
...  return {}
...
 >>> reg=IDictInterface(zope.component.getGlobalSiteManager())
 >>> reg['root_factory'] = root_factory
 >>> print reg['root_factory']

 >>> print zope.component.getUtility(zope.interface.Interface,  
name="root_factory")



Matt
___
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] make zope.component.registry.Components inherit from dict?

2009-11-23 Thread Martin Aspeli
Hi Chris,

Chris McDonough wrote:
> Martin Aspeli wrote:
>> We need to make sure that we're not inventing a different way to achieve 
>> something which is already possible. This will lead to confusion, 
>> because people will have to know "which way" is applicable in a given 
>> situation, and the distinction will seem arbitrary.
> 
> I fear we are indeed inventing a different way to achieve something which is 
> already possible.  We aren't doing it arbitrarily, though: the current way 
> just 
> requires the use of an interface instead of a string.  Interface usage for 
> such 
> a simple pattern implies a cognitive load that appears to exceed the pain 
> point 
> of most Python developers who are not already familiar with Zope.  So we'd 
> like 
> to ameliorate that as best we can.

I wish I knew what "ameliorate" meant, but I'm sure I agree.

My concern is that we also have a pretty large existing user base to 
worry about, and we wouldn't want to confuse them. Or, indeed, new users 
confronted with code that has been written up to this point.

>   >> In a system like this, there are no interfaces; the string 'root_factory'
>>> performs the same job as the IRootFactory interface for registration and 
>>> lookup.  I'd like to make the ZCA registry operate like this.  There's 
>>> really 
>>> no reason for there to be an interface hanging around to represent this 
>>> thing: 
>>> we're using the ZCA as a complicated dictionary here.
>> I think there is a reason, though you may not agree it's a good one. The 
>> interface makes a promise about what the component is supposed to be 
>> able to do. We don't enforce that in our duck-typing programming 
>> language, but I think there is value in being able to say, "I want an 
>> object that conforms to this interface (i.e. delivers what the interface 
>> promises) - please get me the best one you've got".
> 
> That is indeed the promise.  But obviously the object you get back needn't 
> *actually* implement the interface you asked for; it's only conventional.  It 
> is the same with a dictionary lookup: if you document that, for your 
> application, reg['root_factory'] will return an object implementing 
> IRootFactory, it's pretty much equivalent as far as I can tell.  Use of the 
> ZCA 
> API to store and retrieve instances implementing an interface isn't required 
> to 
> get benefit out of the existence of that interface.

No, that's true, except perhaps that it's two things to worry about: an 
interface and the related name.

> I guess I can only point at the rationales in 
> 

Yep, and I agree with these.

>> Off the top of my head, another way to think of this *might* be to say 
>> that the 'dict access' is basically looking up a *named* utility 
>> providing a very generic marker interface, e.g. 
>> zope.component.interfaces.IUtility or even just 
>> zope.interface.Interface. That way reg['foo'] == getUtility(IUtility, 
>> name='foo'). Obviously, assignment would register in the same way.
>>
>> I'm not sure it's "better", though. :)
> 
> That would also be fine, and it would normalize things a bit, although the 
> implementation would be harder and it would result in slower lookups.  But if 
> it made folks feel better than inheriting from dict, I'd be +1 on it.

I think it would be nicer, because we could tell a story like this:

  - if you just want a place to store things by name...
  - ... which can be overridden at runtime or customised with local 
components ...
  - ... and you don't care too much about the notion of an interface ...
  - ... then here's the ZCA way to look up a component by name only

To register:

   reg = getSiteManager()
   reg['rootfactory'] = MyRoot()

To retrieve:

   reg['rootfactory']

To delete:

   del reg['rootfactory']


The equivalent ideas would be:

   reg.registerUtility(MyRoot(), provides=Interface, name='rootfactory')
   getUtility(Interface, name='rootfactory')
   reg.unregisterUtility(provides=Interface, name='rootfactory')

Although I suspect we want a marker interface that's a bit more specific 
than just 'Interface' since we already have some things that register 
interfaces as utility, I think. So maybe:

   class IAnonymousUtility(Interface):
   pass

Martin

-- 
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
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] make zope.component.registry.Components inherit from dict?

2009-11-23 Thread Chris McDonough
Chris McDonough wrote:
> 
>> Off the top of my head, another way to think of this *might* be to say 
>> that the 'dict access' is basically looking up a *named* utility 
>> providing a very generic marker interface, e.g. 
>> zope.component.interfaces.IUtility or even just 
>> zope.interface.Interface. That way reg['foo'] == getUtility(IUtility, 
>> name='foo'). Obviously, assignment would register in the same way.
>>
>> I'm not sure it's "better", though. :)
> 
> That would also be fine, and it would normalize things a bit, although the 
> implementation would be harder and it would result in slower lookups.  But if 
> it made folks feel better than inheriting from dict, I'd be +1 on it.

Meh, I just remembered that I tried this.  The current implementation requires 
that the "name" value be a literal string object (or at least something 
convertable to Unicode).  I think we could relax this requirement; it really 
only needs to be hashable.  I wouldn't want to deploy the API if the keys were 
required to only be strings.

- 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] make zope.component.registry.Components inherit from dict?

2009-11-23 Thread Chris McDonough
Martin Aspeli wrote:
> We need to make sure that we're not inventing a different way to achieve 
> something which is already possible. This will lead to confusion, 
> because people will have to know "which way" is applicable in a given 
> situation, and the distinction will seem arbitrary.

I fear we are indeed inventing a different way to achieve something which is 
already possible.  We aren't doing it arbitrarily, though: the current way just 
requires the use of an interface instead of a string.  Interface usage for such 
a simple pattern implies a cognitive load that appears to exceed the pain point 
of most Python developers who are not already familiar with Zope.  So we'd like 
to ameliorate that as best we can.

  >> In a system like this, there are no interfaces; the string 'root_factory'
>> performs the same job as the IRootFactory interface for registration and 
>> lookup.  I'd like to make the ZCA registry operate like this.  There's 
>> really 
>> no reason for there to be an interface hanging around to represent this 
>> thing: 
>> we're using the ZCA as a complicated dictionary here.
> 
> I think there is a reason, though you may not agree it's a good one. The 
> interface makes a promise about what the component is supposed to be 
> able to do. We don't enforce that in our duck-typing programming 
> language, but I think there is value in being able to say, "I want an 
> object that conforms to this interface (i.e. delivers what the interface 
> promises) - please get me the best one you've got".

That is indeed the promise.  But obviously the object you get back needn't 
*actually* implement the interface you asked for; it's only conventional.  It 
is the same with a dictionary lookup: if you document that, for your 
application, reg['root_factory'] will return an object implementing 
IRootFactory, it's pretty much equivalent as far as I can tell.  Use of the ZCA 
API to store and retrieve instances implementing an interface isn't required to 
get benefit out of the existence of that interface.

>> It would also obviously be possible to just add a dictionary instance 
>> attribute 
>> to a registry, so instead of subclassing Components from dict, you might do:
>>
>> reg = getSiteManager()
>> reg.simple['root_factory'] = root_factory
>>
>> To be honest, I don't mind one way or another; I'd just like to push 
>> whatever 
>> we do upstream if possible.  If we move too far away from the stock ZCA 
>> facilities, it becomes harder to integrate Zope apps into BFG and vice versa.
> 
> I whole-heartedly agree, and I think it's important that we use the 
> momentum behind BFG (and other consumers of the ZTK) to drive the ZTK 
> forward. Anything else would be stupid.
> 
> I'm still concerned that your proposal basically leaves us with two ways 
> of implementing the singleton pattern with the ZCA, and I'm not sure 
> that's in our best interest. I'd be interested to hear your thoughts 
> further, though.

I guess I can only point at the rationales in 


> Off the top of my head, another way to think of this *might* be to say 
> that the 'dict access' is basically looking up a *named* utility 
> providing a very generic marker interface, e.g. 
> zope.component.interfaces.IUtility or even just 
> zope.interface.Interface. That way reg['foo'] == getUtility(IUtility, 
> name='foo'). Obviously, assignment would register in the same way.
> 
> I'm not sure it's "better", though. :)

That would also be fine, and it would normalize things a bit, although the 
implementation would be harder and it would result in slower lookups.  But if 
it made folks feel better than inheriting from dict, I'd be +1 on it.

- 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] make zope.component.registry.Components inherit from dict?

2009-11-23 Thread Martin Aspeli
Chris McDonough wrote:

>> A lookup keyed entirely on strings and not interfaces is perfectly 
>> possible using the ZCA, just register your utility to provide 
>> z.i.Interface and name it.  Your semantics are the same as the simple 
>> dictionary use-case, but it doesn't force people to choose one means of 
>> access over another.
> 
> I don't think I understand.  Could you provide an example?

See my post - I think Matt and I had the same thought.

> I don't really have enough context to understand how it would be confusing, 
> but 
> I trust that it would.  Persistent registries are traversable?

The ++etc++site namespace shows you persistent components. You can 
delete them in the ZMI to remove registrations, and, in some Zope 3 
apps, add them via an add menu, even.

In Zope 2, there's been some mixing of OFS.Folder with component 
registries, and OFS.Folder uses some dict API. However, I think it'd be 
OK to "break" that and use a more bespoke screen to be honest.


> In practice, I don't actually find it very useful to register somthing that 
> you 
> know will be a singleton as a literal ZCA utility, anyway, because there's 
> exactly one lookup pattern: set it, get it.  I don't think I've ever 
> performed 
> an unnamed utility lookup expecting that a "more specific" implementation of 
> a 
> utility might be returned because I've passed some subtype of a more general 
> interface.  How about you?

No, but I have expected a local registry to be able to override, which 
is an important use case.

> Ok, so be it, we will diverge.  Shame, that, because it will mean that 
> software 
> libraries composed expecting the r.bfg registry may not work under Zope, 
> further fracturing things.

Let's not give up just yet. I think there's a lot of value in 
convergence here, so we should be able to find an approach that will. 
And Matt and I aren't the only voices to be heard.

Martin

-- 
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
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] make zope.component.registry.Components inherit from dict?

2009-11-23 Thread Chris McDonough
Matthew Wilkes wrote:
>> In a system like this, there are no interfaces; the string 
>> 'root_factory' performs the same job as the IRootFactory interface for 
>> registration and lookup.  I'd like to make the ZCA registry operate 
>> like this.  There's really no reason for there to be an interface 
>> hanging around to represent this thing: we're using the ZCA as a 
>> complicated dictionary here.
> 
> Right, but I think mixing the two is just going to be confusing.  Your 
> alternative spelling may well be useful, but only if it works within the 
> confines of the ZCA itself, otherwise you're just hijacking the 
> component root for your own (nefarious) purposes.
> 
> A lookup keyed entirely on strings and not interfaces is perfectly 
> possible using the ZCA, just register your utility to provide 
> z.i.Interface and name it.  Your semantics are the same as the simple 
> dictionary use-case, but it doesn't force people to choose one means of 
> access over another.

I don't think I understand.  Could you provide an example?

> Creating shim methods for the dict-interface (or a useful subset) could 
> hook in registration, querying and unregistration of utilities in a 
> vaguely sensible way.
> 
> But, here is where the ZCA eyes come back into play, I wouldn't add this 
> to the ZCA itself.  One reason being that Hanno's been working on a more 
> useful persistent component root for Zope that brings in bits of OFS, 
> hooking a dict in there would just be confusing.

I don't really have enough context to understand how it would be confusing, but 
I trust that it would.  Persistent registries are traversable?

> So, if only there was a way of specifying a new set of functions and 
> defining a way of mapping them onto an existing object…
> 
> I'd say make an adapter that adds the dict interface as a wrapper around 
> named utilities and provide that to BFG users.  That way you don't 
> pollute the namespace of the ZCA object, interoperability with other 
> code is maintained and you get your user-friendly interface.

Using a helper wrapper for utility registration here is not useful if it 
requires the developer to understand interfaces, so such wrapper would need to 
look like this:

class UnnamedUtilityWrapper(object):
 def __init__(self, registry):
 self._mappings = {'root_factory':IRootFactory, 'settings':ISettings}
 self.registry = registry

 def __getitem__(self, name):
 return self.registry.getUtility(self._mappings[name])

 def __setitem__(self, name, value):
 return self.registry.registerUtility(value, self._mappings[name])

  ... the remainder of the dictionary interface ...

And that would just be silly from the perspective of someone reading the code 
for the first time.  It would be even more confusing if you came across it than 
would use of the ZCA registerUtility/getUtility APIs.

In practice, I don't actually find it very useful to register somthing that you 
know will be a singleton as a literal ZCA utility, anyway, because there's 
exactly one lookup pattern: set it, get it.  I don't think I've ever performed 
an unnamed utility lookup expecting that a "more specific" implementation of a 
utility might be returned because I've passed some subtype of a more general 
interface.  How about you?

On the other hand the registry in BFG is the single place that "contains 
configuration", and a root factory is definitely configuration.

Ok, so be it, we will diverge.  Shame, that, because it will mean that software 
libraries composed expecting the r.bfg registry may not work under Zope, 
further fracturing things.

- 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] make zope.component.registry.Components inherit from dict?

2009-11-23 Thread Martin Aspeli
Matthew Wilkes wrote:

> Right, but I think mixing the two is just going to be confusing.  Your  
> alternative spelling may well be useful, but only if it works within  
> the confines of the ZCA itself, otherwise you're just hijacking the  
> component root for your own (nefarious) purposes.

The site manager != the component site. In Plone, getSite() returns the 
Plone site object; getSiteManager() returns an IComponents instance or 
whatever that interface is. So making that implement the dict API is OK.

Martin

-- 
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
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] make zope.component.registry.Components inherit from dict?

2009-11-23 Thread Martin Aspeli
Hi Chris,

>>> In repoze.bfg, we've actually decided to use a subclass of the component
>>> registry which also inherits from "dict".  This makes it possible to 
>>> spell
>>> common unnamed "utility" registrations and lookups as:
>>>
>>> utility = SomeUtilityImplementation()
>>> registry['someutility'] = utility


I rather like the simplicity of this, so in general +1, but let's hear 
Matt out too.

>> While I'm all for simplification, this makes very little sense to me.  
>> If this is an unnamed registration why is there a name ('someutility') 
>> involved?
>>
>> If it was a named registration against Interface, or if the key was an 
>> interface/dotted name that'd make sense.
> 
> You may have Zope Component Developer's Eyes, a common disease in these 
> parts. ;-)

I know you were joking, but bear in mind that you're proposing a change 
to the most fundamental part of the Zope ecosystem, so that disease is 
not really a disease. :)

We need to make sure that we're not inventing a different way to achieve 
something which is already possible. This will lead to confusion, 
because people will have to know "which way" is applicable in a given 
situation, and the distinction will seem arbitrary.

> If you haven't already, you might take a look at the example after the 
> paragraph that starts with "But we recognize that developers who my want to 
> extend the framework..." within:
> 
> 

Nice write-up. :)

> In a system like this, there are no interfaces; the string 'root_factory' 
> performs the same job as the IRootFactory interface for registration and 
> lookup.  I'd like to make the ZCA registry operate like this.  There's really 
> no reason for there to be an interface hanging around to represent this 
> thing: 
> we're using the ZCA as a complicated dictionary here.

I think there is a reason, though you may not agree it's a good one. The 
interface makes a promise about what the component is supposed to be 
able to do. We don't enforce that in our duck-typing programming 
language, but I think there is value in being able to say, "I want an 
object that conforms to this interface (i.e. delivers what the interface 
promises) - please get me the best one you've got".

> It would also obviously be possible to just add a dictionary instance 
> attribute 
> to a registry, so instead of subclassing Components from dict, you might do:
> 
> reg = getSiteManager()
> reg.simple['root_factory'] = root_factory
> 
> To be honest, I don't mind one way or another; I'd just like to push whatever 
> we do upstream if possible.  If we move too far away from the stock ZCA 
> facilities, it becomes harder to integrate Zope apps into BFG and vice versa.

I whole-heartedly agree, and I think it's important that we use the 
momentum behind BFG (and other consumers of the ZTK) to drive the ZTK 
forward. Anything else would be stupid.

I'm still concerned that your proposal basically leaves us with two ways 
of implementing the singleton pattern with the ZCA, and I'm not sure 
that's in our best interest. I'd be interested to hear your thoughts 
further, though.

Off the top of my head, another way to think of this *might* be to say 
that the 'dict access' is basically looking up a *named* utility 
providing a very generic marker interface, e.g. 
zope.component.interfaces.IUtility or even just 
zope.interface.Interface. That way reg['foo'] == getUtility(IUtility, 
name='foo'). Obviously, assignment would register in the same way.

I'm not sure it's "better", though. :)

Martin

-- 
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
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] make zope.component.registry.Components inherit from dict?

2009-11-23 Thread Matthew Wilkes
> You may have Zope Component Developer's Eyes, a common disease in  
> these parts. ;-)

The goggles, they do nothing.

> Under the hood, the system does something like this when a root  
> factory needs to be registered:
>
>  from repoze.bfg.interfaces import IRootFactory
>  from zope.component import getSiteManager
>
>  reg = getSiteManager()
>  reg.registerUtility(root_factory, IRootFactory)
>
> Then when the system needs to look it up again, it needs to do this:
>
>  root_factory = getUtility(IRootFactory)

Looks sensible.

> If you notice, there is no "key" for this utility other than the  
> IRootFactory interface (it's unnamed).  In this case, also, there  
> will never be a registration made against a subclass of  
> IRootFactory.  In this scenario, if we weren't using ZCA at all,  
> we'd probably do something like this:
>
>  reg = get_some_registry()
>  reg['root_factory'] = root_factory

Sure.

> In a system like this, there are no interfaces; the string  
> 'root_factory' performs the same job as the IRootFactory interface  
> for registration and lookup.  I'd like to make the ZCA registry  
> operate like this.  There's really no reason for there to be an  
> interface hanging around to represent this thing: we're using the  
> ZCA as a complicated dictionary here.

Right, but I think mixing the two is just going to be confusing.  Your  
alternative spelling may well be useful, but only if it works within  
the confines of the ZCA itself, otherwise you're just hijacking the  
component root for your own (nefarious) purposes.

A lookup keyed entirely on strings and not interfaces is perfectly  
possible using the ZCA, just register your utility to provide  
z.i.Interface and name it.  Your semantics are the same as the simple  
dictionary use-case, but it doesn't force people to choose one means  
of access over another.

Creating shim methods for the dict-interface (or a useful subset)  
could hook in registration, querying and unregistration of utilities  
in a vaguely sensible way.

But, here is where the ZCA eyes come back into play, I wouldn't add  
this to the ZCA itself.  One reason being that Hanno's been working on  
a more useful persistent component root for Zope that brings in bits  
of OFS, hooking a dict in there would just be confusing.

So, if only there was a way of specifying a new set of functions and  
defining a way of mapping them onto an existing object…

I'd say make an adapter that adds the dict interface as a wrapper  
around named utilities and provide that to BFG users.  That way you  
don't pollute the namespace of the ZCA object, interoperability with  
other code is maintained and you get your user-friendly interface.

Matt
___
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] make zope.component.registry.Components inherit from dict?

2009-11-23 Thread Chris McDonough
Matthew Wilkes wrote:
> Hi Chris,
> 
> On 2009-11-24, at 0324, Chris McDonough wrote:
> 
>> In repoze.bfg, we've actually decided to use a subclass of the component
>> registry which also inherits from "dict".  This makes it possible to 
>> spell
>> common unnamed "utility" registrations and lookups as:
>>
>> utility = SomeUtilityImplementation()
>> registry['someutility'] = utility
> 
> While I'm all for simplification, this makes very little sense to me.  
> If this is an unnamed registration why is there a name ('someutility') 
> involved?
> 
> If it was a named registration against Interface, or if the key was an 
> interface/dotted name that'd make sense.

You may have Zope Component Developer's Eyes, a common disease in these parts. 
;-)

If you haven't already, you might take a look at the example after the 
paragraph that starts with "But we recognize that developers who my want to 
extend the framework..." within:



> Could you expand on what the key is supposed to represent?

Sure.  Let's take an example from repoze.bfg itself.

repoze.bfg allows an application developer to register a "root factory" for a 
given application.  There is only ever one of these for any application, and 
thus only one ever needs to be registered.

For purposes of example, a root factory might be the "root" method of a 
particular ZODB connection, e.g. "root = conn.root()".  It's a callable that 
returns the sole root object for a given application.  For purposes of example, 
let's pretend it's this:

   def root_factory(environ):
   return {}

Under the hood, the system does something like this when a root factory needs 
to be registered:

   from repoze.bfg.interfaces import IRootFactory
   from zope.component import getSiteManager

   reg = getSiteManager()
   reg.registerUtility(root_factory, IRootFactory)

Then when the system needs to look it up again, it needs to do this:

   root_factory = getUtility(IRootFactory)

If you notice, there is no "key" for this utility other than the IRootFactory 
interface (it's unnamed).  In this case, also, there will never be a 
registration made against a subclass of IRootFactory.  In this scenario, if we 
weren't using ZCA at all, we'd probably do something like this:

   reg = get_some_registry()
   reg['root_factory'] = root_factory

In a system like this, there are no interfaces; the string 'root_factory' 
performs the same job as the IRootFactory interface for registration and 
lookup.  I'd like to make the ZCA registry operate like this.  There's really 
no reason for there to be an interface hanging around to represent this thing: 
we're using the ZCA as a complicated dictionary here.

It would also obviously be possible to just add a dictionary instance attribute 
to a registry, so instead of subclassing Components from dict, you might do:

reg = getSiteManager()
reg.simple['root_factory'] = root_factory

To be honest, I don't mind one way or another; I'd just like to push whatever 
we do upstream if possible.  If we move too far away from the stock ZCA 
facilities, it becomes harder to integrate Zope apps into BFG and vice versa.

- 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] make zope.component.registry.Components inherit from dict?

2009-11-23 Thread Matthew Wilkes
Hi Chris,

On 2009-11-24, at 0324, Chris McDonough wrote:

> In repoze.bfg, we've actually decided to use a subclass of the  
> component
> registry which also inherits from "dict".  This makes it possible to  
> spell
> common unnamed "utility" registrations and lookups as:
>
> utility = SomeUtilityImplementation()
> registry['someutility'] = utility

While I'm all for simplification, this makes very little sense to me.   
If this is an unnamed registration why is there a name ('someutility')  
involved?

If it was a named registration against Interface, or if the key was an  
interface/dotted name that'd make sense.

Could you expand on what the key is supposed to represent?

Matt
___
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 )