[Zope3-checkins] SVN: Zope3/branches/srichter-blow-services/src/zope/ Updated to the latest head version of the trunk. It did not fix the 4

Stephan Richter srichter at cosmos.phy.tufts.edu
Thu Feb 10 12:48:37 EST 2005


Log message for revision 29103:
  Updated to the latest head version of the trunk. It did not fix the 4 
  ftests failures though. :(
  

Changed:
  U   Zope3/branches/srichter-blow-services/src/zope/app/authentication/browser/special-groups.txt
  A   Zope3/branches/srichter-blow-services/src/zope/app/component/tests/components.py
  U   Zope3/branches/srichter-blow-services/src/zope/app/container/browser/metaconfigure.py
  U   Zope3/branches/srichter-blow-services/src/zope/app/container/browser/tests/test_directive.py
  U   Zope3/branches/srichter-blow-services/src/zope/app/form/browser/source.py
  U   Zope3/branches/srichter-blow-services/src/zope/app/form/browser/source.txt
  U   Zope3/branches/srichter-blow-services/src/zope/app/form/tests/test_utility.py
  U   Zope3/branches/srichter-blow-services/src/zope/app/form/utility.py
  U   Zope3/branches/srichter-blow-services/src/zope/app/i18n/translationdomain.py
  U   Zope3/branches/srichter-blow-services/src/zope/app/publisher/browser/tests/test_directives.py
  U   Zope3/branches/srichter-blow-services/src/zope/app/registration/registration.py
  UU  Zope3/branches/srichter-blow-services/src/zope/app/security/vocabulary.py
  U   Zope3/branches/srichter-blow-services/src/zope/app/securitypolicy/browser/granting.pt
  U   Zope3/branches/srichter-blow-services/src/zope/app/securitypolicy/tests/functional.py
  U   Zope3/branches/srichter-blow-services/src/zope/bforest/bforest.py
  U   Zope3/branches/srichter-blow-services/src/zope/bforest/bforest.txt
  U   Zope3/branches/srichter-blow-services/src/zope/schema/_field.py

-=-
Modified: Zope3/branches/srichter-blow-services/src/zope/app/authentication/browser/special-groups.txt
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/authentication/browser/special-groups.txt	2005-02-10 15:21:18 UTC (rev 29102)
+++ Zope3/branches/srichter-blow-services/src/zope/app/authentication/browser/special-groups.txt	2005-02-10 17:48:37 UTC (rev 29103)
@@ -21,19 +21,19 @@
   ... Authorization: Basic mgr:mgrpw
   ... Content-Type: multipart/form-data; boundary=---------------------------51955270618919134971413296540
   ... 
-  ... -----------------------------51955270618919134971413296540
-  ... Content-Disposition: form-data; name="field.prefix"
-  ... 
-  ... users.
-  ... -----------------------------51955270618919134971413296540
-  ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
-  ... 
-  ... Add
-  ... -----------------------------51955270618919134971413296540
-  ... Content-Disposition: form-data; name="add_input_name"
-  ... 
-  ... 
-  ... -----------------------------51955270618919134971413296540--
+  ... -----------------------------51955270618919134971413296540
+  ... Content-Disposition: form-data; name="field.prefix"
+  ... 
+  ... users.
+  ... -----------------------------51955270618919134971413296540
+  ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
+  ... 
+  ... Add
+  ... -----------------------------51955270618919134971413296540
+  ... Content-Disposition: form-data; name="add_input_name"
+  ... 
+  ... 
+  ... -----------------------------51955270618919134971413296540--
   ... """)
   HTTP/1.1 303 See Other
   ...
@@ -45,380 +45,378 @@
   ... Authorization: Basic mgr:mgrpw
   ... Content-Type: multipart/form-data; boundary=---------------------------1211945862063657304996683149
   ... 
-  ... -----------------------------1211945862063657304996683149
-  ... Content-Disposition: form-data; name="field.name"
+  ... -----------------------------1211945862063657304996683149
+  ... Content-Disposition: form-data; name="field.name"
+  ... 
+  ... users
+  ... -----------------------------1211945862063657304996683149
+  ... Content-Disposition: form-data; name="field.interface"
+  ... 
+  ... zope.app.authentication.interfaces.ISearchableAuthenticationPlugin
+  ... -----------------------------1211945862063657304996683149
+  ... Content-Disposition: form-data; name="field.interface-empty-marker"
+  ... 
+  ... 1
+  ... -----------------------------1211945862063657304996683149
+  ... Content-Disposition: form-data; name="field.permission"
+  ... 
+  ... 
+  ... -----------------------------1211945862063657304996683149
+  ... Content-Disposition: form-data; name="field.permission-empty-marker"
+  ... 
+  ... 1
+  ... -----------------------------1211945862063657304996683149
+  ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
+  ... 
+  ... Add
+  ... -----------------------------1211945862063657304996683149--
+  ... """)
+  HTTP/1.1 303 See Other
+  ...
+
+Add a principal to it:
+
+  >>> print http(r"""
+  ... POST /++etc++site/default/PrincipalFolder/+/AddPrincipalInformation.html%3D HTTP/1.1
+  ... Authorization: Basic mgr:mgrpw
+  ... Content-Type: multipart/form-data; boundary=---------------------------10033016405103631412002637985
   ... 
-  ... users
-  ... -----------------------------1211945862063657304996683149
-  ... Content-Disposition: form-data; name="field.interface"
+  ... -----------------------------10033016405103631412002637985
+  ... Content-Disposition: form-data; name="field.login"
+  ... 
+  ... bob
+  ... -----------------------------10033016405103631412002637985
+  ... Content-Disposition: form-data; name="field.password"
+  ... 
+  ... 123
+  ... -----------------------------10033016405103631412002637985
+  ... Content-Disposition: form-data; name="field.title"
+  ... 
+  ... Bob
+  ... -----------------------------10033016405103631412002637985
+  ... Content-Disposition: form-data; name="field.description"
+  ... 
+  ... 
+  ... -----------------------------10033016405103631412002637985
+  ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
+  ... 
+  ... Add
+  ... -----------------------------10033016405103631412002637985
+  ... Content-Disposition: form-data; name="add_input_name"
+  ... 
+  ... 
+  ... -----------------------------10033016405103631412002637985--
+  ... """)
+  HTTP/1.1 303 See Other
+  ...
+
+Create a pluggable-authentication utility:
+
+  >>> print http(r"""
+  ... POST /++etc++site/default/@@contents.html HTTP/1.1
+  ... Authorization: Basic mgr:mgrpw
+  ... Content-Type: application/x-www-form-urlencoded
   ... 
-  ... zope.app.authentication.interfaces.ISearchableAuthenticationPlugin
-  ... -----------------------------1211945862063657304996683149
-  ... Content-Disposition: form-data; name="field.interface-empty-marker"
+  ... type_name=BrowserAdd__zope.app.authentication.authentication.LocalPluggableAuthentication&new_value=""")
+  HTTP/1.1 303 See Other
+  ...
+
+and register it:
+
+  >>> print http(r"""
+  ... POST /++etc++site/default/LocalPluggableAuthentication/addRegistration.html HTTP/1.1
+  ... Authorization: Basic mgr:mgrpw
+  ... Content-Type: multipart/form-data; boundary=---------------------------2567744622114531019698320091
+  ... Referer: http://localhost:8081/++etc++site/default/LocalPluggableAuthentication/addRegistration.html
   ... 
-  ... 1
-  ... -----------------------------1211945862063657304996683149
-  ... Content-Disposition: form-data; name="field.permission"
+  ... -----------------------------2567744622114531019698320091
+  ... Content-Disposition: form-data; name="field.name"
+  ... 
+  ... 
+  ... -----------------------------2567744622114531019698320091
+  ... Content-Disposition: form-data; name="field.interface"
+  ... 
+  ... zope.app.security.interfaces.IAuthentication
+  ... -----------------------------2567744622114531019698320091
+  ... Content-Disposition: form-data; name="field.interface-empty-marker"
+  ... 
+  ... 1
+  ... -----------------------------2567744622114531019698320091
+  ... Content-Disposition: form-data; name="field.permission"
+  ... 
+  ... 
+  ... -----------------------------2567744622114531019698320091
+  ... Content-Disposition: form-data; name="field.permission-empty-marker"
+  ... 
+  ... 1
+  ... -----------------------------2567744622114531019698320091
+  ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
+  ... 
+  ... Add
+  ... -----------------------------2567744622114531019698320091--
+  ... """)
+  HTTP/1.1 303 See Other
+  ...
+
+and configure it:
+
+  >>> print http(r"""
+  ... POST /++etc++site/default/LocalPluggableAuthentication/@@edit.html HTTP/1.1
+  ... Authorization: Basic mgr:mgrpw
+  ... Content-Type: multipart/form-data; boundary=---------------------------12424310211503201098946683515
   ... 
+  ... -----------------------------12424310211503201098946683515
+  ... Content-Disposition: form-data; name="field.extractors.to"
+  ... 
+  ... HTTP Basic
+  ... -----------------------------12424310211503201098946683515
+  ... Content-Disposition: form-data; name="field.extractors-empty-marker"
+  ... 
+  ... 
+  ... -----------------------------12424310211503201098946683515
+  ... Content-Disposition: form-data; name="field.authenticators.to"
+  ... 
+  ... users
+  ... -----------------------------12424310211503201098946683515
+  ... Content-Disposition: form-data; name="field.authenticators-empty-marker"
+  ... 
+  ... 
+  ... -----------------------------12424310211503201098946683515
+  ... Content-Disposition: form-data; name="field.challengers.to"
+  ... 
+  ... No Challenge if Authenticated
+  ... -----------------------------12424310211503201098946683515
+  ... Content-Disposition: form-data; name="field.challengers.to"
+  ... 
+  ... Zope Realm HTTP Basic
+  ... -----------------------------12424310211503201098946683515
+  ... Content-Disposition: form-data; name="field.challengers-empty-marker"
+  ... 
+  ... 
+  ... -----------------------------12424310211503201098946683515
+  ... Content-Disposition: form-data; name="field.factories.to"
+  ... 
+  ... Default
+  ... -----------------------------12424310211503201098946683515
+  ... Content-Disposition: form-data; name="field.factories-empty-marker"
+  ... 
+  ... 
+  ... -----------------------------12424310211503201098946683515
+  ... Content-Disposition: form-data; name="field.searchers.to"
+  ... 
+  ... users
+  ... -----------------------------12424310211503201098946683515
+  ... Content-Disposition: form-data; name="field.searchers-empty-marker"
+  ... 
+  ... 
+  ... -----------------------------12424310211503201098946683515
+  ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
+  ... 
+  ... Change
+  ... -----------------------------12424310211503201098946683515
+  ... Content-Disposition: form-data; name="field.extractors"
+  ... 
+  ... HTTP Basic
+  ... -----------------------------12424310211503201098946683515
+  ... Content-Disposition: form-data; name="field.authenticators"
+  ... 
+  ... users
+  ... -----------------------------12424310211503201098946683515
+  ... Content-Disposition: form-data; name="field.challengers"
+  ... 
+  ... No Challenge if Authenticated
+  ... -----------------------------12424310211503201098946683515
+  ... Content-Disposition: form-data; name="field.challengers"
+  ... 
+  ... Zope Realm HTTP Basic
+  ... -----------------------------12424310211503201098946683515
+  ... Content-Disposition: form-data; name="field.factories"
+  ... 
+  ... Default
+  ... -----------------------------12424310211503201098946683515
+  ... Content-Disposition: form-data; name="field.searchers"
+  ... 
+  ... users
+  ... -----------------------------12424310211503201098946683515--
+  ... """)
+  HTTP/1.1 200 Ok
+  ...
+
+Normally, the anonymous role has view, we'll deny it:
+
+  >>> print http(r"""
+  ... POST /++etc++site/AllRolePermissions.html HTTP/1.1
+  ... Authorization: Basic mgr:mgrpw
+  ... Content-Type: application/x-www-form-urlencoded
   ... 
-  ... -----------------------------1211945862063657304996683149
-  ... Content-Disposition: form-data; name="field.permission-empty-marker"
+  ... role_id=zope.Anonymous""" 
+  ... """&Deny%3Alist=zope.View""" 
+  ... """&Deny%3Alist=zope.app.dublincore.view""" 
+  ... """&SUBMIT_ROLE=Save+Changes""")
+  HTTP/1.1 200 Ok
+  ...
+
+Now, if we try to access the main page as an anonymous user, we'll be unauthorized:
+
+  >>> print http(r"""
+  ... GET / HTTP/1.1
+  ... """)
+  HTTP/1.1 401 Unauthorized
+  ...
+
+We'll even be unauthorized if we try to access it as bob:
+
+  >>> print http(r"""
+  ... GET / HTTP/1.1
+  ... Authorization: Basic bob:123
+  ... """)
+  HTTP/1.1 403 Forbidden
+  ...
+
+No, let's grant view to the authenticated group:
+
+  >>> print http(r"""
+  ... POST /@@grant.html HTTP/1.1
+  ... Authorization: Basic mgr:mgrpw
+  ... Content-Type: application/x-www-form-urlencoded
   ... 
-  ... 1
-  ... -----------------------------1211945862063657304996683149
-  ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
+  ... field.principal=em9wZS5BdXRoZW50aWNhdGVk&field.principal.displayed=y"""
+  ... """&field.em9wZS5BdXRoZW50aWNhdGVk.permission.zope.View=allow"""
+  ... """&field.em9wZS5BdXRoZW50aWNhdGVk.permission.zope.app.dublincore.view=allow"""
+  ... """&GRANT_SUBMIT=Change""")
+  HTTP/1.1 200 Ok
+  ...
+
+Now, with this, we can access the main page as bob, but not as an
+anonymous user:
+
+  >>> print http(r"""
+  ... GET / HTTP/1.1
+  ... Authorization: Basic bob:123
+  ... """)
+  HTTP/1.1 200 Ok
+  ...
+
+  >>> print http(r"""
+  ... GET / HTTP/1.1
+  ... """)
+  HTTP/1.1 401 Unauthorized
+  ...
+
+Now, we'll grant to unauthenticated:
+
+  >>> print http(r"""
+  ... POST /@@grant.html HTTP/1.1
+  ... Authorization: Basic mgr:mgrpw
+  ... Content-Type: application/x-www-form-urlencoded
+  ... Referer: http://localhost:8081/@@grant.html
   ... 
-  ... Add
-  ... -----------------------------1211945862063657304996683149--
+  ... field.principal=em9wZS5Bbnlib2R5"""
+  ... """&field.em9wZS5Bbnlib2R5.permission.zope.View=allow"""
+  ... """&field.em9wZS5Bbnlib2R5.permission.zope.app.dublincore.view=allow"""
+  ... """&GRANT_SUBMIT=Change""")
+  HTTP/1.1 200 Ok
+  ...
+
+With this, we can access the page as either bob or anonymous:
+
+  >>> print http(r"""
+  ... GET / HTTP/1.1
+  ... Authorization: Basic bob:123
   ... """)
