Repository: Pylons/pyramid

Issue:
Document that registry can be used as dictionary
Currently ability to use `Registry` as a `dict` is only implied: for example, it is used in such way in alchemy scaffold to store and retrieve DB session factory. Maybe it is a good idea to explicitly document that `Registry` is a `dict` subclass?


Discussion:
@PavloKapyshin do you mean like this?
http://docs.pylonsproject.org/projects/pyramid/en/latest/api/registry.html

Or something else?
In retrospective, I admit title and text may be a bit misleading :) Basically, I suggest to make `__getitem__` and `__setitem__` methods (minimal set of methods to avoid relying on implementation details) of `Registry` part of its documented API.

Why: `alchemy` scaffolding generates code that relies on `config.registry[...]`. Generated code is part of an application, so it is nice to have benefits of documented API.

Or maybe I misunderstand something, and that aspect of application registry is documented?

Resolving patch:
diff --git a/docs/conf.py b/docs/conf.py
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -81,7 +81,8 @@ def nothing(*arg):
     'webtest': ('http://webtest.pythonpaste.org/en/latest', None),
     'who': ('http://repozewho.readthedocs.org/en/latest', None),
     'zcml': ('http://docs.pylonsproject.org/projects/pyramid-zcml/en/latest', None),
-    'zcomponent': ('http://zopecomponent.readthedocs.io/en/stable/', None),
+    'zcomponent': ('http://zopecomponent.readthedocs.io/en/latest/', None),
+    'zinterface': ('http://zopeinterface.readthedocs.io/en/latest/', None),
 }
 
 
diff --git a/pyramid/registry.py b/pyramid/registry.py
--- a/pyramid/registry.py
+++ b/pyramid/registry.py
@@ -9,28 +9,44 @@
 from pyramid.decorator import reify
 
 from pyramid.interfaces import (
-    ISettings,
     IIntrospector,
     IIntrospectable,
+    ISettings,
     )
 
+from pyramid.path import (
+    CALLER_PACKAGE,
+    caller_package,
+)
+
 empty = text_('')
 
 class Registry(Components, dict):
-    """ A registry object is an :term:`application registry`.  It is used by
-    the framework itself to perform mappings of URLs to view callables, as
-    well as servicing other various framework duties. A registry has its own
-    internal API, but this API is rarely used by Pyramid application
-    developers (it's usually only used by developers of the Pyramid
-    framework).  But it has a number of attributes that may be useful to
-    application developers within application code, such as ``settings``,
-    which is a dictionary containing application deployment settings.
+    """ A registry object is an :term:`application registry`.
+
+    It is used by the framework itself to perform mappings of URLs to view
+    callables, as well as servicing other various framework duties. A registry
+    has its own internal API, but this API is rarely used by Pyramid
+    application developers (it's usually only used by developers of the
+    Pyramid framework and Pyramid addons).  But it has a number of attributes
+    that may be useful to application developers within application code,
+    such as ``settings``, which is a dictionary containing application
+    deployment settings.
 
     For information about the purpose and usage of the application registry,
     see :ref:`zca_chapter`.
 
+    The registry may be used both as an :class:`pyramid.interfaces.IDict` and
+    as a Zope component registry.
+    These two ways of storing configuration are independent.
+    Applications will tend to prefer to store information as key-values
+    whereas addons may prefer to use the component registry to avoid naming
+    conflicts and to provide more complex lookup mechanisms.
+
     The application registry is usually accessed as ``request.registry`` in
-    application code.
+    application code. By the time a registry is used to handle requests it
+    should be considered frozen and read-only. Any changes to its internal
+    state should be done with caution and concern for thread-safety.
 
     """
 
@@ -40,13 +56,16 @@ class Registry(Components, dict):
 
     _settings = None
 
-    def __init__(self, *arg, **kw):
+    def __init__(self, package_name=CALLER_PACKAGE):
         # add a registry-instance-specific lock, which is used when the lookup
         # cache is mutated
         self._lock = threading.Lock()
         # add a view lookup cache
         self._clear_view_lookup_cache()
-        Components.__init__(self, *arg, **kw)
+        if package_name is CALLER_PACKAGE:
+            package_name = caller_package().__name__
+        Components.__init__(self, package_name)
+        dict.__init__(self)
 
     def _clear_view_lookup_cache(self):
         self._view_lookup_cache = {}


Test patch:
diff --git a/pyramid/tests/test_registry.py b/pyramid/tests/test_registry.py
--- a/pyramid/tests/test_registry.py
+++ b/pyramid/tests/test_registry.py
@@ -27,6 +27,10 @@ def test_package_name(self):
         registry = self._getTargetClass()(package_name)
         self.assertEqual(registry.package_name, package_name)
 
+    def test_default_package_name(self):
+        registry = self._getTargetClass()()
+        self.assertEqual(registry.package_name, 'pyramid.tests')
+
     def test_registerHandler_and_notify(self):
         registry = self._makeOne()
         self.assertEqual(registry.has_listeners, False)