stephenroller / dotfiles

My dotfiles

This URL has Read+Write access

dotfiles / .pythonrc.py
100755 299 lines (254 sloc) 9.24 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
def _pythonrc():
    # Enable readline, tab completion, and history
 
    try:
        import readline
    except ImportError:
        import sys
        print >> sys.stderr, 'readline unavailable - tab completion disabled.'
    else:
        import rlcompleter
 
        class TabCompleter(rlcompleter.Completer):
            """Completer that supports indenting"""
 
            def complete(self, text, state):
                if not text:
                    return (' ', None)[state]
                else:
                    return rlcompleter.Completer.complete(self, text, state)
 
        readline.parse_and_bind('tab: complete')
        readline.set_completer(TabCompleter().complete)
 
        import atexit
        import os
 
        if 'NOHIST' not in os.environ:
            history_path = os.path.expanduser('~/.pyhistory')
            atexit.register(lambda: readline.write_history_file(history_path))
            if os.path.isfile(history_path):
                readline.read_history_file(history_path)
            readline.set_history_length(1000)
 
    # Pretty print evaluated expressions
 
    import __builtin__
    import inspect
    import pprint
    import pydoc
    import sys
    import types
 
    help_types = (types.BuiltinFunctionType, types.BuiltinMethodType,
                  types.FunctionType, types.MethodType, types.ModuleType,
                  types.TypeType, types.UnboundMethodType,
                  # method_descriptor
                  type(list.remove))
 
    def formatargs(func):
        """Returns a string representing a function's argument specification,
as if it were from source code.
 
For example:
 
>>> class Foo(object):
... def bar(self, x=1, *y, **z):
... pass
...
>>> formatargs(Foo.bar)
'self, x=1, *y, **z'
"""
 
        args, varargs, varkw, defs = inspect.getargspec(func)
 
        # Fill in default values
        if defs:
            last = len(args) - 1
            for i, val in enumerate(reversed(defs)):
                args[last - i] = '%s=%r' % (args[last - i], val)
 
        # Fill in variable arguments
        if varargs:
            args.append('*%s' % varargs)
        if varkw:
            args.append('**%s' % varkw)
 
        return ', '.join(args)
 
    def _ioctl_width(fd):
 
        from fcntl import ioctl
        from struct import pack, unpack
        from termios import TIOCGWINSZ
        return unpack('HHHH',
                      ioctl(fd, TIOCGWINSZ, pack('HHHH', 0, 0, 0, 0)))[1]
 
    def get_width():
        """Returns terminal width"""
 
        width = 0
        try:
            width = _ioctl_width(0) or _ioctl_width(1) or _ioctl_width(2)
        except ImportError:
            pass
        if not width:
            import os
            width = os.environ.get('COLUMNS', 0)
        return width
 
    def pprinthook(value):
        """Pretty print an object to sys.stdout and also save it in
__builtin__.
"""
 
        if value is None:
            return
        __builtin__._ = value
 
        if isinstance(value, help_types):
            reprstr = repr(value)
            try:
                if inspect.isfunction(value):
                    parts = reprstr.split(' ')
                    parts[1] = '%s(%s)' % (parts[1], formatargs(value))
                    reprstr = ' '.join(parts)
                elif inspect.ismethod(value):
                    parts = reprstr[:-1].split(' ')
                    parts[2] = '%s(%s)' % (parts[2], formatargs(value))
                    reprstr = ' '.join(parts) + '>'
            except TypeError:
                pass
            print reprstr
            if getattr(value, '__doc__', None):
                print
                print pydoc.getdoc(value)
        else:
            pprint.pprint(value, width=get_width() or 80)
 
    sys.displayhook = pprinthook
 
    try:
        if sys.platform == 'win32':
            raise ImportError()
        try:
            from cStringIO import StringIO
        except ImportError:
            from StringIO import StringIO
        from pygments import highlight
        from pygments.lexers import PythonTracebackLexer
        from pygments.formatters import TerminalFormatter
 
        _old_excepthook = sys.excepthook
        def excepthook(exctype, value, traceback):
            """Prints exceptions to sys.stderr and colorizes them"""
 
            # traceback.format_exception() isn't used because it's
            # inconsistent with the built-in formatter
            old_stderr = sys.stderr
            sys.stderr = StringIO()
            try:
                _old_excepthook(exctype, value, traceback)
                s = sys.stderr.getvalue()
                s = highlight(s, PythonTracebackLexer(), TerminalFormatter())
                old_stderr.write(s)
            finally:
                sys.stderr = old_stderr
 
        sys.excepthook = excepthook
    except ImportError:
        pass
 
    # linecache.updatecache() replacement that actually works with zips
    import os
    import sys
    from linecache import cache
    def updatecache(filename, module_globals=None):
        """Update a cache entry and return its list of lines.
If something's wrong, print a message, discard the cache entry,
and return an empty list."""
 
        if filename in cache:
            del cache[filename]
        if not filename or filename[0] + filename[-1] == '<>':
            return []
 
        fullname = filename
        try:
            stat = os.stat(fullname)
        except os.error, msg:
            basename = os.path.split(filename)[1]
 
            if module_globals and '__loader__' in module_globals:
                name = module_globals.get('__name__')
                loader = module_globals['__loader__']
                get_source = getattr(loader, 'get_source', None)
 
                if name and get_source:
                    try:
                        data = get_source(name)
                    except (ImportError, IOError):
                        pass
                    else:
                        if data is None:
                            return []
                        cache[filename] = (
                            len(data), None,
                            [line+'\n' for line in data.splitlines()], fullname
                        )
                        return cache[filename][2]
 
            for dirname in sys.path:
                try:
                    fullname = os.path.join(dirname, basename)
                except (TypeError, AttributeError):
                    pass
                else:
                    try:
                        stat = os.stat(fullname)
                        break
                    except os.error:
                        pass
            else:
                return []
        try:
            fp = open(fullname, 'rU')
            lines = fp.readlines()
            fp.close()
        except IOError, msg:
            return []
        size, mtime = stat.st_size, stat.st_mtime
        cache[filename] = size, mtime, lines, fullname
        return lines
 
    import linecache
    linecache.updatecache = updatecache
 