-  HTTP/1.1 303 See Other
+  HTTP/1.1 200 Ok
   ...
 
-# Add a principal to it:
-# 
-#   >>> print http(r"""
-#   ... POST /++etc++site/default/PrincipalFolder/+/AddPrincipalInformation.html%3D HTTP/1.1
-#   ... Authorization: Basic mgr:mgrpw
-#   ... Content-Type: multipart/form-data; boundary=---------------------------10033016405103631412002637985
-#   ... 
-#   ... -----------------------------10033016405103631412002637985
-#   ... Content-Disposition: form-data; name="field.login"
-#   ... 
-#   ... bob
-#   ... -----------------------------10033016405103631412002637985
-#   ... Content-Disposition: form-data; name="field.password"
-#   ... 
-#   ... 123
-#   ... -----------------------------10033016405103631412002637985
-#   ... Content-Disposition: form-data; name="field.title"
-#   ... 
-#   ... Bob
-#   ... -----------------------------10033016405103631412002637985
-#   ... Content-Disposition: form-data; name="field.description"
-#   ... 
-#   ... 
-#   ... -----------------------------10033016405103631412002637985
-#   ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
-#   ... 
-#   ... Add
-#   ... -----------------------------10033016405103631412002637985
-#   ... Content-Disposition: form-data; name="add_input_name"
-#   ... 
-#   ... 
-#   ... -----------------------------10033016405103631412002637985--
-#   ... """)
-#   HTTP/1.1 303 See Other
-#   ...
-# 
-# Create a pluggable-authentication utility:
-# 
-#   >>> print http(r"""
-#   ... POST /++etc++site/default/@@contents.html HTTP/1.1
-#   ... Authorization: Basic mgr:mgrpw
-#   ... Content-Type: application/x-www-form-urlencoded
-#   ... 
-#   ... type_name=BrowserAdd__zope.app.authentication.authentication.LocalPluggableAuthentication&new_value=""")
-#   HTTP/1.1 303 See Other
-#   ...
-# 
-# and register it:
-# 
-#   >>> print http(r"""
-#   ... POST /++etc++site/default/LocalPluggableAuthentication/addRegistration.html HTTP/1.1
-#   ... Authorization: Basic mgr:mgrpw
-#   ... Content-Type: multipart/form-data; boundary=---------------------------2567744622114531019698320091
-#   ... Referer: http://localhost:8081/++etc++site/default/LocalPluggableAuthentication/addRegistration.html
-#   ... 
-#   ... -----------------------------2567744622114531019698320091
-#   ... Content-Disposition: form-data; name="field.name"
-#   ... 
-#   ... 
-#   ... -----------------------------2567744622114531019698320091
-#   ... Content-Disposition: form-data; name="field.interface"
-#   ... 
-#   ... zope.app.security.interfaces.IAuthentication
-#   ... -----------------------------2567744622114531019698320091
-#   ... Content-Disposition: form-data; name="field.interface-empty-marker"
-#   ... 
-#   ... 1
-#   ... -----------------------------2567744622114531019698320091
-#   ... Content-Disposition: form-data; name="field.permission"
-#   ... 
-#   ... 
-#   ... -----------------------------2567744622114531019698320091
-#   ... Content-Disposition: form-data; name="field.permission-empty-marker"
-#   ... 
-#   ... 1
-#   ... -----------------------------2567744622114531019698320091
-#   ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
-#   ... 
-#   ... Add
-#   ... -----------------------------2567744622114531019698320091--
-#   ... """)
-#   HTTP/1.1 303 See Other
-#   ...
-# 
-# and configure it:
-# 
-#   >>> print http(r"""
-#   ... POST /++etc++site/default/LocalPluggableAuthentication/@@edit.html HTTP/1.1
-#   ... Authorization: Basic mgr:mgrpw
-#   ... Content-Type: multipart/form-data; boundary=---------------------------12424310211503201098946683515
-#   ... 
-#   ... -----------------------------12424310211503201098946683515
-#   ... Content-Disposition: form-data; name="field.extractors.to"
-#   ... 
-#   ... HTTP Basic
-#   ... -----------------------------12424310211503201098946683515
-#   ... Content-Disposition: form-data; name="field.extractors-empty-marker"
-#   ... 
-#   ... 
-#   ... -----------------------------12424310211503201098946683515
-#   ... Content-Disposition: form-data; name="field.authenticators.to"
-#   ... 
-#   ... users
-#   ... -----------------------------12424310211503201098946683515
-#   ... Content-Disposition: form-data; name="field.authenticators-empty-marker"
-#   ... 
-#   ... 
-#   ... -----------------------------12424310211503201098946683515
-#   ... Content-Disposition: form-data; name="field.challengers.to"
-#   ... 
-#   ... No Challenge if Authenticated
-#   ... -----------------------------12424310211503201098946683515
-#   ... Content-Disposition: form-data; name="field.challengers.to"
-#   ... 
-#   ... Zope Realm HTTP Basic
-#   ... -----------------------------12424310211503201098946683515
-#   ... Content-Disposition: form-data; name="field.challengers-empty-marker"
-#   ... 
-#   ... 
-#   ... -----------------------------12424310211503201098946683515
-#   ... Content-Disposition: form-data; name="field.factories.to"
-#   ... 
-#   ... Default
-#   ... -----------------------------12424310211503201098946683515
-#   ... Content-Disposition: form-data; name="field.factories-empty-marker"
-#   ... 
-#   ... 
-#   ... -----------------------------12424310211503201098946683515
-#   ... Content-Disposition: form-data; name="field.searchers.to"
-#   ... 
-#   ... users
-#   ... -----------------------------12424310211503201098946683515
-#   ... Content-Disposition: form-data; name="field.searchers-empty-marker"
-#   ... 
-#   ... 
-#   ... -----------------------------12424310211503201098946683515
-#   ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
-#   ... 
-#   ... Change
-#   ... -----------------------------12424310211503201098946683515
-#   ... Content-Disposition: form-data; name="field.extractors"
-#   ... 
-#   ... HTTP Basic
-#   ... -----------------------------12424310211503201098946683515
-#   ... Content-Disposition: form-data; name="field.authenticators"
-#   ... 
-#   ... users
-#   ... -----------------------------12424310211503201098946683515
-#   ... Content-Disposition: form-data; name="field.challengers"
-#   ... 
-#   ... No Challenge if Authenticated
-#   ... -----------------------------12424310211503201098946683515
-#   ... Content-Disposition: form-data; name="field.challengers"
-#   ... 
-#   ... Zope Realm HTTP Basic
-#   ... -----------------------------12424310211503201098946683515
-#   ... Content-Disposition: form-data; name="field.factories"
-#   ... 
-#   ... Default
-#   ... -----------------------------12424310211503201098946683515
-#   ... Content-Disposition: form-data; name="field.searchers"
-#   ... 
-#   ... users
-#   ... -----------------------------12424310211503201098946683515--
-#   ... """)
-#   HTTP/1.1 200 Ok
-#   ...
-# 
-# Normally, the anonymous role has view, we'll deny it:
-# 
-#   >>> print http(r"""
-#   ... POST /++etc++site/AllRolePermissions.html HTTP/1.1
-#   ... Authorization: Basic mgr:mgrpw
-#   ... Content-Type: application/x-www-form-urlencoded
-#   ... 
-#   ... role_id=zope.Anonymous""" 
-#   ... """&Deny%3Alist=zope.View""" 
-#   ... """&Deny%3Alist=zope.app.dublincore.view""" 
-#   ... """&SUBMIT_ROLE=Save+Changes""")
-#   HTTP/1.1 200 Ok
-#   ...
-# 
-# Now, if we try to access the main page as an anonymous user, we'll be
-# unauthorized:
-# 
-#   >>> print http(r"""
-#   ... GET / HTTP/1.1
-#   ... """)
-#   HTTP/1.1 401 Unauthorized
-#   ...
-# 
-# We'll even be unauthorized if we try to access it as bob:
-# 
-#   >>> print http(r"""
-#   ... GET / HTTP/1.1
-#   ... Authorization: Basic bob:123
-#   ... """)
-#   HTTP/1.1 403 Forbidden
-#   ...
-# 
-# No, let's grant view to the authenticated group:
-# 
-#   >>> print http(r"""
-#   ... POST /@@grant.html HTTP/1.1
-#   ... Authorization: Basic mgr:mgrpw
-#   ... Content-Type: application/x-www-form-urlencoded
-#   ... 
-#   ... field.principal=em9wZS5BdXRoZW50aWNhdGVk&field.principal.displayed=y"""
-#   ... """&field.em9wZS5BdXRoZW50aWNhdGVk.permission.zope.View=allow"""
-#   ... """&field.em9wZS5BdXRoZW50aWNhdGVk.permission.zope.app.dublincore.view=allow"""
-#   ... """&GRANT_SUBMIT=Change""")
-#   HTTP/1.1 200 Ok
-#   ...
-# 
-# Now, with this, we can access the main page as bob, but not as an
-# anonymous user:
-# 
-#   >>> print http(r"""
-#   ... GET / HTTP/1.1
-#   ... Authorization: Basic bob:123
-#   ... """)
-#   HTTP/1.1 200 Ok
-#   ...
-# 
-#   >>> print http(r"""
-#   ... GET / HTTP/1.1
-#   ... """)
-#   HTTP/1.1 401 Unauthorized
-#   ...
-# 
-# Now, we'll grant to unauthenticated:
-# 
-#   >>> print http(r"""
-#   ... POST /@@grant.html HTTP/1.1
-#   ... Authorization: Basic mgr:mgrpw
-#   ... Content-Type: application/x-www-form-urlencoded
-#   ... Referer: http://localhost:8081/@@grant.html
-#   ... 
-#   ... field.principal=em9wZS5Bbnlib2R5"""
-#   ... """&field.em9wZS5Bbnlib2R5.permission.zope.View=allow"""
-#   ... """&field.em9wZS5Bbnlib2R5.permission.zope.app.dublincore.view=allow"""
-#   ... """&GRANT_SUBMIT=Change""")
-#   HTTP/1.1 200 Ok
-#   ...
-# 
-# With this, we can access the page as either bob or anonymous:
-# 
-#   >>> print http(r"""
-#   ... GET / HTTP/1.1
-#   ... Authorization: Basic bob:123
-#   ... """)
-#   HTTP/1.1 200 Ok
-#   ...
-# 
-#   >>> print http(r"""
-#   ... GET / HTTP/1.1
-#   ... """)
-#   HTTP/1.1 200 Ok
-#   ...
-# 
-# Now, we'll remove the authenticated group grant:
-# 
-#   >>> print http(r"""
-#   ... POST /@@grant.html HTTP/1.1
-#   ... Authorization: Basic mgr:mgrpw
-#   ... Content-Type: application/x-www-form-urlencoded
-#   ... 
-#   ... field.principal=em9wZS5BdXRoZW50aWNhdGVk"""
-#   ... """&field.em9wZS5BdXRoZW50aWNhdGVk.permission.zope.View=unset"""
-#   ... """&field.em9wZS5BdXRoZW50aWNhdGVk.permission.zope.app.dublincore.view=unset"""
-#   ... """&GRANT_SUBMIT=Change""")
-#   HTTP/1.1 200 Ok
-#   ...
-# 
-# And anonymous people will be able to access the page, but bob won't be able to:
-# 
-#   >>> print http(r"""
-#   ... GET / HTTP/1.1
-#   ... Authorization: Basic bob:123
-#   ... """)
-#   HTTP/1.1 403 Forbidden
-#   ...
-# 
-#   >>> print http(r"""
-#   ... GET / HTTP/1.1
-#   ... """)
-#   HTTP/1.1 200 Ok
-#   ...
-# 
-# Now, we'll remove the unauthenticated group grant:
-# 
-#   >>> print http(r"""
-#   ... POST /@@grant.html HTTP/1.1
-#   ... Authorization: Basic mgr:mgrpw
-#   ... Content-Type: application/x-www-form-urlencoded
-#   ... Referer: http://localhost:8081/@@grant.html
-#   ... 
-#   ... field.principal=em9wZS5Bbnlib2R5"""
-#   ... """&field.em9wZS5Bbnlib2R5.permission.zope.View=unset"""
-#   ... """&field.em9wZS5Bbnlib2R5.permission.zope.app.dublincore.view=unset"""
-#   ... """&GRANT_SUBMIT=Change""")
-#   HTTP/1.1 200 Ok
-#   ...
-# 
-# and neither bob nor anonymous can access:
-# 
-#   >>> print http(r"""
-#   ... GET / HTTP/1.1
-#   ... Authorization: Basic bob:123
-#   ... """)
-#   HTTP/1.1 403 Forbidden
-#   ...
-# 
-#   >>> print http(r"""
-#   ... GET / HTTP/1.1
-#   ... """)
-#   HTTP/1.1 401 Unauthorized
-#   ...
-# 
-# Finally, we'll grant to everybody:
-# 
-#   >>> print http(r"""
-#   ... POST /@@grant.html HTTP/1.1
-#   ... Authorization: Basic mgr:mgrpw
-#   ... Content-Type: application/x-www-form-urlencoded
-#   ... 
-#   ... field.principal=em9wZS5FdmVyeWJvZHk_"""
-#   ... """&field.em9wZS5FdmVyeWJvZHk_.permission.zope.View=allow"""
-#   ... """&field.em9wZS5FdmVyeWJvZHk_.permission.zope.app.dublincore.view=allow"""
-#   ... """&GRANT_SUBMIT=Change""", handle_errors = False)
-#   HTTP/1.1 200 Ok
-#   ...
-# 
-# and both bob nor anonymous can access:
-# 
-#   >>> print http(r"""
-#   ... GET / HTTP/1.1
-#   ... Authorization: Basic bob:123
-#   ... """)
-#   HTTP/1.1 200 Ok
-#   ...
-# 
-#   >>> print http(r"""
-#   ... GET / HTTP/1.1
-#   ... """)
-#   HTTP/1.1 200 Ok
-#   ...
+  >>> print http(r"""
+  ... GET / HTTP/1.1
+  ... """)
+  HTTP/1.1 200 Ok
+  ...
 
