Skip to content

Commit

Permalink
Refactor the local scope object
Browse files Browse the repository at this point in the history
  • Loading branch information
Liam Cooke committed May 18, 2017
1 parent dd0fb0c commit a652d94
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 16 deletions.
1 change: 0 additions & 1 deletion see/features.py
Expand Up @@ -58,7 +58,6 @@ class Feature(object):
"""

def __init__(self, symbol, attrs=None):
super(Feature, self).__init__()
self.symbol = symbol
self.attrs = compact(set, attrs)

Expand Down
34 changes: 20 additions & 14 deletions see/inspector.py
@@ -1,5 +1,5 @@
"""
see.see
see.inspector
Object inspector
Copyright (c) 2009-2017 Liam Cooke
Expand All @@ -15,28 +15,32 @@
from .features import FEATURES, PY3


class LocalScope(object):
class DefaultArg(object):
"""
Local scope proxy object.
An object to use as the default argument to ``see``. This allows for
a distinction between calling ``see()`` without arguments and calling it
with a falsey argument like ``see(None)``.
"""
def __repr__(self):
return 'anything'

def _update(self, frame=None):
"""
Replace this object's namespace with the local namespace of a given
stack frame.
"""
self.__dict__ = frame.f_locals
DEFAULT_ARG = DefaultArg()

LOCALS = LocalScope()

class Namespace(object):
"""
An object that provides attribute access to its namespace.
See also: ``types.SimpleNamespace`` in Python 3.
"""
def __init__(self, namespace):
self.__dict__.update(namespace)


class SeeResult(tuple):
"""
Tuple-like output with a pretty string representation.
"""

def __new__(self, actions=None):
return tuple.__new__(self, actions or [])

Expand All @@ -55,7 +59,7 @@ def __repr__(self):
subsequent_indent=indent)


def see(obj=LOCALS, pattern=None, r=None):
def see(obj=DEFAULT_ARG, pattern=None, r=None):
"""
Inspect an object. Like the ``dir()`` builtin, but easier on the eyes.
Expand All @@ -77,10 +81,12 @@ def see(obj=LOCALS, pattern=None, r=None):
? raised an exception
"""
use_locals = obj is LOCALS
use_locals = obj is DEFAULT_ARG

if use_locals:
# Get the local scope from the caller's stack frame.
LOCALS._update(inspect.currentframe().f_back)
# Typically this is the scope of an interactive Python session.
obj = Namespace(inspect.currentframe().f_back.f_locals)

actions = []
attrs = dir(obj)
Expand Down
2 changes: 1 addition & 1 deletion tests/test_see.py
Expand Up @@ -42,7 +42,7 @@ class TestSee(unittest.TestCase):
def test_see_with_no_args(self):
# Act
out = see.see()
default_arg = see.inspector.LOCALS
default_arg = see.inspector.DEFAULT_ARG

# Assert
self.assertIsInstance(out, see.inspector.SeeResult)
Expand Down

0 comments on commit a652d94

Please sign in to comment.