Skip to content

Commit be9689d

Browse files
committed
Lots more code tidying (#92): removal of redundant unicode prefixes on strings, removal of redundant backward compatibility code in the compat module (this now has nothing of interest for compatibility and should be renamed utils or something similar)
1 parent 231c417 commit be9689d

27 files changed

+512
-577
lines changed

Diff for: dbsuite/astex.py

+65-2
Large diffs are not rendered by default.

Diff for: dbsuite/compat.py

+58-233
Original file line numberDiff line numberDiff line change
@@ -31,162 +31,8 @@
3131
)
3232

3333
import sys
34-
import types
3534

36-
__all__ = []
37-
38-
39-
# all() and any() recipes
40-
if sys.hexversion < 0x02050000:
41-
__all__.append('all')
42-
def all(iterable):
43-
for element in iterable:
44-
if not element:
45-
return False
46-
return True
47-
48-
__all__.append('any')
49-
def any(iterable):
50-
for element in iterable:
51-
if element:
52-
return True
53-
return False
54-
55-
56-
__all__.append('attrgetter')
57-
__all__.append('itemgetter')
58-
# multiple item extraction in itemgetter and attrgetter
59-
if sys.hexversion < 0x02050000:
60-
def attrgetter(*attrs):
61-
if len(attrs) == 0:
62-
raise TypeError('attrgetter expected 1 arguments, got 0')
63-
elif len(attrs) == 1:
64-
attr = attrs[0]
65-
def getter(obj):
66-
return getattr(obj, attr)
67-
else:
68-
def getter(obj):
69-
return tuple(getattr(obj, attr) for attr in attrs)
70-
return getter
71-
72-
def itemgetter(*items):
73-
if len(items) == 0:
74-
raise TypeError('itemgetter expected 1 arguments, got 0')
75-
elif len(items) == 1:
76-
item = items[0]
77-
def getter(obj):
78-
return obj[item]
79-
else:
80-
def getter(obj):
81-
return tuple(obj[item] for item in items)
82-
return getter
83-
else:
84-
from operator import itemgetter, attrgetter
85-
86-
87-
# Named tuple recipe (http://code.activestate.com/recipes/500261/)
88-
__all__.append('namedtuple')
89-
if sys.hexversion < 0x02060000:
90-
from operator import itemgetter as _itemgetter
91-
from keyword import iskeyword as _iskeyword
92-
import sys as _sys
93-
94-
def namedtuple(typename, field_names, verbose=False):
95-
"""Returns a new subclass of tuple with named fields.
96-
97-
>>> Point = namedtuple('Point', 'x y')
98-
>>> Point.__doc__ # docstring for the new class
99-
'Point(x, y)'
100-
>>> p = Point(11, y=22) # instantiate with positional args or keywords
101-
>>> p[0] + p[1] # indexable like a plain tuple
102-
33
103-
>>> x, y = p # unpack like a regular tuple
104-
>>> x, y
105-
(11, 22)
106-
>>> p.x + p.y # fields also accessable by name
107-
33
108-
>>> d = p._asdict() # convert to a dictionary
109-
>>> d['x']
110-
11
111-
>>> Point(**d) # convert from a dictionary
112-
Point(x=11, y=22)
113-
>>> p._replace(x=100) # _replace() is like str.replace() but targets named fields
114-
Point(x=100, y=22)
115-
116-
"""
117-
118-
# Parse and validate the field names. Validation serves two purposes,
119-
# generating informative error messages and preventing template injection attacks.
120-
if isinstance(field_names, basestring):
121-
field_names = field_names.replace(',', ' ').split() # names separated by whitespace and/or commas
122-
field_names = tuple(map(str, field_names))
123-
for name in (typename,) + field_names:
124-
if not min(c.isalnum() or c=='_' for c in name):
125-
raise ValueError('Type names and field names can only contain alphanumeric characters and underscores: %r' % name)
126-
if _iskeyword(name):
127-
raise ValueError('Type names and field names cannot be a keyword: %r' % name)
128-
if name[0].isdigit():
129-
raise ValueError('Type names and field names cannot start with a number: %r' % name)
130-
seen_names = set()
131-
for name in field_names:
132-
if name.startswith('_'):
133-
raise ValueError('Field names cannot start with an underscore: %r' % name)
134-
if name in seen_names:
135-
raise ValueError('Encountered duplicate field name: %r' % name)
136-
seen_names.add(name)
137-
138-
# Create and fill-in the class template
139-
numfields = len(field_names)
140-
argtxt = repr(field_names).replace("'", "")[1:-1] # tuple repr without parens or quotes
141-
reprtxt = ', '.join('%s=%%r' % name for name in field_names)
142-
dicttxt = ', '.join('%r: t[%d]' % (name, pos) for pos, name in enumerate(field_names))
143-
template = '''\
144-
class %(typename)s(tuple):
145-
'%(typename)s(%(argtxt)s)' \n
146-
__slots__ = () \n
147-
_fields = %(field_names)r \n
148-
def __new__(cls, %(argtxt)s):
149-
return tuple.__new__(cls, (%(argtxt)s)) \n
150-
@classmethod
151-
def _make(cls, iterable, new=tuple.__new__, len=len):
152-
'Make a new %(typename)s object from a sequence or iterable'
153-
result = new(cls, iterable)
154-
if len(result) != %(numfields)d:
155-
raise TypeError('Expected %(numfields)d arguments, got %%d' %% len(result))
156-
return result \n
157-
def __repr__(self):
158-
return '%(typename)s(%(reprtxt)s)' %% self \n
159-
def _asdict(t):
160-
'Return a new dict which maps field names to their values'
161-
return {%(dicttxt)s} \n
162-
def _replace(self, **kwds):
163-
'Return a new %(typename)s object replacing specified fields with new values'
164-
result = self._make(map(kwds.pop, %(field_names)r, self))
165-
if kwds:
166-
raise ValueError('Got unexpected field names: %%r' %% kwds.keys())
167-
return result \n\n''' % locals()
168-
for i, name in enumerate(field_names):
169-
template += ' %s = property(itemgetter(%d))\n' % (name, i)
170-
if verbose:
171-
print template
172-
173-
# Execute the template string in a temporary namespace
174-
namespace = dict(itemgetter=_itemgetter)
175-
try:
176-
exec template in namespace
177-
except SyntaxError, e:
178-
raise SyntaxError(e.message + ':\n' + template)
179-
result = namespace[typename]
180-
181-
# For pickling to work, the __module__ variable needs to be set to the frame
182-
# where the named tuple is created. Bypass this step in enviroments where
183-
# sys._getframe is not defined (Jython for example).
184-
if hasattr(_sys, '_getframe') and _sys.platform != 'cli':
185-
result.__module__ = _sys._getframe(1).f_globals['__name__']
186-
187-
return result
188-
else:
189-
from collections import namedtuple
35+
__all__ = ['namedslice', 'cachedproperty']
19036