+Now, we'll remove the authenticated group grant:
+
+  >>> print http(r"""
+  ... POST /@@grant.html HTTP/1.1
+  ... Authorization: Basic mgr:mgrpw
+  ... Content-Type: application/x-www-form-urlencoded
+  ... 
+  ... field.principal=em9wZS5BdXRoZW50aWNhdGVk"""
+  ... """&field.em9wZS5BdXRoZW50aWNhdGVk.permission.zope.View=unset"""
+  ... """&field.em9wZS5BdXRoZW50aWNhdGVk.permission.zope.app.dublincore.view=unset"""
+  ... """&GRANT_SUBMIT=Change""")
+  HTTP/1.1 200 Ok
+  ...
+
+And anonymous people will be able to access the page, but bob won't be able to:
+
+  >>> print http(r"""
+  ... GET / HTTP/1.1
+  ... Authorization: Basic bob:123
+  ... """)
+  HTTP/1.1 403 Forbidden
+  ...
+
+  >>> print http(r"""
+  ... GET / HTTP/1.1
+  ... """)
+  HTTP/1.1 200 Ok
+  ...
+
+Now, we'll remove the unauthenticated group grant:
+
+  >>> print http(r"""
+  ... POST /@@grant.html HTTP/1.1
+  ... Authorization: Basic mgr:mgrpw
+  ... Content-Type: application/x-www-form-urlencoded
+  ... Referer: http://localhost:8081/@@grant.html
+  ... 
+  ... field.principal=em9wZS5Bbnlib2R5"""
+  ... """&field.em9wZS5Bbnlib2R5.permission.zope.View=unset"""
+  ... """&field.em9wZS5Bbnlib2R5.permission.zope.app.dublincore.view=unset"""
+  ... """&GRANT_SUBMIT=Change""")
+  HTTP/1.1 200 Ok
+  ...
+
+and neither bob nor anonymous can access:
+
+  >>> print http(r"""
+  ... GET / HTTP/1.1
+  ... Authorization: Basic bob:123
+  ... """)
+  HTTP/1.1 403 Forbidden
+  ...
+
+  >>> print http(r"""
+  ... GET / HTTP/1.1
+  ... """)
+  HTTP/1.1 401 Unauthorized
+  ...
+
+Finally, we'll grant to everybody:
+
+  >>> print http(r"""
+  ... POST /@@grant.html HTTP/1.1
+  ... Authorization: Basic mgr:mgrpw
+  ... Content-Type: application/x-www-form-urlencoded
+  ... 
+  ... field.principal=em9wZS5FdmVyeWJvZHk_"""
+  ... """&field.em9wZS5FdmVyeWJvZHk_.permission.zope.View=allow"""
+  ... """&field.em9wZS5FdmVyeWJvZHk_.permission.zope.app.dublincore.view=allow"""
+  ... """&GRANT_SUBMIT=Change""", handle_errors = False)
+  HTTP/1.1 200 Ok
+  ...
+
+and both bob nor anonymous can access:
+
+  >>> print http(r"""
+  ... GET / HTTP/1.1
+  ... Authorization: Basic bob:123
+  ... """)
+  HTTP/1.1 200 Ok
+  ...
+
+  >>> print http(r"""
+  ... GET / HTTP/1.1
+  ... """)
+  HTTP/1.1 200 Ok
+  ...