# Make sure modules in the current directory can't interfere
import sys
try:
    try:
        cwd = sys.path.index('')
        sys.path.pop(cwd)
    except ValueError:
        cwd = None
 
    # Run the main function and don't let it taint the global namespace
    try:
        _pythonrc()
        del _pythonrc
    finally:
        if cwd is not None:
            sys.path.insert(cwd, '')
finally:
    del sys
 
def source(obj):
    """Displays the source code of an object.
 
Applies syntax highlighting if Pygments is available.
"""
 
    import sys
 
    from inspect import findsource, getmodule, getsource, getsourcefile
    try:
        # Check to see if the object is defined in a shared library, which
        # findsource() doesn't do properly (see issue4050)
        if not getsourcefile(obj):
            raise TypeError()
        s = getsource(obj)
    except TypeError:
        print >> sys.stderr, ("Source code unavailable (maybe it's part of "
                              "a C extension?)")
        return
 
    import re
    enc = 'ascii'
    for line in findsource(getmodule(obj))[0][:2]:
        m = re.search(r'coding[:=]\s*([-\w.]+)', line)
        if m:
            enc = m.group(1)
    try:
        s = s.decode(enc, 'replace')
    except LookupError:
        s = s.decode('ascii', 'replace')
 
    try:
        if sys.platform == 'win32':
            raise ImportError()
        from pygments import highlight
        from pygments.lexers import PythonLexer
        from pygments.formatters import TerminalFormatter
        s = highlight(s, PythonLexer(), TerminalFormatter())
    except (ImportError, UnicodeError):
        pass
 
    import os
    from pydoc import pager
    has_lessopts = 'LESS' in os.environ
    lessopts = os.environ.get('LESS', '')
    try:
        os.environ['LESS'] = lessopts + ' -R'
        pager(s.encode(sys.stdout.encoding, 'replace'))
    finally:
        if has_lessopts:
            os.environ['LESS'] = lessopts
        else:
            os.environ.pop('LESS', None)