19137

19238
def namedslice(cls, obj):
@@ -222,8 +68,6 @@ def namedslice(cls, obj):
22268
return cls(*(getattr(obj, attr, None) for attr in cls._fields))
22369

22470

225-
# Caching decorators
226-
__all__.append('cachedproperty')
22771
class cachedproperty(property):
22872
"""Convert a method into a cached property"""
22973

@@ -239,89 +83,70 @@ def fget(s):
23983
super(cachedproperty, self).__init__(fget)
24084

24185

242-
# Console/terminal size calculation (urgh!)
24386
__all__.append('terminal_size')
24487
if sys.platform.startswith('win'):
245-
try:
246-
import win32console
247-
import win32api
248-
hstdin, hstdout, hstderr = win32api.STD_INPUT_HANDLE, win32api.STD_OUTPUT_HANDLE, win32api.STD_ERROR_HANDLE
249-
except ImportError:
250-
hstdin, hstdout, hstderr = -10, -11, -12
251-
try:
252-
import ctypes
253-
import struct
254-
except ImportError:
255-
# If neither ctypes (Python 2.5+) nor PyWin32 (extension) is
256-
# available, simply default to 80x25
257-
def query_console_size(handle):
258-
return None
259-
else:
260-
# ctypes query_console_size() adapted from
261-
# http://code.activestate.com/recipes/440694/
262-
def query_console_size(handle):
263-
h = windll.kernel32.GetStdHandle(handle)
264-
if h:
265-
buf = create_string_buffer(22)
266-
if windll.kernel32.GetConsoleScreenBufferInfo(h, buf):
267-
(
268-
bufx, bufy,
269-
curx, cury,
270-
wattr,
271-
left, top, right, bottom,
272-
maxx, maxy,
273-
) = struct.unpack('hhhhHhhhhhh', buf.raw)
274-
return (right - left + 1, bottom - top + 1)
275-
return None
276-
else:
277-
# PyWin32 query_console_size() adapted from
278-
# http://groups.google.com/group/comp.lang.python/msg/f0febe6a8de9666b
279-
def query_console_size(handle):
280-
try:
281-
csb = win32console.GetStdHandle(handle)
282-
csbi = csb.GetConsoleScreenBufferInfo()
283-
size = csbi['Window']
284-
return (size.Right - size.Left + 1, size.Bottom - size.Top + 1)
285-
except:
286-
return None
287-
def default_console_size():
288-
return (80, 25)
88+
# ctypes query_console_size() adapted from
89+
# http://code.activestate.com/recipes/440694/
90+
import ctypes
91+
92+
def terminal_size():
93+
"Returns the size (cols, rows) of the console"
94+
95+
def get_handle_size(handle):
96+
"Subroutine for querying terminal size from std handle"
97+
handle = ctypes.windll.kernel32.GetStdHandle(handle)
98+
if handle:
99+
buf = ctypes.create_string_buffer(22)
100+
if ctypes.windll.kernel32.GetConsoleScreenBufferInfo(
101+
handle, buf):
102+
(left, top, right, bottom) = struct.unpack(
103+
str('hhhhHhhhhhh'), buf.raw)[5:9]
104+
return (right - left + 1, bottom - top + 1)
105+
return None
106+
107+
stdin, stdout, stderr = -10, -11, -12
108+
return (
109+
get_handle_size(stderr) or
110+
get_handle_size(stdout) or
111+
get_handle_size(stdin) or
112+
# Default
113+
(80, 25)
114+
)
115+
289116
else:
290-
# POSIX query_console_size() adapted from
291-
# http://mail.python.org/pipermail/python-list/2006-February/365594.html
292-
# http://mail.python.org/pipermail/python-list/2000-May/033365.html
293117
import fcntl
294118
import termios
295-
import struct
296119
import os
297-
hstdin, hstdout, hstderr = 0, 1, 2
298-
def query_console_size(handle):
299-
try:
300-
buf = fcntl.ioctl(handle, termios.TIOCGWINSZ, '12345678')
301-
row, col, rpx, cpx = struct.unpack('hhhh', buf)
302-
return (col, row)
303-
except:
304-
return None
305-
def default_console_size():
306-
try:
120+
121+
def terminal_size():
122+
"Returns the size (cols, rows) of the console"
123+
124+
def get_handle_size(handle):
125+
"Subroutine for querying terminal size from std handle"
126+
try:
127+
buf = fcntl.ioctl(handle, termios.TIOCGWINSZ, '12345678')
128+
row, col = struct.unpack(str('hhhh'), buf)[0:2]
129+
return (col, row)
130+
except IOError:
131+
return None
132+
133+
stdin, stdout, stderr = 0, 1, 2
134+
# Try stderr first as it's the least likely to be redirected
135+
result = (
136+
get_handle_size(stderr) or
137+
get_handle_size(stdout) or
138+
get_handle_size(stdin)
139+
)
140+
if not result:
307141
fd = os.open(os.ctermid(), os.O_RDONLY)
308142
try:
309-
result = query_console_size(fd)
143+
result = get_handle_size(fd)
310144
finally:
311145
os.close(fd)
312-
except OSError:
313-
result = None
314-
if result:
315-
return result
316-
try:
317-
return (os.environ['COLUMNS'], os.environ['LINES'])
318-
except:
319-
return (80, 25)
320-
321-
def terminal_size():
322-
# Try stderr first as it's the least likely to be redirected
323-
for handle in (hstderr, hstdout, hstdin):
324-
result = query_console_size(handle)
325-
if result:
326-
return result
327-
return default_console_size()
146+
if not result:
147+
try:
148+
result = (os.environ['COLUMNS'], os.environ['LINES'])
149+
except KeyError:
150+
# Default
151+
result = (80, 24)
152+
return result

0 commit comments

Comments
 (0)