Added: Zope3/branches/srichter-blow-services/src/zope/app/component/tests/components.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/component/tests/components.py	2005-02-10 15:21:18 UTC (rev 29102)
+++ Zope3/branches/srichter-blow-services/src/zope/app/component/tests/components.py	2005-02-10 17:48:37 UTC (rev 29103)
@@ -0,0 +1,41 @@
+##############################################################################
+#
+# Copyright (c) 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Components for testing
+
+$Id$
+"""
+from zope.interface import Interface, Attribute, implements
+from zope.component import adapts
+
+class IApp(Interface):
+    a = Attribute('test attribute')
+    def f(): "test func"
+
+class IContent(Interface): pass
+
+class Content(object):
+    implements(IContent)
+
+class Comp(object):
+    adapts(IContent)
+    implements(IApp)
+
+    def __init__(self, *args):
+        # Ignore arguments passed to constructor
+        pass
+
+    a = 1
+    def f(): pass
+
+comp = Comp()

Modified: Zope3/branches/srichter-blow-services/src/zope/app/container/browser/metaconfigure.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/container/browser/metaconfigure.py	2005-02-10 15:21:18 UTC (rev 29102)
+++ Zope3/branches/srichter-blow-services/src/zope/app/container/browser/metaconfigure.py	2005-02-10 17:48:37 UTC (rev 29103)
@@ -15,7 +15,6 @@
 
 $Id$
 """
-
 __docformat__ = 'restructuredtext'
 
 from zope.app.component.fields import LayerField
@@ -61,7 +60,6 @@
         required=False
         )
 
-
 def containerViews(_context, for_, contents=None, add=None, index=None,
                    layer=IDefaultBrowserLayer):
     """Set up container views for a given content type."""

