Commits

Jonathan Eunice committed d4a268c

@property properties now correctly reported

Comments (0)

Files changed (4)

 
     show.set(where=True)
     
-will turn on location reporting.
+will turn on location reporting. This can also be set on call-by-call basis.
+``show`` is built atop the `options <http://pypi.python.org/pypi/options>`_ module
+for configuration management, and also the output management of
+`say <http://pypi.python.org/pypi/say>`_. All ``say`` options work in show.
+See that module for additional detail.
 
-``show.props(x)`` shows the properties of object x. An optional second
+Showing Collections
+===================
+
+Showing Object Properties
+=========================
+
+::
+
+    show.props(x)
+    
+shows the properties of object ``x``. ("Properties" here
+is generic language for "values" or "attributes" associated with
+an object, and isn't used in the technical sense of Python properties.)
+Properties will be listed alphabetically, but with those starting with underscores
+(``_``), usually indicating "private" data, sorted after those that are
+conventionally considered public.
+
+If ``x`` has real ``@property`` members, those too displayed. However, other class
+attributes that ``x`` rightfully inherits, but that are not directly present in the
+``x`` instance, will not be displayed.
+
+An optional second
 parameter can determine which properties are shown. E.g.::
 
     show.props(x, 'name,age')
 Interactive Limitations
 =======================
 
-Sadly, because Python provides weaker introspection during
-interactive operation, (see e.g. `this <http://stackoverflow.com/questions/13204161/how-to-access-the-calling-source-line-from-interactive-shell>`_)
-``show()`` is somewhat limited in interactive use. It works at the main
-level and usually in imported modules, but does work within the body of functions defined
-interactively.
+``show`` has  draft support for both interactive Python and iPython.
+It orks well at the
+interactive prompt, and within imported modules. It cannot, however, be used
+within functions and classes defined within the interactive session. This is
+due to how Python supprots--or fails to support--introspection in this instance.
+Whether this is a hard limit, or something
+that can be worked around over time, remains to be seen.
+
+See e.g. `this <http://stackoverflow.com/questions/13204161/how-to-access-the-calling-source-line-from-interactive-shell>`_.
 
 Notes
 =====
-
- *  ``show`` is the companion to, and built on the output management of,
-    `say <http://pypi.python.org/pypi/say>`_.
    
- *  Automated multi-version testing is managed with the wonderful
+ *  Automated multi-version testing managed with the wonderful
     `pytest <http://pypi.python.org/pypi/pytest>`_
-    and `tox <http://pypi.python.org/pypi/tox>`_ modules. ``show`` is 
+    and `tox <http://pypi.python.org/pypi/tox>`_. ``show`` is 
     successfully packaged for, and tested against, all late-model verions of
     Python: 2.6, 2.7, 3.2, and 3.3, as well as PyPy 1.9 (based on 2.7.2).
  
- *  ``show`` has 
-    draft support for interactive Python and iPython. Works well at the
-    interactive prompt, and within imported modules; it cannot, however, be used
-    within interactively defined functions and classes. There may be a hard limit
-    on Python introspection of interactive code. Or it could be something
-    that can be worked around over time.
- 
  *  The author, `Jonathan Eunice <mailto:jonathan.eunice@gmail.com>`_ or
     `@jeunice on Twitter <http://twitter.com/jeunice>`_
     welcomes your comments and suggestions.
 
 setup(
     name='show',
-    version=verno("0.414"),
+    version=verno("0.430"),
     author='Jonathan Eunice',
     author_email='jonathan.eunice@gmail.com',
     description='Debug print statements, done right. E.g. show(x)',
 """Debugging print features. """
 
-import string, inspect, sys, os, re, collections
+import inspect, sys, os, re, six
 from options import Options, OptionsContext
-from say import *
+from say import Say, fmt
 from show.linecacher import *
 import linecache, ast, codegen
 from mementos import MementoMetaclass, with_metaclass
                 return n.func.id
             elif isinstance(n.func, ast.Attribute):
                 a = n.func
-                if isinstance(a.value, ast.Name):
+                if isinstance(a.value, ast.Name): 
                     return '.'.join([a.value.id, a.attr])
                 else:
                     return None # could be an attribute of a call, but for those, we don't much care
                 if props:
                     proplist = props.split(',')
                 else:
-                    proplist = sorted([ k for k in value.__dict__.keys() if not k.startswith('_') ])
+                    propkeys = list(value.__dict__.keys())
+                    cdict = value.__class__.__dict__
+                    realproperties = [ k for k in cdict.keys() if isinstance(cdict[k], property) ]
+                    propkeys.extend(realproperties)
+                    proplist = sorted(propkeys, key=lambda x: x.replace('_','~'))
                 propvals = [ "{0}={1}".format(p, self.value_repr(getattr(value, p))) for p in proplist ]
                 return "{0}: {1}".format(name, ' '.join(propvals))
             except Exception:

test/test_show.py

     class OO(object):
         def __init__(self, name, age, address):
             self.name = name
+            self._name = name.upper()
             self.age  = age
             self.address = address
         def test(self):
     
     oo = OO('Joe', 36, 'Waverly Place')
 
-    assert show.props(oo) == "oo: address='Waverly Place' age=36 name='Joe'"
+    assert show.props(oo) == "oo: address='Waverly Place' age=36 name='Joe' _name='JOE'"
+    
+def test_show_real_properties():
+        
+    class P(object):
+        def __init__(self, name):
+            self._name = name.upper()
+            self.name = name
+        @property
+        def namer(self):
+            return self._name.lower()
+        def named(self):
+            return self.name
+    
+    p = P('Joe')
+    assert show.props(p) == "p: name='Joe' namer='joe' _name='JOE'"