Skip to content
Browse files

add rudimentary object description code

  • Loading branch information...
1 parent 5e92f34 commit 8b6f09d965a6e637b795a8268c310c81fcb43a10 @mcdonc mcdonc committed
Showing with 100 additions and 7 deletions.
  1. +14 −0 TODO.txt
  2. +2 −0 pyramid/config/__init__.py
  3. +2 −2 pyramid/config/adapters.py
  4. +6 −3 pyramid/config/factories.py
  5. +2 −1 pyramid/config/routes.py
  6. +8 −1 pyramid/config/views.py
  7. +66 −0 pyramid/util.py
View
14 TODO.txt
@@ -8,6 +8,20 @@ Must-Have
- Fix SQLA tutorial to match alchemy scaffold.
+- Introspection:
+
+ * More specific filename/lineno info instead of opaque string (or a way to
+ parse the opaque string into filename/lineno info).
+
+ * categorize() return value ordering not right yet.
+
+ * implement ptweens and proutes based on introspection instead of current
+ state of affairs.
+
+ * introspection hiding for directives?
+
+ * usage docs.
+
Nice-to-Have
------------
View
2 pyramid/config/__init__.py
@@ -34,6 +34,7 @@
from pyramid.threadlocal import manager
from pyramid.util import DottedNameResolver
from pyramid.util import WeakOrderedSet
+from pyramid.util import object_description
from pyramid.config.adapters import AdaptersConfiguratorMixin
from pyramid.config.assets import AssetsConfiguratorMixin
@@ -219,6 +220,7 @@ class Configurator(
basepath = None
includepath = ()
info = ''
+ object_description = staticmethod(object_description)
def __init__(self,
registry=None,
View
4 pyramid/config/adapters.py
@@ -29,7 +29,7 @@ def register():
self.registry.registerHandler(subscriber, iface)
intr = self.introspectable('subscribers',
id(subscriber),
- repr(subscriber),
+ self.object_description(subscriber),
'subscriber')
intr['subscriber'] = subscriber
intr['interfaces'] = iface
@@ -62,7 +62,7 @@ def register():
intr = self.introspectable(
'response adapters',
discriminator,
- repr(adapter),
+ self.object_description(adapter),
'response adapter')
intr['adapter'] = adapter
intr['type'] = type_or_iface
View
9 pyramid/config/factories.py
@@ -27,7 +27,8 @@ def register():
self.registry.registerUtility(factory, IRootFactory)
self.registry.registerUtility(factory, IDefaultRootFactory) # b/c
- intr = self.introspectable('root factories', None, repr(factory),
+ intr = self.introspectable('root factories', None,
+ self.object_description(factory),
'root factory')
intr['factory'] = factory
self.action(IRootFactory, register, introspectables=(intr,))
@@ -50,7 +51,8 @@ def set_session_factory(self, factory):
factory = self.maybe_dotted(factory)
def register():
self.registry.registerUtility(factory, ISessionFactory)
- intr = self.introspectable('session factory', None, repr(factory),
+ intr = self.introspectable('session factory', None,
+ self.object_description(factory),
'session factory')
intr['factory'] = factory
self.action(ISessionFactory, register, introspectables=(intr,))
@@ -74,7 +76,8 @@ def set_request_factory(self, factory):
factory = self.maybe_dotted(factory)
def register():
self.registry.registerUtility(factory, IRequestFactory)
- intr = self.introspectable('request factory', None, repr(factory),
+ intr = self.introspectable('request factory', None,
+ self.object_description(factory),
'request factory')
intr['factory'] = factory
self.action(IRequestFactory, register, introspectables=(intr,))
View
3 pyramid/config/routes.py
@@ -365,7 +365,8 @@ def add_route(self,
mapper = self.get_routes_mapper()
- intr = self.introspectable('routes', name, name, 'route')
+ intr = self.introspectable('routes', name,
+ '%s (%s)' % (name, pattern), 'route')
intr['name'] = name
intr['pattern'] = pattern
intr['factory'] = factory
View
9 pyramid/config/views.py
@@ -931,7 +931,14 @@ def view(context, request):
xhr, accept, header, path_info, match_param]
discriminator.extend(sorted([hash(x) for x in custom_predicates]))
discriminator = tuple(discriminator)
- view_intr = self.introspectable('views', discriminator, repr(view),
+ if inspect.isclass(view) and attr:
+ view_desc = 'method %r of %s' % (
+ attr, self.object_description(view))
+ else:
+ view_desc = self.object_description(view)
+ view_intr = self.introspectable('views',
+ discriminator,
+ view_desc,
'view')
view_intr.update(
dict(name=name,
View
66 pyramid/util.py
@@ -1,5 +1,7 @@
+import inspect
import pkg_resources
import sys
+import types
import weakref
from pyramid.compat import string_types
@@ -228,3 +230,67 @@ def strings_differ(string1, string2):
return invalid_bits != 0
+def object_description(object):
+ """ Produce a human-consumable string description of ``object``, usually
+ involving a Python dotted name. For example:
+
+ .. code-block:: python
+
+ >>> object_description(None)
+ 'None'
+ >>> from xml.dom import minidom
+ >>> object_description(minidom)
+ 'module xml.dom.minidom'
+ >>> object_description(minidom.Attr)
+ 'class xml.dom.minidom.Attr'
+ >>> object_description(minidom.Attr.appendChild)
+ 'method appendChild of class xml.dom.minidom.Attr'
+ >>>
+
+ If this method cannot identify the type of the object, a generic
+ description ala ``object <object.__name__>`` will be returned.
+
+ If the object passed is already a string, it is simply returned. If it
+ is a boolean, an integer, a list, a tuple, a set, or ``None``, a
+ (possibly shortened) string representation is returned.
+ """
+ if isinstance(object, string_types):
+ return object
+ if isinstance(object, (bool, int, float, long, types.NoneType)):
+ return str(object)
+ if isinstance(object, (tuple, set)):
+ return shortrepr(object, ')')
+ if isinstance(object, list):
+ return shortrepr(object, ']')
+ if isinstance(object, dict):
+ return shortrepr(object, '}')
+ module = inspect.getmodule(object)
+ modulename = module.__name__
+ if inspect.ismodule(object):
+ return 'module %s' % modulename
+ if inspect.ismethod(object):
+ oself = getattr(object, '__self__', None)
+ if oself is None:
+ oself = getattr(object, 'im_self', None)
+ oself.__class__
+ return 'method %s of class %s.%s' (object.__name__, modulename,
+ oself.__class__.__name___)
+
+ if inspect.isclass(object):
+ dottedname = '%s.%s' % (modulename, object.__name__)
+ return 'class %s' % dottedname
+ if inspect.isfunction(object):
+ dottedname = '%s.%s' % (modulename, object.__name__)
+ return 'function %s' % dottedname
+ if inspect.isbuiltin(object):
+ dottedname = '%s.%s' % (modulename, object.__name__)
+ return 'builtin %s' % dottedname
+ if hasattr(object, '__name__'):
+ return 'object %s' % object.__name__
+ return 'object %s' % str(object)
+
+def shortrepr(object, closer):
+ r = str(object)
+ if len(r) > 100:
+ r = r[:100] + '... %s' % closer
+ return r

0 comments on commit 8b6f09d

Please sign in to comment.
Something went wrong with that request. Please try again.