Modified: Zope3/branches/srichter-blow-services/src/zope/app/container/browser/tests/test_directive.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/container/browser/tests/test_directive.py	2005-02-10 15:21:18 UTC (rev 29102)
+++ Zope3/branches/srichter-blow-services/src/zope/app/container/browser/tests/test_directive.py	2005-02-10 17:48:37 UTC (rev 29103)
@@ -284,6 +284,123 @@
        'info')))
     """
 
+def test_containerViews_layer():
+    """
+    >>> from zope.app.publisher.browser.menu import menus
+    >>> from zope.interface.interface import InterfaceClass
+    >>> zmi_views = InterfaceClass('zmi_views', __module__='zope.app.menus')
+    >>> menus.zmi_views = zmi_views
+    >>> zmi_actions = InterfaceClass('zmi_actions', __module__='zope.app.menus')
+    >>> menus.zmi_actions = zmi_actions
+
+    >>> context = Context()
+    >>> containerViews(context, for_=I, contents='zope.ManageContent',
+    ...                add='zope.ManageContent', index='zope.View', layer=ITestLayer)
+    >>> context
+    ((('adapter',
+       (<InterfaceClass zope.app.container.browser.tests.test_directive.I>,
+        <InterfaceClass zope.publisher.interfaces.browser.IBrowserRequest>),
+       <InterfaceClass zope.app.menus.zmi_views>,
+       u'Contents'),
+      <function handler>,
+      ('provideAdapter',
+       (<InterfaceClass zope.app.container.browser.tests.test_directive.I>,
+        <InterfaceClass zope.publisher.interfaces.browser.IBrowserRequest>),
+       <InterfaceClass zope.app.menus.zmi_views>,
+       u'Contents',
+       <zope.app.publisher.browser.menu.MenuItemFactory object>,
+       '')),
+     (None,
+      <function provideInterface>,
+      ('', <InterfaceClass zope.app.menus.zmi_views>)),
+     (None,
+      <function provideInterface>,
+      ('',
+       <InterfaceClass zope.app.container.browser.tests.test_directive.I>)),
+     (None,
+      <function provideInterface>,
+      ('',
+       <InterfaceClass zope.publisher.interfaces.browser.IBrowserRequest>)),
+     (None,
+      <function provideInterface>,
+      ('',
+       <InterfaceClass zope.app.container.browser.tests.test_directive.I>)),
+     (('view',
+       <InterfaceClass zope.app.container.browser.tests.test_directive.I>,
+       'contents.html',
+       <InterfaceClass zope.publisher.interfaces.browser.IBrowserRequest>,
+       <InterfaceClass zope.app.container.browser.tests.test_directive.ITestLayer>),
+      <function handler>,
+      ('provideAdapter',
+       (<InterfaceClass zope.app.container.browser.tests.test_directive.I>,
+        <InterfaceClass zope.app.container.browser.tests.test_directive.ITestLayer>),
+       <InterfaceClass zope.interface.Interface>,
+       'contents.html',
+       <class 'zope.app.publisher.browser.viewmeta.Contents'>,
+       'info')),
+     (None,
+      <function provideInterface>,
+      ('',
+       <InterfaceClass zope.app.container.browser.tests.test_directive.I>)),
+     (('view',
+       <InterfaceClass zope.app.container.browser.tests.test_directive.I>,
+       'index.html',
+       <InterfaceClass zope.publisher.interfaces.browser.IBrowserRequest>,
+       <InterfaceClass zope.app.container.browser.tests.test_directive.ITestLayer>),
+      <function handler>,
+      ('provideAdapter',
+       (<InterfaceClass zope.app.container.browser.tests.test_directive.I>,
+        <InterfaceClass zope.app.container.browser.tests.test_directive.ITestLayer>),
+       <InterfaceClass zope.interface.Interface>,
+       'index.html',
+       <class 'zope.app.publisher.browser.viewmeta.Contents'>,
+       'info')),
+     (('adapter',
+       (<InterfaceClass zope.app.container.browser.tests.test_directive.I>,
+        <InterfaceClass zope.publisher.interfaces.browser.IBrowserRequest>),
+       <InterfaceClass zope.app.menus.zmi_actions>,
+       u'Add'),
+      <function handler>,
+      ('provideAdapter',
+       (<InterfaceClass zope.app.container.browser.tests.test_directive.I>,
+        <InterfaceClass zope.publisher.interfaces.browser.IBrowserRequest>),
+       <InterfaceClass zope.app.menus.zmi_actions>,
+       u'Add',
+       <zope.app.publisher.browser.menu.MenuItemFactory object>,
+       'info')),
+     (None,
+      <function provideInterface>,
+      ('', <InterfaceClass zope.app.menus.zmi_actions>)),
+     (None,
+      <function provideInterface>,
+      ('',
+       <InterfaceClass zope.app.container.browser.tests.test_directive.I>)),
+     (None,
+      <function provideInterface>,
+      ('',
+       <InterfaceClass zope.publisher.interfaces.browser.IBrowserRequest>)),
+     (None,
+      <function provideInterface>,
+      ('',
+       <InterfaceClass zope.app.container.browser.tests.test_directive.I>)),
+     (None,
+      <function provideInterface>,
+      ('', <InterfaceClass zope.interface.Interface>)),
+     (('view',
+       (<InterfaceClass zope.app.container.browser.tests.test_directive.I>,
+        <InterfaceClass zope.app.container.browser.tests.test_directive.ITestLayer>),
+       '+',
+       <InterfaceClass zope.interface.Interface>),
+      <function handler>,
+      ('provideAdapter',
+       (<InterfaceClass zope.app.container.browser.tests.test_directive.I>,
+        <InterfaceClass zope.app.container.browser.tests.test_directive.ITestLayer>),
+       <InterfaceClass zope.interface.Interface>,
+       '+',
+       <class 'zope.app.publisher.browser.viewmeta.+'>,
+       'info')))
+    """
+
 def test_suite():
     return unittest.TestSuite((
         DocTestSuite(),

Modified: Zope3/branches/srichter-blow-services/src/zope/app/form/browser/source.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/form/browser/source.py	2005-02-10 15:21:18 UTC (rev 29102)
+++ Zope3/branches/srichter-blow-services/src/zope/app/form/browser/source.py	2005-02-10 17:48:37 UTC (rev 29103)
@@ -148,10 +148,20 @@
 
         term = None
         if value == field.missing_value:
-            result.append(u'  ' +
+            result.append('  <div class="row">')
+            result.append('    <div class="label">')
+            result.append(u'     ' +
+                          self._translate(_("SourceDisplayWidget-label",
+                                            default="Selected"))
+                          )
+            result.append('    </div>')
+            result.append('    <div class="field">')
+            result.append(u'     ' +
                           self._translate(_("SourceDisplayWidget-missing",
                                             default="Nothing"))
                           )
+            result.append('    </div>')
+            result.append('  </div>')
         else:
             try:
                 term = self.terms.getTerm(value)
@@ -161,10 +171,19 @@
                                                 default="Nothing Valid"))
                               )
             else:
-                result.append(u'  ' + cgi.escape(term.title))
+                result.append('  <div class="row">')
+                result.append('    <div class="label">')
+                result.append(u'     ' +
+                              self._translate(_("SourceDisplayWidget-label",
+                                                default="Selected"))
+                              )
+                result.append('    </div>')
+                result.append('    <div class="field">')
+                result.append(u'     ' + cgi.escape(term.title))
+                result.append('    </div>')
+                result.append('  </div>')
                 result.append('  <input type="hidden" name="%s" value="%s">'
                               % (self.name, cgi.escape(term.token)))
-        result.append('  <br>')
 
         result.append('  <input type="hidden" name="%s.displayed" value="y">'
                       % self.name)

Modified: Zope3/branches/srichter-blow-services/src/zope/app/form/browser/source.txt
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/form/browser/source.txt	2005-02-10 15:21:18 UTC (rev 29102)
+++ Zope3/branches/srichter-blow-services/src/zope/app/form/browser/source.txt	2005-02-10 17:48:37 UTC (rev 29103)
@@ -127,8 +127,14 @@
 
   >>> print widget()
   <div class="value">
-    Nothing
-    <br>
+    <div class="row">
+      <div class="label">
+       Selected
+      </div>
+      <div class="field">
+       Nothing
+      </div>
+    </div>
     <input type="hidden" name="field.dog.displayed" value="y">
     <div class="queries">
       <div class="query">
@@ -181,8 +187,14 @@
 
   >>> print widget()
   <div class="value">
-    Nothing
-    <br>
+    <div class="row">
+      <div class="label">
+       Selected
+      </div>
+      <div class="field">
+       Nothing
+      </div>
+    </div>
     <input type="hidden" name="field.dog.displayed" value="y">
     <div class="queries">
       <div class="query">
@@ -213,9 +225,15 @@
 
   >>> print widget()
   <div class="value">
-    spot
+    <div class="row">
+      <div class="label">
+       Selected
+      </div>
+      <div class="field">
+       spot
+      </div>
+    </div>
     <input type="hidden" name="field.dog" value="c3BvdA==">
-    <br>
     <input type="hidden" name="field.dog.displayed" value="y">
     <div class="queries">
       <div class="query">
@@ -291,8 +309,14 @@
 
   >>> print widget()
   <div class="value">
-    Nothing
-    <br>
+    <div class="row">
+      <div class="label">
+       Selected
+      </div>
+      <div class="field">
+       Nothing
+      </div>
+    </div>
     <input type="hidden" name="field.pet.displayed" value="y">
     <div class="queries">
       <div class="query">
@@ -320,8 +344,14 @@
 
   >>> print widget() # doctest:
   <div class="value">
-    Nothing
-    <br>
+    <div class="row">
+      <div class="label">
+       Selected
+      </div>
+      <div class="field">
+       Nothing
+      </div>
+    </div>
     <input type="hidden" name="field.pet.displayed" value="y">
     <div class="queries">
       <div class="query">
@@ -360,9 +390,15 @@
 
   >>> print widget()
   <div class="value">
-    tabby
+    <div class="row">
+      <div class="label">
+       Selected
+      </div>
+      <div class="field">
+       tabby
+      </div>
+    </div>
     <input type="hidden" name="field.pet" value="dGFiYnk=">
-    <br>
     <input type="hidden" name="field.pet.displayed" value="y">
     <div class="queries">
       <div class="query">

Modified: Zope3/branches/srichter-blow-services/src/zope/app/form/tests/test_utility.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/form/tests/test_utility.py	2005-02-10 15:21:18 UTC (rev 29102)
+++ Zope3/branches/srichter-blow-services/src/zope/app/form/tests/test_utility.py	2005-02-10 17:48:37 UTC (rev 29103)
@@ -21,6 +21,7 @@
 from zope.component.interfaces import IViewFactory
 from zope.component.exceptions import ComponentLookupError
 from zope.publisher.browser import TestRequest
+from zope.security.interfaces import ForbiddenAttribute
 
 from zope.schema import Field, Int
 from zope.schema.interfaces import IField, IInt
@@ -535,6 +536,44 @@
      
         >>> tearDown()
         """
+
+    def test_forbiddenAttributes(self):
+        """Tests that forbidden attributes cause an error in widget setup.
+
+        >>> setUp()
+
+        If an attribute cannot be read from a source object because it's
+        forbidden, the ForbiddenAttribute error is allowed to pass through
+        to the caller.
+
+        We'll create a field that raises a ForbiddenError itself to simulate
+        what would happen when a proxied object's attribute is accessed without
+        the required permission.
+
+            >>> class AlwaysForbidden(Field):
+            ...     def get(self, source):
+            ...         raise ForbiddenAttribute(source, self.__name__)
+
+        We'll also create a schema using this field:
+
+            >>> class IMySchema(Interface):
+            ...     tryme = AlwaysForbidden()
+
+        When we use setUpEditWidgets to configure a view with IMySchema:
+
+            >>> view = BrowserView('some context', TestRequest())
+            >>> setUpEditWidgets(view, IMySchema)
+            Traceback (most recent call last):
+            ForbiddenAttribute: ('some context', 'tryme')
+
+        The same applies to setUpDisplayWidgets:
+
+            >>> setUpDisplayWidgets(view, IMySchema)
+            Traceback (most recent call last):
+            ForbiddenAttribute: ('some context', 'tryme')
+
+        >>> tearDown()
+        """
         
 class TestFormSetUp(object):
     

Modified: Zope3/branches/srichter-blow-services/src/zope/app/form/utility.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/form/utility.py	2005-02-10 15:21:18 UTC (rev 29102)
+++ Zope3/branches/srichter-blow-services/src/zope/app/form/utility.py	2005-02-10 17:48:37 UTC (rev 29103)
@@ -34,6 +34,7 @@
 """
 __docformat__ = 'restructuredtext'
 
+from zope.security.interfaces import ForbiddenAttribute
 from zope.schema import getFieldsInOrder
 from zope.app import zapi
 from zope.app.form.interfaces import IWidget
@@ -181,6 +182,8 @@
             viewType = inputType
         try:
             value = field.get(source)
+        except ForbiddenAttribute:
+            raise
         except AttributeError, v:
             value = no_value
         setUpWidget(view, name, field, viewType, value, prefix,

Modified: Zope3/branches/srichter-blow-services/src/zope/app/i18n/translationdomain.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/i18n/translationdomain.py	2005-02-10 15:21:18 UTC (rev 29102)
+++ Zope3/branches/srichter-blow-services/src/zope/app/i18n/translationdomain.py	2005-02-10 17:48:37 UTC (rev 29103)
@@ -266,7 +266,7 @@
     >>> domain1 = TranslationDomain()
     >>> domain1.domain = 'domain1'
 
-    >>> from zope.app.component import registration 
+    >>> from zope.app.registration import registration
     >>> event = registration.RegistrationDeactivatedEvent(
     ...     Registration(domain1, 'domain1'))
 

Modified: Zope3/branches/srichter-blow-services/src/zope/app/publisher/browser/tests/test_directives.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/publisher/browser/tests/test_directives.py	2005-02-10 15:21:18 UTC (rev 29102)
+++ Zope3/branches/srichter-blow-services/src/zope/app/publisher/browser/tests/test_directives.py	2005-02-10 17:48:37 UTC (rev 29103)
@@ -90,7 +90,6 @@
     def index(self):
         return self
 
-
 class ITestMenu(Interface):
     """Test menu."""
 

Modified: Zope3/branches/srichter-blow-services/src/zope/app/registration/registration.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/registration/registration.py	2005-02-10 15:21:18 UTC (rev 29102)
+++ Zope3/branches/srichter-blow-services/src/zope/app/registration/registration.py	2005-02-10 17:48:37 UTC (rev 29103)
@@ -19,6 +19,7 @@
 
 from zope.app.component import registration
 from zope.component import subscribers
+from zope.component import subscribers
 
 RegistrationEvent = registration.RegistrationEvent
 RegistrationActivatedEvent = registration.RegistrationActivatedEvent

Modified: Zope3/branches/srichter-blow-services/src/zope/app/security/vocabulary.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/security/vocabulary.py	2005-02-10 15:21:18 UTC (rev 29102)
+++ Zope3/branches/srichter-blow-services/src/zope/app/security/vocabulary.py	2005-02-10 17:48:37 UTC (rev 29103)
@@ -15,7 +15,7 @@
 
 This vocabulary provides permission IDs.
 
-$Id: $
+$Id$
 """
 from zope.security.checker import CheckerPublic
 from zope.app import zapi
@@ -207,13 +207,18 @@
         """
         i = 0
         auth = zapi.getUtility(IAuthentication)
+        yielded = []
         while True:
             queriables = ISourceQueriables(auth, None)
             if queriables is None:
                 yield unicode(i), auth
             else:
                 for qid, queriable in queriables.getQueriables():
-                    yield unicode(i)+'.'+unicode(qid), queriable
+                    # ensure that we dont return same yielded utility more 
+                    # then once
+                    if queriable not in yielded:
+                        yield unicode(i)+'.'+unicode(qid), queriable
+                        yielded.append(queriable)
             auth = queryNextUtility(auth, IAuthentication)
             if auth is None:
                 break


Property changes on: Zope3/branches/srichter-blow-services/src/zope/app/security/vocabulary.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Modified: Zope3/branches/srichter-blow-services/src/zope/app/securitypolicy/browser/granting.pt
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/securitypolicy/browser/granting.pt	2005-02-10 15:21:18 UTC (rev 29102)
+++ Zope3/branches/srichter-blow-services/src/zope/app/securitypolicy/browser/granting.pt	2005-02-10 17:48:37 UTC (rev 29103)
@@ -1,63 +1,82 @@
 <html metal:use-macro="context/@@standard_macros/page">
 <body>
 <div metal:fill-slot="body" i18n:domain="zope">
+  <h2 i18n:translate="">Granting Roles and Permissions to Principals</h2>
+  <p tal:define="status view/status"
+     tal:condition="status"
+     tal:content="status" />
+  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 
-<h2 i18n:translate="">Granting Roles and Permissions to Principals</h2>
+  <form action="" method="POST">
 
-<p tal:define="status view/status"
-   tal:condition="status"
-   tal:content="status" />
+    <div tal:content="structure view/principal_widget">...</div>
 
-<form action="" method="post">
-<p i18n:translate="">Select a principal:</p>
-<div tal:content="structure view/principal_widget">...</div>
+    <div tal:condition="view/principal">
 
-<div tal:condition="view/principal">
+      <h2 i18n:translate="">Grants for the selected principal</h2>
+      <input type="submit" name="GRANT_SUBMIT" value="Change" 
+             i18n:attributes="value grant-submit" />
 
-  <h2 i18n:translate="">Grants for the selected principal</h2>
+      <table width="100%" border="0">
+        <tr>
+          <td valign="top">
+            <table class="matrix">
+              <tr>
+                <td i18n:translate=""><strong>Roles</strong>&nbsp;</td>
+                <td i18n:translate=""><strong>Allow</strong>&nbsp;</td>
+                <td i18n:translate=""><strong>Unset</strong>&nbsp;</td>
+                <td i18n:translate=""><strong>Deny</strong>&nbsp;</td>
+              </tr>
+              <tr tal:repeat="widget view/roles">
+                <td valign="top" nowrap>
+                  <div class="label">
+                    <label for="field.name" title="The widget's hint"
+                           tal:attributes="for widget/name; title widget/hint"
+                           tal:content="widget/label">The Label</label>
+                  </div>
+                </td>
+                <tal:block tal:content="structure widget">
+                  roles widget
+                </tal:block>
+              </tr>
+              <tr>
+                <td colspan="2"><a href="#top" i18n:translate="">^ top</a></td>
+              </tr>
+            </table>
+          </td>
+          <td valign="top">
+            <table class="matrix">
+              <tr>
+                <td i18n:translate=""><strong>Permissions</strong>&nbsp;</td>
+                <td i18n:translate=""><strong>Allow</strong>&nbsp;</td>
+                <td i18n:translate=""><strong>Unset</strong>&nbsp;</td>
+                <td i18n:translate=""><strong>Deny</strong>&nbsp;</td>
+              </tr>
+              <tr tal:repeat="widget view/permissions">
+                <td valign="top" nowrap>
+                  <div class="label">
+                    <label for="field.name" title="The widget's hint"
+                           tal:attributes="for widget/name; title widget/hint"
+                           tal:content="widget/label">The Label</label>
+                  </div>
+                </td>
+                <tal:block tal:content="structure widget">
+                  permission widget
+                </tal:block>
+              </tr>
+              <tr>
+                <td colspan="2"><a href="#top" i18n:translate="">^ top</a></td>
+              </tr>
+            </table>
+          </td>
+        </tr>
+      </table>
+      <input type="submit" name="GRANT_SUBMIT" value="Change" 
+             i18n:attributes="value grant-submit" />
 
-  <input type="submit" name="GRANT_SUBMIT" value="Change" 
-         i18n:attributes="value grant-submit" />
-
-<table width="100%">
-  <tr>
-    <th i18n:translate="">Roles:</th>
-    <th i18n:translate="">Permissions:</th>
-  <tr/>
-  <tr>
-    <td valign="top">
-      <div class="row" tal:repeat="widget view/roles">
-        <div class="label">
-          <label for="field.name" title="The widget's hint"
-            tal:attributes="for widget/name; title widget/hint"
-            tal:content="widget/label">The Label</label>
-        </div>
-        <div class="field" tal:content="structure widget">
-          <input type="text" style="width:100%"/>
-        </div>
-      </div>
-    </td>
-    <td valign="top">
-      <div class="row" tal:repeat="widget view/permissions">
-        <div class="label">
-          <label for="field.name" title="The widget's hint"
-            tal:attributes="for widget/name; title widget/hint"
-            tal:content="widget/label">The Label</label>
-        </div>
-        <div class="field" tal:content="structure widget">
-          <input type="text" style="width:100%"/>
-        </div>
-      </div>
-    </td>
-  <tr/>
-</table>
-
-  <input type="submit" name="GRANT_SUBMIT" value="Change" 
-         i18n:attributes="value grant-submit" />
-
+    </div>
+  </form>
 </div>
-</form>
-
-</div>
 </body>
 </html>

Modified: Zope3/branches/srichter-blow-services/src/zope/app/securitypolicy/tests/functional.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/app/securitypolicy/tests/functional.py	2005-02-10 15:21:18 UTC (rev 29102)
+++ Zope3/branches/srichter-blow-services/src/zope/app/securitypolicy/tests/functional.py	2005-02-10 17:48:37 UTC (rev 29103)
@@ -15,8 +15,9 @@
 
 $Id$
 """
+
 from zope import interface
-from zope.app.testing import functional
+from zope.app.tests import functional
 
 class ManagerSetup:
     interface.implements(functional.IManagerSetup)

Modified: Zope3/branches/srichter-blow-services/src/zope/bforest/bforest.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/bforest/bforest.py	2005-02-10 15:21:18 UTC (rev 29102)
+++ Zope3/branches/srichter-blow-services/src/zope/bforest/bforest.py	2005-02-10 17:48:37 UTC (rev 29103)
@@ -123,13 +123,49 @@
         else:
             return True
     
-    def __cmp__(self, d):
-        # this is probably not the most efficient approach, but I'm not sure
-        # what is, and this is certainly among the simplest.  Don't do 
-        # comparisons with large bforests unless you are willing to pay the
-        # price.  Improvements welcome.
-        return cmp(dict(self), dict(d))
+    def __eq__(self, other):
+        if not isinstance(other, dict):
+            if (isinstance(other, AbstractBForest) and 
+                self._treemodule is not other._treemodule):
+                return False
+            try:
+                other = dict(other)
+            except TypeError:
+                return False
+        return dict(self)==other # :-/
     
+    def __gt__(self, other):
+        if not isinstance(other, dict):
+            try:
+                other = dict(other)
+            except TypeError:
+                return id(self) > id(other)
+        return dict(self) > other
+
+    def __lt__(self, other):
+        if not isinstance(other, dict):
+            try:
+                other = dict(other)
+            except TypeError:
+                return id(self) < id(other)
+        return dict(self) < other
+        
+    def __ge__(self, other):
+        if not isinstance(other, dict):
+            try:
+                other = dict(other)
+            except TypeError:
+                return id(self) >= id(other)
+        return dict(self) >= other
+        
+    def __le__(self, other):
+        if not isinstance(other, dict):
+            try:
+                other = dict(other)
+            except TypeError:
+                return id(self) <= id(other)
+        return dict(self) <= other
+
     def __len__(self):
         return len(self.tree())
     

Modified: Zope3/branches/srichter-blow-services/src/zope/bforest/bforest.txt
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/bforest/bforest.txt	2005-02-10 15:21:18 UTC (rev 29102)
+++ Zope3/branches/srichter-blow-services/src/zope/bforest/bforest.txt	2005-02-10 17:48:37 UTC (rev 29103)
@@ -15,187 +15,233 @@
 First let's instantiate a bforest and look at an empty example.  By default,
 a new bforest creates two composite btree buckets.
 
->>> d = BForest()
->>> list(d.keys())
-[]
->>> list(d.values())
-[]
->>> len(d.buckets)
-2
->>> dummy_key = KeyGenerator()
->>> d.get(dummy_key)
->>> d.get(dummy_key, 42)
-42
+    >>> d = BForest()
+    >>> list(d.keys())
+    []
+    >>> list(d.values())
+    []
+    >>> len(d.buckets)
+    2
+    >>> dummy_key = KeyGenerator()
+    >>> d.get(dummy_key)
+    >>> d.get(dummy_key, 42)
+    42
 
 Now we'll populate it.  We'll first create a dictionary we'll use to compare.
 
->>> original = {}
->>> for i in range(10):
-...     original[KeyGenerator()] = ValueGenerator()
-... 
->>> d.update(original)
->>> d == original
-True
->>> d_keys = list(d.keys())
->>> d_keys.sort()
->>> o_keys = original.keys()
->>> o_keys.sort()
->>> d_keys == o_keys
-True
->>> d_values = list(d.values())
->>> d_values.sort()
->>> o_values = original.values()
->>> o_values.sort()
->>> o_values == d_values
-True
->>> d_items = list(d.items())
->>> d_items.sort()
->>> o_items = original.items()
->>> o_items.sort()
->>> o_items == d_items
-True
->>> key, value = d.popitem()
->>> value == original.pop(key)
-True
->>> key, value = original.popitem()
->>> value == d.pop(key)
-True
->>> len(d) == len(original)
-True
+    >>> original = {}
+    >>> for i in range(10):
+    ...     original[KeyGenerator()] = ValueGenerator()
+    ... 
+    >>> d.update(original)
+    >>> d == original
+    True
+    >>> d_keys = list(d.keys())
+    >>> d_keys.sort()
+    >>> o_keys = original.keys()
+    >>> o_keys.sort()
+    >>> d_keys == o_keys
+    True
+    >>> d_values = list(d.values())
+    >>> d_values.sort()
+    >>> o_values = original.values()
+    >>> o_values.sort()
+    >>> o_values == d_values
+    True
+    >>> d_items = list(d.items())
+    >>> d_items.sort()
+    >>> o_items = original.items()
+    >>> o_items.sort()
+    >>> o_items == d_items
+    True
+    >>> key, value = d.popitem()
+    >>> value == original.pop(key)
+    True
+    >>> key, value = original.popitem()
+    >>> value == d.pop(key)
+    True
+    >>> len(d) == len(original)
+    True
 
 Now let's rotate the buckets.
 
->>> d.rotateBucket()
+    >>> d.rotateBucket()
 
 ...and we'll do the exact same test as above, first.
 
->>> d == original
-True
->>> d_keys = list(d.keys())
->>> d_keys.sort()
->>> o_keys = original.keys()
->>> o_keys.sort()
->>> d_keys == o_keys
-True
->>> d_values = list(d.values())
->>> d_values.sort()
->>> o_values = original.values()
->>> o_values.sort()
->>> o_values == d_values
-True
->>> d_items = list(d.items())
->>> d_items.sort()
->>> o_items = original.items()
->>> o_items.sort()
->>> o_items == d_items
-True
->>> key, value = d.popitem()
->>> value == original.pop(key)
-True
->>> key, value = original.popitem()
->>> value == d.pop(key)
-True
->>> len(d) == len(original)
-True
+    >>> d == original
+    True
+    >>> d_keys = list(d.keys())
+    >>> d_keys.sort()
+    >>> o_keys = original.keys()
+    >>> o_keys.sort()
+    >>> d_keys == o_keys
+    True
+    >>> d_values = list(d.values())
+    >>> d_values.sort()
+    >>> o_values = original.values()
+    >>> o_values.sort()
+    >>> o_values == d_values
+    True
+    >>> d_items = list(d.items())
+    >>> d_items.sort()
+    >>> o_items = original.items()
+    >>> o_items.sort()
+    >>> o_items == d_items
+    True
+    >>> key, value = d.popitem()
+    >>> value == original.pop(key)
+    True
+    >>> key, value = original.popitem()
+    >>> value == d.pop(key)
+    True
+    >>> len(d) == len(original)
+    True
 
 Now we'll make a new dictionary to represent changes made after the bucket
 rotation.
 
->>> second = {}
->>> for i in range(10):
-...     key = KeyGenerator()
-...     value = ValueGenerator()
-...     second[key] = value
-...     d[key] = value
-... 
->>> original.update(second)
+    >>> second = {}
+    >>> for i in range(10):
+    ...     key = KeyGenerator()
+    ...     value = ValueGenerator()
+    ...     second[key] = value
+    ...     d[key] = value
+    ... 
+    >>> original.update(second)
 
 ...and we'll do almost the exact same test as above, first.
 
->>> d == original
-True
->>> d_keys = list(d.keys())
->>> d_keys.sort()
->>> o_keys = original.keys()
->>> o_keys.sort()
->>> d_keys == o_keys
-True
->>> d_values = list(d.values())
->>> d_values.sort()
->>> o_values = original.values()
->>> o_values.sort()
->>> o_values == d_values
-True
->>> d_items = list(d.items())
->>> d_items.sort()
->>> o_items = original.items()
->>> o_items.sort()
->>> o_items == d_items
-True
->>> key, value = d.popitem()
->>> ignore = second.pop(key, None) # keep second up-to-date
->>> value == original.pop(key)
-True
->>> key, value = original.popitem()
->>> ignore = second.pop(key, None) # keep second up-to-date
->>> value == d.pop(key)
-True
->>> len(d) == len(original)
-True
+    >>> d == original
+    True
+    >>> d_keys = list(d.keys())
+    >>> d_keys.sort()
+    >>> o_keys = original.keys()
+    >>> o_keys.sort()
+    >>> d_keys == o_keys
+    True
+    >>> d_values = list(d.values())
+    >>> d_values.sort()
+    >>> o_values = original.values()
+    >>> o_values.sort()
+    >>> o_values == d_values
+    True
+    >>> d_items = list(d.items())
+    >>> d_items.sort()
+    >>> o_items = original.items()
+    >>> o_items.sort()
+    >>> o_items == d_items
+    True
+    >>> key, value = d.popitem()
+    >>> ignore = second.pop(key, None) # keep second up-to-date
+    >>> value == original.pop(key)
+    True
+    >>> key, value = original.popitem()
+    >>> ignore = second.pop(key, None) # keep second up-to-date
+    >>> value == d.pop(key)
+    True
+    >>> len(d) == len(original)
+    True
 
 Now if we rotate the buckets, the first set of items will be gone, but the 
 second will remain.
 
->>> d.rotateBucket()
->>> d == original
-False
->>> d == second
-True
+    >>> d.rotateBucket()
+    >>> d == original
+    False
+    >>> d == second
+    True
 
 Let's set a value, check the copy behavior,  and then rotate it one more time.
 
->>> third = {KeyGenerator(): ValueGenerator()}
->>> d.update(third)
->>> copy = d.copy()
->>> copy == d
-True
->>> copy != second # because second doesn't have the values of third
-True
->>> list(copy.buckets[0].items()) == list(d.buckets[0].items())
-True
->>> list(copy.buckets[1].items()) == list(d.buckets[1].items())
-True
->>> copy[KeyGenerator()] = ValueGenerator()
->>> copy == d
-False
->>> d.rotateBucket()
->>> d == third
-True
->>> d.clear()
->>> d == BForest() == {}
-True
+    >>> third = {KeyGenerator(): ValueGenerator()}
+    >>> d.update(third)
+    >>> copy = d.copy()
+    >>> copy == d
+    True
+    >>> copy != second # because second doesn't have the values of third
+    True
+    >>> list(copy.buckets[0].items()) == list(d.buckets[0].items())
+    True
+    >>> list(copy.buckets[1].items()) == list(d.buckets[1].items())
+    True
+    >>> copy[KeyGenerator()] = ValueGenerator()
+    >>> copy == d
+    False
+    >>> d.rotateBucket()
+    >>> d == third
+    True
+    >>> d.clear()
+    >>> d == BForest() == {}
+    True
+    
+    >>> d.update(second)
 
->>> d.update(second)
-
 We'll make a value in one bucket that we'll override in another.
 
->>> d[third.keys()[0]] = ValueGenerator()
->>> d.rotateBucket()
->>> d.update(third)
->>> second.update(third)
->>> d == second
-True
->>> second == d
-True
+    >>> d[third.keys()[0]] = ValueGenerator()
+    >>> d.rotateBucket()
+    >>> d.update(third)
+    >>> second.update(third)
+    >>> d == second
+    True
+    >>> second == d
+    True
 
 The tree method converts the bforest to a btree as efficiently as I know how
 for a common case of more items in buckets than buckets.
 
->>> tree = d.tree()
->>> d_items = list(d.items())
->>> d_items.sort()
->>> t_items = list(tree.items())
->>> t_items.sort()
->>> t_items == d_items
-True
+    >>> tree = d.tree()
+    >>> d_items = list(d.items())
+    >>> d_items.sort()
+    >>> t_items = list(tree.items())
+    >>> t_items.sort()
+    >>> t_items == d_items
+    True
 
+Finally, comparisons work similarly to dicts but in a simpleminded 
+way--improvements welcome!  We've already looked at a lot of examples above,
+but here are some additional cases
+
+    >>> d == None
+    False
+    >>> d != None
+    True
+    >>> None == d
+    False
+    >>> d != None
+    True
+    >>> d >= second
+    True
+    >>> d >= dict(second)
+    True
+    >>> d <= second
+    True
+    >>> d <= dict(second)
+    True
+    >>> d > second
+    False
+    >>> d > dict(second)
+    False
+    >>> d < second
+    False
+    >>> d > dict(second)
+    False
+    >>> second.popitem()[0] in d
+    True
+    >>> d > second
+    True
+    >>> d < second
+    False
+    >>> d >= second
+    True
+    >>> d <= second
+    False
+    >>> second < d
+    True
+    >>> second > d
+    False
+    >>> second <= d
+    True
+    >>> second >= d
+    False

Modified: Zope3/branches/srichter-blow-services/src/zope/schema/_field.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/schema/_field.py	2005-02-10 15:21:18 UTC (rev 29102)
+++ Zope3/branches/srichter-blow-services/src/zope/schema/_field.py	2005-02-10 17:48:37 UTC (rev 29103)
@@ -271,19 +271,19 @@
 
     To illustrate, we'll use a text value type. All values must be unicode.
 
-	    >>> field = TextLine(required=True)
+            >>> field = TextLine(required=True)
 
-	To validate a sequence of various values:
+        To validate a sequence of various values:
 
-	    >>> errors = _validate_sequence(field, ('foo', u'bar', 1))
-	    >>> errors
-	    [foo <type 'unicode'>, 1 <type 'unicode'>]
+            >>> errors = _validate_sequence(field, ('foo', u'bar', 1))
+            >>> errors
+            [foo <type 'unicode'>, 1 <type 'unicode'>]
 
-	The only valid value in the sequence is the second item. The others
-	generated errors.
+        The only valid value in the sequence is the second item. The others
+        generated errors.
 
-	We can use the optional errors argument to collect additional errors
-	for a new sequence:
+        We can use the optional errors argument to collect additional errors
+        for a new sequence:
 
         >>> errors = _validate_sequence(field, (2, u'baz'), errors)
         >>> errors



More information about the Zope3-Checkins mailing list