1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/lib/UserDict.py Tue Aug 30 22:09:17 2016 +0200
1.3 @@ -0,0 +1,176 @@
1.4 +"""A more or less complete user-defined wrapper around dictionary objects."""
1.5 +
1.6 +class UserDict:
1.7 + def __init__(self, dict=None, **kwargs):
1.8 + self.data = {}
1.9 + if dict is not None:
1.10 + self.update(dict)
1.11 + if len(kwargs):
1.12 + self.update(kwargs)
1.13 + def __repr__(self): return repr(self.data)
1.14 + def __cmp__(self, dict):
1.15 + if isinstance(dict, UserDict):
1.16 + return cmp(self.data, dict.data)
1.17 + else:
1.18 + return cmp(self.data, dict)
1.19 + __hash__ = None # Avoid Py3k warning
1.20 + def __len__(self): return len(self.data)
1.21 + def __getitem__(self, key):
1.22 + if key in self.data:
1.23 + return self.data[key]
1.24 + if hasattr(self.__class__, "__missing__"):
1.25 + return self.__class__.__missing__(self, key)
1.26 + raise KeyError(key)
1.27 + def __setitem__(self, key, item): self.data[key] = item
1.28 + def __delitem__(self, key): del self.data[key]
1.29 + def clear(self): self.data.clear()
1.30 + def copy(self):
1.31 + if self.__class__ is UserDict:
1.32 + return UserDict(self.data.copy())
1.33 + import copy
1.34 + data = self.data
1.35 + try:
1.36 + self.data = {}
1.37 + c = copy.copy(self)
1.38 + finally:
1.39 + self.data = data
1.40 + c.update(self)
1.41 + return c
1.42 + def keys(self): return self.data.keys()
1.43 + def items(self): return self.data.items()
1.44 + def iteritems(self): return self.data.iteritems()
1.45 + def iterkeys(self): return self.data.iterkeys()
1.46 + def itervalues(self): return self.data.itervalues()
1.47 + def values(self): return self.data.values()
1.48 + def has_key(self, key): return key in self.data
1.49 + def update(self, dict=None, **kwargs):
1.50 + if dict is None:
1.51 + pass
1.52 + elif isinstance(dict, UserDict):
1.53 + self.data.update(dict.data)
1.54 + elif isinstance(dict, type({})) or not hasattr(dict, 'items'):
1.55 + self.data.update(dict)
1.56 + else:
1.57 + for k, v in dict.items():
1.58 + self[k] = v
1.59 + if len(kwargs):
1.60 + self.data.update(kwargs)
1.61 + def get(self, key, failobj=None):
1.62 + if key not in self:
1.63 + return failobj
1.64 + return self[key]
1.65 + def setdefault(self, key, failobj=None):
1.66 + if key not in self:
1.67 + self[key] = failobj
1.68 + return self[key]
1.69 + def pop(self, key, *args):
1.70 + return self.data.pop(key, *args)
1.71 + def popitem(self):
1.72 + return self.data.popitem()
1.73 + def __contains__(self, key):
1.74 + return key in self.data
1.75 + @classmethod
1.76 + def fromkeys(cls, iterable, value=None):
1.77 + d = cls()
1.78 + for key in iterable:
1.79 + d[key] = value
1.80 + return d
1.81 +
1.82 +class IterableUserDict(UserDict):
1.83 + def __iter__(self):
1.84 + return iter(self.data)
1.85 +
1.86 +class DictMixin:
1.87 + # Mixin defining all dictionary methods for classes that already have
1.88 + # a minimum dictionary interface including getitem, setitem, delitem,
1.89 + # and keys. Without knowledge of the subclass constructor, the mixin
1.90 + # does not define __init__() or copy(). In addition to the four base
1.91 + # methods, progressively more efficiency comes with defining
1.92 + # __contains__(), __iter__(), and iteritems().
1.93 +
1.94 + # second level definitions support higher levels
1.95 + def __iter__(self):
1.96 + for k in self.keys():
1.97 + yield k
1.98 + def has_key(self, key):
1.99 + try:
1.100 + self[key]
1.101 + except KeyError:
1.102 + return False
1.103 + return True
1.104 + def __contains__(self, key):
1.105 + return self.has_key(key)
1.106 +
1.107 + # third level takes advantage of second level definitions
1.108 + def iteritems(self):
1.109 + for k in self:
1.110 + yield (k, self[k])
1.111 + def iterkeys(self):
1.112 + return self.__iter__()
1.113 +
1.114 + # fourth level uses definitions from lower levels
1.115 + def itervalues(self):
1.116 + for _, v in self.iteritems():
1.117 + yield v
1.118 + def values(self):
1.119 + return [v for _, v in self.iteritems()]
1.120 + def items(self):
1.121 + return list(self.iteritems())
1.122 + def clear(self):
1.123 + for key in self.keys():
1.124 + del self[key]
1.125 + def setdefault(self, key, default=None):
1.126 + try:
1.127 + return self[key]
1.128 + except KeyError:
1.129 + self[key] = default
1.130 + return default
1.131 + def pop(self, key, *args):
1.132 + if len(args) > 1:
1.133 + raise TypeError, "pop expected at most 2 arguments, got "\
1.134 + + repr(1 + len(args))
1.135 + try:
1.136 + value = self[key]
1.137 + except KeyError:
1.138 + if args:
1.139 + return args[0]
1.140 + raise
1.141 + del self[key]
1.142 + return value
1.143 + def popitem(self):
1.144 + try:
1.145 + k, v = self.iteritems().next()
1.146 + except StopIteration:
1.147 + raise KeyError, 'container is empty'
1.148 + del self[k]
1.149 + return (k, v)
1.150 + def update(self, other=None, **kwargs):
1.151 + # Make progressively weaker assumptions about "other"
1.152 + if other is None:
1.153 + pass
1.154 + elif hasattr(other, 'iteritems'): # iteritems saves memory and lookups
1.155 + for k, v in other.iteritems():
1.156 + self[k] = v
1.157 + elif hasattr(other, 'keys'):
1.158 + for k in other.keys():
1.159 + self[k] = other[k]
1.160 + else:
1.161 + for k, v in other:
1.162 + self[k] = v
1.163 + if kwargs:
1.164 + self.update(kwargs)
1.165 + def get(self, key, default=None):
1.166 + try:
1.167 + return self[key]
1.168 + except KeyError:
1.169 + return default
1.170 + def __repr__(self):
1.171 + return repr(dict(self.iteritems()))
1.172 + def __cmp__(self, other):
1.173 + if other is None:
1.174 + return 1
1.175 + if isinstance(other, DictMixin):
1.176 + other = dict(other.iteritems())
1.177 + return cmp(dict(self.iteritems()), other)
1.178 + def __len__(self):
1.179 + return len(self.keys())
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/lib/__builtins__/__init__.py Tue Aug 30 22:09:17 2016 +0200
2.3 @@ -0,0 +1,105 @@
2.4 +#!/usr/bin/env python
2.5 +
2.6 +"""
2.7 +Simple built-in classes and functions.
2.8 +
2.9 +Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk>
2.10 +
2.11 +This program is free software; you can redistribute it and/or modify it under
2.12 +the terms of the GNU General Public License as published by the Free Software
2.13 +Foundation; either version 3 of the License, or (at your option) any later
2.14 +version.
2.15 +
2.16 +This program is distributed in the hope that it will be useful, but WITHOUT
2.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
2.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
2.19 +details.
2.20 +
2.21 +You should have received a copy of the GNU General Public License along with
2.22 +this program. If not, see <http://www.gnu.org/licenses/>.
2.23 +"""
2.24 +
2.25 +from __builtins__.core import object, type, function, BaseException, Exception, Warning
2.26 +
2.27 +# Exceptions.
2.28 +
2.29 +from __builtins__.exception import (
2.30 + ArithmeticError,
2.31 + AssertionError,
2.32 + AttributeError,
2.33 + DeprecationWarning,
2.34 + EOFError,
2.35 + EnvironmentError,
2.36 + FloatingPointError,
2.37 + FutureWarning,
2.38 + GeneratorExit,
2.39 + ImportError,
2.40 + ImportWarning,
2.41 + IndentationError,
2.42 + IndexError,
2.43 + IOError,
2.44 + KeyError,
2.45 + KeyboardInterrupt,
2.46 + LookupError,
2.47 + MemoryError,
2.48 + NameError,
2.49 + NotImplementedError,
2.50 + OSError,
2.51 + OverflowError,
2.52 + PendingDeprecationWarning,
2.53 + ReferenceError,
2.54 + RuntimeError,
2.55 + RuntimeWarning,
2.56 + StandardError,
2.57 + StopIteration,
2.58 + SyntaxError,
2.59 + SyntaxWarning,
2.60 + SystemError,
2.61 + SystemExit,
2.62 + TabError,
2.63 + TypeError,
2.64 + UnboundLocalError,
2.65 + UnicodeDecodeError,
2.66 + UnicodeEncodeError,
2.67 + UnicodeError,
2.68 + UnicodeTranslateError,
2.69 + UnicodeWarning,
2.70 + UserWarning,
2.71 + ValueError,
2.72 + ZeroDivisionError
2.73 + )
2.74 +
2.75 +
2.76 +# Classes.
2.77 +
2.78 +from __builtins__.bool import bool
2.79 +from __builtins__.buffer import buffer
2.80 +from __builtins__.complex import complex
2.81 +from __builtins__.dict import dict
2.82 +from __builtins__.ellipsis import ellipsis
2.83 +from __builtins__.file import file
2.84 +from __builtins__.float import float
2.85 +from __builtins__.int import int
2.86 +from __builtins__.span import xrange, slice
2.87 +from __builtins__.iterator import listiterator
2.88 +from __builtins__.list import list
2.89 +from __builtins__.long import long
2.90 +from __builtins__.none import NoneType
2.91 +from __builtins__.notimplemented import NotImplementedType
2.92 +from __builtins__.property import property
2.93 +from __builtins__.set import frozenset, set
2.94 +from __builtins__.string import basestring, str, unicode
2.95 +from __builtins__.tuple import tuple
2.96 +
2.97 +# Functions.
2.98 +
2.99 +from __builtins__.attribute import getattr, hasattr, setattr
2.100 +from __builtins__.character import chr, hex, oct, ord, unichr
2.101 +from __builtins__.comparable import cmp, hash
2.102 +from __builtins__.identity import callable, help, id, isinstance, issubclass, repr
2.103 +from __builtins__.io import eval, open, raw_input
2.104 +from __builtins__.iterable import all, any, enumerate, filter, iter, len, map, max, min, range, reduce, reversed, sorted, sum, zip
2.105 +from __builtins__.namespace import dir, globals, locals, vars
2.106 +from __builtins__.numeric import abs, divmod, pow, round
2.107 +
2.108 +# vim: tabstop=4 expandtab shiftwidth=4
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/lib/__builtins__/attribute.py Tue Aug 30 22:09:17 2016 +0200
3.3 @@ -0,0 +1,40 @@
3.4 +#!/usr/bin/env python
3.5 +
3.6 +"""
3.7 +Attribute-related functions.
3.8 +
3.9 +Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk>
3.10 +
3.11 +This program is free software; you can redistribute it and/or modify it under
3.12 +the terms of the GNU General Public License as published by the Free Software
3.13 +Foundation; either version 3 of the License, or (at your option) any later
3.14 +version.
3.15 +
3.16 +This program is distributed in the hope that it will be useful, but WITHOUT
3.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
3.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
3.19 +details.
3.20 +
3.21 +You should have received a copy of the GNU General Public License along with
3.22 +this program. If not, see <http://www.gnu.org/licenses/>.
3.23 +"""
3.24 +
3.25 +_getattr_default=object() # a unique placeholder for a missing value
3.26 +
3.27 +def getattr(obj, name, default=_getattr_default):
3.28 +
3.29 + "Implementation of getattr."
3.30 +
3.31 + try:
3.32 + return _getattr(obj, name)
3.33 + except AttributeError:
3.34 + if default is not _getattr_default:
3.35 + return default
3.36 + else:
3.37 + raise
3.38 +
3.39 +def hasattr(obj, name): pass
3.40 +def setattr(obj, name, value): pass
3.41 +def _getattr(obj, name): pass
3.42 +
3.43 +# vim: tabstop=4 expandtab shiftwidth=4
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/lib/__builtins__/bool.py Tue Aug 30 22:09:17 2016 +0200
4.3 @@ -0,0 +1,29 @@
4.4 +#!/usr/bin/env python
4.5 +
4.6 +"""
4.7 +Boolean objects.
4.8 +
4.9 +Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk>
4.10 +
4.11 +This program is free software; you can redistribute it and/or modify it under
4.12 +the terms of the GNU General Public License as published by the Free Software
4.13 +Foundation; either version 3 of the License, or (at your option) any later
4.14 +version.
4.15 +
4.16 +This program is distributed in the hope that it will be useful, but WITHOUT
4.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
4.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
4.19 +details.
4.20 +
4.21 +You should have received a copy of the GNU General Public License along with
4.22 +this program. If not, see <http://www.gnu.org/licenses/>.
4.23 +"""
4.24 +
4.25 +class bool(object):
4.26 + def __bool__(self):
4.27 + "Identity operation."
4.28 + return self
4.29 + def __str__(self):
4.30 + return self is True and "True" or "False"
4.31 +
4.32 +# vim: tabstop=4 expandtab shiftwidth=4
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/lib/__builtins__/buffer.py Tue Aug 30 22:09:17 2016 +0200
5.3 @@ -0,0 +1,27 @@
5.4 +#!/usr/bin/env python
5.5 +
5.6 +"""
5.7 +Buffer object.
5.8 +
5.9 +Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk>
5.10 +
5.11 +This program is free software; you can redistribute it and/or modify it under
5.12 +the terms of the GNU General Public License as published by the Free Software
5.13 +Foundation; either version 3 of the License, or (at your option) any later
5.14 +version.
5.15 +
5.16 +This program is distributed in the hope that it will be useful, but WITHOUT
5.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
5.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
5.19 +details.
5.20 +
5.21 +You should have received a copy of the GNU General Public License along with
5.22 +this program. If not, see <http://www.gnu.org/licenses/>.
5.23 +"""
5.24 +
5.25 +class buffer(object):
5.26 + def __init__(self, size): pass
5.27 + def append(self, s): pass
5.28 + def __str__(self): pass
5.29 +
5.30 +# vim: tabstop=4 expandtab shiftwidth=4
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/lib/__builtins__/character.py Tue Aug 30 22:09:17 2016 +0200
6.3 @@ -0,0 +1,28 @@
6.4 +#!/usr/bin/env python
6.5 +
6.6 +"""
6.7 +Character-related functions.
6.8 +
6.9 +Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk>
6.10 +
6.11 +This program is free software; you can redistribute it and/or modify it under
6.12 +the terms of the GNU General Public License as published by the Free Software
6.13 +Foundation; either version 3 of the License, or (at your option) any later
6.14 +version.
6.15 +
6.16 +This program is distributed in the hope that it will be useful, but WITHOUT
6.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
6.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
6.19 +details.
6.20 +
6.21 +You should have received a copy of the GNU General Public License along with
6.22 +this program. If not, see <http://www.gnu.org/licenses/>.
6.23 +"""
6.24 +
6.25 +def chr(i): pass
6.26 +def hex(number): pass
6.27 +def oct(number): pass
6.28 +def ord(c): pass
6.29 +def unichr(i): pass
6.30 +
6.31 +# vim: tabstop=4 expandtab shiftwidth=4
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/lib/__builtins__/comparable.py Tue Aug 30 22:09:17 2016 +0200
7.3 @@ -0,0 +1,25 @@
7.4 +#!/usr/bin/env python
7.5 +
7.6 +"""
7.7 +Comparison-related functions.
7.8 +
7.9 +Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk>
7.10 +
7.11 +This program is free software; you can redistribute it and/or modify it under
7.12 +the terms of the GNU General Public License as published by the Free Software
7.13 +Foundation; either version 3 of the License, or (at your option) any later
7.14 +version.
7.15 +
7.16 +This program is distributed in the hope that it will be useful, but WITHOUT
7.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
7.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
7.19 +details.
7.20 +
7.21 +You should have received a copy of the GNU General Public License along with
7.22 +this program. If not, see <http://www.gnu.org/licenses/>.
7.23 +"""
7.24 +
7.25 +def cmp(x, y): pass
7.26 +def hash(obj): pass
7.27 +
7.28 +# vim: tabstop=4 expandtab shiftwidth=4
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/lib/__builtins__/complex.py Tue Aug 30 22:09:17 2016 +0200
8.3 @@ -0,0 +1,57 @@
8.4 +#!/usr/bin/env python
8.5 +
8.6 +"""
8.7 +Complex number objects.
8.8 +
8.9 +Copyright (C) 2015, 2016 Paul Boddie <paul@boddie.org.uk>
8.10 +
8.11 +This program is free software; you can redistribute it and/or modify it under
8.12 +the terms of the GNU General Public License as published by the Free Software
8.13 +Foundation; either version 3 of the License, or (at your option) any later
8.14 +version.
8.15 +
8.16 +This program is distributed in the hope that it will be useful, but WITHOUT
8.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
8.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
8.19 +details.
8.20 +
8.21 +You should have received a copy of the GNU General Public License along with
8.22 +this program. If not, see <http://www.gnu.org/licenses/>.
8.23 +"""
8.24 +
8.25 +class complex(object):
8.26 + def __init__(self, real, imag=None):
8.27 + self.real = real
8.28 + self.imag = imag
8.29 +
8.30 + def __iadd__(self, other): pass
8.31 + def __isub__(self, other): pass
8.32 + def __add__(self, other): pass
8.33 + def __radd__(self, other): pass
8.34 + def __sub__(self, other): pass
8.35 + def __rsub__(self, other): pass
8.36 + def __mul__(self, other): pass
8.37 + def __rmul__(self, other): pass
8.38 + def __div__(self, other): pass
8.39 + def __rdiv__(self, other): pass
8.40 + def __floordiv__(self, other): pass
8.41 + def __rfloordiv__(self, other): pass
8.42 + def __and__(self, other): pass
8.43 + def __rand__(self, other): pass
8.44 + def __or__(self, other): pass
8.45 + def __ror__(self, other): pass
8.46 + def __xor__(self, other): pass
8.47 + def __rxor__(self, other): pass
8.48 + def __lt__(self, other): pass
8.49 + def __gt__(self, other): pass
8.50 + def __le__(self, other): pass
8.51 + def __ge__(self, other): pass
8.52 + def __eq__(self, other): pass
8.53 + def __ne__(self, other): pass
8.54 + def __neg__(self): pass
8.55 + def __pos__(self): pass
8.56 + def __str__(self): pass
8.57 + def __bool__(self): pass
8.58 + def conjugate(self): pass
8.59 +
8.60 +# vim: tabstop=4 expandtab shiftwidth=4
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2 +++ b/lib/__builtins__/core.py Tue Aug 30 22:09:17 2016 +0200
9.3 @@ -0,0 +1,45 @@
9.4 +#!/usr/bin/env python
9.5 +
9.6 +"""
9.7 +Core objects.
9.8 +
9.9 +Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk>
9.10 +
9.11 +This program is free software; you can redistribute it and/or modify it under
9.12 +the terms of the GNU General Public License as published by the Free Software
9.13 +Foundation; either version 3 of the License, or (at your option) any later
9.14 +version.
9.15 +
9.16 +This program is distributed in the hope that it will be useful, but WITHOUT
9.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
9.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
9.19 +details.
9.20 +
9.21 +You should have received a copy of the GNU General Public License along with
9.22 +this program. If not, see <http://www.gnu.org/licenses/>.
9.23 +"""
9.24 +
9.25 +class object:
9.26 + def __init__(self):
9.27 + "No-operation."
9.28 + pass
9.29 + def __bool__(self):
9.30 + "Objects are true by default."
9.31 + return True
9.32 +
9.33 +class function(object):
9.34 + def __init__(self):
9.35 +
9.36 + # Reserve special attributes for function instances.
9.37 +
9.38 + self.__fn__ = None
9.39 + self.__args__ = None
9.40 +
9.41 +class type(object):
9.42 + pass
9.43 +
9.44 +class BaseException(object): pass
9.45 +class Exception(BaseException): pass
9.46 +class Warning(object): pass
9.47 +
9.48 +# vim: tabstop=4 expandtab shiftwidth=4
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2 +++ b/lib/__builtins__/dict.py Tue Aug 30 22:09:17 2016 +0200
10.3 @@ -0,0 +1,48 @@
10.4 +#!/usr/bin/env python
10.5 +
10.6 +"""
10.7 +Dictionary objects.
10.8 +
10.9 +Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk>
10.10 +
10.11 +This program is free software; you can redistribute it and/or modify it under
10.12 +the terms of the GNU General Public License as published by the Free Software
10.13 +Foundation; either version 3 of the License, or (at your option) any later
10.14 +version.
10.15 +
10.16 +This program is distributed in the hope that it will be useful, but WITHOUT
10.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
10.19 +details.
10.20 +
10.21 +You should have received a copy of the GNU General Public License along with
10.22 +this program. If not, see <http://www.gnu.org/licenses/>.
10.23 +"""
10.24 +
10.25 +from __builtins__.iterator import listiterator
10.26 +
10.27 +class dict(object):
10.28 + def __init__(self, *args): pass
10.29 + def __setitem__(self, key, value): pass
10.30 + def __delitem__(self, key, value): pass
10.31 +
10.32 + def __getitem__(self, key):
10.33 + # Note usage.
10.34 + KeyError
10.35 +
10.36 + def clear(self): pass
10.37 + def has_key(self): pass
10.38 + def keys(self): pass
10.39 + def values(self): pass
10.40 + def items(self): pass
10.41 + def get(self, key): pass
10.42 + def setdefault(self, key, value): pass
10.43 + def update(self, other): pass
10.44 +
10.45 + def __iter__(self):
10.46 +
10.47 + "Return an iterator."
10.48 +
10.49 + return listiterator(self.keys())
10.50 +
10.51 +# vim: tabstop=4 expandtab shiftwidth=4
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
11.2 +++ b/lib/__builtins__/ellipsis.py Tue Aug 30 22:09:17 2016 +0200
11.3 @@ -0,0 +1,24 @@
11.4 +#!/usr/bin/env python
11.5 +
11.6 +"""
11.7 +Ellipsis object.
11.8 +
11.9 +Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk>
11.10 +
11.11 +This program is free software; you can redistribute it and/or modify it under
11.12 +the terms of the GNU General Public License as published by the Free Software
11.13 +Foundation; either version 3 of the License, or (at your option) any later
11.14 +version.
11.15 +
11.16 +This program is distributed in the hope that it will be useful, but WITHOUT
11.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
11.19 +details.
11.20 +
11.21 +You should have received a copy of the GNU General Public License along with
11.22 +this program. If not, see <http://www.gnu.org/licenses/>.
11.23 +"""
11.24 +
11.25 +class ellipsis: pass
11.26 +
11.27 +# vim: tabstop=4 expandtab shiftwidth=4
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
12.2 +++ b/lib/__builtins__/exception/__init__.py Tue Aug 30 22:09:17 2016 +0200
12.3 @@ -0,0 +1,89 @@
12.4 +#!/usr/bin/env python
12.5 +
12.6 +"""
12.7 +Exception objects.
12.8 +
12.9 +Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk>
12.10 +
12.11 +This program is free software; you can redistribute it and/or modify it under
12.12 +the terms of the GNU General Public License as published by the Free Software
12.13 +Foundation; either version 3 of the License, or (at your option) any later
12.14 +version.
12.15 +
12.16 +This program is distributed in the hope that it will be useful, but WITHOUT
12.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12.19 +details.
12.20 +
12.21 +You should have received a copy of the GNU General Public License along with
12.22 +this program. If not, see <http://www.gnu.org/licenses/>.
12.23 +"""
12.24 +
12.25 +from __builtins__.exception.assertion import (
12.26 + AssertionError
12.27 + )
12.28 +
12.29 +from __builtins__.exception.base import (
12.30 + GeneratorExit,
12.31 + IndexError,
12.32 + KeyError,
12.33 + LookupError,
12.34 + NotImplementedError,
12.35 + ReferenceError,
12.36 + StandardError,
12.37 + StopIteration,
12.38 + TypeError,
12.39 + ValueError
12.40 + )
12.41 +
12.42 +from __builtins__.exception.io import (
12.43 + EOFError,
12.44 + IOError,
12.45 + KeyboardInterrupt
12.46 + )
12.47 +
12.48 +from __builtins__.exception.naming import (
12.49 + AttributeError,
12.50 + ImportError,
12.51 + ImportWarning,
12.52 + NameError,
12.53 + UnboundLocalError
12.54 + )
12.55 +
12.56 +from __builtins__.exception.numeric import (
12.57 + ArithmeticError,
12.58 + FloatingPointError,
12.59 + OverflowError,
12.60 + ZeroDivisionError
12.61 + )
12.62 +
12.63 +from __builtins__.exception.program import (
12.64 + DeprecationWarning,
12.65 + FutureWarning,
12.66 + IndentationError,
12.67 + PendingDeprecationWarning,
12.68 + SyntaxError,
12.69 + SyntaxWarning,
12.70 + TabError,
12.71 + UserWarning
12.72 + )
12.73 +
12.74 +from __builtins__.exception.system import (
12.75 + EnvironmentError,
12.76 + MemoryError,
12.77 + OSError,
12.78 + RuntimeError,
12.79 + RuntimeWarning,
12.80 + SystemError,
12.81 + SystemExit
12.82 + )
12.83 +
12.84 +from __builtins__.exception.unicode import (
12.85 + UnicodeDecodeError,
12.86 + UnicodeEncodeError,
12.87 + UnicodeError,
12.88 + UnicodeTranslateError,
12.89 + UnicodeWarning
12.90 + )
12.91 +
12.92 +# vim: tabstop=4 expandtab shiftwidth=4
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
13.2 +++ b/lib/__builtins__/exception/assertion.py Tue Aug 30 22:09:17 2016 +0200
13.3 @@ -0,0 +1,24 @@
13.4 +#!/usr/bin/env python
13.5 +
13.6 +"""
13.7 +Assertion exception objects.
13.8 +
13.9 +Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk>
13.10 +
13.11 +This program is free software; you can redistribute it and/or modify it under
13.12 +the terms of the GNU General Public License as published by the Free Software
13.13 +Foundation; either version 3 of the License, or (at your option) any later
13.14 +version.
13.15 +
13.16 +This program is distributed in the hope that it will be useful, but WITHOUT
13.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13.19 +details.
13.20 +
13.21 +You should have received a copy of the GNU General Public License along with
13.22 +this program. If not, see <http://www.gnu.org/licenses/>.
13.23 +"""
13.24 +
13.25 +class AssertionError(Exception): pass
13.26 +
13.27 +# vim: tabstop=4 expandtab shiftwidth=4
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
14.2 +++ b/lib/__builtins__/exception/base.py Tue Aug 30 22:09:17 2016 +0200
14.3 @@ -0,0 +1,33 @@
14.4 +#!/usr/bin/env python
14.5 +
14.6 +"""
14.7 +Base exception objects.
14.8 +
14.9 +Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk>
14.10 +
14.11 +This program is free software; you can redistribute it and/or modify it under
14.12 +the terms of the GNU General Public License as published by the Free Software
14.13 +Foundation; either version 3 of the License, or (at your option) any later
14.14 +version.
14.15 +
14.16 +This program is distributed in the hope that it will be useful, but WITHOUT
14.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14.19 +details.
14.20 +
14.21 +You should have received a copy of the GNU General Public License along with
14.22 +this program. If not, see <http://www.gnu.org/licenses/>.
14.23 +"""
14.24 +
14.25 +class GeneratorExit(Exception): pass
14.26 +class IndexError(Exception): pass
14.27 +class KeyError(Exception): pass
14.28 +class LookupError(Exception): pass
14.29 +class NotImplementedError(Exception): pass
14.30 +class ReferenceError(Exception): pass
14.31 +class StandardError(Exception): pass
14.32 +class StopIteration(Exception): pass
14.33 +class TypeError(Exception): pass
14.34 +class ValueError(Exception): pass
14.35 +
14.36 +# vim: tabstop=4 expandtab shiftwidth=4
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
15.2 +++ b/lib/__builtins__/exception/io.py Tue Aug 30 22:09:17 2016 +0200
15.3 @@ -0,0 +1,26 @@
15.4 +#!/usr/bin/env python
15.5 +
15.6 +"""
15.7 +Input/output exception objects.
15.8 +
15.9 +Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk>
15.10 +
15.11 +This program is free software; you can redistribute it and/or modify it under
15.12 +the terms of the GNU General Public License as published by the Free Software
15.13 +Foundation; either version 3 of the License, or (at your option) any later
15.14 +version.
15.15 +
15.16 +This program is distributed in the hope that it will be useful, but WITHOUT
15.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
15.19 +details.
15.20 +
15.21 +You should have received a copy of the GNU General Public License along with
15.22 +this program. If not, see <http://www.gnu.org/licenses/>.
15.23 +"""
15.24 +
15.25 +class EOFError(Exception): pass
15.26 +class IOError(Exception): pass
15.27 +class KeyboardInterrupt(Exception): pass
15.28 +
15.29 +# vim: tabstop=4 expandtab shiftwidth=4
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
16.2 +++ b/lib/__builtins__/exception/naming.py Tue Aug 30 22:09:17 2016 +0200
16.3 @@ -0,0 +1,28 @@
16.4 +#!/usr/bin/env python
16.5 +
16.6 +"""
16.7 +Name-related exception objects.
16.8 +
16.9 +Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk>
16.10 +
16.11 +This program is free software; you can redistribute it and/or modify it under
16.12 +the terms of the GNU General Public License as published by the Free Software
16.13 +Foundation; either version 3 of the License, or (at your option) any later
16.14 +version.
16.15 +
16.16 +This program is distributed in the hope that it will be useful, but WITHOUT
16.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
16.19 +details.
16.20 +
16.21 +You should have received a copy of the GNU General Public License along with
16.22 +this program. If not, see <http://www.gnu.org/licenses/>.
16.23 +"""
16.24 +
16.25 +class AttributeError(Exception): pass
16.26 +class ImportError(Exception): pass
16.27 +class ImportWarning(Warning): pass
16.28 +class NameError(Exception): pass
16.29 +class UnboundLocalError(Exception): pass
16.30 +
16.31 +# vim: tabstop=4 expandtab shiftwidth=4
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
17.2 +++ b/lib/__builtins__/exception/numeric.py Tue Aug 30 22:09:17 2016 +0200
17.3 @@ -0,0 +1,27 @@
17.4 +#!/usr/bin/env python
17.5 +
17.6 +"""
17.7 +Numeric exception objects.
17.8 +
17.9 +Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk>
17.10 +
17.11 +This program is free software; you can redistribute it and/or modify it under
17.12 +the terms of the GNU General Public License as published by the Free Software
17.13 +Foundation; either version 3 of the License, or (at your option) any later
17.14 +version.
17.15 +
17.16 +This program is distributed in the hope that it will be useful, but WITHOUT
17.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
17.19 +details.
17.20 +
17.21 +You should have received a copy of the GNU General Public License along with
17.22 +this program. If not, see <http://www.gnu.org/licenses/>.
17.23 +"""
17.24 +
17.25 +class ArithmeticError(Exception): pass
17.26 +class FloatingPointError(Exception): pass
17.27 +class OverflowError(Exception): pass
17.28 +class ZeroDivisionError(Exception): pass
17.29 +
17.30 +# vim: tabstop=4 expandtab shiftwidth=4
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
18.2 +++ b/lib/__builtins__/exception/program.py Tue Aug 30 22:09:17 2016 +0200
18.3 @@ -0,0 +1,31 @@
18.4 +#!/usr/bin/env python
18.5 +
18.6 +"""
18.7 +Program exception objects.
18.8 +
18.9 +Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk>
18.10 +
18.11 +This program is free software; you can redistribute it and/or modify it under
18.12 +the terms of the GNU General Public License as published by the Free Software
18.13 +Foundation; either version 3 of the License, or (at your option) any later
18.14 +version.
18.15 +
18.16 +This program is distributed in the hope that it will be useful, but WITHOUT
18.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
18.19 +details.
18.20 +
18.21 +You should have received a copy of the GNU General Public License along with
18.22 +this program. If not, see <http://www.gnu.org/licenses/>.
18.23 +"""
18.24 +
18.25 +class DeprecationWarning(Exception): pass
18.26 +class FutureWarning(Warning): pass
18.27 +class IndentationError(Exception): pass
18.28 +class PendingDeprecationWarning(Warning): pass
18.29 +class SyntaxError(Exception): pass
18.30 +class SyntaxWarning(Warning): pass
18.31 +class TabError(Exception): pass
18.32 +class UserWarning(Warning): pass
18.33 +
18.34 +# vim: tabstop=4 expandtab shiftwidth=4
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
19.2 +++ b/lib/__builtins__/exception/system.py Tue Aug 30 22:09:17 2016 +0200
19.3 @@ -0,0 +1,30 @@
19.4 +#!/usr/bin/env python
19.5 +
19.6 +"""
19.7 +System exception objects.
19.8 +
19.9 +Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk>
19.10 +
19.11 +This program is free software; you can redistribute it and/or modify it under
19.12 +the terms of the GNU General Public License as published by the Free Software
19.13 +Foundation; either version 3 of the License, or (at your option) any later
19.14 +version.
19.15 +
19.16 +This program is distributed in the hope that it will be useful, but WITHOUT
19.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
19.19 +details.
19.20 +
19.21 +You should have received a copy of the GNU General Public License along with
19.22 +this program. If not, see <http://www.gnu.org/licenses/>.
19.23 +"""
19.24 +
19.25 +class EnvironmentError(Exception): pass
19.26 +class MemoryError(Exception): pass
19.27 +class OSError(Exception): pass
19.28 +class RuntimeError(Exception): pass
19.29 +class RuntimeWarning(Warning): pass
19.30 +class SystemError(Exception): pass
19.31 +class SystemExit(Exception): pass
19.32 +
19.33 +# vim: tabstop=4 expandtab shiftwidth=4
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
20.2 +++ b/lib/__builtins__/exception/unicode.py Tue Aug 30 22:09:17 2016 +0200
20.3 @@ -0,0 +1,28 @@
20.4 +#!/usr/bin/env python
20.5 +
20.6 +"""
20.7 +Unicode exception objects.
20.8 +
20.9 +Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk>
20.10 +
20.11 +This program is free software; you can redistribute it and/or modify it under
20.12 +the terms of the GNU General Public License as published by the Free Software
20.13 +Foundation; either version 3 of the License, or (at your option) any later
20.14 +version.
20.15 +
20.16 +This program is distributed in the hope that it will be useful, but WITHOUT
20.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
20.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
20.19 +details.
20.20 +
20.21 +You should have received a copy of the GNU General Public License along with
20.22 +this program. If not, see <http://www.gnu.org/licenses/>.
20.23 +"""
20.24 +
20.25 +class UnicodeDecodeError(Exception): pass
20.26 +class UnicodeEncodeError(Exception): pass
20.27 +class UnicodeError(Exception): pass
20.28 +class UnicodeTranslateError(Exception): pass
20.29 +class UnicodeWarning(Warning): pass
20.30 +
20.31 +# vim: tabstop=4 expandtab shiftwidth=4
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
21.2 +++ b/lib/__builtins__/file.py Tue Aug 30 22:09:17 2016 +0200
21.3 @@ -0,0 +1,29 @@
21.4 +#!/usr/bin/env python
21.5 +
21.6 +"""
21.7 +File objects.
21.8 +
21.9 +Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk>
21.10 +
21.11 +This program is free software; you can redistribute it and/or modify it under
21.12 +the terms of the GNU General Public License as published by the Free Software
21.13 +Foundation; either version 3 of the License, or (at your option) any later
21.14 +version.
21.15 +
21.16 +This program is distributed in the hope that it will be useful, but WITHOUT
21.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
21.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
21.19 +details.
21.20 +
21.21 +You should have received a copy of the GNU General Public License along with
21.22 +this program. If not, see <http://www.gnu.org/licenses/>.
21.23 +"""
21.24 +
21.25 +class file(object):
21.26 + def read(self, n=None): pass
21.27 + def write(self, s): pass
21.28 + def close(self): pass
21.29 + def readline(self, size=None): pass
21.30 + def readlines(self, size=None): pass
21.31 +
21.32 +# vim: tabstop=4 expandtab shiftwidth=4
22.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
22.2 +++ b/lib/__builtins__/float.py Tue Aug 30 22:09:17 2016 +0200
22.3 @@ -0,0 +1,54 @@
22.4 +#!/usr/bin/env python
22.5 +
22.6 +"""
22.7 +Floating point objects.
22.8 +
22.9 +Copyright (C) 2015, 2016 Paul Boddie <paul@boddie.org.uk>
22.10 +
22.11 +This program is free software; you can redistribute it and/or modify it under
22.12 +the terms of the GNU General Public License as published by the Free Software
22.13 +Foundation; either version 3 of the License, or (at your option) any later
22.14 +version.
22.15 +
22.16 +This program is distributed in the hope that it will be useful, but WITHOUT
22.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
22.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
22.19 +details.
22.20 +
22.21 +You should have received a copy of the GNU General Public License along with
22.22 +this program. If not, see <http://www.gnu.org/licenses/>.
22.23 +"""
22.24 +
22.25 +class float(object):
22.26 + def __init__(self, number_or_string=None):
22.27 + # Note member.
22.28 + self.data = 0
22.29 +
22.30 + def __iadd__(self, other): pass
22.31 + def __isub__(self, other): pass
22.32 + def __add__(self, other): pass
22.33 + def __radd__(self, other): pass
22.34 + def __sub__(self, other): pass
22.35 + def __rsub__(self, other): pass
22.36 + def __mul__(self, other): pass
22.37 + def __rmul__(self, other): pass
22.38 + def __div__(self, other): pass
22.39 + def __rdiv__(self, other): pass
22.40 + def __floordiv__(self, other): pass
22.41 + def __rfloordiv__(self, other): pass
22.42 + def __mod__(self, other): pass
22.43 + def __rmod__(self, other): pass
22.44 + def __pow__(self, other): pass
22.45 + def __rpow__(self, other): pass
22.46 + def __lt__(self, other): pass
22.47 + def __gt__(self, other): pass
22.48 + def __le__(self, other): pass
22.49 + def __ge__(self, other): pass
22.50 + def __eq__(self, other): pass
22.51 + def __ne__(self, other): pass
22.52 + def __neg__(self): pass
22.53 + def __pos__(self): pass
22.54 + def __str__(self): pass
22.55 + def __bool__(self): pass
22.56 +
22.57 +# vim: tabstop=4 expandtab shiftwidth=4
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
23.2 +++ b/lib/__builtins__/identity.py Tue Aug 30 22:09:17 2016 +0200
23.3 @@ -0,0 +1,50 @@
23.4 +#!/usr/bin/env python
23.5 +
23.6 +"""
23.7 +Identity-related functions.
23.8 +
23.9 +Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk>
23.10 +
23.11 +This program is free software; you can redistribute it and/or modify it under
23.12 +the terms of the GNU General Public License as published by the Free Software
23.13 +Foundation; either version 3 of the License, or (at your option) any later
23.14 +version.
23.15 +
23.16 +This program is distributed in the hope that it will be useful, but WITHOUT
23.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
23.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
23.19 +details.
23.20 +
23.21 +You should have received a copy of the GNU General Public License along with
23.22 +this program. If not, see <http://www.gnu.org/licenses/>.
23.23 +"""
23.24 +
23.25 +from native import _isinstance
23.26 +
23.27 +def callable(obj): pass
23.28 +def help(*args): pass
23.29 +def id(obj): pass
23.30 +
23.31 +def isinstance(obj, cls_or_tuple):
23.32 +
23.33 + """
23.34 + Return whether 'obj' is an instance of 'cls_or_tuple', where the latter is
23.35 + either a class or a tuple of classes.
23.36 + """
23.37 +
23.38 + # NOTE: CPython insists on tuples, but any sequence might be considered
23.39 + # NOTE: acceptable.
23.40 +
23.41 + if _isinstance(cls_or_tuple, tuple):
23.42 + for cls in cls_or_tuple:
23.43 + if obj.__class__ is cls or _isinstance(obj, cls):
23.44 + return True
23.45 + return False
23.46 + else:
23.47 + return obj.__class__ is cls_or_tuple or _isinstance(obj, cls_or_tuple)
23.48 +
23.49 +def issubclass(obj, cls_or_tuple): pass
23.50 +
23.51 +def repr(obj): pass
23.52 +
23.53 +# vim: tabstop=4 expandtab shiftwidth=4
24.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
24.2 +++ b/lib/__builtins__/int.py Tue Aug 30 22:09:17 2016 +0200
24.3 @@ -0,0 +1,158 @@
24.4 +#!/usr/bin/env python
24.5 +
24.6 +"""
24.7 +Integer objects.
24.8 +
24.9 +Copyright (C) 2015, 2016 Paul Boddie <paul@boddie.org.uk>
24.10 +
24.11 +This program is free software; you can redistribute it and/or modify it under
24.12 +the terms of the GNU General Public License as published by the Free Software
24.13 +Foundation; either version 3 of the License, or (at your option) any later
24.14 +version.
24.15 +
24.16 +This program is distributed in the hope that it will be useful, but WITHOUT
24.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
24.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
24.19 +details.
24.20 +
24.21 +You should have received a copy of the GNU General Public License along with
24.22 +this program. If not, see <http://www.gnu.org/licenses/>.
24.23 +"""
24.24 +
24.25 +import native
24.26 +
24.27 +class int(object):
24.28 + def __init__(self, number_or_string=None):
24.29 + # Note member.
24.30 + self.data = 0
24.31 +
24.32 + def __iadd__(self, other):
24.33 + "Return a new int for the operation."
24.34 + return _binary_op(self, other, native._int_add)
24.35 +
24.36 + def __isub__(self, other):
24.37 + "Return a new int for the operation."
24.38 + return _binary_op(self, other, native._int_sub)
24.39 +
24.40 + def __imul__(self, other):
24.41 + "Return a new int for the operation."
24.42 + return _binary_op(self, other, native._int_mul)
24.43 +
24.44 + def __idiv__(self, other):
24.45 + "Return a new int for the operation."
24.46 + return _binary_op(self, other, native._int_div)
24.47 +
24.48 + def __imod__(self, other):
24.49 + "Return a new int for the operation."
24.50 + return _binary_op(self, other, native._int_mod)
24.51 +
24.52 + def __ipow__(self, other):
24.53 + "Return a new int for the operation."
24.54 + return _binary_op(self, other, native._int_pow)
24.55 +
24.56 + def __iand__(self, other):
24.57 + "Return a new int for the operation."
24.58 + return _binary_op(self, other, native._int_and)
24.59 +
24.60 + def __ior__(self, other):
24.61 + "Return a new int for the operation."
24.62 + return _binary_op(self, other, native._int_or)
24.63 +
24.64 + def __ixor__(self, other):
24.65 + "Return a new int for the operation."
24.66 + return _binary_op(self, other, native._int_xor)
24.67 +
24.68 + __add__ = __radd__ = __iadd__
24.69 + __sub__ = __isub__
24.70 +
24.71 + def __rsub__(self, other):
24.72 + "Return a new int for the operation."
24.73 + return _binary_op(self, other, native._int_rsub)
24.74 +
24.75 + __mul__ = __rmul__ = __imul__
24.76 + __div__ = __idiv__
24.77 +
24.78 + def __rdiv__(self, other):
24.79 + "Return a new int for the operation."
24.80 + return _binary_op(self, other, native._int_rdiv)
24.81 +
24.82 + def __floordiv__(self, other): pass
24.83 + def __rfloordiv__(self, other): pass
24.84 + def __ifloordiv__(self, other): pass
24.85 +
24.86 + __mod__ = __imod__
24.87 +
24.88 + def __rmod__(self, other):
24.89 + "Return a new int for the operation."
24.90 + return _binary_op(self, other, native._int_rmod)
24.91 +
24.92 + __pow__ = __ipow__
24.93 +
24.94 + def __rpow__(self, other):
24.95 + "Return a new int for the operation."
24.96 + return _binary_op(self, other, native._int_rpow)
24.97 +
24.98 + __and__ = __rand__ = __iand__
24.99 + __or__ = __ror__ = __ior__
24.100 + __xor__ = __rxor__ = __ixor__
24.101 +
24.102 + def __lt__(self, other):
24.103 + "Return a new boolean for the comparison."
24.104 + return _binary_op(self, other, native._int_lt)
24.105 +
24.106 + def __gt__(self, other):
24.107 + "Return a new boolean for the comparison."
24.108 + return _binary_op(self, other, native._int_gt)
24.109 +
24.110 + def __le__(self, other):
24.111 + "Return a new boolean for the comparison."
24.112 + return _negate(self.__gt__(other))
24.113 +
24.114 + def __ge__(self, other):
24.115 + "Return a new boolean for the comparison."
24.116 + return _negate(self.__lt__(other))
24.117 +
24.118 + def __eq__(self, other):
24.119 + "Return a new boolean for the comparison."
24.120 + return _binary_op(self, other, native._int_eq)
24.121 +
24.122 + def __ne__(self, other):
24.123 + "Return a new boolean for the comparison."
24.124 + return _negate(self.__eq__(other))
24.125 +
24.126 + def __invert__(self): pass
24.127 + def __neg__(self): pass
24.128 + def __pos__(self): pass
24.129 + def __str__(self): pass
24.130 + def __lshift__(self): pass
24.131 + def __rlshift__(self): pass
24.132 + def __rshift__(self): pass
24.133 + def __rrshift__(self): pass
24.134 + def __ilshift__(self): pass
24.135 + def __irshift__(self): pass
24.136 +
24.137 + def __bool__(self):
24.138 + "Return whether this int is non-zero."
24.139 + return _negate(native._int_eq(self, 0))
24.140 +
24.141 +# Utility functions.
24.142 +
24.143 +def _binary_op(self, other, op):
24.144 +
24.145 + "Test the type of 'other' and perform 'op'."
24.146 +
24.147 + if self.__class__ is other.__class__:
24.148 + return op(self, other)
24.149 + else:
24.150 + return NotImplemented
24.151 +
24.152 +def _negate(result):
24.153 +
24.154 + "Negate any valid logical value."
24.155 +
24.156 + if result is NotImplemented:
24.157 + return result
24.158 + else:
24.159 + return not result
24.160 +
24.161 +# vim: tabstop=4 expandtab shiftwidth=4
25.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
25.2 +++ b/lib/__builtins__/io.py Tue Aug 30 22:09:17 2016 +0200
25.3 @@ -0,0 +1,26 @@
25.4 +#!/usr/bin/env python
25.5 +
25.6 +"""
25.7 +Input/output-related functions.
25.8 +
25.9 +Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk>
25.10 +
25.11 +This program is free software; you can redistribute it and/or modify it under
25.12 +the terms of the GNU General Public License as published by the Free Software
25.13 +Foundation; either version 3 of the License, or (at your option) any later
25.14 +version.
25.15 +
25.16 +This program is distributed in the hope that it will be useful, but WITHOUT
25.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
25.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
25.19 +details.
25.20 +
25.21 +You should have received a copy of the GNU General Public License along with
25.22 +this program. If not, see <http://www.gnu.org/licenses/>.
25.23 +"""
25.24 +
25.25 +def eval(source, globals=None, locals=None): pass
25.26 +def open(name, mode=None, buffering=None): pass
25.27 +def raw_input(prompt=None): pass
25.28 +
25.29 +# vim: tabstop=4 expandtab shiftwidth=4
26.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
26.2 +++ b/lib/__builtins__/iterable.py Tue Aug 30 22:09:17 2016 +0200
26.3 @@ -0,0 +1,74 @@
26.4 +#!/usr/bin/env python
26.5 +
26.6 +"""
26.7 +Iteration-related functions.
26.8 +
26.9 +Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk>
26.10 +
26.11 +This program is free software; you can redistribute it and/or modify it under
26.12 +the terms of the GNU General Public License as published by the Free Software
26.13 +Foundation; either version 3 of the License, or (at your option) any later
26.14 +version.
26.15 +
26.16 +This program is distributed in the hope that it will be useful, but WITHOUT
26.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
26.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
26.19 +details.
26.20 +
26.21 +You should have received a copy of the GNU General Public License along with
26.22 +this program. If not, see <http://www.gnu.org/licenses/>.
26.23 +"""
26.24 +
26.25 +from __builtins__.span import xrange
26.26 +
26.27 +def all(iterable): pass
26.28 +def any(iterable): pass
26.29 +def enumerate(iterable): pass
26.30 +def filter(function, sequence): pass
26.31 +def iter(collection):
26.32 +
26.33 + "Implementation of iter without callable plus sentinel support."
26.34 +
26.35 + return collection.__iter__()
26.36 +
26.37 +def len(obj):
26.38 +
26.39 + "Implementation of len."
26.40 +
26.41 + return obj.__len__()
26.42 +
26.43 +def map(function, *args): pass
26.44 +
26.45 +def max(*args):
26.46 +
26.47 + "Implementation of max."
26.48 +
26.49 + highest = args[0]
26.50 + for arg in args[1:]:
26.51 + if arg > highest:
26.52 + highest = arg
26.53 + return highest
26.54 +
26.55 +def min(*args):
26.56 +
26.57 + "Implementation of min."
26.58 +
26.59 + lowest = args[0]
26.60 + for arg in args[1:]:
26.61 + if arg > lowest:
26.62 + lowest = arg
26.63 + return lowest
26.64 +
26.65 +def range(start_or_end, end=None, step=1):
26.66 +
26.67 + "Implementation of range."
26.68 +
26.69 + return list(xrange(start_or_end, end, step))
26.70 +
26.71 +def reduce(function, sequence, initial=None): pass
26.72 +def reversed(sequence): pass
26.73 +def sorted(iterable, cmp=None, key=None, reverse=False): pass
26.74 +def sum(sequence, start=0): pass
26.75 +def zip(*args): pass
26.76 +
26.77 +# vim: tabstop=4 expandtab shiftwidth=4
27.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
27.2 +++ b/lib/__builtins__/iterator.py Tue Aug 30 22:09:17 2016 +0200
27.3 @@ -0,0 +1,44 @@
27.4 +#!/usr/bin/env python
27.5 +
27.6 +"""
27.7 +Iterator objects.
27.8 +
27.9 +Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk>
27.10 +
27.11 +This program is free software; you can redistribute it and/or modify it under
27.12 +the terms of the GNU General Public License as published by the Free Software
27.13 +Foundation; either version 3 of the License, or (at your option) any later
27.14 +version.
27.15 +
27.16 +This program is distributed in the hope that it will be useful, but WITHOUT
27.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
27.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
27.19 +details.
27.20 +
27.21 +You should have received a copy of the GNU General Public License along with
27.22 +this program. If not, see <http://www.gnu.org/licenses/>.
27.23 +"""
27.24 +
27.25 +class listiterator(object):
27.26 +
27.27 + "Implementation of listiterator."
27.28 +
27.29 + def __init__(self, l):
27.30 +
27.31 + "Initialise with the given list 'l'."
27.32 +
27.33 + self.l = l
27.34 + self.i = 0
27.35 +
27.36 + def next(self):
27.37 +
27.38 + "Return the next item."
27.39 +
27.40 + try:
27.41 + value = self.l[self.i]
27.42 + self.i += 1
27.43 + return value
27.44 + except IndexError:
27.45 + raise StopIteration()
27.46 +
27.47 +# vim: tabstop=4 expandtab shiftwidth=4
28.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
28.2 +++ b/lib/__builtins__/list.py Tue Aug 30 22:09:17 2016 +0200
28.3 @@ -0,0 +1,91 @@
28.4 +#!/usr/bin/env python
28.5 +
28.6 +"""
28.7 +List objects.
28.8 +
28.9 +Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk>
28.10 +
28.11 +This program is free software; you can redistribute it and/or modify it under
28.12 +the terms of the GNU General Public License as published by the Free Software
28.13 +Foundation; either version 3 of the License, or (at your option) any later
28.14 +version.
28.15 +
28.16 +This program is distributed in the hope that it will be useful, but WITHOUT
28.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
28.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
28.19 +details.
28.20 +
28.21 +You should have received a copy of the GNU General Public License along with
28.22 +this program. If not, see <http://www.gnu.org/licenses/>.
28.23 +"""
28.24 +
28.25 +from __builtins__.sequence import *
28.26 +
28.27 +class list(object):
28.28 +
28.29 + "Implementation of list."
28.30 +
28.31 + def __init__(self, args=None):
28.32 +
28.33 + "Initialise the list."
28.34 +
28.35 + if args is not None:
28.36 + self.extend(args)
28.37 +
28.38 + def __new__(self):
28.39 + # Reserve space for a fragment reference.
28.40 + self._elements = None
28.41 +
28.42 + def __getitem__(self, index):
28.43 +
28.44 + "Return the item or slice specified by 'index'."
28.45 +
28.46 + return _getitem(self, index)
28.47 +
28.48 + def __contains__(self, value): pass
28.49 + def __setitem__(self, index, value): pass
28.50 + def __delitem__(self, index): pass
28.51 +
28.52 + def __getslice__(self, start, end=None):
28.53 +
28.54 + "Return a slice starting from 'start', with the optional 'end'."
28.55 +
28.56 + return _getslice(self, start, end)
28.57 +
28.58 + def __setslice__(self, start, end, slice): pass
28.59 + def __delslice__(self, start, end): pass
28.60 + def append(self, value): pass
28.61 + def insert(self, i, value): pass
28.62 +
28.63 + def extend(self, iterable):
28.64 +
28.65 + "Extend the list with the contents of 'iterable'."
28.66 +
28.67 + for i in iterable:
28.68 + self.append(i)
28.69 +
28.70 + def pop(self): pass
28.71 + def reverse(self): pass
28.72 + def sort(self, cmp=None, key=None, reverse=0): pass
28.73 + def __len__(self): pass
28.74 + def __add__(self, other): pass
28.75 + def __iadd__(self, other): pass
28.76 + def __str__(self): pass
28.77 +
28.78 + def __bool__(self):
28.79 +
28.80 + "Lists are true if non-empty."
28.81 +
28.82 + return self.__len__() != 0
28.83 +
28.84 + def __iter__(self):
28.85 +
28.86 + "Return an iterator."
28.87 +
28.88 + return listiterator(self)
28.89 +
28.90 + # Special implementation methods.
28.91 +
28.92 + def __get_single_item__(self, index): pass
28.93 +
28.94 +# vim: tabstop=4 expandtab shiftwidth=4
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
29.2 +++ b/lib/__builtins__/long.py Tue Aug 30 22:09:17 2016 +0200
29.3 @@ -0,0 +1,53 @@
29.4 +#!/usr/bin/env python
29.5 +
29.6 +"""
29.7 +Long objects.
29.8 +
29.9 +Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk>
29.10 +
29.11 +This program is free software; you can redistribute it and/or modify it under
29.12 +the terms of the GNU General Public License as published by the Free Software
29.13 +Foundation; either version 3 of the License, or (at your option) any later
29.14 +version.
29.15 +
29.16 +This program is distributed in the hope that it will be useful, but WITHOUT
29.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
29.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
29.19 +details.
29.20 +
29.21 +You should have received a copy of the GNU General Public License along with
29.22 +this program. If not, see <http://www.gnu.org/licenses/>.
29.23 +"""
29.24 +
29.25 +class long(object):
29.26 + def __init__(self, number_or_string=None): pass
29.27 + def __iadd__(self, other): pass
29.28 + def __isub__(self, other): pass
29.29 + def __add__(self, other): pass
29.30 + def __radd__(self, other): pass
29.31 + def __sub__(self, other): pass
29.32 + def __rsub__(self, other): pass
29.33 + def __mul__(self, other): pass
29.34 + def __rmul__(self, other): pass
29.35 + def __div__(self, other): pass
29.36 + def __rdiv__(self, other): pass
29.37 + def __floordiv__(self, other): pass
29.38 + def __rfloordiv__(self, other): pass
29.39 + def __and__(self, other): pass
29.40 + def __rand__(self, other): pass
29.41 + def __or__(self, other): pass
29.42 + def __ror__(self, other): pass
29.43 + def __xor__(self, other): pass
29.44 + def __rxor__(self, other): pass
29.45 + def __lt__(self, other): pass
29.46 + def __gt__(self, other): pass
29.47 + def __le__(self, other): pass
29.48 + def __ge__(self, other): pass
29.49 + def __eq__(self, other): pass
29.50 + def __ne__(self, other): pass
29.51 + def __neg__(self): pass
29.52 + def __pos__(self): pass
29.53 + def __str__(self): pass
29.54 + def __bool__(self): pass
29.55 +
29.56 +# vim: tabstop=4 expandtab shiftwidth=4
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
30.2 +++ b/lib/__builtins__/namespace.py Tue Aug 30 22:09:17 2016 +0200
30.3 @@ -0,0 +1,27 @@
30.4 +#!/usr/bin/env python
30.5 +
30.6 +"""
30.7 +Namespace-related functions.
30.8 +
30.9 +Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk>
30.10 +
30.11 +This program is free software; you can redistribute it and/or modify it under
30.12 +the terms of the GNU General Public License as published by the Free Software
30.13 +Foundation; either version 3 of the License, or (at your option) any later
30.14 +version.
30.15 +
30.16 +This program is distributed in the hope that it will be useful, but WITHOUT
30.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
30.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
30.19 +details.
30.20 +
30.21 +You should have received a copy of the GNU General Public License along with
30.22 +this program. If not, see <http://www.gnu.org/licenses/>.
30.23 +"""
30.24 +
30.25 +def dir(obj=None): pass
30.26 +def globals(): pass
30.27 +def locals(): pass
30.28 +def vars(obj=None): pass
30.29 +
30.30 +# vim: tabstop=4 expandtab shiftwidth=4
31.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
31.2 +++ b/lib/__builtins__/none.py Tue Aug 30 22:09:17 2016 +0200
31.3 @@ -0,0 +1,27 @@
31.4 +#!/usr/bin/env python
31.5 +
31.6 +"""
31.7 +None objects.
31.8 +
31.9 +Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk>
31.10 +
31.11 +This program is free software; you can redistribute it and/or modify it under
31.12 +the terms of the GNU General Public License as published by the Free Software
31.13 +Foundation; either version 3 of the License, or (at your option) any later
31.14 +version.
31.15 +
31.16 +This program is distributed in the hope that it will be useful, but WITHOUT
31.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
31.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
31.19 +details.
31.20 +
31.21 +You should have received a copy of the GNU General Public License along with
31.22 +this program. If not, see <http://www.gnu.org/licenses/>.
31.23 +"""
31.24 +
31.25 +class NoneType:
31.26 + def __bool__(self):
31.27 + "None is always false."
31.28 + return False
31.29 +
31.30 +# vim: tabstop=4 expandtab shiftwidth=4
32.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
32.2 +++ b/lib/__builtins__/notimplemented.py Tue Aug 30 22:09:17 2016 +0200
32.3 @@ -0,0 +1,24 @@
32.4 +#!/usr/bin/env python
32.5 +
32.6 +"""
32.7 +Not implemented object.
32.8 +
32.9 +Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk>
32.10 +
32.11 +This program is free software; you can redistribute it and/or modify it under
32.12 +the terms of the GNU General Public License as published by the Free Software
32.13 +Foundation; either version 3 of the License, or (at your option) any later
32.14 +version.
32.15 +
32.16 +This program is distributed in the hope that it will be useful, but WITHOUT
32.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
32.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
32.19 +details.
32.20 +
32.21 +You should have received a copy of the GNU General Public License along with
32.22 +this program. If not, see <http://www.gnu.org/licenses/>.
32.23 +"""
32.24 +
32.25 +class NotImplementedType: pass
32.26 +
32.27 +# vim: tabstop=4 expandtab shiftwidth=4
33.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
33.2 +++ b/lib/__builtins__/numeric.py Tue Aug 30 22:09:17 2016 +0200
33.3 @@ -0,0 +1,27 @@
33.4 +#!/usr/bin/env python
33.5 +
33.6 +"""
33.7 +Numeric functions.
33.8 +
33.9 +Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk>
33.10 +
33.11 +This program is free software; you can redistribute it and/or modify it under
33.12 +the terms of the GNU General Public License as published by the Free Software
33.13 +Foundation; either version 3 of the License, or (at your option) any later
33.14 +version.
33.15 +
33.16 +This program is distributed in the hope that it will be useful, but WITHOUT
33.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
33.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
33.19 +details.
33.20 +
33.21 +You should have received a copy of the GNU General Public License along with
33.22 +this program. If not, see <http://www.gnu.org/licenses/>.
33.23 +"""
33.24 +
33.25 +def abs(number): pass
33.26 +def divmod(x, y): pass
33.27 +def pow(x, y, z=None): pass
33.28 +def round(number, ndigits=None): pass
33.29 +
33.30 +# vim: tabstop=4 expandtab shiftwidth=4
34.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
34.2 +++ b/lib/__builtins__/operator.py Tue Aug 30 22:09:17 2016 +0200
34.3 @@ -0,0 +1,40 @@
34.4 +#!/usr/bin/env python
34.5 +
34.6 +"""
34.7 +Operator-related functions.
34.8 +
34.9 +Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk>
34.10 +
34.11 +This program is free software; you can redistribute it and/or modify it under
34.12 +the terms of the GNU General Public License as published by the Free Software
34.13 +Foundation; either version 3 of the License, or (at your option) any later
34.14 +version.
34.15 +
34.16 +This program is distributed in the hope that it will be useful, but WITHOUT
34.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
34.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
34.19 +details.
34.20 +
34.21 +You should have received a copy of the GNU General Public License along with
34.22 +this program. If not, see <http://www.gnu.org/licenses/>.
34.23 +"""
34.24 +
34.25 +def _binary_op(self, other, op):
34.26 +
34.27 + "Test the type of 'other' and perform 'op'."
34.28 +
34.29 + if self.__class__ is other.__class__:
34.30 + return op(self, other)
34.31 + else:
34.32 + return NotImplemented
34.33 +
34.34 +def _negate(result):
34.35 +
34.36 + "Negate any valid logical value."
34.37 +
34.38 + if result is NotImplemented:
34.39 + return result
34.40 + else:
34.41 + return not result
34.42 +
34.43 +# vim: tabstop=4 expandtab shiftwidth=4
35.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
35.2 +++ b/lib/__builtins__/property.py Tue Aug 30 22:09:17 2016 +0200
35.3 @@ -0,0 +1,25 @@
35.4 +#!/usr/bin/env python
35.5 +
35.6 +"""
35.7 +Property objects.
35.8 +
35.9 +Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk>
35.10 +
35.11 +This program is free software; you can redistribute it and/or modify it under
35.12 +the terms of the GNU General Public License as published by the Free Software
35.13 +Foundation; either version 3 of the License, or (at your option) any later
35.14 +version.
35.15 +
35.16 +This program is distributed in the hope that it will be useful, but WITHOUT
35.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
35.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
35.19 +details.
35.20 +
35.21 +You should have received a copy of the GNU General Public License along with
35.22 +this program. If not, see <http://www.gnu.org/licenses/>.
35.23 +"""
35.24 +
35.25 +class property(object):
35.26 + def __init__(fget=None, fset=None, fdel=None, doc=None): pass
35.27 +
35.28 +# vim: tabstop=4 expandtab shiftwidth=4
36.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
36.2 +++ b/lib/__builtins__/sequence.py Tue Aug 30 22:09:17 2016 +0200
36.3 @@ -0,0 +1,96 @@
36.4 +#!/usr/bin/env python
36.5 +
36.6 +"""
36.7 +Sequence operations.
36.8 +
36.9 +Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk>
36.10 +
36.11 +This program is free software; you can redistribute it and/or modify it under
36.12 +the terms of the GNU General Public License as published by the Free Software
36.13 +Foundation; either version 3 of the License, or (at your option) any later
36.14 +version.
36.15 +
36.16 +This program is distributed in the hope that it will be useful, but WITHOUT
36.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
36.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
36.19 +details.
36.20 +
36.21 +You should have received a copy of the GNU General Public License along with
36.22 +this program. If not, see <http://www.gnu.org/licenses/>.
36.23 +"""
36.24 +
36.25 +from native import _isinstance
36.26 +
36.27 +def _getitem(seq, index):
36.28 +
36.29 + "Return the item or slice specified by 'index'."
36.30 +
36.31 + if _isinstance(index, int):
36.32 + index = _normalise_index(index, seq.__len__())
36.33 + return seq.__get_single_item__(index)
36.34 + elif _isinstance(index, slice):
36.35 + return seq.__getslice__(index.start, index.end)
36.36 + else:
36.37 + raise TypeError
36.38 +
36.39 +def _getslice(seq, start, end=None):
36.40 +
36.41 + "Return a slice starting from 'start', with the optional 'end'."
36.42 +
36.43 + length = seq.__len__()
36.44 +
36.45 + if start is None:
36.46 + start = 0
36.47 + else:
36.48 + start = _normalise_index(start, length)
36.49 +
36.50 + if end is None:
36.51 + end = length
36.52 + else:
36.53 + end = _normalise_index(end, length)
36.54 +
36.55 + result = []
36.56 + while start < end:
36.57 + result.append(seq.__get_single_item__(start))
36.58 + start += 1
36.59 + return result
36.60 +
36.61 +def _get_absolute_index(index, length):
36.62 +
36.63 + """
36.64 + Return the absolute index for 'index' given a collection having the
36.65 + specified 'length'.
36.66 + """
36.67 +
36.68 + if index < 0:
36.69 + return length + index
36.70 + else:
36.71 + return index
36.72 +
36.73 +def _normalise_index(index, length):
36.74 +
36.75 + "Normalise 'index' for a collection having the specified 'length'."
36.76 +
36.77 + return _min(length, _max(0, _get_absolute_index(index, length)))
36.78 +
36.79 +def _max(x, y):
36.80 +
36.81 + "Return the maximum of 'x' and 'y'."
36.82 +
36.83 + if x >= y:
36.84 + return x
36.85 + else:
36.86 + return y
36.87 +
36.88 +def _min(x, y):
36.89 +
36.90 + "Return the minimum of 'x' and 'y'."
36.91 +
36.92 + if x <= y:
36.93 + return x
36.94 + else:
36.95 + return y
36.96 +
36.97 +def _tuple(l): pass
36.98 +
36.99 +# vim: tabstop=4 expandtab shiftwidth=4
37.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
37.2 +++ b/lib/__builtins__/set.py Tue Aug 30 22:09:17 2016 +0200
37.3 @@ -0,0 +1,51 @@
37.4 +#!/usr/bin/env python
37.5 +
37.6 +"""
37.7 +Set objects.
37.8 +
37.9 +Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk>
37.10 +
37.11 +This program is free software; you can redistribute it and/or modify it under
37.12 +the terms of the GNU General Public License as published by the Free Software
37.13 +Foundation; either version 3 of the License, or (at your option) any later
37.14 +version.
37.15 +
37.16 +This program is distributed in the hope that it will be useful, but WITHOUT
37.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
37.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
37.19 +details.
37.20 +
37.21 +You should have received a copy of the GNU General Public License along with
37.22 +this program. If not, see <http://www.gnu.org/licenses/>.
37.23 +"""
37.24 +
37.25 +class frozenset(object):
37.26 + def __init__(self, iterable): pass
37.27 +
37.28 +class set(object):
37.29 + def __init__(self, iterable): pass
37.30 + def add(self, item): pass
37.31 + def clear(self): pass
37.32 + def copy(self): pass
37.33 + def difference(self, other): pass
37.34 + def difference_update(self, other): pass
37.35 + def discard(self, item): pass
37.36 + def intersection(self, other): pass
37.37 + def intersection_update(self, other): pass
37.38 + def issubset(self, other): pass
37.39 + def issuperset(self, other): pass
37.40 +
37.41 + def __iter__(self):
37.42 +
37.43 + "Return an iterator."
37.44 +
37.45 + return listiterator(list(self))
37.46 +
37.47 + def pop(self): pass
37.48 + def remove(self, item): pass
37.49 + def symmetric_difference(self, other): pass
37.50 + def symmetric_difference_update(self, other): pass
37.51 + def union(self, other): pass
37.52 + def update(self, other): pass
37.53 +
37.54 +# vim: tabstop=4 expandtab shiftwidth=4
38.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
38.2 +++ b/lib/__builtins__/span.py Tue Aug 30 22:09:17 2016 +0200
38.3 @@ -0,0 +1,71 @@
38.4 +#!/usr/bin/env python
38.5 +
38.6 +"""
38.7 +Span-related objects.
38.8 +
38.9 +Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk>
38.10 +
38.11 +This program is free software; you can redistribute it and/or modify it under
38.12 +the terms of the GNU General Public License as published by the Free Software
38.13 +Foundation; either version 3 of the License, or (at your option) any later
38.14 +version.
38.15 +
38.16 +This program is distributed in the hope that it will be useful, but WITHOUT
38.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
38.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
38.19 +details.
38.20 +
38.21 +You should have received a copy of the GNU General Public License along with
38.22 +this program. If not, see <http://www.gnu.org/licenses/>.
38.23 +"""
38.24 +
38.25 +class xrange(object):
38.26 +
38.27 + "Implementation of xrange."
38.28 +
38.29 + NO_END = object()
38.30 +
38.31 + def __init__(self, start_or_end, end=NO_END, step=1):
38.32 +
38.33 + "Initialise the xrange with the given 'start_or_end', 'end' and 'step'."
38.34 +
38.35 + if end is xrange.NO_END:
38.36 + self.start = 0
38.37 + self.end = start_or_end
38.38 + else:
38.39 + self.start = start_or_end
38.40 + self.end = end
38.41 +
38.42 + self.step = step
38.43 + self.current = self.start
38.44 + self.limited = self.end is not xrange.NO_END
38.45 +
38.46 + def __iter__(self):
38.47 +
38.48 + "Return an iterator, currently self."
38.49 +
38.50 + return self
38.51 +
38.52 + def next(self):
38.53 +
38.54 + "Return the next item or raise a StopIteration exception."
38.55 +
38.56 + if self.limited:
38.57 + if self.step < 0 and self.current <= self.end or self.step > 0 and self.current >= self.end:
38.58 + raise StopIteration()
38.59 +
38.60 + current = self.current
38.61 + self.current += self.step
38.62 + return current
38.63 +
38.64 +class slice(xrange):
38.65 +
38.66 + "Implementation of slice."
38.67 +
38.68 + def __init__(self, start_or_end=None, end=xrange.NO_END, step=1):
38.69 +
38.70 + "Initialise the slice with the given 'start_or_end', 'end' and 'step'."
38.71 +
38.72 + xrange.__init__(self, start_or_end, end, step)
38.73 +
38.74 +# vim: tabstop=4 expandtab shiftwidth=4
39.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
39.2 +++ b/lib/__builtins__/string.py Tue Aug 30 22:09:17 2016 +0200
39.3 @@ -0,0 +1,107 @@
39.4 +#!/usr/bin/env python
39.5 +
39.6 +"""
39.7 +String objects.
39.8 +
39.9 +Copyright (C) 2015, 2016 Paul Boddie <paul@boddie.org.uk>
39.10 +
39.11 +This program is free software; you can redistribute it and/or modify it under
39.12 +the terms of the GNU General Public License as published by the Free Software
39.13 +Foundation; either version 3 of the License, or (at your option) any later
39.14 +version.
39.15 +
39.16 +This program is distributed in the hope that it will be useful, but WITHOUT
39.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
39.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
39.19 +details.
39.20 +
39.21 +You should have received a copy of the GNU General Public License along with
39.22 +this program. If not, see <http://www.gnu.org/licenses/>.
39.23 +"""
39.24 +
39.25 +from __builtins__.operator import *
39.26 +import native
39.27 +
39.28 +class basestring(object):
39.29 + def __init__(self, data=None):
39.30 + # Note member.
39.31 + self.data = data
39.32 +
39.33 + def __contains__(self, value): pass
39.34 +
39.35 + def __getitem__(self, index):
39.36 + # Note usage.
39.37 + IndexError
39.38 +
39.39 + def __getslice__(self, start, end=None): pass
39.40 +
39.41 + def __iadd__(self, other):
39.42 + "Return a new string for the operation."
39.43 + return _binary_op(self, other, native._str_add)
39.44 +
39.45 + __add__ = __radd__ = __iadd__
39.46 +
39.47 + def __mul__(self, other): pass
39.48 + def __rmul__(self, other): pass
39.49 + def __mod__(self, other): pass
39.50 + def __rmod__(self, other): pass
39.51 +
39.52 + def __lt__(self, other):
39.53 + "Return a new boolean for the comparison."
39.54 + return _binary_op(self, other, native._str_lt)
39.55 +
39.56 + def __gt__(self, other):
39.57 + "Return a new boolean for the comparison."
39.58 + return _binary_op(self, other, native._str_gt)
39.59 +
39.60 + def __le__(self, other):
39.61 + "Return a new boolean for the comparison."
39.62 + return _negate(self.__gt__(other))
39.63 +
39.64 + def __ge__(self, other):
39.65 + "Return a new boolean for the comparison."
39.66 + return _negate(self.__lt__(other))
39.67 +
39.68 + def __eq__(self, other):
39.69 + "Return a new boolean for the comparison."
39.70 + return _binary_op(self, other, native._str_eq)
39.71 +
39.72 + def __ne__(self, other):
39.73 + "Return a new boolean for the comparison."
39.74 + return _negate(self.__eq__(other))
39.75 +
39.76 + def __len__(self): pass
39.77 + def __str__(self): pass
39.78 +
39.79 + def __bool__(self):
39.80 + return _negate(native._str_eq(self, ""))
39.81 +
39.82 + def endswith(self, s): pass
39.83 + def find(self, sub, start=None, end=None): pass
39.84 + def index(self, sub, start=None, end=None): pass
39.85 + def join(self, l): pass
39.86 + def lower(self): pass
39.87 + def lstrip(self, chars=None): pass
39.88 + def replace(self, old, new, count=None): pass
39.89 + def rfind(self, sub, start=None, end=None): pass
39.90 + def rsplit(self, sep=None, maxsplit=None): pass
39.91 + def rstrip(self, chars=None): pass
39.92 + def split(self, sep=None, maxsplit=None): pass
39.93 + def splitlines(self, keepends=False): pass
39.94 + def startswith(self, s): pass
39.95 + def strip(self, chars=None): pass
39.96 + def upper(self): pass
39.97 +
39.98 + def __iter__(self):
39.99 +
39.100 + "Return an iterator."
39.101 +
39.102 + return listiterator(self)
39.103 +
39.104 +class str(basestring):
39.105 + pass
39.106 +
39.107 +class unicode(basestring):
39.108 + def encode(self, encoding): pass
39.109 +
39.110 +# vim: tabstop=4 expandtab shiftwidth=4
40.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
40.2 +++ b/lib/__builtins__/tuple.py Tue Aug 30 22:09:17 2016 +0200
40.3 @@ -0,0 +1,62 @@
40.4 +#!/usr/bin/env python
40.5 +
40.6 +"""
40.7 +Tuple objects.
40.8 +
40.9 +Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk>
40.10 +
40.11 +This program is free software; you can redistribute it and/or modify it under
40.12 +the terms of the GNU General Public License as published by the Free Software
40.13 +Foundation; either version 3 of the License, or (at your option) any later
40.14 +version.
40.15 +
40.16 +This program is distributed in the hope that it will be useful, but WITHOUT
40.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
40.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
40.19 +details.
40.20 +
40.21 +You should have received a copy of the GNU General Public License along with
40.22 +this program. If not, see <http://www.gnu.org/licenses/>.
40.23 +"""
40.24 +
40.25 +from __builtins__.sequence import *
40.26 +
40.27 +class tuple(object):
40.28 +
40.29 + "Implementation of tuple."
40.30 +
40.31 + def __init__(self, args): pass
40.32 +
40.33 + def __getitem__(self, index):
40.34 +
40.35 + "Return the item or slice specified by 'index'."
40.36 +
40.37 + return _getitem(self, index)
40.38 +
40.39 + def __getslice__(self, start, end=None):
40.40 +
40.41 + "Return a slice starting from 'start', with the optional 'end'."
40.42 +
40.43 + return _tuple(_getslice(self, start, end))
40.44 +
40.45 + def __len__(self): pass
40.46 + def __add__(self, other): pass
40.47 + def __str__(self): pass
40.48 +
40.49 + def __bool__(self):
40.50 +
40.51 + "Tuples are true if non-empty."
40.52 +
40.53 + return self.__len__() != 0
40.54 +
40.55 + def __iter__(self):
40.56 +
40.57 + "Return an iterator."
40.58 +
40.59 + return listiterator(self)
40.60 +
40.61 + # Special implementation methods.
40.62 +
40.63 + def __get_single_item__(self, index): pass
40.64 +
40.65 +# vim: tabstop=4 expandtab shiftwidth=4
42.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
42.2 +++ b/lib/_random.py Tue Aug 30 22:09:17 2016 +0200
42.3 @@ -0,0 +1,30 @@
42.4 +#!/usr/bin/env python
42.5 +
42.6 +"""
42.7 +Random numbers.
42.8 +
42.9 +Copyright (C) 2012 Paul Boddie <paul@boddie.org.uk>
42.10 +
42.11 +This program is free software; you can redistribute it and/or modify it under
42.12 +the terms of the GNU General Public License as published by the Free Software
42.13 +Foundation; either version 3 of the License, or (at your option) any later
42.14 +version.
42.15 +
42.16 +This program is distributed in the hope that it will be useful, but WITHOUT
42.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
42.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
42.19 +details.
42.20 +
42.21 +You should have received a copy of the GNU General Public License along with
42.22 +this program. If not, see <http://www.gnu.org/licenses/>.
42.23 +"""
42.24 +
42.25 +class Random:
42.26 + def getrandbits(self, k): pass
42.27 + def getstate(self): pass
42.28 + def jumpahead(self, x): pass
42.29 + def random(self): pass
42.30 + def seed(self, n=None): pass
42.31 + def setstate(self, state): pass
42.32 +
42.33 +# vim: tabstop=4 expandtab shiftwidth=4
43.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
43.2 +++ b/lib/_sre.py Tue Aug 30 22:09:17 2016 +0200
43.3 @@ -0,0 +1,44 @@
43.4 +#!/usr/bin/env python
43.5 +
43.6 +CODESIZE = 4
43.7 +MAGIC = 20140812
43.8 +
43.9 +class RegexObject:
43.10 +
43.11 + def __init__(self, flags, groups, groupindex, pattern):
43.12 + self.flags = flags
43.13 + self.groups = groups
43.14 + self.groupindex = groupindex
43.15 + self.pattern = pattern
43.16 +
43.17 + def search(self, string, pos=None, endpos=None): pass
43.18 + def match(self, string, pos=None, endpos=None): pass
43.19 + def split(self, string, maxsplit=0): pass
43.20 + def findall(self, string, pos=None, endpos=None): pass
43.21 + def finditer(self, string, pos=None, endpos=None): pass
43.22 + def sub(self, repl, string, count=0): pass
43.23 + def subn(self, repl, string, count=0): pass
43.24 +
43.25 +class MatchObject:
43.26 +
43.27 + def __init__(self, pos, endpos, lastindex, lastgroup, re, string):
43.28 + self.pos = pos
43.29 + self.endpos = endpos
43.30 + self.lastindex = lastindex
43.31 + self.lastgroup = lastgroup
43.32 + self.re = re
43.33 + self.string = string
43.34 +
43.35 + def expand(self, template): pass
43.36 + def group(self, *groups): pass
43.37 + def groups(self, default=None): pass
43.38 + def groupdict(self, default=None): pass
43.39 + def start(self, group=None): pass
43.40 + def end(self, group=None): pass
43.41 + def span(self, group=None): pass
43.42 +
43.43 +def compile(pattern, flags=0): pass
43.44 +def getcodesize(): pass
43.45 +def getlower(c): pass
43.46 +
43.47 +# vim: tabstop=4 expandtab shiftwidth=4
44.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
44.2 +++ b/lib/_weakref.py Tue Aug 30 22:09:17 2016 +0200
44.3 @@ -0,0 +1,29 @@
44.4 +#!/usr/bin/env python
44.5 +
44.6 +"""
44.7 +Weak references.
44.8 +
44.9 +Copyright (C) 2012 Paul Boddie <paul@boddie.org.uk>
44.10 +
44.11 +This program is free software; you can redistribute it and/or modify it under
44.12 +the terms of the GNU General Public License as published by the Free Software
44.13 +Foundation; either version 3 of the License, or (at your option) any later
44.14 +version.
44.15 +
44.16 +This program is distributed in the hope that it will be useful, but WITHOUT
44.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
44.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
44.19 +details.
44.20 +
44.21 +You should have received a copy of the GNU General Public License along with
44.22 +this program. If not, see <http://www.gnu.org/licenses/>.
44.23 +"""
44.24 +
44.25 +class ref:
44.26 + pass
44.27 +
44.28 +def getweakrefcount(obj): pass
44.29 +def getweakrefs(obj): pass
44.30 +def proxy(obj, callback=None): pass
44.31 +
44.32 +# vim: tabstop=4 expandtab shiftwidth=4
45.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
45.2 +++ b/lib/array.py Tue Aug 30 22:09:17 2016 +0200
45.3 @@ -0,0 +1,53 @@
45.4 +#!/usr/bin/env python
45.5 +
45.6 +"""
45.7 +Array functions and objects.
45.8 +
45.9 +Copyright (C) 2011, 2014 Paul Boddie <paul@boddie.org.uk>
45.10 +
45.11 +This program is free software; you can redistribute it and/or modify it under
45.12 +the terms of the GNU General Public License as published by the Free Software
45.13 +Foundation; either version 3 of the License, or (at your option) any later
45.14 +version.
45.15 +
45.16 +This program is distributed in the hope that it will be useful, but WITHOUT
45.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
45.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
45.19 +details.
45.20 +
45.21 +You should have received a copy of the GNU General Public License along with
45.22 +this program. If not, see <http://www.gnu.org/licenses/>.
45.23 +"""
45.24 +
45.25 +class array:
45.26 +
45.27 + """
45.28 + An array of primitive objects.
45.29 + NOTE: In principle, arrays of full instances could be supported with
45.30 + NOTE: knowledge of the size of each instance.
45.31 + """
45.32 +
45.33 + def __init__(self, typecode, itemsize):
45.34 + self.typecode = typecode
45.35 + self.itemsize = itemsize
45.36 +
45.37 + def append(self, value): pass
45.38 + def buffer_info(self): pass
45.39 + def byteswap(self): pass
45.40 + def count(self, value): pass
45.41 + def extend(self, l): pass
45.42 + def fromfile(self, f): pass
45.43 + def fromlist(self, l): pass
45.44 + def fromstring(self, s): pass
45.45 + def index(self, value): pass
45.46 + def insert(self, index, value): pass
45.47 + def pop(self): pass
45.48 + def read(self): pass
45.49 + def remove(self, value): pass
45.50 + def reverse(self): pass
45.51 + def tofile(self): pass
45.52 + def tolist(self): pass
45.53 + def tostring(self): pass
45.54 + def write(self): pass
45.55 +
45.56 +# vim: tabstop=4 expandtab shiftwidth=4
47.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
47.2 +++ b/lib/collections.py Tue Aug 30 22:09:17 2016 +0200
47.3 @@ -0,0 +1,36 @@
47.4 +#!/usr/bin/env python
47.5 +
47.6 +"""
47.7 +Collections.
47.8 +
47.9 +Copyright (C) 2013 Paul Boddie <paul@boddie.org.uk>
47.10 +
47.11 +This program is free software; you can redistribute it and/or modify it under
47.12 +the terms of the GNU General Public License as published by the Free Software
47.13 +Foundation; either version 3 of the License, or (at your option) any later
47.14 +version.
47.15 +
47.16 +This program is distributed in the hope that it will be useful, but WITHOUT
47.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
47.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
47.19 +details.
47.20 +
47.21 +You should have received a copy of the GNU General Public License along with
47.22 +this program. If not, see <http://www.gnu.org/licenses/>.
47.23 +"""
47.24 +
47.25 +class defaultdict(dict):
47.26 + pass
47.27 +
47.28 +class deque(object):
47.29 + def append(x): pass
47.30 + def appendleft(x): pass
47.31 + def clear(): pass
47.32 + def extend(iterable): pass
47.33 + def extendleft(iterable): pass
47.34 + def pop(): pass
47.35 + def popleft(): pass
47.36 + def remove(value): pass
47.37 + def rotate(n): pass
47.38 +
47.39 +# vim: tabstop=4 expandtab shiftwidth=4
48.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
48.2 +++ b/lib/copy.py Tue Aug 30 22:09:17 2016 +0200
48.3 @@ -0,0 +1,25 @@
48.4 +#!/usr/bin/env python
48.5 +
48.6 +"""
48.7 +Copying functions.
48.8 +
48.9 +Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk>
48.10 +
48.11 +This program is free software; you can redistribute it and/or modify it under
48.12 +the terms of the GNU General Public License as published by the Free Software
48.13 +Foundation; either version 3 of the License, or (at your option) any later
48.14 +version.
48.15 +
48.16 +This program is distributed in the hope that it will be useful, but WITHOUT
48.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
48.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
48.19 +details.
48.20 +
48.21 +You should have received a copy of the GNU General Public License along with
48.22 +this program. If not, see <http://www.gnu.org/licenses/>.
48.23 +"""
48.24 +
48.25 +def copy(x): pass
48.26 +def deepcopy(x): pass
48.27 +
48.28 +# vim: tabstop=4 expandtab shiftwidth=4
49.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
49.2 +++ b/lib/exceptions.py Tue Aug 30 22:09:17 2016 +0200
49.3 @@ -0,0 +1,1 @@
49.4 +from __builtins__.exception import *
50.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
50.2 +++ b/lib/genericos.py Tue Aug 30 22:09:17 2016 +0200
50.3 @@ -0,0 +1,48 @@
50.4 +#!/usr/bin/env python
50.5 +
50.6 +from posix.io import fstat
50.7 +from posix.filesys import listdir, lstat, readlink
50.8 +from posix.process import getcwd, getcwdu, getuid
50.9 +
50.10 +class OSError(EnvironmentError):
50.11 + pass
50.12 +
50.13 +error = OSError
50.14 +environ = {}
50.15 +
50.16 +def execl(file, *args): pass
50.17 +def execle(file, *args): pass
50.18 +def execlp(file, *args): pass
50.19 +def execlpe(file, *args): pass
50.20 +def execv(path, args): pass
50.21 +def execve(path, args, env): pass
50.22 +def execvp(file, args): pass
50.23 +def execvpe(file, args, env): pass
50.24 +def getenv(key, default=None): pass
50.25 +def makedirs(name, mode=511): pass
50.26 +def popen2(cmd, mode='t', bufsize=-1): pass
50.27 +def popen3(cmd, mode='t', bufsize=-1): pass
50.28 +def popen4(cmd, mode='t', bufsize=-1): pass
50.29 +def removedirs(name): pass
50.30 +def renames(old, new): pass
50.31 +def spawnl(mode, file, *args): pass
50.32 +def spawnle(mode, file, *args): pass
50.33 +def spawnlp(mode, file, *args): pass
50.34 +def spawnlpe(mode, file, *args): pass
50.35 +def spawnv(mode, file, args): pass
50.36 +def spawnve(mode, file, args, env): pass
50.37 +def spawnvp(mode, file, args): pass
50.38 +def spawnvpe(mode, file, args, env): pass
50.39 +def walk(top, topdown=True, onerror=None, followlinks=False): pass
50.40 +
50.41 +P_WAIT = 0
50.42 +P_NOWAIT = P_NOWAITO = 1
50.43 +
50.44 +SEEK_CUR = 1
50.45 +SEEK_END = 2
50.46 +SEEK_SET = 0
50.47 +
50.48 +name = 'posix'
50.49 +linesep = '\n'
50.50 +
50.51 +# vim: tabstop=4 expandtab shiftwidth=4
51.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
51.2 +++ b/lib/genericpath.py Tue Aug 30 22:09:17 2016 +0200
51.3 @@ -0,0 +1,105 @@
51.4 +"""
51.5 +Path operations common to more than one OS
51.6 +Do not use directly. The OS specific modules import the appropriate
51.7 +functions from this module themselves.
51.8 +"""
51.9 +from os import error, stat
51.10 +from stat import *
51.11 +
51.12 +__all__ = ['commonprefix', 'exists', 'getatime', 'getctime', 'getmtime',
51.13 + 'getsize', 'isdir', 'isfile']
51.14 +
51.15 +
51.16 +# Does a path exist?
51.17 +# This is false for dangling symbolic links on systems that support them.
51.18 +def exists(path):
51.19 + """Test whether a path exists. Returns False for broken symbolic links"""
51.20 + try:
51.21 + stat(path)
51.22 + except error:
51.23 + return False
51.24 + return True
51.25 +
51.26 +
51.27 +# This follows symbolic links, so both islink() and isdir() can be true
51.28 +# for the same path ono systems that support symlinks
51.29 +def isfile(path):
51.30 + """Test whether a path is a regular file"""
51.31 + try:
51.32 + st = stat(path)
51.33 + except error:
51.34 + return False
51.35 + return stat.S_ISREG(st.st_mode)
51.36 +
51.37 +
51.38 +# Is a path a directory?
51.39 +# This follows symbolic links, so both islink() and isdir()
51.40 +# can be true for the same path on systems that support symlinks
51.41 +def isdir(s):
51.42 + """Return true if the pathname refers to an existing directory."""
51.43 + try:
51.44 + st = stat(s)
51.45 + except error:
51.46 + return False
51.47 + return stat.S_ISDIR(st.st_mode)
51.48 +
51.49 +
51.50 +def getsize(filename):
51.51 + """Return the size of a file, reported by os.stat()."""
51.52 + return stat(filename).st_size
51.53 +
51.54 +
51.55 +def getmtime(filename):
51.56 + """Return the last modification time of a file, reported by os.stat()."""
51.57 + return stat(filename).st_mtime
51.58 +
51.59 +
51.60 +def getatime(filename):
51.61 + """Return the last access time of a file, reported by os.stat()."""
51.62 + return stat(filename).st_atime
51.63 +
51.64 +
51.65 +def getctime(filename):
51.66 + """Return the metadata change time of a file, reported by os.stat()."""
51.67 + return stat(filename).st_ctime
51.68 +
51.69 +
51.70 +# Return the longest prefix of all list elements.
51.71 +def commonprefix(m):
51.72 + "Given a list of pathnames, returns the longest common leading component"
51.73 + if not m: return ''
51.74 + s1 = min(m)
51.75 + s2 = max(m)
51.76 + for i, c in enumerate(s1):
51.77 + if c != s2[i]:
51.78 + return s1[:i]
51.79 + return s1
51.80 +
51.81 +# Split a path in root and extension.
51.82 +# The extension is everything starting at the last dot in the last
51.83 +# pathname component; the root is everything before that.
51.84 +# It is always true that root + ext == p.
51.85 +
51.86 +# Generic implementation of splitext, to be parametrized with
51.87 +# the separators
51.88 +def _splitext(p, sep, altsep, extsep):
51.89 + """Split the extension from a pathname.
51.90 +
51.91 + Extension is everything from the last dot to the end, ignoring
51.92 + leading dots. Returns "(root, ext)"; ext may be empty."""
51.93 +
51.94 + sepIndex = p.rfind(sep)
51.95 + if altsep:
51.96 + altsepIndex = p.rfind(altsep)
51.97 + sepIndex = max(sepIndex, altsepIndex)
51.98 +
51.99 + dotIndex = p.rfind(extsep)
51.100 + if dotIndex > sepIndex:
51.101 + # skip all leading dots
51.102 + filenameIndex = sepIndex + 1
51.103 + while filenameIndex < dotIndex:
51.104 + if p[filenameIndex] != extsep:
51.105 + return p[:dotIndex], p[dotIndex:]
51.106 + filenameIndex += 1
51.107 +
51.108 + return p, ''
52.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
52.2 +++ b/lib/itertools.py Tue Aug 30 22:09:17 2016 +0200
52.3 @@ -0,0 +1,199 @@
52.4 +#!/usr/bin/env python
52.5 +
52.6 +class chain:
52.7 + def __init__(self, *iterables):
52.8 + pass
52.9 +
52.10 + def __iter__(self):
52.11 + pass
52.12 +
52.13 + def from_iterable(self, iterable):
52.14 + pass
52.15 +
52.16 + def next(self):
52.17 + pass
52.18 +
52.19 +class combinations:
52.20 + def __init__(self, iterable, r):
52.21 + pass
52.22 +
52.23 + def __iter__(self):
52.24 + pass
52.25 +
52.26 + def next(self):
52.27 + pass
52.28 +
52.29 +class combinations_with_replacement:
52.30 + def __init__(self, iterable, r):
52.31 + pass
52.32 +
52.33 + def __iter__(self):
52.34 + pass
52.35 +
52.36 + def next(self):
52.37 + pass
52.38 +
52.39 +class compress:
52.40 + def __init__(self, data, selectors):
52.41 + pass
52.42 +
52.43 + def __iter__(self):
52.44 + pass
52.45 +
52.46 + def next(self):
52.47 + pass
52.48 +
52.49 +class count:
52.50 + def __init__(self, start=0, step=1):
52.51 + pass
52.52 +
52.53 + def __iter__(self):
52.54 + pass
52.55 +
52.56 + def next(self):
52.57 + pass
52.58 +
52.59 +class cycle:
52.60 + def __init__(self, iterable):
52.61 + pass
52.62 +
52.63 + def __iter__(self):
52.64 + pass
52.65 +
52.66 + def next(self):
52.67 + pass
52.68 +
52.69 +class dropwhile:
52.70 + def __init__(self, predicate, iterable):
52.71 + pass
52.72 +
52.73 + def __iter__(self):
52.74 + pass
52.75 +
52.76 + def next(self):
52.77 + pass
52.78 +
52.79 +class groupby:
52.80 + def __init__(self, iterable, keyfunc=None):
52.81 + pass
52.82 +
52.83 + def __iter__(self):
52.84 + pass
52.85 +
52.86 + def next(self):
52.87 + pass
52.88 +
52.89 +class ifilter:
52.90 + def __init__(self, function, sequence):
52.91 + pass
52.92 +
52.93 + def __iter__(self):
52.94 + pass
52.95 +
52.96 + def next(self):
52.97 + pass
52.98 +
52.99 +class ifilterfalse:
52.100 + def __init__(self, function, sequence):
52.101 + pass
52.102 +
52.103 + def __iter__(self):
52.104 + pass
52.105 +
52.106 + def next(self):
52.107 + pass
52.108 +
52.109 +class imap:
52.110 + def __init__(self, func, *iterables):
52.111 + pass
52.112 +
52.113 + def __iter__(self):
52.114 + pass
52.115 +
52.116 + def next(self):
52.117 + pass
52.118 +
52.119 +class islice:
52.120 + def __init__(self, iterable, start_or_stop, stop=None, step=None):
52.121 + pass
52.122 +
52.123 + def __iter__(self):
52.124 + pass
52.125 +
52.126 + def next(self):
52.127 + pass
52.128 +
52.129 +class izip:
52.130 + def __init__(self, *args):
52.131 + pass
52.132 +
52.133 + def __iter__(self):
52.134 + pass
52.135 +
52.136 + def next(self):
52.137 + pass
52.138 +
52.139 +class izip_longest:
52.140 + def __init__(self, *args, **kw): #fillvalue=None
52.141 + pass
52.142 +
52.143 + def __iter__(self):
52.144 + pass
52.145 +
52.146 + def next(self):
52.147 + pass
52.148 +
52.149 +class permutations:
52.150 + def __init__(self, iterable, r=None):
52.151 + pass
52.152 +
52.153 + def __iter__(self):
52.154 + pass
52.155 +
52.156 + def next(self):
52.157 + pass
52.158 +
52.159 +class product:
52.160 + def __init__(self, *iterables):
52.161 + pass
52.162 +
52.163 + def __iter__(self):
52.164 + pass
52.165 +
52.166 + def next(self):
52.167 + pass
52.168 +
52.169 +class repeat:
52.170 + def __init__(self, object, times=None):
52.171 + pass
52.172 +
52.173 + def __iter__(self):
52.174 + pass
52.175 +
52.176 + def next(self):
52.177 + pass
52.178 +
52.179 +class starmap:
52.180 + def __init__(self, function, sequence):
52.181 + pass
52.182 +
52.183 + def __iter__(self):
52.184 + pass
52.185 +
52.186 + def next(self):
52.187 + pass
52.188 +
52.189 +class takewhile:
52.190 + def __init__(self, predicate, iterable):
52.191 + pass
52.192 +
52.193 + def __iter__(self):
52.194 + pass
52.195 +
52.196 + def next(self):
52.197 + pass
52.198 +
52.199 +def tee(iterable, n=2):
52.200 + pass
52.201 +
52.202 +# vim: tabstop=4 expandtab shiftwidth=4
53.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
53.2 +++ b/lib/math.py Tue Aug 30 22:09:17 2016 +0200
53.3 @@ -0,0 +1,58 @@
53.4 +#!/usr/bin/env python
53.5 +
53.6 +"""
53.7 +Mathematical functions.
53.8 +
53.9 +Copyright (C) 2012 Paul Boddie <paul@boddie.org.uk>
53.10 +
53.11 +This program is free software; you can redistribute it and/or modify it under
53.12 +the terms of the GNU General Public License as published by the Free Software
53.13 +Foundation; either version 3 of the License, or (at your option) any later
53.14 +version.
53.15 +
53.16 +This program is distributed in the hope that it will be useful, but WITHOUT
53.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
53.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
53.19 +details.
53.20 +
53.21 +You should have received a copy of the GNU General Public License along with
53.22 +this program. If not, see <http://www.gnu.org/licenses/>.
53.23 +"""
53.24 +
53.25 +def pow(x, y):
53.26 +
53.27 + "Return x ** y."
53.28 +
53.29 + return x ** y
53.30 +
53.31 +def acos(x): pass
53.32 +def asin(x): pass
53.33 +def atan(x): pass
53.34 +def atan2(y, x): pass
53.35 +def ceil(x): pass
53.36 +def cos(x): pass
53.37 +def cosh(x): pass
53.38 +def degrees(x): pass
53.39 +def exp(x): pass
53.40 +def fabs(x): pass
53.41 +def floor(x): pass
53.42 +def fmod(x, y): pass
53.43 +def frexp(x): pass
53.44 +def hypot(x, y): pass
53.45 +def ldexp(x, i): pass
53.46 +def log(x, base=None): pass
53.47 +def log10(x): pass
53.48 +def modf(x): pass
53.49 +def radians(x): pass
53.50 +def sin(x): pass
53.51 +def sinh(x): pass
53.52 +def sqrt(x): pass
53.53 +def tan(x): pass
53.54 +def tanh(x): pass
53.55 +
53.56 +# NOTE: From Python 2.7 on i386.
53.57 +
53.58 +e = 2.718281828459045
53.59 +pi = 3.141592653589793
53.60 +
53.61 +# vim: tabstop=4 expandtab shiftwidth=4
54.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
54.2 +++ b/lib/native.py Tue Aug 30 22:09:17 2016 +0200
54.3 @@ -0,0 +1,51 @@
54.4 +#!/usr/bin/env python
54.5 +
54.6 +"""
54.7 +Native library functions.
54.8 +
54.9 +Copyright (C) 2011, 2015, 2016 Paul Boddie <paul@boddie.org.uk>
54.10 +
54.11 +This program is free software; you can redistribute it and/or modify it under
54.12 +the terms of the GNU General Public License as published by the Free Software
54.13 +Foundation; either version 3 of the License, or (at your option) any later
54.14 +version.
54.15 +
54.16 +This program is distributed in the hope that it will be useful, but WITHOUT
54.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
54.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
54.19 +details.
54.20 +
54.21 +You should have received a copy of the GNU General Public License along with
54.22 +this program. If not, see <http://www.gnu.org/licenses/>.
54.23 +"""
54.24 +
54.25 +def _is(x, y): pass
54.26 +def _is_not(x, y): pass
54.27 +
54.28 +def _int_add(self, other): pass
54.29 +def _int_sub(self, other): pass
54.30 +def _int_mul(self, other): pass
54.31 +def _int_div(self, other): pass
54.32 +def _int_mod(self, other): pass
54.33 +def _int_pow(self, other): pass
54.34 +def _int_and(self, other): pass
54.35 +def _int_or(self, other): pass
54.36 +def _int_xor(self, other): pass
54.37 +
54.38 +def _int_rsub(self, other): pass
54.39 +def _int_rdiv(self, other): pass
54.40 +def _int_rmod(self, other): pass
54.41 +def _int_rpow(self, other): pass
54.42 +
54.43 +def _int_lt(self, other): pass
54.44 +def _int_gt(self, other): pass
54.45 +def _int_eq(self, other): pass
54.46 +
54.47 +def _str_add(self, other): pass
54.48 +def _str_lt(self, other): pass
54.49 +def _str_gt(self, other): pass
54.50 +def _str_eq(self, other): pass
54.51 +
54.52 +def _isinstance(obj, cls): pass
54.53 +
54.54 +# vim: tabstop=4 expandtab shiftwidth=4
55.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
55.2 +++ b/lib/operator/__init__.py Tue Aug 30 22:09:17 2016 +0200
55.3 @@ -0,0 +1,28 @@
55.4 +#!/usr/bin/env python
55.5 +
55.6 +"""
55.7 +Operator support.
55.8 +
55.9 +Copyright (C) 2015, 2016 Paul Boddie <paul@boddie.org.uk>
55.10 +
55.11 +This program is free software; you can redistribute it and/or modify it under
55.12 +the terms of the GNU General Public License as published by the Free Software
55.13 +Foundation; either version 3 of the License, or (at your option) any later
55.14 +version.
55.15 +
55.16 +This program is distributed in the hope that it will be useful, but WITHOUT
55.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
55.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
55.19 +details.
55.20 +
55.21 +You should have received a copy of the GNU General Public License along with
55.22 +this program. If not, see <http://www.gnu.org/licenses/>.
55.23 +"""
55.24 +
55.25 +from operator.binary import *
55.26 +from operator.unary import *
55.27 +from operator.augmented import *
55.28 +from operator.comparison import *
55.29 +from operator.sequence import *
55.30 +
55.31 +# vim: tabstop=4 expandtab shiftwidth=4
56.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
56.2 +++ b/lib/operator/augmented.py Tue Aug 30 22:09:17 2016 +0200
56.3 @@ -0,0 +1,69 @@
56.4 +#!/usr/bin/env python
56.5 +
56.6 +"""
56.7 +Operator support.
56.8 +
56.9 +Copyright (C) 2010, 2013, 2015 Paul Boddie <paul@boddie.org.uk>
56.10 +
56.11 +This program is free software; you can redistribute it and/or modify it under
56.12 +the terms of the GNU General Public License as published by the Free Software
56.13 +Foundation; either version 3 of the License, or (at your option) any later
56.14 +version.
56.15 +
56.16 +This program is distributed in the hope that it will be useful, but WITHOUT
56.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
56.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
56.19 +details.
56.20 +
56.21 +You should have received a copy of the GNU General Public License along with
56.22 +this program. If not, see <http://www.gnu.org/licenses/>.
56.23 +"""
56.24 +
56.25 +from operator.core import augassign
56.26 +
56.27 +# These functions defer method lookup by wrapping the attribute access in
56.28 +# lambda functions. Thus, the appropriate methods are defined locally, but no
56.29 +# attempt to obtain them is made until the generic function is called.
56.30 +
56.31 +# NOTE: The compiler should make it possible for the following functions to call
56.32 +# NOTE: the generic operator implementations with no additional call overhead.
56.33 +
56.34 +# Augmented assignment functions.
56.35 +
56.36 +def iadd(a, b):
56.37 + return augassign(a, b, lambda a: a.__iadd__, lambda a: a.__add__, lambda b: b.__radd__)
56.38 +
56.39 +def iand_(a, b):
56.40 + return augassign(a, b, lambda a: a.__iand__, lambda a: a.__and__, lambda b: b.__rand__)
56.41 +
56.42 +def idiv(a, b):
56.43 + return augassign(a, b, lambda a: a.__idiv__, lambda a: a.__div__, lambda b: b.__rdiv__)
56.44 +
56.45 +def ifloordiv(a, b):
56.46 + return augassign(a, b, lambda a: a.__ifloordiv__, lambda a: a.__floordiv__, lambda b: b.__rfloordiv__)
56.47 +
56.48 +def ilshift(a, b):
56.49 + return augassign(a, b, lambda a: a.__ilshift__, lambda a: a.__lshift__, lambda b: b.__rlshift__)
56.50 +
56.51 +def imod(a, b):
56.52 + return augassign(a, b, lambda a: a.__imod__, lambda a: a.__mod__, lambda b: b.__rmod__)
56.53 +
56.54 +def imul(a, b):
56.55 + return augassign(a, b, lambda a: a.__imul__, lambda a: a.__mul__, lambda b: b.__rmul__)
56.56 +
56.57 +def ior_(a, b):
56.58 + return augassign(a, b, lambda a: a.__ior__, lambda a: a.__or__, lambda b: b.__ror__)
56.59 +
56.60 +def ipow(a, b):
56.61 + return augassign(a, b, lambda a: a.__ipow__, lambda a: a.__pow__, lambda b: b.__rpow__)
56.62 +
56.63 +def irshift(a, b):
56.64 + return augassign(a, b, lambda a: a.__irshift__, lambda a: a.__rshift__, lambda b: b.__rrshift__)
56.65 +
56.66 +def isub(a, b):
56.67 + return augassign(a, b, lambda a: a.__isub__, lambda a: a.__sub__, lambda b: b.__rsub__)
56.68 +
56.69 +def ixor(a, b):
56.70 + return augassign(a, b, lambda a: a.__ixor__, lambda a: a.__xor__, lambda b: b.__rxor__)
56.71 +
56.72 +# vim: tabstop=4 expandtab shiftwidth=4
57.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
57.2 +++ b/lib/operator/binary.py Tue Aug 30 22:09:17 2016 +0200
57.3 @@ -0,0 +1,78 @@
57.4 +#!/usr/bin/env python
57.5 +
57.6 +"""
57.7 +Operator support.
57.8 +
57.9 +Copyright (C) 2010, 2013, 2015, 2016 Paul Boddie <paul@boddie.org.uk>
57.10 +
57.11 +This program is free software; you can redistribute it and/or modify it under
57.12 +the terms of the GNU General Public License as published by the Free Software
57.13 +Foundation; either version 3 of the License, or (at your option) any later
57.14 +version.
57.15 +
57.16 +This program is distributed in the hope that it will be useful, but WITHOUT
57.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
57.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
57.19 +details.
57.20 +
57.21 +You should have received a copy of the GNU General Public License along with
57.22 +this program. If not, see <http://www.gnu.org/licenses/>.
57.23 +"""
57.24 +
57.25 +from operator.core import binary_op, is_, is_not
57.26 +
57.27 +# These functions defer method lookup by wrapping the attribute access in
57.28 +# lambda functions. Thus, the appropriate methods are defined locally, but no
57.29 +# attempt to obtain them is made until the generic function is called.
57.30 +
57.31 +# NOTE: The compiler should make it possible for the following functions to call
57.32 +# NOTE: the generic operator implementations with no additional call overhead.
57.33 +
57.34 +# Binary operator functions.
57.35 +
57.36 +def add(a, b):
57.37 + return binary_op(a, b, lambda a: a.__add__, lambda b: b.__radd__)
57.38 +
57.39 +def and_(a, b):
57.40 + return binary_op(a, b, lambda a: a.__and__, lambda b: b.__rand__)
57.41 +
57.42 +def contains(a, b):
57.43 + return in_(b, a)
57.44 +
57.45 +def div(a, b):
57.46 + return binary_op(a, b, lambda a: a.__div__, lambda b: b.__rdiv__)
57.47 +
57.48 +def floordiv(a, b):
57.49 + return binary_op(a, b, lambda a: a.__floordiv__, lambda b: b.__rfloordiv__)
57.50 +
57.51 +def in_(a, b):
57.52 + return a.__contains__(b)
57.53 +
57.54 +def not_in(a, b):
57.55 + return not a.__contains__(b)
57.56 +
57.57 +def lshift(a, b):
57.58 + return binary_op(a, b, lambda a: a.__lshift__, lambda b: b.__rlshift__)
57.59 +
57.60 +def mod(a, b):
57.61 + return binary_op(a, b, lambda a: a.__mod__, lambda b: b.__rmod__)
57.62 +
57.63 +def mul(a, b):
57.64 + return binary_op(a, b, lambda a: a.__mul__, lambda b: b.__rmul__)
57.65 +
57.66 +def or_(a, b):
57.67 + return binary_op(a, b, lambda a: a.__or__, lambda b: b.__ror__)
57.68 +
57.69 +def pow(a, b):
57.70 + return binary_op(a, b, lambda a: a.__pow__, lambda b: b.__rpow__)
57.71 +
57.72 +def rshift(a, b):
57.73 + return binary_op(a, b, lambda a: a.__rshift__, lambda b: b.__rrshift__)
57.74 +
57.75 +def sub(a, b):
57.76 + return binary_op(a, b, lambda a: a.__sub__, lambda b: b.__rsub__)
57.77 +
57.78 +def xor(a, b):
57.79 + return binary_op(a, b, lambda a: a.__xor__, lambda b: b.__rxor__)
57.80 +
57.81 +# vim: tabstop=4 expandtab shiftwidth=4
58.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
58.2 +++ b/lib/operator/comparison.py Tue Aug 30 22:09:17 2016 +0200
58.3 @@ -0,0 +1,51 @@
58.4 +#!/usr/bin/env python
58.5 +
58.6 +"""
58.7 +Operator support.
58.8 +
58.9 +Copyright (C) 2010, 2013, 2015 Paul Boddie <paul@boddie.org.uk>
58.10 +
58.11 +This program is free software; you can redistribute it and/or modify it under
58.12 +the terms of the GNU General Public License as published by the Free Software
58.13 +Foundation; either version 3 of the License, or (at your option) any later
58.14 +version.
58.15 +
58.16 +This program is distributed in the hope that it will be useful, but WITHOUT
58.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
58.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
58.19 +details.
58.20 +
58.21 +You should have received a copy of the GNU General Public License along with
58.22 +this program. If not, see <http://www.gnu.org/licenses/>.
58.23 +"""
58.24 +
58.25 +from operator.core import binary_op
58.26 +
58.27 +# These functions defer method lookup by wrapping the attribute access in
58.28 +# lambda functions. Thus, the appropriate methods are defined locally, but no
58.29 +# attempt to obtain them is made until the generic function is called.
58.30 +
58.31 +# NOTE: The compiler should make it possible for the following functions to call
58.32 +# NOTE: the generic operator implementations with no additional call overhead.
58.33 +
58.34 +# Comparison functions.
58.35 +
58.36 +def eq(a, b):
58.37 + return binary_op(a, b, lambda a: a.__eq__, lambda b: b.__eq__)
58.38 +
58.39 +def ge(a, b):
58.40 + return binary_op(a, b, lambda a: a.__ge__, lambda b: b.__le__)
58.41 +
58.42 +def gt(a, b):
58.43 + return binary_op(a, b, lambda a: a.__gt__, lambda b: b.__lt__)
58.44 +
58.45 +def le(a, b):
58.46 + return binary_op(a, b, lambda a: a.__le__, lambda b: b.__ge__)
58.47 +
58.48 +def lt(a, b):
58.49 + return binary_op(a, b, lambda a: a.__lt__, lambda b: b.__gt__)
58.50 +
58.51 +def ne(a, b):
58.52 + return binary_op(a, b, lambda a: a.__ne__, lambda b: b.__ne__)
58.53 +
58.54 +# vim: tabstop=4 expandtab shiftwidth=4
59.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
59.2 +++ b/lib/operator/core.py Tue Aug 30 22:09:17 2016 +0200
59.3 @@ -0,0 +1,114 @@
59.4 +#!/usr/bin/env python
59.5 +
59.6 +"""
59.7 +Operator support.
59.8 +
59.9 +Copyright (C) 2010, 2013, 2015, 2016 Paul Boddie <paul@boddie.org.uk>
59.10 +
59.11 +This program is free software; you can redistribute it and/or modify it under
59.12 +the terms of the GNU General Public License as published by the Free Software
59.13 +Foundation; either version 3 of the License, or (at your option) any later
59.14 +version.
59.15 +
59.16 +This program is distributed in the hope that it will be useful, but WITHOUT
59.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
59.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
59.19 +details.
59.20 +
59.21 +You should have received a copy of the GNU General Public License along with
59.22 +this program. If not, see <http://www.gnu.org/licenses/>.
59.23 +"""
59.24 +
59.25 +# Define "is" and "is not" in terms of native operations. They are imported by
59.26 +# the operator.binary module.
59.27 +
59.28 +from native import _is as is_, _is_not as is_not
59.29 +
59.30 +def binary_op(a, b, left_accessor, right_accessor):
59.31 +
59.32 + """
59.33 + A single parameterised function providing the binary operator mechanism for
59.34 + arguments 'a' and 'b' using accessors given as 'left_accessor' and
59.35 + 'right_accessor' which provide the methods for the operands.
59.36 + """
59.37 +
59.38 + # First, try and get a method for the left argument, and then call it with
59.39 + # the right argument.
59.40 +
59.41 + try:
59.42 + fn = left_accessor(a)
59.43 + except AttributeError:
59.44 + pass
59.45 + else:
59.46 + result = fn(b)
59.47 + if is_not(result, NotImplemented):
59.48 + return result
59.49 +
59.50 + # Otherwise, try and get a method for the right argument, and then call it
59.51 + # with the left argument.
59.52 +
59.53 + try:
59.54 + fn = right_accessor(b)
59.55 + except AttributeError:
59.56 + pass
59.57 + else:
59.58 + result = fn(a)
59.59 + if is_not(result, NotImplemented):
59.60 + return result
59.61 +
59.62 + # Where no methods were available, or if neither method could support the
59.63 + # operation, raise an exception.
59.64 +
59.65 + raise TypeError
59.66 +
59.67 +def unary_op(a, accessor):
59.68 +
59.69 + """
59.70 + A single parameterised function providing the unary operator mechanism for
59.71 + the argument 'a' using the given 'accessor' to provide the method for the
59.72 + operand.
59.73 + """
59.74 +
59.75 + # First, try and get a method for the argument, and then call it.
59.76 +
59.77 + try:
59.78 + fn = accessor(a)
59.79 + except AttributeError:
59.80 + pass
59.81 + else:
59.82 + result = fn()
59.83 + if is_not(result, NotImplemented):
59.84 + return result
59.85 +
59.86 + # Where no method was available, or if the method could not support the
59.87 + # operation, raise an exception.
59.88 +
59.89 + raise TypeError
59.90 +
59.91 +def augassign(a, b, augmented_accessor, left_accessor, right_accessor):
59.92 +
59.93 + """
59.94 + A single parameterised function providing the augmented assignment mechanism
59.95 + for arguments 'a' and 'b' either using 'augmented_accessor' (directly
59.96 + affecting 'a') or using 'left_accessor' and 'right_accessor' (conventional
59.97 + operator method accessors).
59.98 +
59.99 + The result of the assignment is returned.
59.100 + """
59.101 +
59.102 + # First, try and get a method that directly affects the assignment target.
59.103 +
59.104 + try:
59.105 + fn = augmented_accessor(a)
59.106 + except AttributeError:
59.107 + pass
59.108 + else:
59.109 + result = fn(b)
59.110 + if is_not(result, NotImplemented):
59.111 + return result
59.112 +
59.113 + # Otherwise, attempt a conventional binary operation.
59.114 +
59.115 + return binary_op(a, b, left_accessor, right_accessor)
59.116 +
59.117 +# vim: tabstop=4 expandtab shiftwidth=4
60.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
60.2 +++ b/lib/operator/sequence.py Tue Aug 30 22:09:17 2016 +0200
60.3 @@ -0,0 +1,46 @@
60.4 +#!/usr/bin/env python
60.5 +
60.6 +"""
60.7 +Operator support.
60.8 +
60.9 +Copyright (C) 2010, 2013, 2015 Paul Boddie <paul@boddie.org.uk>
60.10 +
60.11 +This program is free software; you can redistribute it and/or modify it under
60.12 +the terms of the GNU General Public License as published by the Free Software
60.13 +Foundation; either version 3 of the License, or (at your option) any later
60.14 +version.
60.15 +
60.16 +This program is distributed in the hope that it will be useful, but WITHOUT
60.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
60.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
60.19 +details.
60.20 +
60.21 +You should have received a copy of the GNU General Public License along with
60.22 +this program. If not, see <http://www.gnu.org/licenses/>.
60.23 +"""
60.24 +
60.25 +# Necessary import since the operator module gets imported very early during
60.26 +# builtins initialisation.
60.27 +
60.28 +from __builtins__.span import slice
60.29 +
60.30 +# NOTE: The compiler should make it possible for the following functions to call
60.31 +# NOTE: the generic operator implementations with no additional call overhead.
60.32 +
60.33 +# Access and slicing functions.
60.34 +
60.35 +def getitem(a, b):
60.36 + return a.__getitem__(b)
60.37 +
60.38 +def setitem(a, b, c):
60.39 + a.__setitem__(b, c)
60.40 +
60.41 +# NOTE: Should be able to optimise temporary instance allocations for slices.
60.42 +
60.43 +def getslice(a, b, c):
60.44 + return a.__getitem__(slice(b, c))
60.45 +
60.46 +def setslice(a, b, c, d):
60.47 + a.__setitem__(slice(b, c), d)
60.48 +
60.49 +# vim: tabstop=4 expandtab shiftwidth=4
61.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
61.2 +++ b/lib/operator/unary.py Tue Aug 30 22:09:17 2016 +0200
61.3 @@ -0,0 +1,45 @@
61.4 +#!/usr/bin/env python
61.5 +
61.6 +"""
61.7 +Operator support.
61.8 +
61.9 +Copyright (C) 2010, 2013, 2015 Paul Boddie <paul@boddie.org.uk>
61.10 +
61.11 +This program is free software; you can redistribute it and/or modify it under
61.12 +the terms of the GNU General Public License as published by the Free Software
61.13 +Foundation; either version 3 of the License, or (at your option) any later
61.14 +version.
61.15 +
61.16 +This program is distributed in the hope that it will be useful, but WITHOUT
61.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
61.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
61.19 +details.
61.20 +
61.21 +You should have received a copy of the GNU General Public License along with
61.22 +this program. If not, see <http://www.gnu.org/licenses/>.
61.23 +"""
61.24 +
61.25 +from operator.core import unary_op
61.26 +
61.27 +# These functions defer method lookup by wrapping the attribute access in
61.28 +# lambda functions. Thus, the appropriate methods are defined locally, but no
61.29 +# attempt to obtain them is made until the generic function is called.
61.30 +
61.31 +# NOTE: The compiler should make it possible for the following functions to call
61.32 +# NOTE: the generic operator implementations with no additional call overhead.
61.33 +
61.34 +# Unary operator functions.
61.35 +
61.36 +def invert(a):
61.37 + return unary_op(a, lambda a: a.__invert__)
61.38 +
61.39 +def neg(a):
61.40 + return unary_op(a, lambda a: a.__neg__)
61.41 +
61.42 +def not_(a):
61.43 + return not a
61.44 +
61.45 +def pos(a):
61.46 + return unary_op(a, lambda a: a.__pos__)
61.47 +
61.48 +# vim: tabstop=4 expandtab shiftwidth=4
63.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
63.2 +++ b/lib/parser.py Tue Aug 30 22:09:17 2016 +0200
63.3 @@ -0,0 +1,27 @@
63.4 +#!/usr/bin/env python
63.5 +
63.6 +class ASTType:
63.7 + pass
63.8 +
63.9 +class ParserError(Exception):
63.10 + pass
63.11 +
63.12 +class STType:
63.13 + pass
63.14 +
63.15 +def ast2list(ast): pass
63.16 +def ast2tuple(ast): pass
63.17 +def compileast(ast, filename=None): pass
63.18 +def compilest(st): pass
63.19 +def expr(s): pass
63.20 +def isexpr(ast): pass
63.21 +def issuite(ast): pass
63.22 +def sequence2ast(sequence): pass
63.23 +def sequence2st(sequence): pass
63.24 +def st2list(st, line_info=None, col_info=None): pass
63.25 +def st2tuple(st, line_info=None, col_info=None): pass
63.26 +def suite(suite): pass
63.27 +def tuple2ast(sequence): pass
63.28 +def tuple2st(sequence): pass
63.29 +
63.30 +# vim: tabstop=4 expandtab shiftwidth=4
64.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
64.2 +++ b/lib/posix/__init__.py Tue Aug 30 22:09:17 2016 +0200
64.3 @@ -0,0 +1,12 @@
64.4 +#!/usr/bin/env python
64.5 +
64.6 +from posix.core import name, linesep
64.7 +from posix.conf import *
64.8 +from posix.filesys import *
64.9 +from posix.io import *
64.10 +from posix.process import *
64.11 +from posix.random import *
64.12 +from posix.stat import *
64.13 +from posix.temp import *
64.14 +
64.15 +# vim: tabstop=4 expandtab shiftwidth=4
65.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
65.2 +++ b/lib/posix/conf.py Tue Aug 30 22:09:17 2016 +0200
65.3 @@ -0,0 +1,8 @@
65.4 +#!/usr/bin/env python
65.5 +
65.6 +def confstr(name): pass
65.7 +def pathconf(path, name): pass
65.8 +def strerror(code): pass
65.9 +def sysconf(name): pass
65.10 +
65.11 +# vim: tabstop=4 expandtab shiftwidth=4
66.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
66.2 +++ b/lib/posix/core.py Tue Aug 30 22:09:17 2016 +0200
66.3 @@ -0,0 +1,6 @@
66.4 +#!/usr/bin/env python
66.5 +
66.6 +name = 'posix'
66.7 +linesep = '\n'
66.8 +
66.9 +# vim: tabstop=4 expandtab shiftwidth=4
67.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
67.2 +++ b/lib/posix/filesys.py Tue Aug 30 22:09:17 2016 +0200
67.3 @@ -0,0 +1,31 @@
67.4 +#!/usr/bin/env python
67.5 +
67.6 +def access(path, mode): pass
67.7 +def chdir(path): pass
67.8 +def chmod(path, mode): pass
67.9 +def chown(path, uid, gid): pass
67.10 +def lchown(path, uid, gid): pass
67.11 +def link(src, dst): pass
67.12 +def listdir(path): pass
67.13 +def lstat(path): pass
67.14 +def major(device): pass
67.15 +def makedev(major, minor): pass
67.16 +def minor(device): pass
67.17 +def mkdir(path, mode=0777): pass
67.18 +def mkfifo(filename, mode=0666): pass
67.19 +def mknod(filename, mode=0600, device=None): pass
67.20 +def read(fd, buffersize): pass
67.21 +def readlink(path): pass
67.22 +def remove(path): pass
67.23 +def rename(old, new): pass
67.24 +def rmdir(path): pass
67.25 +def symlink(src, dst): pass
67.26 +def unlink(path): pass
67.27 +def utime(path, (atime, mtime)): pass
67.28 +
67.29 +F_OK = 0
67.30 +R_OK = 4
67.31 +W_OK = 2
67.32 +X_OK = 1
67.33 +
67.34 +# vim: tabstop=4 expandtab shiftwidth=4
68.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
68.2 +++ b/lib/posix/io.py Tue Aug 30 22:09:17 2016 +0200
68.3 @@ -0,0 +1,54 @@
68.4 +#!/usr/bin/env python
68.5 +
68.6 +def close(fd): pass
68.7 +def closerange(fd_low, fd_high): pass
68.8 +def dup(fd): pass
68.9 +def dup2(old_fd, new_fd): pass
68.10 +def fchdir(fildes): pass
68.11 +def fchmod(fd, mode): pass
68.12 +def fchown(fd, uid, gid): pass
68.13 +def fdatasync(fildes): pass
68.14 +def fdopen(fd, mode='r', bufsize=None): pass
68.15 +def fpathconf(fd, name): pass
68.16 +def fstat(fd): pass
68.17 +def fstatvfs(fd): pass
68.18 +def fsync(fildes): pass
68.19 +def ftruncate(fd, length): pass
68.20 +def isatty(fd): pass
68.21 +def lseek(fd, pos, how): pass
68.22 +def open(filename, flag, mode=0777): pass
68.23 +def openpty(): pass
68.24 +def pipe(): pass
68.25 +def putenv(key, value): pass
68.26 +def times(): pass
68.27 +def ttyname(fd): pass
68.28 +def umask(new_mask): pass
68.29 +def uname(): pass
68.30 +def unsetenv(key): pass
68.31 +def write(fd, string): pass
68.32 +
68.33 +O_APPEND = 1024
68.34 +O_ASYNC = 8192
68.35 +O_CREAT = 64
68.36 +O_DIRECT = 16384
68.37 +O_DIRECTORY = 65536
68.38 +O_DSYNC = 4096
68.39 +O_EXCL = 128
68.40 +O_LARGEFILE = 32768
68.41 +O_NDELAY = 2048
68.42 +O_NOATIME = 262144
68.43 +O_NOCTTY = 256
68.44 +O_NOFOLLOW = 131072
68.45 +O_NONBLOCK = 2048
68.46 +O_RDONLY = 0
68.47 +O_RDWR = 2
68.48 +O_RSYNC = 1052672
68.49 +O_SYNC = 1052672
68.50 +O_TRUNC = 512
68.51 +O_WRONLY = 1
68.52 +
68.53 +SEEK_CUR = 1
68.54 +SEEK_END = 2
68.55 +SEEK_SET = 0
68.56 +
68.57 +# vim: tabstop=4 expandtab shiftwidth=4
69.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
69.2 +++ b/lib/posix/process.py Tue Aug 30 22:09:17 2016 +0200
69.3 @@ -0,0 +1,86 @@
69.4 +#!/usr/bin/env python
69.5 +
69.6 +def abort(): pass
69.7 +def chroot(path): pass
69.8 +def ctermid(): pass
69.9 +def execv(path, args): pass
69.10 +def execve(path, args, env): pass
69.11 +def fork(): pass
69.12 +def forkpty(): pass
69.13 +def getcwd(): pass
69.14 +def getcwdu(): pass
69.15 +def getegid(): pass
69.16 +def geteuid(): pass
69.17 +def getgid(): pass
69.18 +def getgroups(): pass
69.19 +def getloadavg(): pass
69.20 +def getlogin(): pass
69.21 +def getpgid(pid): pass
69.22 +def getpgrp(): pass
69.23 +def getpid(): pass
69.24 +def getppid(): pass
69.25 +def getresgid(): pass
69.26 +def getresuid(): pass
69.27 +def getsid(pid): pass
69.28 +def getuid(): pass
69.29 +def initgroups(username, gid): pass
69.30 +def kill(pid, sig): pass
69.31 +def killpg(pgid, sig): pass
69.32 +def nice(inc): pass
69.33 +def popen(command, mode='r', bufsize=None): pass
69.34 +def setegid(gid): pass
69.35 +def seteuid(uid): pass
69.36 +def setgid(gid): pass
69.37 +def setgroups(list): pass
69.38 +def setpgid(pid, pgrp): pass
69.39 +def setpgrp(): pass
69.40 +def setregid(rgid, egid): pass
69.41 +def setresgid(rgid, egid, sgid): pass
69.42 +def setresuid(ruid, euid, suid): pass
69.43 +def setreuid(ruid, euid): pass
69.44 +def setsid(): pass
69.45 +def setuid(uid): pass
69.46 +def system(command): pass
69.47 +def tcgetpgrp(fd): pass
69.48 +def tcsetpgrp(fd, pgid): pass
69.49 +def wait(): pass
69.50 +def wait3(options): pass
69.51 +def wait4(pid, options): pass
69.52 +def waitpid(pid, options): pass
69.53 +
69.54 +def WCOREDUMP(status): pass
69.55 +def WEXITSTATUS(status): pass
69.56 +def WIFCONTINUED(status): pass
69.57 +def WIFEXITED(status): pass
69.58 +def WIFSIGNALED(status): pass
69.59 +def WIFSTOPPED(status): pass
69.60 +def WSTOPSIG(status): pass
69.61 +def WTERMSIG(status): pass
69.62 +
69.63 +EX_CANTCREAT = 73
69.64 +EX_CONFIG = 78
69.65 +EX_DATAERR = 65
69.66 +EX_IOERR = 74
69.67 +EX_NOHOST = 68
69.68 +EX_NOINPUT = 66
69.69 +EX_NOPERM = 77
69.70 +EX_NOUSER = 67
69.71 +EX_OK = 0
69.72 +EX_OSERR = 71
69.73 +EX_OSFILE = 72
69.74 +EX_PROTOCOL = 76
69.75 +EX_SOFTWARE = 70
69.76 +EX_TEMPFAIL = 75
69.77 +EX_UNAVAILABLE = 69
69.78 +EX_USAGE = 64
69.79 +
69.80 +NGROUPS_MAX = 65536
69.81 +
69.82 +P_WAIT = 0
69.83 +P_NOWAIT = P_NOWAITO = 1
69.84 +
69.85 +WCONTINUED = 8
69.86 +WNOHANG = 1
69.87 +WUNTRACED = 2
69.88 +
69.89 +# vim: tabstop=4 expandtab shiftwidth=4
70.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
70.2 +++ b/lib/posix/random.py Tue Aug 30 22:09:17 2016 +0200
70.3 @@ -0,0 +1,5 @@
70.4 +#!/usr/bin/env python
70.5 +
70.6 +def urandom(n): pass
70.7 +
70.8 +# vim: tabstop=4 expandtab shiftwidth=4
71.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
71.2 +++ b/lib/posix/stat.py Tue Aug 30 22:09:17 2016 +0200
71.3 @@ -0,0 +1,56 @@
71.4 +#!/usr/bin/env python
71.5 +
71.6 +class stat_result:
71.7 + def __init__(self, st_atime, st_blksize, st_blocks, st_ctime, st_dev, st_gid, st_ino, st_mode, st_mtime, st_nlink, st_rdev, st_size, st_uid):
71.8 + self.st_atime = st_atime
71.9 + self.st_blksize = st_blksize
71.10 + self.st_blocks = st_blocks
71.11 + self.st_ctime = st_ctime
71.12 + self.st_dev = st_dev
71.13 + self.st_gid = st_gid
71.14 + self.st_ino = st_ino
71.15 + self.st_mode = st_mode
71.16 + self.st_mtime = st_mtime
71.17 + self.st_nlink = st_nlink
71.18 + self.st_rdev = st_rdev
71.19 + self.st_size = st_size
71.20 + self.st_uid = st_uid
71.21 +
71.22 + n_fields = 16
71.23 + n_sequence_fields = 10
71.24 + n_unnamed_fields = 3
71.25 +
71.26 +class statvfs_result:
71.27 + def __init__(self, f_bavail, f_bfree, f_blocks, f_bsize, f_favail, f_ffree, f_files, f_flag, f_frsize, f_namemax):
71.28 + self.f_bavail = f_bavail
71.29 + self.f_bfree = f_bfree
71.30 + self.f_blocks = f_blocks
71.31 + self.f_bsize = f_bsize
71.32 + self.f_favail = f_favail
71.33 + self.f_ffree = f_ffree
71.34 + self.f_files = f_files
71.35 + self.f_flag = f_flag
71.36 + self.f_frsize = f_frsize
71.37 + self.f_namemax = f_namemax
71.38 +
71.39 + n_fields = 10
71.40 + n_sequence_fields = 10
71.41 + n_unnamed_fields = 0
71.42 +
71.43 +def stat(path): pass
71.44 +def stat_float_times(newval=None): pass
71.45 +def statvfs(path): pass
71.46 +
71.47 +ST_APPEND = 256
71.48 +ST_MANDLOCK = 64
71.49 +ST_NOATIME = 1024
71.50 +ST_NODEV = 4
71.51 +ST_NODIRATIME = 2048
71.52 +ST_NOEXEC = 8
71.53 +ST_NOSUID = 2
71.54 +ST_RDONLY = 1
71.55 +ST_RELATIME = 4096
71.56 +ST_SYNCHRONOUS = 16
71.57 +ST_WRITE = 128
71.58 +
71.59 +# vim: tabstop=4 expandtab shiftwidth=4
72.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
72.2 +++ b/lib/posix/temp.py Tue Aug 30 22:09:17 2016 +0200
72.3 @@ -0,0 +1,9 @@
72.4 +#!/usr/bin/env python
72.5 +
72.6 +def tempnam(dir=None, prefix=None): pass
72.7 +def tmpfile(): pass
72.8 +def tmpnam(): pass
72.9 +
72.10 +TMP_MAX = 238328
72.11 +
72.12 +# vim: tabstop=4 expandtab shiftwidth=4
73.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
73.2 +++ b/lib/posixpath.py Tue Aug 30 22:09:17 2016 +0200
73.3 @@ -0,0 +1,420 @@
73.4 +"""Common operations on Posix pathnames.
73.5 +
73.6 +Instead of importing this module directly, import os and refer to
73.7 +this module as os.path. The "os.path" name is an alias for this
73.8 +module on Posix systems; on other systems (e.g. Mac, Windows),
73.9 +os.path provides the same operations in a manner specific to that
73.10 +platform, and is an alias to another module (e.g. macpath, ntpath).
73.11 +
73.12 +Some of this can actually be useful on non-Posix systems too, e.g.
73.13 +for manipulation of the pathname component of URLs.
73.14 +"""
73.15 +
73.16 +from genericos import environ, error, fstat, getcwd, getcwdu, getuid, listdir, lstat, readlink
73.17 +import sys
73.18 +import stat
73.19 +import genericpath
73.20 +from genericpath import *
73.21 +
73.22 +try:
73.23 + _unicode = unicode
73.24 +except NameError:
73.25 + # If Python is built without Unicode support, the unicode type
73.26 + # will not exist. Fake one.
73.27 + class _unicode(object):
73.28 + pass
73.29 +
73.30 +__all__ = ["normcase","isabs","join","splitdrive","split","splitext",
73.31 + "basename","dirname","commonprefix","getsize","getmtime",
73.32 + "getatime","getctime","islink","exists","lexists","isdir","isfile",
73.33 + "ismount","walk","expanduser","expandvars","normpath","abspath",
73.34 + "samefile","sameopenfile","samestat",
73.35 + "curdir","pardir","sep","pathsep","defpath","altsep","extsep",
73.36 + "devnull","realpath","supports_unicode_filenames","relpath"]
73.37 +
73.38 +# strings representing various path-related bits and pieces
73.39 +curdir = '.'
73.40 +pardir = '..'
73.41 +extsep = '.'
73.42 +sep = '/'
73.43 +pathsep = ':'
73.44 +defpath = ':/bin:/usr/bin'
73.45 +altsep = None
73.46 +devnull = '/dev/null'
73.47 +
73.48 +# Normalize the case of a pathname. Trivial in Posix, string.lower on Mac.
73.49 +# On MS-DOS this may also turn slashes into backslashes; however, other
73.50 +# normalizations (such as optimizing '../' away) are not allowed
73.51 +# (another function should be defined to do that).
73.52 +
73.53 +def normcase(s):
73.54 + """Normalize case of pathname. Has no effect under Posix"""
73.55 + return s
73.56 +
73.57 +
73.58 +# Return whether a path is absolute.
73.59 +# Trivial in Posix, harder on the Mac or MS-DOS.
73.60 +
73.61 +def isabs(s):
73.62 + """Test whether a path is absolute"""
73.63 + return s.startswith('/')
73.64 +
73.65 +
73.66 +# Join pathnames.
73.67 +# Ignore the previous parts if a part is absolute.
73.68 +# Insert a '/' unless the first part is empty or already ends in '/'.
73.69 +
73.70 +def join(a, *p):
73.71 + """Join two or more pathname components, inserting '/' as needed.
73.72 + If any component is an absolute path, all previous path components
73.73 + will be discarded. An empty last part will result in a path that
73.74 + ends with a separator."""
73.75 + path = a
73.76 + for b in p:
73.77 + if b.startswith('/'):
73.78 + path = b
73.79 + elif path == '' or path.endswith('/'):
73.80 + path += b
73.81 + else:
73.82 + path += '/' + b
73.83 + return path
73.84 +
73.85 +
73.86 +# Split a path in head (everything up to the last '/') and tail (the
73.87 +# rest). If the path ends in '/', tail will be empty. If there is no
73.88 +# '/' in the path, head will be empty.
73.89 +# Trailing '/'es are stripped from head unless it is the root.
73.90 +
73.91 +def split(p):
73.92 + """Split a pathname. Returns tuple "(head, tail)" where "tail" is
73.93 + everything after the final slash. Either part may be empty."""
73.94 + i = p.rfind('/') + 1
73.95 + head, tail = p[:i], p[i:]
73.96 + if head and head != '/'*len(head):
73.97 + head = head.rstrip('/')
73.98 + return head, tail
73.99 +
73.100 +
73.101 +# Split a path in root and extension.
73.102 +# The extension is everything starting at the last dot in the last
73.103 +# pathname component; the root is everything before that.
73.104 +# It is always true that root + ext == p.
73.105 +
73.106 +def splitext(p):
73.107 + return genericpath._splitext(p, sep, altsep, extsep)
73.108 +
73.109 +# Split a pathname into a drive specification and the rest of the
73.110 +# path. Useful on DOS/Windows/NT; on Unix, the drive is always empty.
73.111 +
73.112 +def splitdrive(p):
73.113 + """Split a pathname into drive and path. On Posix, drive is always
73.114 + empty."""
73.115 + return '', p
73.116 +
73.117 +
73.118 +# Return the tail (basename) part of a path, same as split(path)[1].
73.119 +
73.120 +def basename(p):
73.121 + """Returns the final component of a pathname"""
73.122 + i = p.rfind('/') + 1
73.123 + return p[i:]
73.124 +
73.125 +
73.126 +# Return the head (dirname) part of a path, same as split(path)[0].
73.127 +
73.128 +def dirname(p):
73.129 + """Returns the directory component of a pathname"""
73.130 + i = p.rfind('/') + 1
73.131 + head = p[:i]
73.132 + if head and head != '/'*len(head):
73.133 + head = head.rstrip('/')
73.134 + return head
73.135 +
73.136 +
73.137 +# Is a path a symbolic link?
73.138 +# This will always return false on systems where os.lstat doesn't exist.
73.139 +
73.140 +def islink(path):
73.141 + """Test whether a path is a symbolic link"""
73.142 + try:
73.143 + st = lstat(path)
73.144 + except (error, AttributeError):
73.145 + return False
73.146 + return stat.S_ISLNK(st.st_mode)
73.147 +
73.148 +# Being true for dangling symbolic links is also useful.
73.149 +
73.150 +def lexists(path):
73.151 + """Test whether a path exists. Returns True for broken symbolic links"""
73.152 + try:
73.153 + lstat(path)
73.154 + except error:
73.155 + return False
73.156 + return True
73.157 +
73.158 +
73.159 +# Are two filenames really pointing to the same file?
73.160 +
73.161 +def samefile(f1, f2):
73.162 + """Test whether two pathnames reference the same actual file"""
73.163 + s1 = stat(f1)
73.164 + s2 = stat(f2)
73.165 + return samestat(s1, s2)
73.166 +
73.167 +
73.168 +# Are two open files really referencing the same file?
73.169 +# (Not necessarily the same file descriptor!)
73.170 +
73.171 +def sameopenfile(fp1, fp2):
73.172 + """Test whether two open file objects reference the same file"""
73.173 + s1 = fstat(fp1)
73.174 + s2 = fstat(fp2)
73.175 + return samestat(s1, s2)
73.176 +
73.177 +
73.178 +# Are two stat buffers (obtained from stat, fstat or lstat)
73.179 +# describing the same file?
73.180 +
73.181 +def samestat(s1, s2):
73.182 + """Test whether two stat buffers reference the same file"""
73.183 + return s1.st_ino == s2.st_ino and \
73.184 + s1.st_dev == s2.st_dev
73.185 +
73.186 +
73.187 +# Is a path a mount point?
73.188 +# (Does this work for all UNIXes? Is it even guaranteed to work by Posix?)
73.189 +
73.190 +def ismount(path):
73.191 + """Test whether a path is a mount point"""
73.192 + if islink(path):
73.193 + # A symlink can never be a mount point
73.194 + return False
73.195 + try:
73.196 + s1 = lstat(path)
73.197 + s2 = lstat(join(path, '..'))
73.198 + except error:
73.199 + return False # It doesn't exist -- so not a mount point :-)
73.200 + dev1 = s1.st_dev
73.201 + dev2 = s2.st_dev
73.202 + if dev1 != dev2:
73.203 + return True # path/.. on a different device as path
73.204 + ino1 = s1.st_ino
73.205 + ino2 = s2.st_ino
73.206 + if ino1 == ino2:
73.207 + return True # path/.. is the same i-node as path
73.208 + return False
73.209 +
73.210 +
73.211 +# Directory tree walk.
73.212 +# For each directory under top (including top itself, but excluding
73.213 +# '.' and '..'), func(arg, dirname, filenames) is called, where
73.214 +# dirname is the name of the directory and filenames is the list
73.215 +# of files (and subdirectories etc.) in the directory.
73.216 +# The func may modify the filenames list, to implement a filter,
73.217 +# or to impose a different order of visiting.
73.218 +
73.219 +def walk(top, func, arg):
73.220 + """Directory tree walk with callback function.
73.221 +
73.222 + For each directory in the directory tree rooted at top (including top
73.223 + itself, but excluding '.' and '..'), call func(arg, dirname, fnames).
73.224 + dirname is the name of the directory, and fnames a list of the names of
73.225 + the files and subdirectories in dirname (excluding '.' and '..'). func
73.226 + may modify the fnames list in-place (e.g. via del or slice assignment),
73.227 + and walk will only recurse into the subdirectories whose names remain in
73.228 + fnames; this can be used to implement a filter, or to impose a specific
73.229 + order of visiting. No semantics are defined for, or required of, arg,
73.230 + beyond that arg is always passed to func. It can be used, e.g., to pass
73.231 + a filename pattern, or a mutable object designed to accumulate
73.232 + statistics. Passing None for arg is common."""
73.233 + try:
73.234 + names = listdir(top)
73.235 + except error:
73.236 + return
73.237 + func(arg, top, names)
73.238 + for name in names:
73.239 + name = join(top, name)
73.240 + try:
73.241 + st = lstat(name)
73.242 + except error:
73.243 + continue
73.244 + if stat.S_ISDIR(st.st_mode):
73.245 + walk(name, func, arg)
73.246 +
73.247 +
73.248 +# Expand paths beginning with '~' or '~user'.
73.249 +# '~' means $HOME; '~user' means that user's home directory.
73.250 +# If the path doesn't begin with '~', or if the user or $HOME is unknown,
73.251 +# the path is returned unchanged (leaving error reporting to whatever
73.252 +# function is called with the expanded path as argument).
73.253 +# See also module 'glob' for expansion of *, ? and [...] in pathnames.
73.254 +# (A function should also be defined to do full *sh-style environment
73.255 +# variable expansion.)
73.256 +
73.257 +def expanduser(path):
73.258 + """Expand ~ and ~user constructions. If user or $HOME is unknown,
73.259 + do nothing."""
73.260 + if not path.startswith('~'):
73.261 + return path
73.262 + i = path.find('/', 1)
73.263 + if i < 0:
73.264 + i = len(path)
73.265 + if i == 1:
73.266 + if 'HOME' not in environ:
73.267 + import pwd
73.268 + userhome = pwd.getpwuid(getuid()).pw_dir
73.269 + else:
73.270 + userhome = environ['HOME']
73.271 + else:
73.272 + import pwd
73.273 + try:
73.274 + pwent = pwd.getpwnam(path[1:i])
73.275 + except KeyError:
73.276 + return path
73.277 + userhome = pwent.pw_dir
73.278 + userhome = userhome.rstrip('/')
73.279 + return (userhome + path[i:]) or '/'
73.280 +
73.281 +
73.282 +# Expand paths containing shell variable substitutions.
73.283 +# This expands the forms $variable and ${variable} only.
73.284 +# Non-existent variables are left unchanged.
73.285 +
73.286 +_varprog = None
73.287 +
73.288 +def expandvars(path):
73.289 + """Expand shell variables of form $var and ${var}. Unknown variables
73.290 + are left unchanged."""
73.291 + global _varprog
73.292 + if '$' not in path:
73.293 + return path
73.294 + if not _varprog:
73.295 + import re
73.296 + _varprog = re.compile(r'\$(\w+|\{[^}]*\})')
73.297 + i = 0
73.298 + while True:
73.299 + m = _varprog.search(path, i)
73.300 + if not m:
73.301 + break
73.302 + i, j = m.span(0)
73.303 + name = m.group(1)
73.304 + if name.startswith('{') and name.endswith('}'):
73.305 + name = name[1:-1]
73.306 + if name in environ:
73.307 + tail = path[j:]
73.308 + path = path[:i] + environ[name]
73.309 + i = len(path)
73.310 + path += tail
73.311 + else:
73.312 + i = j
73.313 + return path
73.314 +
73.315 +
73.316 +# Normalize a path, e.g. A//B, A/./B and A/foo/../B all become A/B.
73.317 +# It should be understood that this may change the meaning of the path
73.318 +# if it contains symbolic links!
73.319 +
73.320 +def normpath(path):
73.321 + """Normalize path, eliminating double slashes, etc."""
73.322 + # Preserve unicode (if path is unicode)
73.323 + slash, dot = (u'/', u'.') if isinstance(path, _unicode) else ('/', '.')
73.324 + if path == '':
73.325 + return dot
73.326 + initial_slashes = path.startswith('/')
73.327 + # POSIX allows one or two initial slashes, but treats three or more
73.328 + # as single slash.
73.329 + if (initial_slashes and
73.330 + path.startswith('//') and not path.startswith('///')):
73.331 + initial_slashes = 2
73.332 + comps = path.split('/')
73.333 + new_comps = []
73.334 + for comp in comps:
73.335 + if comp in ('', '.'):
73.336 + continue
73.337 + if (comp != '..' or (not initial_slashes and not new_comps) or
73.338 + (new_comps and new_comps[-1] == '..')):
73.339 + new_comps.append(comp)
73.340 + elif new_comps:
73.341 + new_comps.pop()
73.342 + comps = new_comps
73.343 + path = slash.join(comps)
73.344 + if initial_slashes:
73.345 + path = slash*initial_slashes + path
73.346 + return path or dot
73.347 +
73.348 +
73.349 +def abspath(path):
73.350 + """Return an absolute path."""
73.351 + if not isabs(path):
73.352 + if isinstance(path, _unicode):
73.353 + cwd = getcwdu()
73.354 + else:
73.355 + cwd = getcwd()
73.356 + path = join(cwd, path)
73.357 + return normpath(path)
73.358 +
73.359 +
73.360 +# Return a canonical path (i.e. the absolute location of a file on the
73.361 +# filesystem).
73.362 +
73.363 +def realpath(filename):
73.364 + """Return the canonical path of the specified filename, eliminating any
73.365 +symbolic links encountered in the path."""
73.366 + if isabs(filename):
73.367 + bits = ['/'] + filename.split('/')[1:]
73.368 + else:
73.369 + bits = [''] + filename.split('/')
73.370 +
73.371 + for i in range(2, len(bits)+1):
73.372 + component = join(*bits[0:i])
73.373 + # Resolve symbolic links.
73.374 + if islink(component):
73.375 + resolved = _resolve_link(component)
73.376 + if resolved is None:
73.377 + # Infinite loop -- return original component + rest of the path
73.378 + return abspath(join(*([component] + bits[i:])))
73.379 + else:
73.380 + newpath = join(*([resolved] + bits[i:]))
73.381 + return realpath(newpath)
73.382 +
73.383 + return abspath(filename)
73.384 +
73.385 +
73.386 +def _resolve_link(path):
73.387 + """Internal helper function. Takes a path and follows symlinks
73.388 + until we either arrive at something that isn't a symlink, or
73.389 + encounter a path we've seen before (meaning that there's a loop).
73.390 + """
73.391 + paths_seen = set()
73.392 + while islink(path):
73.393 + if path in paths_seen:
73.394 + # Already seen this path, so we must have a symlink loop
73.395 + return None
73.396 + paths_seen.add(path)
73.397 + # Resolve where the link points to
73.398 + resolved = readlink(path)
73.399 + if not isabs(resolved):
73.400 + dir = dirname(path)
73.401 + path = normpath(join(dir, resolved))
73.402 + else:
73.403 + path = normpath(resolved)
73.404 + return path
73.405 +
73.406 +supports_unicode_filenames = (sys.platform == 'darwin')
73.407 +
73.408 +def relpath(path, start=curdir):
73.409 + """Return a relative version of a path"""
73.410 +
73.411 + if not path:
73.412 + raise ValueError("no path specified")
73.413 +
73.414 + start_list = [x for x in abspath(start).split(sep) if x]
73.415 + path_list = [x for x in abspath(path).split(sep) if x]
73.416 +
73.417 + # Work out how much of the filepath is shared by start and path.
73.418 + i = len(commonprefix([start_list, path_list]))
73.419 +
73.420 + rel_list = [pardir] * (len(start_list)-i) + path_list[i:]
73.421 + if not rel_list:
73.422 + return curdir
73.423 + return join(*rel_list)
74.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
74.2 +++ b/lib/pwd.py Tue Aug 30 22:09:17 2016 +0200
74.3 @@ -0,0 +1,22 @@
74.4 +#!/usr/bin/env python
74.5 +
74.6 +class struct_passwd:
74.7 +
74.8 + def __init__(self, pw_dir, pw_gecos, pw_gid, pw_name, pw_passwd, pw_shell, pw_uid):
74.9 + self.pw_dir = pw_dir
74.10 + self.pw_gecos = pw_gecos
74.11 + self.pw_gid = pw_gid
74.12 + self.pw_name = pw_name
74.13 + self.pw_passwd = pw_passwd
74.14 + self.pw_shell = pw_shell
74.15 + self.pw_uid = pw_uid
74.16 +
74.17 + n_fields = 7
74.18 + n_sequence_fields = 7
74.19 + n_unnamed_fields = 0
74.20 +
74.21 +def getpwall(): pass
74.22 +def getpwnam(name): pass
74.23 +def getpwuid(uid): pass
74.24 +
74.25 +# vim: tabstop=4 expandtab shiftwidth=4
75.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
75.2 +++ b/lib/pygame/__init__.py Tue Aug 30 22:09:17 2016 +0200
75.3 @@ -0,0 +1,24 @@
75.4 +#!/usr/bin/env python
75.5 +
75.6 +"""
75.7 +PyGame compatibility package.
75.8 +
75.9 +Copyright (C) 2011 Paul Boddie <paul@boddie.org.uk>
75.10 +
75.11 +This program is free software; you can redistribute it and/or modify it under
75.12 +the terms of the GNU General Public License as published by the Free Software
75.13 +Foundation; either version 3 of the License, or (at your option) any later
75.14 +version.
75.15 +
75.16 +This program is distributed in the hope that it will be useful, but WITHOUT
75.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
75.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
75.19 +details.
75.20 +
75.21 +You should have received a copy of the GNU General Public License along with
75.22 +this program. If not, see <http://www.gnu.org/licenses/>.
75.23 +"""
75.24 +
75.25 +from pygame.constants import *
75.26 +
75.27 +# vim: tabstop=4 expandtab shiftwidth=4
77.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
77.2 +++ b/lib/random.py Tue Aug 30 22:09:17 2016 +0200
77.3 @@ -0,0 +1,11 @@
77.4 +#!/usr/bin/env python
77.5 +
77.6 +from _random import Random
77.7 +
77.8 +def random():
77.9 + pass
77.10 +
77.11 +def randrange(start, stop=None, step=1):
77.12 + pass
77.13 +
77.14 +# vim: tabstop=4 expandtab shiftwidth=4
78.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
78.2 +++ b/lib/re.py Tue Aug 30 22:09:17 2016 +0200
78.3 @@ -0,0 +1,315 @@
78.4 +#
78.5 +# Secret Labs' Regular Expression Engine
78.6 +#
78.7 +# re-compatible interface for the sre matching engine
78.8 +#
78.9 +# Copyright (c) 1998-2001 by Secret Labs AB. All rights reserved.
78.10 +#
78.11 +# This version of the SRE library can be redistributed under CNRI's
78.12 +# Python 1.6 license. For any other use, please contact Secret Labs
78.13 +# AB (info@pythonware.com).
78.14 +#
78.15 +# Portions of this engine have been developed in cooperation with
78.16 +# CNRI. Hewlett-Packard provided funding for 1.6 integration and
78.17 +# other compatibility work.
78.18 +#
78.19 +
78.20 +r"""Support for regular expressions (RE).
78.21 +
78.22 +This module provides regular expression matching operations similar to
78.23 +those found in Perl. It supports both 8-bit and Unicode strings; both
78.24 +the pattern and the strings being processed can contain null bytes and
78.25 +characters outside the US ASCII range.
78.26 +
78.27 +Regular expressions can contain both special and ordinary characters.
78.28 +Most ordinary characters, like "A", "a", or "0", are the simplest
78.29 +regular expressions; they simply match themselves. You can
78.30 +concatenate ordinary characters, so last matches the string 'last'.
78.31 +
78.32 +The special characters are:
78.33 + "." Matches any character except a newline.
78.34 + "^" Matches the start of the string.
78.35 + "$" Matches the end of the string or just before the newline at
78.36 + the end of the string.
78.37 + "*" Matches 0 or more (greedy) repetitions of the preceding RE.
78.38 + Greedy means that it will match as many repetitions as possible.
78.39 + "+" Matches 1 or more (greedy) repetitions of the preceding RE.
78.40 + "?" Matches 0 or 1 (greedy) of the preceding RE.
78.41 + *?,+?,?? Non-greedy versions of the previous three special characters.
78.42 + {m,n} Matches from m to n repetitions of the preceding RE.
78.43 + {m,n}? Non-greedy version of the above.
78.44 + "\\" Either escapes special characters or signals a special sequence.
78.45 + [] Indicates a set of characters.
78.46 + A "^" as the first character indicates a complementing set.
78.47 + "|" A|B, creates an RE that will match either A or B.
78.48 + (...) Matches the RE inside the parentheses.
78.49 + The contents can be retrieved or matched later in the string.
78.50 + (?iLmsux) Set the I, L, M, S, U, or X flag for the RE (see below).
78.51 + (?:...) Non-grouping version of regular parentheses.
78.52 + (?P<name>...) The substring matched by the group is accessible by name.
78.53 + (?P=name) Matches the text matched earlier by the group named name.
78.54 + (?#...) A comment; ignored.
78.55 + (?=...) Matches if ... matches next, but doesn't consume the string.
78.56 + (?!...) Matches if ... doesn't match next.
78.57 + (?<=...) Matches if preceded by ... (must be fixed length).
78.58 + (?<!...) Matches if not preceded by ... (must be fixed length).
78.59 + (?(id/name)yes|no) Matches yes pattern if the group with id/name matched,
78.60 + the (optional) no pattern otherwise.
78.61 +
78.62 +The special sequences consist of "\\" and a character from the list
78.63 +below. If the ordinary character is not on the list, then the
78.64 +resulting RE will match the second character.
78.65 + \number Matches the contents of the group of the same number.
78.66 + \A Matches only at the start of the string.
78.67 + \Z Matches only at the end of the string.
78.68 + \b Matches the empty string, but only at the start or end of a word.
78.69 + \B Matches the empty string, but not at the start or end of a word.
78.70 + \d Matches any decimal digit; equivalent to the set [0-9].
78.71 + \D Matches any non-digit character; equivalent to the set [^0-9].
78.72 + \s Matches any whitespace character; equivalent to [ \t\n\r\f\v].
78.73 + \S Matches any non-whitespace character; equiv. to [^ \t\n\r\f\v].
78.74 + \w Matches any alphanumeric character; equivalent to [a-zA-Z0-9_].
78.75 + With LOCALE, it will match the set [0-9_] plus characters defined
78.76 + as letters for the current locale.
78.77 + \W Matches the complement of \w.
78.78 + \\ Matches a literal backslash.
78.79 +
78.80 +This module exports the following functions:
78.81 + match Match a regular expression pattern to the beginning of a string.
78.82 + search Search a string for the presence of a pattern.
78.83 + sub Substitute occurrences of a pattern found in a string.
78.84 + subn Same as sub, but also return the number of substitutions made.
78.85 + split Split a string by the occurrences of a pattern.
78.86 + findall Find all occurrences of a pattern in a string.
78.87 + finditer Return an iterator yielding a match object for each match.
78.88 + compile Compile a pattern into a RegexObject.
78.89 + purge Clear the regular expression cache.
78.90 + escape Backslash all non-alphanumerics in a string.
78.91 +
78.92 +Some of the functions in this module takes flags as optional parameters:
78.93 + I IGNORECASE Perform case-insensitive matching.
78.94 + L LOCALE Make \w, \W, \b, \B, dependent on the current locale.
78.95 + M MULTILINE "^" matches the beginning of lines (after a newline)
78.96 + as well as the string.
78.97 + "$" matches the end of lines (before a newline) as well
78.98 + as the end of the string.
78.99 + S DOTALL "." matches any character at all, including the newline.
78.100 + X VERBOSE Ignore whitespace and comments for nicer looking RE's.
78.101 + U UNICODE Make \w, \W, \b, \B, dependent on the Unicode locale.
78.102 +
78.103 +This module also defines an exception 'error'.
78.104 +
78.105 +"""
78.106 +
78.107 +from sre_constants import BRANCH, SUBPATTERN
78.108 +import sys
78.109 +import sre_compile
78.110 +import sre_parse
78.111 +
78.112 +# public symbols
78.113 +__all__ = [ "match", "search", "sub", "subn", "split", "findall",
78.114 + "compile", "purge", "template", "escape", "I", "L", "M", "S", "X",
78.115 + "U", "IGNORECASE", "LOCALE", "MULTILINE", "DOTALL", "VERBOSE",
78.116 + "UNICODE", "error" ]
78.117 +
78.118 +__version__ = "2.2.1"
78.119 +
78.120 +# flags
78.121 +I = IGNORECASE = sre_compile.SRE_FLAG_IGNORECASE # ignore case
78.122 +L = LOCALE = sre_compile.SRE_FLAG_LOCALE # assume current 8-bit locale
78.123 +U = UNICODE = sre_compile.SRE_FLAG_UNICODE # assume unicode locale
78.124 +M = MULTILINE = sre_compile.SRE_FLAG_MULTILINE # make anchors look for newline
78.125 +S = DOTALL = sre_compile.SRE_FLAG_DOTALL # make dot match newline
78.126 +X = VERBOSE = sre_compile.SRE_FLAG_VERBOSE # ignore whitespace and comments
78.127 +
78.128 +# sre extensions (experimental, don't rely on these)
78.129 +T = TEMPLATE = sre_compile.SRE_FLAG_TEMPLATE # disable backtracking
78.130 +DEBUG = sre_compile.SRE_FLAG_DEBUG # dump pattern after compilation
78.131 +
78.132 +# sre exception
78.133 +error = sre_compile.error
78.134 +
78.135 +# --------------------------------------------------------------------
78.136 +# public interface
78.137 +
78.138 +def match(pattern, string, flags=0):
78.139 + """Try to apply the pattern at the start of the string, returning
78.140 + a match object, or None if no match was found."""
78.141 + return _compile(pattern, flags).match(string)
78.142 +
78.143 +def search(pattern, string, flags=0):
78.144 + """Scan through string looking for a match to the pattern, returning
78.145 + a match object, or None if no match was found."""
78.146 + return _compile(pattern, flags).search(string)
78.147 +
78.148 +def sub(pattern, repl, string, count=0, flags=0):
78.149 + """Return the string obtained by replacing the leftmost
78.150 + non-overlapping occurrences of the pattern in string by the
78.151 + replacement repl. repl can be either a string or a callable;
78.152 + if a string, backslash escapes in it are processed. If it is
78.153 + a callable, it's passed the match object and must return
78.154 + a replacement string to be used."""
78.155 + return _compile(pattern, flags).sub(repl, string, count)
78.156 +
78.157 +def subn(pattern, repl, string, count=0, flags=0):
78.158 + """Return a 2-tuple containing (new_string, number).
78.159 + new_string is the string obtained by replacing the leftmost
78.160 + non-overlapping occurrences of the pattern in the source
78.161 + string by the replacement repl. number is the number of
78.162 + substitutions that were made. repl can be either a string or a
78.163 + callable; if a string, backslash escapes in it are processed.
78.164 + If it is a callable, it's passed the match object and must
78.165 + return a replacement string to be used."""
78.166 + return _compile(pattern, flags).subn(repl, string, count)
78.167 +
78.168 +def split(pattern, string, maxsplit=0, flags=0):
78.169 + """Split the source string by the occurrences of the pattern,
78.170 + returning a list containing the resulting substrings."""
78.171 + return _compile(pattern, flags).split(string, maxsplit)
78.172 +
78.173 +def findall(pattern, string, flags=0):
78.174 + """Return a list of all non-overlapping matches in the string.
78.175 +
78.176 + If one or more groups are present in the pattern, return a
78.177 + list of groups; this will be a list of tuples if the pattern
78.178 + has more than one group.
78.179 +
78.180 + Empty matches are included in the result."""
78.181 + return _compile(pattern, flags).findall(string)
78.182 +
78.183 +if sys.hexversion >= 0x02020000:
78.184 + __all__.append("finditer")
78.185 + def finditer(pattern, string, flags=0):
78.186 + """Return an iterator over all non-overlapping matches in the
78.187 + string. For each match, the iterator returns a match object.
78.188 +
78.189 + Empty matches are included in the result."""
78.190 + return _compile(pattern, flags).finditer(string)
78.191 +
78.192 +def compile(pattern, flags=0):
78.193 + "Compile a regular expression pattern, returning a pattern object."
78.194 + return _compile(pattern, flags)
78.195 +
78.196 +def purge():
78.197 + "Clear the regular expression cache"
78.198 + _cache.clear()
78.199 + _cache_repl.clear()
78.200 +
78.201 +def template(pattern, flags=0):
78.202 + "Compile a template pattern, returning a pattern object"
78.203 + return _compile(pattern, flags|T)
78.204 +
78.205 +_alphanum = frozenset(
78.206 + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
78.207 +
78.208 +def escape(pattern):
78.209 + "Escape all non-alphanumeric characters in pattern."
78.210 + s = list(pattern)
78.211 + alphanum = _alphanum
78.212 + for i, c in enumerate(pattern):
78.213 + if c not in alphanum:
78.214 + if c == "\000":
78.215 + s[i] = "\\000"
78.216 + else:
78.217 + s[i] = "\\" + c
78.218 + return pattern[:0].join(s)
78.219 +
78.220 +# --------------------------------------------------------------------
78.221 +# internals
78.222 +
78.223 +_cache = {}
78.224 +_cache_repl = {}
78.225 +
78.226 +_pattern_type = type(sre_compile.compile("", 0))
78.227 +
78.228 +_MAXCACHE = 100
78.229 +
78.230 +def _compile(*key):
78.231 + # internal: compile pattern
78.232 + cachekey = (type(key[0]),) + key
78.233 + p = _cache.get(cachekey)
78.234 + if p is not None:
78.235 + return p
78.236 + pattern, flags = key
78.237 + if isinstance(pattern, _pattern_type):
78.238 + if flags:
78.239 + raise ValueError('Cannot process flags argument with a compiled pattern')
78.240 + return pattern
78.241 + if not sre_compile.isstring(pattern):
78.242 + raise TypeError, "first argument must be string or compiled pattern"
78.243 + try:
78.244 + p = sre_compile.compile(pattern, flags)
78.245 + except error, v:
78.246 + raise error, v # invalid expression
78.247 + if len(_cache) >= _MAXCACHE:
78.248 + _cache.clear()
78.249 + _cache[cachekey] = p
78.250 + return p
78.251 +
78.252 +def _compile_repl(*key):
78.253 + # internal: compile replacement pattern
78.254 + p = _cache_repl.get(key)
78.255 + if p is not None:
78.256 + return p
78.257 + repl, pattern = key
78.258 + try:
78.259 + p = sre_parse.parse_template(repl, pattern)
78.260 + except error, v:
78.261 + raise error, v # invalid expression
78.262 + if len(_cache_repl) >= _MAXCACHE:
78.263 + _cache_repl.clear()
78.264 + _cache_repl[key] = p
78.265 + return p
78.266 +
78.267 +def _expand(pattern, match, template):
78.268 + # internal: match.expand implementation hook
78.269 + template = sre_parse.parse_template(template, pattern)
78.270 + return sre_parse.expand_template(template, match)
78.271 +
78.272 +def _subx(pattern, template):
78.273 + # internal: pattern.sub/subn implementation helper
78.274 + template = _compile_repl(template, pattern)
78.275 + if not template[0] and len(template[1]) == 1:
78.276 + # literal replacement
78.277 + return template[1][0]
78.278 + def filter(match, template=template):
78.279 + return sre_parse.expand_template(template, match)
78.280 + return filter
78.281 +
78.282 +# --------------------------------------------------------------------
78.283 +# experimental stuff (see python-dev discussions for details)
78.284 +
78.285 +class Scanner:
78.286 + def __init__(self, lexicon, flags=0):
78.287 + self.lexicon = lexicon
78.288 + # combine phrases into a compound pattern
78.289 + p = []
78.290 + s = sre_parse.Pattern()
78.291 + s.flags = flags
78.292 + for phrase, action in lexicon:
78.293 + p.append(sre_parse.SubPattern(s, [
78.294 + (SUBPATTERN, (len(p)+1, sre_parse.parse(phrase, flags))),
78.295 + ]))
78.296 + s.groups = len(p)+1
78.297 + p = sre_parse.SubPattern(s, [(BRANCH, (None, p))])
78.298 + self.scanner = sre_compile.compile(p)
78.299 + def scan(self, string):
78.300 + result = []
78.301 + append = result.append
78.302 + match = self.scanner.scanner(string).match
78.303 + i = 0
78.304 + while 1:
78.305 + m = match()
78.306 + if not m:
78.307 + break
78.308 + j = m.end()
78.309 + if i == j:
78.310 + break
78.311 + action = self.lexicon[m.lastindex-1][1]
78.312 + if hasattr(action, '__call__'):
78.313 + self.match = m
78.314 + action = action(self, m.group())
78.315 + if action is not None:
78.316 + append(action)
78.317 + i = j
78.318 + return result, string[i:]
79.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
79.2 +++ b/lib/sre_constants.py Tue Aug 30 22:09:17 2016 +0200
79.3 @@ -0,0 +1,216 @@
79.4 +#
79.5 +# Secret Labs' Regular Expression Engine
79.6 +#
79.7 +# various symbols used by the regular expression engine.
79.8 +#
79.9 +# Copyright (c) 1998-2001 by Secret Labs AB. All rights reserved.
79.10 +#
79.11 +# See the sre.py file for information on usage and redistribution.
79.12 +#
79.13 +
79.14 +"""Internal support module for sre"""
79.15 +
79.16 +# update when constants are added or removed
79.17 +
79.18 +MAGIC = 20031017
79.19 +
79.20 +# max code word in this release
79.21 +
79.22 +MAXREPEAT = 65535
79.23 +
79.24 +# SRE standard exception (access as sre.error)
79.25 +# should this really be here?
79.26 +
79.27 +class error(Exception):
79.28 + pass
79.29 +
79.30 +# operators
79.31 +
79.32 +FAILURE = "failure"
79.33 +SUCCESS = "success"
79.34 +
79.35 +ANY = "any"
79.36 +ANY_ALL = "any_all"
79.37 +ASSERT = "assert"
79.38 +ASSERT_NOT = "assert_not"
79.39 +AT = "at"
79.40 +BIGCHARSET = "bigcharset"
79.41 +BRANCH = "branch"
79.42 +CALL = "call"
79.43 +CATEGORY = "category"
79.44 +CHARSET = "charset"
79.45 +GROUPREF = "groupref"
79.46 +GROUPREF_IGNORE = "groupref_ignore"
79.47 +GROUPREF_EXISTS = "groupref_exists"
79.48 +IN = "in"
79.49 +IN_IGNORE = "in_ignore"
79.50 +INFO = "info"
79.51 +JUMP = "jump"
79.52 +LITERAL = "literal"
79.53 +LITERAL_IGNORE = "literal_ignore"
79.54 +MARK = "mark"
79.55 +MAX_REPEAT = "max_repeat"
79.56 +MAX_UNTIL = "max_until"
79.57 +MIN_REPEAT = "min_repeat"
79.58 +MIN_UNTIL = "min_until"
79.59 +NEGATE = "negate"
79.60 +NOT_LITERAL = "not_literal"
79.61 +NOT_LITERAL_IGNORE = "not_literal_ignore"
79.62 +RANGE = "range"
79.63 +REPEAT = "repeat"
79.64 +REPEAT_ONE = "repeat_one"
79.65 +SUBPATTERN = "subpattern"
79.66 +MIN_REPEAT_ONE = "min_repeat_one"
79.67 +
79.68 +# positions
79.69 +AT_BEGINNING = "at_beginning"
79.70 +AT_BEGINNING_LINE = "at_beginning_line"
79.71 +AT_BEGINNING_STRING = "at_beginning_string"
79.72 +AT_BOUNDARY = "at_boundary"
79.73 +AT_NON_BOUNDARY = "at_non_boundary"
79.74 +AT_END = "at_end"
79.75 +AT_END_LINE = "at_end_line"
79.76 +AT_END_STRING = "at_end_string"
79.77 +AT_LOC_BOUNDARY = "at_loc_boundary"
79.78 +AT_LOC_NON_BOUNDARY = "at_loc_non_boundary"
79.79 +AT_UNI_BOUNDARY = "at_uni_boundary"
79.80 +AT_UNI_NON_BOUNDARY = "at_uni_non_boundary"
79.81 +
79.82 +# categories
79.83 +CATEGORY_DIGIT = "category_digit"
79.84 +CATEGORY_NOT_DIGIT = "category_not_digit"
79.85 +CATEGORY_SPACE = "category_space"
79.86 +CATEGORY_NOT_SPACE = "category_not_space"
79.87 +CATEGORY_WORD = "category_word"
79.88 +CATEGORY_NOT_WORD = "category_not_word"
79.89 +CATEGORY_LINEBREAK = "category_linebreak"
79.90 +CATEGORY_NOT_LINEBREAK = "category_not_linebreak"
79.91 +CATEGORY_LOC_WORD = "category_loc_word"
79.92 +CATEGORY_LOC_NOT_WORD = "category_loc_not_word"
79.93 +CATEGORY_UNI_DIGIT = "category_uni_digit"
79.94 +CATEGORY_UNI_NOT_DIGIT = "category_uni_not_digit"
79.95 +CATEGORY_UNI_SPACE = "category_uni_space"
79.96 +CATEGORY_UNI_NOT_SPACE = "category_uni_not_space"
79.97 +CATEGORY_UNI_WORD = "category_uni_word"
79.98 +CATEGORY_UNI_NOT_WORD = "category_uni_not_word"
79.99 +CATEGORY_UNI_LINEBREAK = "category_uni_linebreak"
79.100 +CATEGORY_UNI_NOT_LINEBREAK = "category_uni_not_linebreak"
79.101 +
79.102 +OPCODES = [
79.103 +
79.104 + # failure=0 success=1 (just because it looks better that way :-)
79.105 + FAILURE, SUCCESS,
79.106 +
79.107 + ANY, ANY_ALL,
79.108 + ASSERT, ASSERT_NOT,
79.109 + AT,
79.110 + BRANCH,
79.111 + CALL,
79.112 + CATEGORY,
79.113 + CHARSET, BIGCHARSET,
79.114 + GROUPREF, GROUPREF_EXISTS, GROUPREF_IGNORE,
79.115 + IN, IN_IGNORE,
79.116 + INFO,
79.117 + JUMP,
79.118 + LITERAL, LITERAL_IGNORE,
79.119 + MARK,
79.120 + MAX_UNTIL,
79.121 + MIN_UNTIL,
79.122 + NOT_LITERAL, NOT_LITERAL_IGNORE,
79.123 + NEGATE,
79.124 + RANGE,
79.125 + REPEAT,
79.126 + REPEAT_ONE,
79.127 + SUBPATTERN,
79.128 + MIN_REPEAT_ONE
79.129 +
79.130 +]
79.131 +
79.132 +ATCODES = [
79.133 + AT_BEGINNING, AT_BEGINNING_LINE, AT_BEGINNING_STRING, AT_BOUNDARY,
79.134 + AT_NON_BOUNDARY, AT_END, AT_END_LINE, AT_END_STRING,
79.135 + AT_LOC_BOUNDARY, AT_LOC_NON_BOUNDARY, AT_UNI_BOUNDARY,
79.136 + AT_UNI_NON_BOUNDARY
79.137 +]
79.138 +
79.139 +CHCODES = [
79.140 + CATEGORY_DIGIT, CATEGORY_NOT_DIGIT, CATEGORY_SPACE,
79.141 + CATEGORY_NOT_SPACE, CATEGORY_WORD, CATEGORY_NOT_WORD,
79.142 + CATEGORY_LINEBREAK, CATEGORY_NOT_LINEBREAK, CATEGORY_LOC_WORD,
79.143 + CATEGORY_LOC_NOT_WORD, CATEGORY_UNI_DIGIT, CATEGORY_UNI_NOT_DIGIT,
79.144 + CATEGORY_UNI_SPACE, CATEGORY_UNI_NOT_SPACE, CATEGORY_UNI_WORD,
79.145 + CATEGORY_UNI_NOT_WORD, CATEGORY_UNI_LINEBREAK,
79.146 + CATEGORY_UNI_NOT_LINEBREAK
79.147 +]
79.148 +
79.149 +def makedict(list):
79.150 + d = {}
79.151 + i = 0
79.152 + for item in list:
79.153 + d[item] = i
79.154 + i = i + 1
79.155 + return d
79.156 +
79.157 +OPCODES = makedict(OPCODES)
79.158 +ATCODES = makedict(ATCODES)
79.159 +CHCODES = makedict(CHCODES)
79.160 +
79.161 +# replacement operations for "ignore case" mode
79.162 +OP_IGNORE = {
79.163 + GROUPREF: GROUPREF_IGNORE,
79.164 + IN: IN_IGNORE,
79.165 + LITERAL: LITERAL_IGNORE,
79.166 + NOT_LITERAL: NOT_LITERAL_IGNORE
79.167 +}
79.168 +
79.169 +AT_MULTILINE = {
79.170 + AT_BEGINNING: AT_BEGINNING_LINE,
79.171 + AT_END: AT_END_LINE
79.172 +}
79.173 +
79.174 +AT_LOCALE = {
79.175 + AT_BOUNDARY: AT_LOC_BOUNDARY,
79.176 + AT_NON_BOUNDARY: AT_LOC_NON_BOUNDARY
79.177 +}
79.178 +
79.179 +AT_UNICODE = {
79.180 + AT_BOUNDARY: AT_UNI_BOUNDARY,
79.181 + AT_NON_BOUNDARY: AT_UNI_NON_BOUNDARY
79.182 +}
79.183 +
79.184 +CH_LOCALE = {
79.185 + CATEGORY_DIGIT: CATEGORY_DIGIT,
79.186 + CATEGORY_NOT_DIGIT: CATEGORY_NOT_DIGIT,
79.187 + CATEGORY_SPACE: CATEGORY_SPACE,
79.188 + CATEGORY_NOT_SPACE: CATEGORY_NOT_SPACE,
79.189 + CATEGORY_WORD: CATEGORY_LOC_WORD,
79.190 + CATEGORY_NOT_WORD: CATEGORY_LOC_NOT_WORD,
79.191 + CATEGORY_LINEBREAK: CATEGORY_LINEBREAK,
79.192 + CATEGORY_NOT_LINEBREAK: CATEGORY_NOT_LINEBREAK
79.193 +}
79.194 +
79.195 +CH_UNICODE = {
79.196 + CATEGORY_DIGIT: CATEGORY_UNI_DIGIT,
79.197 + CATEGORY_NOT_DIGIT: CATEGORY_UNI_NOT_DIGIT,
79.198 + CATEGORY_SPACE: CATEGORY_UNI_SPACE,
79.199 + CATEGORY_NOT_SPACE: CATEGORY_UNI_NOT_SPACE,
79.200 + CATEGORY_WORD: CATEGORY_UNI_WORD,
79.201 + CATEGORY_NOT_WORD: CATEGORY_UNI_NOT_WORD,
79.202 + CATEGORY_LINEBREAK: CATEGORY_UNI_LINEBREAK,
79.203 + CATEGORY_NOT_LINEBREAK: CATEGORY_UNI_NOT_LINEBREAK
79.204 +}
79.205 +
79.206 +# flags
79.207 +SRE_FLAG_TEMPLATE = 1 # template mode (disable backtracking)
79.208 +SRE_FLAG_IGNORECASE = 2 # case insensitive
79.209 +SRE_FLAG_LOCALE = 4 # honour system locale
79.210 +SRE_FLAG_MULTILINE = 8 # treat target as multiline string
79.211 +SRE_FLAG_DOTALL = 16 # treat target as a single string
79.212 +SRE_FLAG_UNICODE = 32 # use unicode locale
79.213 +SRE_FLAG_VERBOSE = 64 # ignore whitespace and comments
79.214 +SRE_FLAG_DEBUG = 128 # debugging
79.215 +
79.216 +# flags for INFO primitive
79.217 +SRE_INFO_PREFIX = 1 # has prefix
79.218 +SRE_INFO_LITERAL = 2 # entire pattern is literal (given by prefix)
79.219 +SRE_INFO_CHARSET = 4 # pattern starts with character from given set
80.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
80.2 +++ b/lib/sre_parse.py Tue Aug 30 22:09:17 2016 +0200
80.3 @@ -0,0 +1,791 @@
80.4 +#
80.5 +# Secret Labs' Regular Expression Engine
80.6 +#
80.7 +# convert re-style regular expression to sre pattern
80.8 +#
80.9 +# Copyright (c) 1998-2001 by Secret Labs AB. All rights reserved.
80.10 +#
80.11 +# See the sre.py file for information on usage and redistribution.
80.12 +#
80.13 +
80.14 +"""Internal support module for sre"""
80.15 +
80.16 +# XXX: show string offset and offending character for all errors
80.17 +
80.18 +import sys
80.19 +
80.20 +from sre_constants import *
80.21 +
80.22 +SPECIAL_CHARS = ".\\[{()*+?^$|"
80.23 +REPEAT_CHARS = "*+?{"
80.24 +
80.25 +DIGITS = set("0123456789")
80.26 +
80.27 +OCTDIGITS = set("01234567")
80.28 +HEXDIGITS = set("0123456789abcdefABCDEF")
80.29 +
80.30 +WHITESPACE = set(" \t\n\r\v\f")
80.31 +
80.32 +ESCAPES = {
80.33 + r"\a": (LITERAL, ord("\a")),
80.34 + r"\b": (LITERAL, ord("\b")),
80.35 + r"\f": (LITERAL, ord("\f")),
80.36 + r"\n": (LITERAL, ord("\n")),
80.37 + r"\r": (LITERAL, ord("\r")),
80.38 + r"\t": (LITERAL, ord("\t")),
80.39 + r"\v": (LITERAL, ord("\v")),
80.40 + r"\\": (LITERAL, ord("\\"))
80.41 +}
80.42 +
80.43 +CATEGORIES = {
80.44 + r"\A": (AT, AT_BEGINNING_STRING), # start of string
80.45 + r"\b": (AT, AT_BOUNDARY),
80.46 + r"\B": (AT, AT_NON_BOUNDARY),
80.47 + r"\d": (IN, [(CATEGORY, CATEGORY_DIGIT)]),
80.48 + r"\D": (IN, [(CATEGORY, CATEGORY_NOT_DIGIT)]),
80.49 + r"\s": (IN, [(CATEGORY, CATEGORY_SPACE)]),
80.50 + r"\S": (IN, [(CATEGORY, CATEGORY_NOT_SPACE)]),
80.51 + r"\w": (IN, [(CATEGORY, CATEGORY_WORD)]),
80.52 + r"\W": (IN, [(CATEGORY, CATEGORY_NOT_WORD)]),
80.53 + r"\Z": (AT, AT_END_STRING), # end of string
80.54 +}
80.55 +
80.56 +FLAGS = {
80.57 + # standard flags
80.58 + "i": SRE_FLAG_IGNORECASE,
80.59 + "L": SRE_FLAG_LOCALE,
80.60 + "m": SRE_FLAG_MULTILINE,
80.61 + "s": SRE_FLAG_DOTALL,
80.62 + "x": SRE_FLAG_VERBOSE,
80.63 + # extensions
80.64 + "t": SRE_FLAG_TEMPLATE,
80.65 + "u": SRE_FLAG_UNICODE,
80.66 +}
80.67 +
80.68 +class Pattern:
80.69 + # master pattern object. keeps track of global attributes
80.70 + def __init__(self):
80.71 + self.flags = 0
80.72 + self.open = []
80.73 + self.groups = 1
80.74 + self.groupdict = {}
80.75 + self.str = None
80.76 + def opengroup(self, name=None):
80.77 + gid = self.groups
80.78 + self.groups = gid + 1
80.79 + if name is not None:
80.80 + ogid = self.groupdict.get(name, None)
80.81 + if ogid is not None:
80.82 + raise error, ("redefinition of group name %s as group %d; "
80.83 + "was group %d" % (repr(name), gid, ogid))
80.84 + self.groupdict[name] = gid
80.85 + self.open.append(gid)
80.86 + return gid
80.87 + def closegroup(self, gid):
80.88 + self.open.remove(gid)
80.89 + def checkgroup(self, gid):
80.90 + return gid < self.groups and gid not in self.open
80.91 +
80.92 +class SubPattern:
80.93 + # a subpattern, in intermediate form
80.94 + def __init__(self, pattern, data=None):
80.95 + self.pattern = pattern
80.96 + if data is None:
80.97 + data = []
80.98 + self.data = data
80.99 + self.width = None
80.100 + def dump(self, level=0):
80.101 + nl = 1
80.102 + seqtypes = type(()), type([])
80.103 + for op, av in self.data:
80.104 + print level*" " + op,; nl = 0
80.105 + if op == "in":
80.106 + # member sublanguage
80.107 + print; nl = 1
80.108 + for op, a in av:
80.109 + print (level+1)*" " + op, a
80.110 + elif op == "branch":
80.111 + print; nl = 1
80.112 + i = 0
80.113 + for a in av[1]:
80.114 + if i > 0:
80.115 + print level*" " + "or"
80.116 + a.dump(level+1); nl = 1
80.117 + i = i + 1
80.118 + elif type(av) in seqtypes:
80.119 + for a in av:
80.120 + if isinstance(a, SubPattern):
80.121 + if not nl: print
80.122 + a.dump(level+1); nl = 1
80.123 + else:
80.124 + print a, ; nl = 0
80.125 + else:
80.126 + print av, ; nl = 0
80.127 + if not nl: print
80.128 + def __repr__(self):
80.129 + return repr(self.data)
80.130 + def __len__(self):
80.131 + return len(self.data)
80.132 + def __delitem__(self, index):
80.133 + del self.data[index]
80.134 + def __getitem__(self, index):
80.135 + if isinstance(index, slice):
80.136 + return SubPattern(self.pattern, self.data[index])
80.137 + return self.data[index]
80.138 + def __setitem__(self, index, code):
80.139 + self.data[index] = code
80.140 + def insert(self, index, code):
80.141 + self.data.insert(index, code)
80.142 + def append(self, code):
80.143 + self.data.append(code)
80.144 + def getwidth(self):
80.145 + # determine the width (min, max) for this subpattern
80.146 + if self.width:
80.147 + return self.width
80.148 + lo = hi = 0L
80.149 + UNITCODES = (ANY, RANGE, IN, LITERAL, NOT_LITERAL, CATEGORY)
80.150 + REPEATCODES = (MIN_REPEAT, MAX_REPEAT)
80.151 + for op, av in self.data:
80.152 + if op is BRANCH:
80.153 + i = sys.maxint
80.154 + j = 0
80.155 + for av in av[1]:
80.156 + l, h = av.getwidth()
80.157 + i = min(i, l)
80.158 + j = max(j, h)
80.159 + lo = lo + i
80.160 + hi = hi + j
80.161 + elif op is CALL:
80.162 + i, j = av.getwidth()
80.163 + lo = lo + i
80.164 + hi = hi + j
80.165 + elif op is SUBPATTERN:
80.166 + i, j = av[1].getwidth()
80.167 + lo = lo + i
80.168 + hi = hi + j
80.169 + elif op in REPEATCODES:
80.170 + i, j = av[2].getwidth()
80.171 + lo = lo + long(i) * av[0]
80.172 + hi = hi + long(j) * av[1]
80.173 + elif op in UNITCODES:
80.174 + lo = lo + 1
80.175 + hi = hi + 1
80.176 + elif op == SUCCESS:
80.177 + break
80.178 + self.width = int(min(lo, sys.maxint)), int(min(hi, sys.maxint))
80.179 + return self.width
80.180 +
80.181 +class Tokenizer:
80.182 + def __init__(self, string):
80.183 + self.string = string
80.184 + self.index = 0
80.185 + self.__next()
80.186 + def __next(self):
80.187 + if self.index >= len(self.string):
80.188 + self.next = None
80.189 + return
80.190 + char = self.string[self.index]
80.191 + if char[0] == "\\":
80.192 + try:
80.193 + c = self.string[self.index + 1]
80.194 + except IndexError:
80.195 + raise error, "bogus escape (end of line)"
80.196 + char = char + c
80.197 + self.index = self.index + len(char)
80.198 + self.next = char
80.199 + def match(self, char, skip=1):
80.200 + if char == self.next:
80.201 + if skip:
80.202 + self.__next()
80.203 + return 1
80.204 + return 0
80.205 + def get(self):
80.206 + this = self.next
80.207 + self.__next()
80.208 + return this
80.209 + def tell(self):
80.210 + return self.index, self.next
80.211 + def seek(self, index):
80.212 + self.index, self.next = index
80.213 +
80.214 +def isident(char):
80.215 + return "a" <= char <= "z" or "A" <= char <= "Z" or char == "_"
80.216 +
80.217 +def isdigit(char):
80.218 + return "0" <= char <= "9"
80.219 +
80.220 +def isname(name):
80.221 + # check that group name is a valid string
80.222 + if not isident(name[0]):
80.223 + return False
80.224 + for char in name[1:]:
80.225 + if not isident(char) and not isdigit(char):
80.226 + return False
80.227 + return True
80.228 +
80.229 +def _class_escape(source, escape):
80.230 + # handle escape code inside character class
80.231 + code = ESCAPES.get(escape)
80.232 + if code:
80.233 + return code
80.234 + code = CATEGORIES.get(escape)
80.235 + if code:
80.236 + return code
80.237 + try:
80.238 + c = escape[1:2]
80.239 + if c == "x":
80.240 + # hexadecimal escape (exactly two digits)
80.241 + while source.next in HEXDIGITS and len(escape) < 4:
80.242 + escape = escape + source.get()
80.243 + escape = escape[2:]
80.244 + if len(escape) != 2:
80.245 + raise error, "bogus escape: %s" % repr("\\" + escape)
80.246 + return LITERAL, int(escape, 16) & 0xff
80.247 + elif c in OCTDIGITS:
80.248 + # octal escape (up to three digits)
80.249 + while source.next in OCTDIGITS and len(escape) < 4:
80.250 + escape = escape + source.get()
80.251 + escape = escape[1:]
80.252 + return LITERAL, int(escape, 8) & 0xff
80.253 + elif c in DIGITS:
80.254 + raise error, "bogus escape: %s" % repr(escape)
80.255 + if len(escape) == 2:
80.256 + return LITERAL, ord(escape[1])
80.257 + except ValueError:
80.258 + pass
80.259 + raise error, "bogus escape: %s" % repr(escape)
80.260 +
80.261 +def _escape(source, escape, state):
80.262 + # handle escape code in expression
80.263 + code = CATEGORIES.get(escape)
80.264 + if code:
80.265 + return code
80.266 + code = ESCAPES.get(escape)
80.267 + if code:
80.268 + return code
80.269 + try:
80.270 + c = escape[1:2]
80.271 + if c == "x":
80.272 + # hexadecimal escape
80.273 + while source.next in HEXDIGITS and len(escape) < 4:
80.274 + escape = escape + source.get()
80.275 + if len(escape) != 4:
80.276 + raise ValueError
80.277 + return LITERAL, int(escape[2:], 16) & 0xff
80.278 + elif c == "0":
80.279 + # octal escape
80.280 + while source.next in OCTDIGITS and len(escape) < 4:
80.281 + escape = escape + source.get()
80.282 + return LITERAL, int(escape[1:], 8) & 0xff
80.283 + elif c in DIGITS:
80.284 + # octal escape *or* decimal group reference (sigh)
80.285 + if source.next in DIGITS:
80.286 + escape = escape + source.get()
80.287 + if (escape[1] in OCTDIGITS and escape[2] in OCTDIGITS and
80.288 + source.next in OCTDIGITS):
80.289 + # got three octal digits; this is an octal escape
80.290 + escape = escape + source.get()
80.291 + return LITERAL, int(escape[1:], 8) & 0xff
80.292 + # not an octal escape, so this is a group reference
80.293 + group = int(escape[1:])
80.294 + if group < state.groups:
80.295 + if not state.checkgroup(group):
80.296 + raise error, "cannot refer to open group"
80.297 + return GROUPREF, group
80.298 + raise ValueError
80.299 + if len(escape) == 2:
80.300 + return LITERAL, ord(escape[1])
80.301 + except ValueError:
80.302 + pass
80.303 + raise error, "bogus escape: %s" % repr(escape)
80.304 +
80.305 +def _parse_sub(source, state, nested=1):
80.306 + # parse an alternation: a|b|c
80.307 +
80.308 + items = []
80.309 + itemsappend = items.append
80.310 + sourcematch = source.match
80.311 + while 1:
80.312 + itemsappend(_parse(source, state))
80.313 + if sourcematch("|"):
80.314 + continue
80.315 + if not nested:
80.316 + break
80.317 + if not source.next or sourcematch(")", 0):
80.318 + break
80.319 + else:
80.320 + raise error, "pattern not properly closed"
80.321 +
80.322 + if len(items) == 1:
80.323 + return items[0]
80.324 +
80.325 + subpattern = SubPattern(state)
80.326 + subpatternappend = subpattern.append
80.327 +
80.328 + # check if all items share a common prefix
80.329 + while 1:
80.330 + prefix = None
80.331 + for item in items:
80.332 + if not item:
80.333 + break
80.334 + if prefix is None:
80.335 + prefix = item[0]
80.336 + elif item[0] != prefix:
80.337 + break
80.338 + else:
80.339 + # all subitems start with a common "prefix".
80.340 + # move it out of the branch
80.341 + for item in items:
80.342 + del item[0]
80.343 + subpatternappend(prefix)
80.344 + continue # check next one
80.345 + break
80.346 +
80.347 + # check if the branch can be replaced by a character set
80.348 + for item in items:
80.349 + if len(item) != 1 or item[0][0] != LITERAL:
80.350 + break
80.351 + else:
80.352 + # we can store this as a character set instead of a
80.353 + # branch (the compiler may optimize this even more)
80.354 + set = []
80.355 + setappend = set.append
80.356 + for item in items:
80.357 + setappend(item[0])
80.358 + subpatternappend((IN, set))
80.359 + return subpattern
80.360 +
80.361 + subpattern.append((BRANCH, (None, items)))
80.362 + return subpattern
80.363 +
80.364 +def _parse_sub_cond(source, state, condgroup):
80.365 + item_yes = _parse(source, state)
80.366 + if source.match("|"):
80.367 + item_no = _parse(source, state)
80.368 + if source.match("|"):
80.369 + raise error, "conditional backref with more than two branches"
80.370 + else:
80.371 + item_no = None
80.372 + if source.next and not source.match(")", 0):
80.373 + raise error, "pattern not properly closed"
80.374 + subpattern = SubPattern(state)
80.375 + subpattern.append((GROUPREF_EXISTS, (condgroup, item_yes, item_no)))
80.376 + return subpattern
80.377 +
80.378 +_PATTERNENDERS = set("|)")
80.379 +_ASSERTCHARS = set("=!<")
80.380 +_LOOKBEHINDASSERTCHARS = set("=!")
80.381 +_REPEATCODES = set([MIN_REPEAT, MAX_REPEAT])
80.382 +
80.383 +def _parse(source, state):
80.384 + # parse a simple pattern
80.385 + subpattern = SubPattern(state)
80.386 +
80.387 + # precompute constants into local variables
80.388 + subpatternappend = subpattern.append
80.389 + sourceget = source.get
80.390 + sourcematch = source.match
80.391 + _len = len
80.392 + PATTERNENDERS = _PATTERNENDERS
80.393 + ASSERTCHARS = _ASSERTCHARS
80.394 + LOOKBEHINDASSERTCHARS = _LOOKBEHINDASSERTCHARS
80.395 + REPEATCODES = _REPEATCODES
80.396 +
80.397 + while 1:
80.398 +
80.399 + if source.next in PATTERNENDERS:
80.400 + break # end of subpattern
80.401 + this = sourceget()
80.402 + if this is None:
80.403 + break # end of pattern
80.404 +
80.405 + if state.flags & SRE_FLAG_VERBOSE:
80.406 + # skip whitespace and comments
80.407 + if this in WHITESPACE:
80.408 + continue
80.409 + if this == "#":
80.410 + while 1:
80.411 + this = sourceget()
80.412 + if this in (None, "\n"):
80.413 + break
80.414 + continue
80.415 +
80.416 + if this and this[0] not in SPECIAL_CHARS:
80.417 + subpatternappend((LITERAL, ord(this)))
80.418 +
80.419 + elif this == "[":
80.420 + # character set
80.421 + set = []
80.422 + setappend = set.append
80.423 +## if sourcematch(":"):
80.424 +## pass # handle character classes
80.425 + if sourcematch("^"):
80.426 + setappend((NEGATE, None))
80.427 + # check remaining characters
80.428 + start = set[:]
80.429 + while 1:
80.430 + this = sourceget()
80.431 + if this == "]" and set != start:
80.432 + break
80.433 + elif this and this[0] == "\\":
80.434 + code1 = _class_escape(source, this)
80.435 + elif this:
80.436 + code1 = LITERAL, ord(this)
80.437 + else:
80.438 + raise error, "unexpected end of regular expression"
80.439 + if sourcematch("-"):
80.440 + # potential range
80.441 + this = sourceget()
80.442 + if this == "]":
80.443 + if code1[0] is IN:
80.444 + code1 = code1[1][0]
80.445 + setappend(code1)
80.446 + setappend((LITERAL, ord("-")))
80.447 + break
80.448 + elif this:
80.449 + if this[0] == "\\":
80.450 + code2 = _class_escape(source, this)
80.451 + else:
80.452 + code2 = LITERAL, ord(this)
80.453 + if code1[0] != LITERAL or code2[0] != LITERAL:
80.454 + raise error, "bad character range"
80.455 + lo = code1[1]
80.456 + hi = code2[1]
80.457 + if hi < lo:
80.458 + raise error, "bad character range"
80.459 + setappend((RANGE, (lo, hi)))
80.460 + else:
80.461 + raise error, "unexpected end of regular expression"
80.462 + else:
80.463 + if code1[0] is IN:
80.464 + code1 = code1[1][0]
80.465 + setappend(code1)
80.466 +
80.467 + # XXX: <fl> should move set optimization to compiler!
80.468 + if _len(set)==1 and set[0][0] is LITERAL:
80.469 + subpatternappend(set[0]) # optimization
80.470 + elif _len(set)==2 and set[0][0] is NEGATE and set[1][0] is LITERAL:
80.471 + subpatternappend((NOT_LITERAL, set[1][1])) # optimization
80.472 + else:
80.473 + # XXX: <fl> should add charmap optimization here
80.474 + subpatternappend((IN, set))
80.475 +
80.476 + elif this and this[0] in REPEAT_CHARS:
80.477 + # repeat previous item
80.478 + if this == "?":
80.479 + min, max = 0, 1
80.480 + elif this == "*":
80.481 + min, max = 0, MAXREPEAT
80.482 +
80.483 + elif this == "+":
80.484 + min, max = 1, MAXREPEAT
80.485 + elif this == "{":
80.486 + if source.next == "}":
80.487 + subpatternappend((LITERAL, ord(this)))
80.488 + continue
80.489 + here = source.tell()
80.490 + min, max = 0, MAXREPEAT
80.491 + lo = hi = ""
80.492 + while source.next in DIGITS:
80.493 + lo = lo + source.get()
80.494 + if sourcematch(","):
80.495 + while source.next in DIGITS:
80.496 + hi = hi + sourceget()
80.497 + else:
80.498 + hi = lo
80.499 + if not sourcematch("}"):
80.500 + subpatternappend((LITERAL, ord(this)))
80.501 + source.seek(here)
80.502 + continue
80.503 + if lo:
80.504 + min = int(lo)
80.505 + if hi:
80.506 + max = int(hi)
80.507 + if max < min:
80.508 + raise error, "bad repeat interval"
80.509 + else:
80.510 + raise error, "not supported"
80.511 + # figure out which item to repeat
80.512 + if subpattern:
80.513 + item = subpattern[-1:]
80.514 + else:
80.515 + item = None
80.516 + if not item or (_len(item) == 1 and item[0][0] == AT):
80.517 + raise error, "nothing to repeat"
80.518 + if item[0][0] in REPEATCODES:
80.519 + raise error, "multiple repeat"
80.520 + if sourcematch("?"):
80.521 + subpattern[-1] = (MIN_REPEAT, (min, max, item))
80.522 + else:
80.523 + subpattern[-1] = (MAX_REPEAT, (min, max, item))
80.524 +
80.525 + elif this == ".":
80.526 + subpatternappend((ANY, None))
80.527 +
80.528 + elif this == "(":
80.529 + group = 1
80.530 + name = None
80.531 + condgroup = None
80.532 + if sourcematch("?"):
80.533 + group = 0
80.534 + # options
80.535 + if sourcematch("P"):
80.536 + # python extensions
80.537 + if sourcematch("<"):
80.538 + # named group: skip forward to end of name
80.539 + name = ""
80.540 + while 1:
80.541 + char = sourceget()
80.542 + if char is None:
80.543 + raise error, "unterminated name"
80.544 + if char == ">":
80.545 + break
80.546 + name = name + char
80.547 + group = 1
80.548 + if not isname(name):
80.549 + raise error, "bad character in group name"
80.550 + elif sourcematch("="):
80.551 + # named backreference
80.552 + name = ""
80.553 + while 1:
80.554 + char = sourceget()
80.555 + if char is None:
80.556 + raise error, "unterminated name"
80.557 + if char == ")":
80.558 + break
80.559 + name = name + char
80.560 + if not isname(name):
80.561 + raise error, "bad character in group name"
80.562 + gid = state.groupdict.get(name)
80.563 + if gid is None:
80.564 + raise error, "unknown group name"
80.565 + subpatternappend((GROUPREF, gid))
80.566 + continue
80.567 + else:
80.568 + char = sourceget()
80.569 + if char is None:
80.570 + raise error, "unexpected end of pattern"
80.571 + raise error, "unknown specifier: ?P%s" % char
80.572 + elif sourcematch(":"):
80.573 + # non-capturing group
80.574 + group = 2
80.575 + elif sourcematch("#"):
80.576 + # comment
80.577 + while 1:
80.578 + if source.next is None or source.next == ")":
80.579 + break
80.580 + sourceget()
80.581 + if not sourcematch(")"):
80.582 + raise error, "unbalanced parenthesis"
80.583 + continue
80.584 + elif source.next in ASSERTCHARS:
80.585 + # lookahead assertions
80.586 + char = sourceget()
80.587 + dir = 1
80.588 + if char == "<":
80.589 + if source.next not in LOOKBEHINDASSERTCHARS:
80.590 + raise error, "syntax error"
80.591 + dir = -1 # lookbehind
80.592 + char = sourceget()
80.593 + p = _parse_sub(source, state)
80.594 + if not sourcematch(")"):
80.595 + raise error, "unbalanced parenthesis"
80.596 + if char == "=":
80.597 + subpatternappend((ASSERT, (dir, p)))
80.598 + else:
80.599 + subpatternappend((ASSERT_NOT, (dir, p)))
80.600 + continue
80.601 + elif sourcematch("("):
80.602 + # conditional backreference group
80.603 + condname = ""
80.604 + while 1:
80.605 + char = sourceget()
80.606 + if char is None:
80.607 + raise error, "unterminated name"
80.608 + if char == ")":
80.609 + break
80.610 + condname = condname + char
80.611 + group = 2
80.612 + if isname(condname):
80.613 + condgroup = state.groupdict.get(condname)
80.614 + if condgroup is None:
80.615 + raise error, "unknown group name"
80.616 + else:
80.617 + try:
80.618 + condgroup = int(condname)
80.619 + except ValueError:
80.620 + raise error, "bad character in group name"
80.621 + else:
80.622 + # flags
80.623 + if not source.next in FLAGS:
80.624 + raise error, "unexpected end of pattern"
80.625 + while source.next in FLAGS:
80.626 + state.flags = state.flags | FLAGS[sourceget()]
80.627 + if group:
80.628 + # parse group contents
80.629 + if group == 2:
80.630 + # anonymous group
80.631 + group = None
80.632 + else:
80.633 + group = state.opengroup(name)
80.634 + if condgroup:
80.635 + p = _parse_sub_cond(source, state, condgroup)
80.636 + else:
80.637 + p = _parse_sub(source, state)
80.638 + if not sourcematch(")"):
80.639 + raise error, "unbalanced parenthesis"
80.640 + if group is not None:
80.641 + state.closegroup(group)
80.642 + subpatternappend((SUBPATTERN, (group, p)))
80.643 + else:
80.644 + while 1:
80.645 + char = sourceget()
80.646 + if char is None:
80.647 + raise error, "unexpected end of pattern"
80.648 + if char == ")":
80.649 + break
80.650 + raise error, "unknown extension"
80.651 +
80.652 + elif this == "^":
80.653 + subpatternappend((AT, AT_BEGINNING))
80.654 +
80.655 + elif this == "$":
80.656 + subpattern.append((AT, AT_END))
80.657 +
80.658 + elif this and this[0] == "\\":
80.659 + code = _escape(source, this, state)
80.660 + subpatternappend(code)
80.661 +
80.662 + else:
80.663 + raise error, "parser error"
80.664 +
80.665 + return subpattern
80.666 +
80.667 +def parse(str, flags=0, pattern=None):
80.668 + # parse 're' pattern into list of (opcode, argument) tuples
80.669 +
80.670 + source = Tokenizer(str)
80.671 +
80.672 + if pattern is None:
80.673 + pattern = Pattern()
80.674 + pattern.flags = flags
80.675 + pattern.str = str
80.676 +
80.677 + p = _parse_sub(source, pattern, 0)
80.678 +
80.679 + tail = source.get()
80.680 + if tail == ")":
80.681 + raise error, "unbalanced parenthesis"
80.682 + elif tail:
80.683 + raise error, "bogus characters at end of regular expression"
80.684 +
80.685 + if flags & SRE_FLAG_DEBUG:
80.686 + p.dump()
80.687 +
80.688 + if not (flags & SRE_FLAG_VERBOSE) and p.pattern.flags & SRE_FLAG_VERBOSE:
80.689 + # the VERBOSE flag was switched on inside the pattern. to be
80.690 + # on the safe side, we'll parse the whole thing again...
80.691 + return parse(str, p.pattern.flags)
80.692 +
80.693 + return p
80.694 +
80.695 +def parse_template(source, pattern):
80.696 + # parse 're' replacement string into list of literals and
80.697 + # group references
80.698 + s = Tokenizer(source)
80.699 + sget = s.get
80.700 + p = []
80.701 + a = p.append
80.702 + def literal(literal, p=p, pappend=a):
80.703 + if p and p[-1][0] is LITERAL:
80.704 + p[-1] = LITERAL, p[-1][1] + literal
80.705 + else:
80.706 + pappend((LITERAL, literal))
80.707 + sep = source[:0]
80.708 + if type(sep) is type(""):
80.709 + makechar = chr
80.710 + else:
80.711 + makechar = unichr
80.712 + while 1:
80.713 + this = sget()
80.714 + if this is None:
80.715 + break # end of replacement string
80.716 + if this and this[0] == "\\":
80.717 + # group
80.718 + c = this[1:2]
80.719 + if c == "g":
80.720 + name = ""
80.721 + if s.match("<"):
80.722 + while 1:
80.723 + char = sget()
80.724 + if char is None:
80.725 + raise error, "unterminated group name"
80.726 + if char == ">":
80.727 + break
80.728 + name = name + char
80.729 + if not name:
80.730 + raise error, "bad group name"
80.731 + try:
80.732 + index = int(name)
80.733 + if index < 0:
80.734 + raise error, "negative group number"
80.735 + except ValueError:
80.736 + if not isname(name):
80.737 + raise error, "bad character in group name"
80.738 + try:
80.739 + index = pattern.groupindex[name]
80.740 + except KeyError:
80.741 + raise IndexError, "unknown group name"
80.742 + a((MARK, index))
80.743 + elif c == "0":
80.744 + if s.next in OCTDIGITS:
80.745 + this = this + sget()
80.746 + if s.next in OCTDIGITS:
80.747 + this = this + sget()
80.748 + literal(makechar(int(this[1:], 8) & 0xff))
80.749 + elif c in DIGITS:
80.750 + isoctal = False
80.751 + if s.next in DIGITS:
80.752 + this = this + sget()
80.753 + if (c in OCTDIGITS and this[2] in OCTDIGITS and
80.754 + s.next in OCTDIGITS):
80.755 + this = this + sget()
80.756 + isoctal = True
80.757 + literal(makechar(int(this[1:], 8) & 0xff))
80.758 + if not isoctal:
80.759 + a((MARK, int(this[1:])))
80.760 + else:
80.761 + try:
80.762 + this = makechar(ESCAPES[this][1])
80.763 + except KeyError:
80.764 + pass
80.765 + literal(this)
80.766 + else:
80.767 + literal(this)
80.768 + # convert template to groups and literals lists
80.769 + i = 0
80.770 + groups = []
80.771 + groupsappend = groups.append
80.772 + literals = [None] * len(p)
80.773 + for c, s in p:
80.774 + if c is MARK:
80.775 + groupsappend((i, s))
80.776 + # literal[i] is already None
80.777 + else:
80.778 + literals[i] = s
80.779 + i = i + 1
80.780 + return groups, literals
80.781 +
80.782 +def expand_template(template, match):
80.783 + g = match.group
80.784 + sep = match.string[:0]
80.785 + groups, literals = template
80.786 + literals = literals[:]
80.787 + try:
80.788 + for index, group in groups:
80.789 + literals[index] = s = g(group)
80.790 + if s is None:
80.791 + raise error, "unmatched group"
80.792 + except IndexError:
80.793 + raise error, "invalid group reference"
80.794 + return sep.join(literals)
81.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
81.2 +++ b/lib/sys.py Tue Aug 30 22:09:17 2016 +0200
81.3 @@ -0,0 +1,41 @@
81.4 +#!/usr/bin/env python
81.5 +
81.6 +"""
81.7 +System functions and objects.
81.8 +
81.9 +Copyright (C) 2008, 2012, 2014 Paul Boddie <paul@boddie.org.uk>
81.10 +
81.11 +This program is free software; you can redistribute it and/or modify it under
81.12 +the terms of the GNU General Public License as published by the Free Software
81.13 +Foundation; either version 3 of the License, or (at your option) any later
81.14 +version.
81.15 +
81.16 +This program is distributed in the hope that it will be useful, but WITHOUT
81.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
81.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
81.19 +details.
81.20 +
81.21 +You should have received a copy of the GNU General Public License along with
81.22 +this program. If not, see <http://www.gnu.org/licenses/>.
81.23 +"""
81.24 +
81.25 +# Placeholders for run-time data.
81.26 +
81.27 +stdin = file()
81.28 +stdout = file()
81.29 +stderr = file()
81.30 +
81.31 +argv = []
81.32 +path = []
81.33 +
81.34 +hexversion = 0x20703f0 # 2.7.3 final 0
81.35 +maxint = 2147483647 # 2**31 - 1
81.36 +maxunicode = 1114111
81.37 +platform = 'posix'
81.38 +
81.39 +# Functions to be implemented natively.
81.40 +
81.41 +def exit(status=0):
81.42 + pass
81.43 +
81.44 +# vim: tabstop=4 expandtab shiftwidth=4
82.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
82.2 +++ b/lib/threading.py Tue Aug 30 22:09:17 2016 +0200
82.3 @@ -0,0 +1,825 @@
82.4 +#!/usr/bin/env python
82.5 +
82.6 +"""
82.7 +Thread module emulating a subset of Java's threading model.
82.8 +
82.9 +See docs/COPYING.txt and docs/LICENCE-python.txt for copyright and licensing
82.10 +information for Python standard library modules.
82.11 +"""
82.12 +
82.13 +import sys as _sys
82.14 +
82.15 +try:
82.16 + import thread
82.17 +except ImportError:
82.18 + del _sys.modules[__name__]
82.19 + raise
82.20 +
82.21 +from time import time as _time, sleep as _sleep
82.22 +from traceback import format_exc as _format_exc
82.23 +from collections import deque
82.24 +
82.25 +# Rename some stuff so "from threading import *" is safe
82.26 +__all__ = ['activeCount', 'Condition', 'currentThread', 'enumerate', 'Event',
82.27 + 'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Thread',
82.28 + 'Timer', 'setprofile', 'settrace', 'local', 'stack_size']
82.29 +
82.30 +_start_new_thread = thread.start_new_thread
82.31 +_allocate_lock = thread.allocate_lock
82.32 +_get_ident = thread.get_ident
82.33 +ThreadError = thread.error
82.34 +del thread
82.35 +
82.36 +
82.37 +# Support for profile and trace hooks
82.38 +
82.39 +_profile_hook = None
82.40 +_trace_hook = None
82.41 +
82.42 +def setprofile(func):
82.43 + global _profile_hook
82.44 + _profile_hook = func
82.45 +
82.46 +def settrace(func):
82.47 + global _trace_hook
82.48 + _trace_hook = func
82.49 +
82.50 +# Synchronization classes
82.51 +
82.52 +Lock = _allocate_lock
82.53 +
82.54 +def RLock(*args, **kwargs):
82.55 + return _RLock(*args, **kwargs)
82.56 +
82.57 +class _RLock:
82.58 +
82.59 + def __init__(self):
82.60 + self.__block = _allocate_lock()
82.61 + self.__owner = None
82.62 + self.__count = 0
82.63 +
82.64 + def __repr__(self):
82.65 + owner = self.__owner
82.66 + return "<%s(%s, %d)>" % (
82.67 + self.__class__.__name__,
82.68 + owner and owner.getName(),
82.69 + self.__count)
82.70 +
82.71 + def acquire(self, blocking=1):
82.72 + me = currentThread()
82.73 + if self.__owner is me:
82.74 + self.__count = self.__count + 1
82.75 + if __debug__:
82.76 + self._note("%s.acquire(%s): recursive success", self, blocking)
82.77 + return 1
82.78 + rc = self.__block.acquire(blocking)
82.79 + if rc:
82.80 + self.__owner = me
82.81 + self.__count = 1
82.82 + if __debug__:
82.83 + self._note("%s.acquire(%s): initial success", self, blocking)
82.84 + else:
82.85 + if __debug__:
82.86 + self._note("%s.acquire(%s): failure", self, blocking)
82.87 + return rc
82.88 +
82.89 + __enter__ = acquire
82.90 +
82.91 + def release(self):
82.92 + if self.__owner is not currentThread():
82.93 + raise RuntimeError("cannot release un-aquired lock")
82.94 + self.__count = count = self.__count - 1
82.95 + if not count:
82.96 + self.__owner = None
82.97 + self.__block.release()
82.98 + if __debug__:
82.99 + self._note("%s.release(): final release", self)
82.100 + else:
82.101 + if __debug__:
82.102 + self._note("%s.release(): non-final release", self)
82.103 +
82.104 + def __exit__(self, t, v, tb):
82.105 + self.release()
82.106 +
82.107 + # Internal methods used by condition variables
82.108 +
82.109 + def _acquire_restore(self, (count, owner)):
82.110 + self.__block.acquire()
82.111 + self.__count = count
82.112 + self.__owner = owner
82.113 + if __debug__:
82.114 + self._note("%s._acquire_restore()", self)
82.115 +
82.116 + def _release_save(self):
82.117 + if __debug__:
82.118 + self._note("%s._release_save()", self)
82.119 + count = self.__count
82.120 + self.__count = 0
82.121 + owner = self.__owner
82.122 + self.__owner = None
82.123 + self.__block.release()
82.124 + return (count, owner)
82.125 +
82.126 + def _is_owned(self):
82.127 + return self.__owner is currentThread()
82.128 +
82.129 +
82.130 +def Condition(*args, **kwargs):
82.131 + return _Condition(*args, **kwargs)
82.132 +
82.133 +class _Condition:
82.134 +
82.135 + def __init__(self, lock=None):
82.136 + if lock is None:
82.137 + lock = RLock()
82.138 + self.__lock = lock
82.139 + # Export the lock's acquire() and release() methods
82.140 + self.acquire = lock.acquire
82.141 + self.release = lock.release
82.142 + # If the lock defines _release_save() and/or _acquire_restore(),
82.143 + # these override the default implementations (which just call
82.144 + # release() and acquire() on the lock). Ditto for _is_owned().
82.145 + try:
82.146 + self._release_save = lock._release_save
82.147 + except AttributeError:
82.148 + pass
82.149 + try:
82.150 + self._acquire_restore = lock._acquire_restore
82.151 + except AttributeError:
82.152 + pass
82.153 + try:
82.154 + self._is_owned = lock._is_owned
82.155 + except AttributeError:
82.156 + pass
82.157 + self.__waiters = []
82.158 +
82.159 + def __enter__(self):
82.160 + return self.__lock.__enter__()
82.161 +
82.162 + def __exit__(self, *args):
82.163 + return self.__lock.__exit__(*args)
82.164 +
82.165 + def __repr__(self):
82.166 + return "<Condition(%s, %d)>" % (self.__lock, len(self.__waiters))
82.167 +
82.168 + def _release_save(self):
82.169 + self.__lock.release() # No state to save
82.170 +
82.171 + def _acquire_restore(self, x):
82.172 + self.__lock.acquire() # Ignore saved state
82.173 +
82.174 + def _is_owned(self):
82.175 + # Return True if lock is owned by currentThread.
82.176 + # This method is called only if __lock doesn't have _is_owned().
82.177 + if self.__lock.acquire(0):
82.178 + self.__lock.release()
82.179 + return False
82.180 + else:
82.181 + return True
82.182 +
82.183 + def wait(self, timeout=None):
82.184 + if not self._is_owned():
82.185 + raise RuntimeError("cannot wait on un-aquired lock")
82.186 + waiter = _allocate_lock()
82.187 + waiter.acquire()
82.188 + self.__waiters.append(waiter)
82.189 + saved_state = self._release_save()
82.190 + try: # restore state no matter what (e.g., KeyboardInterrupt)
82.191 + if timeout is None:
82.192 + waiter.acquire()
82.193 + if __debug__:
82.194 + self._note("%s.wait(): got it", self)
82.195 + else:
82.196 + # Balancing act: We can't afford a pure busy loop, so we
82.197 + # have to sleep; but if we sleep the whole timeout time,
82.198 + # we'll be unresponsive. The scheme here sleeps very
82.199 + # little at first, longer as time goes on, but never longer
82.200 + # than 20 times per second (or the timeout time remaining).
82.201 + endtime = _time() + timeout
82.202 + delay = 0.0005 # 500 us -> initial delay of 1 ms
82.203 + while True:
82.204 + gotit = waiter.acquire(0)
82.205 + if gotit:
82.206 + break
82.207 + remaining = endtime - _time()
82.208 + if remaining <= 0:
82.209 + break
82.210 + delay = min(delay * 2, remaining, .05)
82.211 + _sleep(delay)
82.212 + if not gotit:
82.213 + if __debug__:
82.214 + self._note("%s.wait(%s): timed out", self, timeout)
82.215 + try:
82.216 + self.__waiters.remove(waiter)
82.217 + except ValueError:
82.218 + pass
82.219 + else:
82.220 + if __debug__:
82.221 + self._note("%s.wait(%s): got it", self, timeout)
82.222 + finally:
82.223 + self._acquire_restore(saved_state)
82.224 +
82.225 + def notify(self, n=1):
82.226 + if not self._is_owned():
82.227 + raise RuntimeError("cannot notify on un-aquired lock")
82.228 + __waiters = self.__waiters
82.229 + waiters = __waiters[:n]
82.230 + if not waiters:
82.231 + if __debug__:
82.232 + self._note("%s.notify(): no waiters", self)
82.233 + return
82.234 + self._note("%s.notify(): notifying %d waiter%s", self, n,
82.235 + n!=1 and "s" or "")
82.236 + for waiter in waiters:
82.237 + waiter.release()
82.238 + try:
82.239 + __waiters.remove(waiter)
82.240 + except ValueError:
82.241 + pass
82.242 +
82.243 + def notifyAll(self):
82.244 + self.notify(len(self.__waiters))
82.245 +
82.246 +
82.247 +def Semaphore(*args, **kwargs):
82.248 + return _Semaphore(*args, **kwargs)
82.249 +
82.250 +class _Semaphore:
82.251 +
82.252 + # After Tim Peters' semaphore class, but not quite the same (no maximum)
82.253 +
82.254 + def __init__(self, value=1):
82.255 + if value < 0:
82.256 + raise ValueError("semaphore initial value must be >= 0")
82.257 + self.__cond = Condition(Lock())
82.258 + self.__value = value
82.259 +
82.260 + def acquire(self, blocking=1):
82.261 + rc = False
82.262 + self.__cond.acquire()
82.263 + while self.__value == 0:
82.264 + if not blocking:
82.265 + break
82.266 + if __debug__:
82.267 + self._note("%s.acquire(%s): blocked waiting, value=%s",
82.268 + self, blocking, self.__value)
82.269 + self.__cond.wait()
82.270 + else:
82.271 + self.__value = self.__value - 1
82.272 + if __debug__:
82.273 + self._note("%s.acquire: success, value=%s",
82.274 + self, self.__value)
82.275 + rc = True
82.276 + self.__cond.release()
82.277 + return rc
82.278 +
82.279 + __enter__ = acquire
82.280 +
82.281 + def release(self):
82.282 + self.__cond.acquire()
82.283 + self.__value = self.__value + 1
82.284 + if __debug__:
82.285 + self._note("%s.release: success, value=%s",
82.286 + self, self.__value)
82.287 + self.__cond.notify()
82.288 + self.__cond.release()
82.289 +
82.290 + def __exit__(self, t, v, tb):
82.291 + self.release()
82.292 +
82.293 +
82.294 +def BoundedSemaphore(*args, **kwargs):
82.295 + return _BoundedSemaphore(*args, **kwargs)
82.296 +
82.297 +class _BoundedSemaphore(_Semaphore):
82.298 + """Semaphore that checks that # releases is <= # acquires"""
82.299 + def __init__(self, value=1):
82.300 + _Semaphore.__init__(self, value)
82.301 + self._initial_value = value
82.302 +
82.303 + def release(self):
82.304 + if self._Semaphore__value >= self._initial_value:
82.305 + raise ValueError, "Semaphore released too many times"
82.306 + return _Semaphore.release(self)
82.307 +
82.308 +
82.309 +def Event(*args, **kwargs):
82.310 + return _Event(*args, **kwargs)
82.311 +
82.312 +class _Event:
82.313 +
82.314 + # After Tim Peters' event class (without is_posted())
82.315 +
82.316 + def __init__(self):
82.317 + self.__cond = Condition(Lock())
82.318 + self.__flag = False
82.319 +
82.320 + def isSet(self):
82.321 + return self.__flag
82.322 +
82.323 + def set(self):
82.324 + self.__cond.acquire()
82.325 + try:
82.326 + self.__flag = True
82.327 + self.__cond.notifyAll()
82.328 + finally:
82.329 + self.__cond.release()
82.330 +
82.331 + def clear(self):
82.332 + self.__cond.acquire()
82.333 + try:
82.334 + self.__flag = False
82.335 + finally:
82.336 + self.__cond.release()
82.337 +
82.338 + def wait(self, timeout=None):
82.339 + self.__cond.acquire()
82.340 + try:
82.341 + if not self.__flag:
82.342 + self.__cond.wait(timeout)
82.343 + finally:
82.344 + self.__cond.release()
82.345 +
82.346 +# Helper to generate new thread names
82.347 +_counter = 0
82.348 +def _newname(template="Thread-%d"):
82.349 + global _counter
82.350 + _counter = _counter + 1
82.351 + return template % _counter
82.352 +
82.353 +# Active thread administration
82.354 +_active_limbo_lock = _allocate_lock()
82.355 +_active = {} # maps thread id to Thread object
82.356 +_limbo = {}
82.357 +
82.358 +
82.359 +# Main class for threads
82.360 +
82.361 +class Thread:
82.362 +
82.363 + __initialized = False
82.364 + # Need to store a reference to sys.exc_info for printing
82.365 + # out exceptions when a thread tries to use a global var. during interp.
82.366 + # shutdown and thus raises an exception about trying to perform some
82.367 + # operation on/with a NoneType
82.368 + __exc_info = _sys.exc_info
82.369 +
82.370 + def __init__(self, group=None, target=None, name=None,
82.371 + args=(), kwargs=None):
82.372 + assert group is None, "group argument must be None for now"
82.373 + if kwargs is None:
82.374 + kwargs = {}
82.375 + self.__target = target
82.376 + self.__name = str(name or _newname())
82.377 + self.__args = args
82.378 + self.__kwargs = kwargs
82.379 + self.__daemonic = self._set_daemon()
82.380 + self.__started = False
82.381 + self.__stopped = False
82.382 + self.__block = Condition(Lock())
82.383 + self.__initialized = True
82.384 + # sys.stderr is not stored in the class like
82.385 + # sys.exc_info since it can be changed between instances
82.386 + self.__stderr = _sys.stderr
82.387 +
82.388 + def _set_daemon(self):
82.389 + # Overridden in _MainThread and _DummyThread
82.390 + return currentThread().isDaemon()
82.391 +
82.392 + def __repr__(self):
82.393 + assert self.__initialized, "Thread.__init__() was not called"
82.394 + status = "initial"
82.395 + if self.__started:
82.396 + status = "started"
82.397 + if self.__stopped:
82.398 + status = "stopped"
82.399 + if self.__daemonic:
82.400 + status = status + " daemon"
82.401 + return "<%s(%s, %s)>" % (self.__class__.__name__, self.__name, status)
82.402 +
82.403 + def start(self):
82.404 + if not self.__initialized:
82.405 + raise RuntimeError("thread.__init__() not called")
82.406 + if self.__started:
82.407 + raise RuntimeError("thread already started")
82.408 + if __debug__:
82.409 + self._note("%s.start(): starting thread", self)
82.410 + _active_limbo_lock.acquire()
82.411 + _limbo[self] = self
82.412 + _active_limbo_lock.release()
82.413 + _start_new_thread(self.__bootstrap, ())
82.414 + self.__started = True
82.415 + _sleep(0.000001) # 1 usec, to let the thread run (Solaris hack)
82.416 +
82.417 + def run(self):
82.418 + if self.__target:
82.419 + self.__target(*self.__args, **self.__kwargs)
82.420 +
82.421 + def __bootstrap(self):
82.422 + # Wrapper around the real bootstrap code that ignores
82.423 + # exceptions during interpreter cleanup. Those typically
82.424 + # happen when a daemon thread wakes up at an unfortunate
82.425 + # moment, finds the world around it destroyed, and raises some
82.426 + # random exception *** while trying to report the exception in
82.427 + # __bootstrap_inner() below ***. Those random exceptions
82.428 + # don't help anybody, and they confuse users, so we suppress
82.429 + # them. We suppress them only when it appears that the world
82.430 + # indeed has already been destroyed, so that exceptions in
82.431 + # __bootstrap_inner() during normal business hours are properly
82.432 + # reported. Also, we only suppress them for daemonic threads;
82.433 + # if a non-daemonic encounters this, something else is wrong.
82.434 + try:
82.435 + self.__bootstrap_inner()
82.436 + except:
82.437 + if self.__daemonic and _sys is None:
82.438 + return
82.439 + raise
82.440 +
82.441 + def __bootstrap_inner(self):
82.442 + try:
82.443 + self.__started = True
82.444 + _active_limbo_lock.acquire()
82.445 + _active[_get_ident()] = self
82.446 + del _limbo[self]
82.447 + _active_limbo_lock.release()
82.448 + if __debug__:
82.449 + self._note("%s.__bootstrap(): thread started", self)
82.450 +
82.451 + if _trace_hook:
82.452 + self._note("%s.__bootstrap(): registering trace hook", self)
82.453 + _sys.settrace(_trace_hook)
82.454 + if _profile_hook:
82.455 + self._note("%s.__bootstrap(): registering profile hook", self)
82.456 + _sys.setprofile(_profile_hook)
82.457 +
82.458 + try:
82.459 + self.run()
82.460 + except SystemExit:
82.461 + if __debug__:
82.462 + self._note("%s.__bootstrap(): raised SystemExit", self)
82.463 + except:
82.464 + if __debug__:
82.465 + self._note("%s.__bootstrap(): unhandled exception", self)
82.466 + # If sys.stderr is no more (most likely from interpreter
82.467 + # shutdown) use self.__stderr. Otherwise still use sys (as in
82.468 + # _sys) in case sys.stderr was redefined since the creation of
82.469 + # self.
82.470 + if _sys:
82.471 + _sys.stderr.write("Exception in thread %s:\n%s\n" %
82.472 + (self.getName(), _format_exc()))
82.473 + else:
82.474 + # Do the best job possible w/o a huge amt. of code to
82.475 + # approximate a traceback (code ideas from
82.476 + # Lib/traceback.py)
82.477 + exc_type, exc_value, exc_tb = self.__exc_info()
82.478 + try:
82.479 + print>>self.__stderr, (
82.480 + "Exception in thread " + self.getName() +
82.481 + " (most likely raised during interpreter shutdown):")
82.482 + print>>self.__stderr, (
82.483 + "Traceback (most recent call last):")
82.484 + while exc_tb:
82.485 + print>>self.__stderr, (
82.486 + ' File "%s", line %s, in %s' %
82.487 + (exc_tb.tb_frame.f_code.co_filename,
82.488 + exc_tb.tb_lineno,
82.489 + exc_tb.tb_frame.f_code.co_name))
82.490 + exc_tb = exc_tb.tb_next
82.491 + print>>self.__stderr, ("%s: %s" % (exc_type, exc_value))
82.492 + # Make sure that exc_tb gets deleted since it is a memory
82.493 + # hog; deleting everything else is just for thoroughness
82.494 + finally:
82.495 + del exc_type, exc_value, exc_tb
82.496 + else:
82.497 + if __debug__:
82.498 + self._note("%s.__bootstrap(): normal return", self)
82.499 + finally:
82.500 + _active_limbo_lock.acquire()
82.501 + try:
82.502 + self.__stop()
82.503 + try:
82.504 + # We don't call self.__delete() because it also
82.505 + # grabs _active_limbo_lock.
82.506 + del _active[_get_ident()]
82.507 + except:
82.508 + pass
82.509 + finally:
82.510 + _active_limbo_lock.release()
82.511 +
82.512 + def __stop(self):
82.513 + self.__block.acquire()
82.514 + self.__stopped = True
82.515 + self.__block.notifyAll()
82.516 + self.__block.release()
82.517 +
82.518 + def __delete(self):
82.519 + "Remove current thread from the dict of currently running threads."
82.520 +
82.521 + # Notes about running with dummy_thread:
82.522 + #
82.523 + # Must take care to not raise an exception if dummy_thread is being
82.524 + # used (and thus this module is being used as an instance of
82.525 + # dummy_threading). dummy_thread.get_ident() always returns -1 since
82.526 + # there is only one thread if dummy_thread is being used. Thus
82.527 + # len(_active) is always <= 1 here, and any Thread instance created
82.528 + # overwrites the (if any) thread currently registered in _active.
82.529 + #
82.530 + # An instance of _MainThread is always created by 'threading'. This
82.531 + # gets overwritten the instant an instance of Thread is created; both
82.532 + # threads return -1 from dummy_thread.get_ident() and thus have the
82.533 + # same key in the dict. So when the _MainThread instance created by
82.534 + # 'threading' tries to clean itself up when atexit calls this method
82.535 + # it gets a KeyError if another Thread instance was created.
82.536 + #
82.537 + # This all means that KeyError from trying to delete something from
82.538 + # _active if dummy_threading is being used is a red herring. But
82.539 + # since it isn't if dummy_threading is *not* being used then don't
82.540 + # hide the exception.
82.541 +
82.542 + _active_limbo_lock.acquire()
82.543 + try:
82.544 + try:
82.545 + del _active[_get_ident()]
82.546 + except KeyError:
82.547 + if 'dummy_threading' not in _sys.modules:
82.548 + raise
82.549 + finally:
82.550 + _active_limbo_lock.release()
82.551 +
82.552 + def join(self, timeout=None):
82.553 + if not self.__initialized:
82.554 + raise RuntimeError("Thread.__init__() not called")
82.555 + if not self.__started:
82.556 + raise RuntimeError("cannot join thread before it is started")
82.557 + if self is currentThread():
82.558 + raise RuntimeError("cannot join current thread")
82.559 +
82.560 + if __debug__:
82.561 + if not self.__stopped:
82.562 + self._note("%s.join(): waiting until thread stops", self)
82.563 + self.__block.acquire()
82.564 + try:
82.565 + if timeout is None:
82.566 + while not self.__stopped:
82.567 + self.__block.wait()
82.568 + if __debug__:
82.569 + self._note("%s.join(): thread stopped", self)
82.570 + else:
82.571 + deadline = _time() + timeout
82.572 + while not self.__stopped:
82.573 + delay = deadline - _time()
82.574 + if delay <= 0:
82.575 + if __debug__:
82.576 + self._note("%s.join(): timed out", self)
82.577 + break
82.578 + self.__block.wait(delay)
82.579 + else:
82.580 + if __debug__:
82.581 + self._note("%s.join(): thread stopped", self)
82.582 + finally:
82.583 + self.__block.release()
82.584 +
82.585 + def getName(self):
82.586 + assert self.__initialized, "Thread.__init__() not called"
82.587 + return self.__name
82.588 +
82.589 + def setName(self, name):
82.590 + assert self.__initialized, "Thread.__init__() not called"
82.591 + self.__name = str(name)
82.592 +
82.593 + def isAlive(self):
82.594 + assert self.__initialized, "Thread.__init__() not called"
82.595 + return self.__started and not self.__stopped
82.596 +
82.597 + def isDaemon(self):
82.598 + assert self.__initialized, "Thread.__init__() not called"
82.599 + return self.__daemonic
82.600 +
82.601 + def setDaemon(self, daemonic):
82.602 + if not self.__initialized:
82.603 + raise RuntimeError("Thread.__init__() not called")
82.604 + if self.__started:
82.605 + raise RuntimeError("cannot set daemon status of active thread");
82.606 + self.__daemonic = daemonic
82.607 +
82.608 +# The timer class was contributed by Itamar Shtull-Trauring
82.609 +
82.610 +def Timer(*args, **kwargs):
82.611 + return _Timer(*args, **kwargs)
82.612 +
82.613 +class _Timer(Thread):
82.614 + """Call a function after a specified number of seconds:
82.615 +
82.616 + t = Timer(30.0, f, args=[], kwargs={})
82.617 + t.start()
82.618 + t.cancel() # stop the timer's action if it's still waiting
82.619 + """
82.620 +
82.621 + def __init__(self, interval, function, args=[], kwargs={}):
82.622 + Thread.__init__(self)
82.623 + self.interval = interval
82.624 + self.function = function
82.625 + self.args = args
82.626 + self.kwargs = kwargs
82.627 + self.finished = Event()
82.628 +
82.629 + def cancel(self):
82.630 + """Stop the timer if it hasn't finished yet"""
82.631 + self.finished.set()
82.632 +
82.633 + def run(self):
82.634 + self.finished.wait(self.interval)
82.635 + if not self.finished.isSet():
82.636 + self.function(*self.args, **self.kwargs)
82.637 + self.finished.set()
82.638 +
82.639 +# Special thread class to represent the main thread
82.640 +# This is garbage collected through an exit handler
82.641 +
82.642 +class _MainThread(Thread):
82.643 +
82.644 + def __init__(self):
82.645 + Thread.__init__(self, name="MainThread")
82.646 + self._Thread__started = True
82.647 + _active_limbo_lock.acquire()
82.648 + _active[_get_ident()] = self
82.649 + _active_limbo_lock.release()
82.650 +
82.651 + def _set_daemon(self):
82.652 + return False
82.653 +
82.654 + def _exitfunc(self):
82.655 + self._Thread__stop()
82.656 + t = _pickSomeNonDaemonThread()
82.657 + if t:
82.658 + if __debug__:
82.659 + self._note("%s: waiting for other threads", self)
82.660 + while t:
82.661 + t.join()
82.662 + t = _pickSomeNonDaemonThread()
82.663 + if __debug__:
82.664 + self._note("%s: exiting", self)
82.665 + self._Thread__delete()
82.666 +
82.667 +def _pickSomeNonDaemonThread():
82.668 + for t in enumerate():
82.669 + if not t.isDaemon() and t.isAlive():
82.670 + return t
82.671 + return None
82.672 +
82.673 +
82.674 +# Dummy thread class to represent threads not started here.
82.675 +# These aren't garbage collected when they die, nor can they be waited for.
82.676 +# If they invoke anything in threading.py that calls currentThread(), they
82.677 +# leave an entry in the _active dict forever after.
82.678 +# Their purpose is to return *something* from currentThread().
82.679 +# They are marked as daemon threads so we won't wait for them
82.680 +# when we exit (conform previous semantics).
82.681 +
82.682 +class _DummyThread(Thread):
82.683 +
82.684 + def __init__(self):
82.685 + Thread.__init__(self, name=_newname("Dummy-%d"))
82.686 +
82.687 + # Thread.__block consumes an OS-level locking primitive, which
82.688 + # can never be used by a _DummyThread. Since a _DummyThread
82.689 + # instance is immortal, that's bad, so release this resource.
82.690 + del self._Thread__block
82.691 +
82.692 + self._Thread__started = True
82.693 + _active_limbo_lock.acquire()
82.694 + _active[_get_ident()] = self
82.695 + _active_limbo_lock.release()
82.696 +
82.697 + def _set_daemon(self):
82.698 + return True
82.699 +
82.700 + def join(self, timeout=None):
82.701 + assert False, "cannot join a dummy thread"
82.702 +
82.703 +
82.704 +# Global API functions
82.705 +
82.706 +def currentThread():
82.707 + try:
82.708 + return _active[_get_ident()]
82.709 + except KeyError:
82.710 + ##print "currentThread(): no current thread for", _get_ident()
82.711 + return _DummyThread()
82.712 +
82.713 +def activeCount():
82.714 + _active_limbo_lock.acquire()
82.715 + count = len(_active) + len(_limbo)
82.716 + _active_limbo_lock.release()
82.717 + return count
82.718 +
82.719 +def enumerate():
82.720 + _active_limbo_lock.acquire()
82.721 + active = _active.values() + _limbo.values()
82.722 + _active_limbo_lock.release()
82.723 + return active
82.724 +
82.725 +from thread import stack_size
82.726 +
82.727 +# Create the main thread object,
82.728 +# and make it available for the interpreter
82.729 +# (Py_Main) as threading._shutdown.
82.730 +
82.731 +_shutdown = _MainThread()._exitfunc
82.732 +
82.733 +# get thread-local implementation, either from the thread
82.734 +# module, or from the python fallback
82.735 +
82.736 +try:
82.737 + from thread import _local as local
82.738 +except ImportError:
82.739 + from _threading_local import local
82.740 +
82.741 +
82.742 +# Self-test code
82.743 +
82.744 +def _test():
82.745 +
82.746 + class BoundedQueue:
82.747 +
82.748 + def __init__(self, limit):
82.749 + self.mon = RLock()
82.750 + self.rc = Condition(self.mon)
82.751 + self.wc = Condition(self.mon)
82.752 + self.limit = limit
82.753 + self.queue = deque()
82.754 +
82.755 + def put(self, item):
82.756 + self.mon.acquire()
82.757 + while len(self.queue) >= self.limit:
82.758 + self._note("put(%s): queue full", item)
82.759 + self.wc.wait()
82.760 + self.queue.append(item)
82.761 + self._note("put(%s): appended, length now %d",
82.762 + item, len(self.queue))
82.763 + self.rc.notify()
82.764 + self.mon.release()
82.765 +
82.766 + def get(self):
82.767 + self.mon.acquire()
82.768 + while not self.queue:
82.769 + self._note("get(): queue empty")
82.770 + self.rc.wait()
82.771 + item = self.queue.popleft()
82.772 + self._note("get(): got %s, %d left", item, len(self.queue))
82.773 + self.wc.notify()
82.774 + self.mon.release()
82.775 + return item
82.776 +
82.777 + class ProducerThread(Thread):
82.778 +
82.779 + def __init__(self, queue, quota):
82.780 + Thread.__init__(self, name="Producer")
82.781 + self.queue = queue
82.782 + self.quota = quota
82.783 +
82.784 + def run(self):
82.785 + from random import random
82.786 + counter = 0
82.787 + while counter < self.quota:
82.788 + counter = counter + 1
82.789 + self.queue.put("%s.%d" % (self.getName(), counter))
82.790 + _sleep(random() * 0.00001)
82.791 +
82.792 +
82.793 + class ConsumerThread(Thread):
82.794 +
82.795 + def __init__(self, queue, count):
82.796 + Thread.__init__(self, name="Consumer")
82.797 + self.queue = queue
82.798 + self.count = count
82.799 +
82.800 + def run(self):
82.801 + while self.count > 0:
82.802 + item = self.queue.get()
82.803 + print item
82.804 + self.count = self.count - 1
82.805 +
82.806 + NP = 3
82.807 + QL = 4
82.808 + NI = 5
82.809 +
82.810 + Q = BoundedQueue(QL)
82.811 + P = []
82.812 + for i in range(NP):
82.813 + t = ProducerThread(Q, NI)
82.814 + t.setName("Producer-%d" % (i+1))
82.815 + P.append(t)
82.816 + C = ConsumerThread(Q, NI*NP)
82.817 + for t in P:
82.818 + t.start()
82.819 + _sleep(0.000001)
82.820 + C.start()
82.821 + for t in P:
82.822 + t.join()
82.823 + C.join()
82.824 +
82.825 +if __name__ == '__main__':
82.826 + _test()
82.827 +
82.828 +# vim: tabstop=4 expandtab shiftwidth=4
84.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
84.2 +++ b/lib/types.py Tue Aug 30 22:09:17 2016 +0200
84.3 @@ -0,0 +1,70 @@
84.4 +#!/usr/bin/env python
84.5 +
84.6 +"""
84.7 +Type objects.
84.8 +
84.9 +Copyright (C) 2012, 2015 Paul Boddie <paul@boddie.org.uk>
84.10 +
84.11 +This program is free software; you can redistribute it and/or modify it under
84.12 +the terms of the GNU General Public License as published by the Free Software
84.13 +Foundation; either version 3 of the License, or (at your option) any later
84.14 +version.
84.15 +
84.16 +This program is distributed in the hope that it will be useful, but WITHOUT
84.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
84.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
84.19 +details.
84.20 +
84.21 +You should have received a copy of the GNU General Public License along with
84.22 +this program. If not, see <http://www.gnu.org/licenses/>.
84.23 +"""
84.24 +
84.25 +# Built-in type duplication.
84.26 +
84.27 +type = type
84.28 +NoneType = NoneType
84.29 +NotImplementedType = NotImplementedType
84.30 +
84.31 +# Synonyms for built-in types.
84.32 +
84.33 +BooleanType = bool
84.34 +BufferType = buffer
84.35 +BuiltinFunctionType = function
84.36 +BuiltinMethodType = function
84.37 +ComplexType = complex
84.38 +DictType = dict
84.39 +EllipsisType = ellipsis
84.40 +FileType = file
84.41 +FloatType = float
84.42 +FunctionType = function
84.43 +IntType = int
84.44 +LambdaType = function
84.45 +ListType = list
84.46 +LongType = long
84.47 +MethodType = function
84.48 +ObjectType = object
84.49 +SliceType = slice
84.50 +StringType = str
84.51 +TupleType = tuple
84.52 +UnboundMethodType = function
84.53 +UnicodeType = unicode
84.54 +XRangeType = xrange
84.55 +
84.56 +StringTypes = (StringType, UnicodeType)
84.57 +
84.58 +# Types without special definitions.
84.59 +
84.60 +ClassType = object
84.61 +GeneratorType = object
84.62 +InstanceType = object
84.63 +ModuleType = object
84.64 +TracebackType = object
84.65 +
84.66 +# Implementation-specific definitions not relevant to micropython.
84.67 +
84.68 +DictProxyType = object
84.69 +FrameType = object
84.70 +GetSetDescriptorType = object
84.71 +MemberDescriptorType = object
84.72 +
84.73 +# vim: tabstop=4 expandtab shiftwidth=4
87.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
87.2 +++ b/test_all.sh Tue Aug 30 22:09:17 2016 +0200
87.3 @@ -0,0 +1,27 @@
87.4 +#!/bin/sh
87.5 +
87.6 +for FILENAME in tests/* ; do
87.7 +
87.8 + # Detect tests in their own subdirectories.
87.9 +
87.10 + if [ -d "$FILENAME" ] ; then
87.11 + if [ -e "$FILENAME/main.py" ] ; then
87.12 + FILENAME="$FILENAME/main.py"
87.13 + else
87.14 + continue
87.15 + fi
87.16 + fi
87.17 +
87.18 + # Run tests without an existing cache.
87.19 +
87.20 + echo "$FILENAME..." 1>&2
87.21 + if ! ./lplc "$FILENAME" -r ; then exit 1 ; fi
87.22 + echo 1>&2
87.23 +
87.24 + # Run tests with an existing cache.
87.25 +
87.26 + echo "$FILENAME (cached)..." 1>&2
87.27 + if ! ./lplc "$FILENAME" ; then exit 1 ; fi
87.28 + echo 1>&2
87.29 +
87.30 +done
89.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
89.2 +++ b/tests/assign_sequence.py Tue Aug 30 22:09:17 2016 +0200
89.3 @@ -0,0 +1,23 @@
89.4 +def f():
89.5 + l = [1, 2, 3]
89.6 + x = l
89.7 + a, b, c = l
89.8 + d, e, f = [1, 2, 3]
89.9 +
89.10 +def g(x):
89.11 + l = [1, 2, 3]
89.12 + m = [4, l, 6]
89.13 + if x:
89.14 + n = l
89.15 + else:
89.16 + n = m
89.17 +
89.18 +l = [1, 2, 3]
89.19 +x = l
89.20 +a, b, c = l
89.21 +d, e, f = [1, 2, 3]
89.22 +m = [4, l, 6]
89.23 +if x:
89.24 + n = l
89.25 +else:
89.26 + n = m
91.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
91.2 +++ b/tests/chains/main.py Tue Aug 30 22:09:17 2016 +0200
91.3 @@ -0,0 +1,10 @@
91.4 +import package.module
91.5 +
91.6 +C = package.module.Class
91.7 +c = package
91.8 +d = c
91.9 +e = c.module
91.10 +f = c.module.Class
91.11 +
91.12 +def t():
91.13 + x = c.module.Class
93.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
93.2 +++ b/tests/chains/package/module.py Tue Aug 30 22:09:17 2016 +0200
93.3 @@ -0,0 +1,2 @@
93.4 +class Class:
93.5 + pass
94.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
94.2 +++ b/tests/chains/package/unused.py Tue Aug 30 22:09:17 2016 +0200
94.3 @@ -0,0 +1,2 @@
94.4 +class Unused:
94.5 + pass
97.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
97.2 +++ b/tests/dicts.py Tue Aug 30 22:09:17 2016 +0200
97.3 @@ -0,0 +1,10 @@
97.4 +def f(d):
97.5 + return d.keys()
97.6 +
97.7 +def g(d):
97.8 + for key, value in d.items():
97.9 + return value
97.10 +
97.11 +d = {"a" : 1, "b" : 2}
97.12 +f(d) # ["a", "b"]
97.13 +g(d) # either 1 or 2
99.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
99.2 +++ b/tests/inheritance_bad/A.py Tue Aug 30 22:09:17 2016 +0200
99.3 @@ -0,0 +1,4 @@
99.4 +from B import E
99.5 +
99.6 +class D(E):
99.7 + d = 3
100.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
100.2 +++ b/tests/inheritance_bad/B.py Tue Aug 30 22:09:17 2016 +0200
100.3 @@ -0,0 +1,4 @@
100.4 +from A import D
100.5 +
100.6 +class E(D):
100.7 + e = 2
101.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
101.2 +++ b/tests/inheritance_bad/main.py Tue Aug 30 22:09:17 2016 +0200
101.3 @@ -0,0 +1,1 @@
101.4 +import A
102.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
102.2 +++ b/tests/listcomp.py Tue Aug 30 22:09:17 2016 +0200
102.3 @@ -0,0 +1,4 @@
102.4 +def f(l, y):
102.5 + return [x for x in l if x > y]
102.6 +
102.7 +result = f([1, 2, 3], 2)
105.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
105.2 +++ b/tests/mutual_import/main.py Tue Aug 30 22:09:17 2016 +0200
105.3 @@ -0,0 +1,3 @@
105.4 +import A
105.5 +
105.6 +A.h(A.C())
107.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
107.2 +++ b/tests/nested_bad.py Tue Aug 30 22:09:17 2016 +0200
107.3 @@ -0,0 +1,11 @@
107.4 +def f(x):
107.5 + def g(y):
107.6 + while 1:
107.7 + def h(z):
107.8 + return x, y, z, a
107.9 + a = 4 # not available for h, available in Python
107.10 + return h
107.11 + return g
107.12 +
107.13 +result = f(1)(2)(3)
107.14 +assert result == (1, 2, 3, 4)
108.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
108.2 +++ b/tests/nested_bad_conditional.py Tue Aug 30 22:09:17 2016 +0200
108.3 @@ -0,0 +1,10 @@
108.4 +a = 4
108.5 +
108.6 +def f(x):
108.7 + if not x:
108.8 + def g(y):
108.9 + return x, y, a
108.10 + return g # UnboundLocalError: not defined if x is true
108.11 +
108.12 +result = f(1)(2)
108.13 +assert result == (1, 2, 4)
109.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
109.2 +++ b/tests/nested_bad_python.py Tue Aug 30 22:09:17 2016 +0200
109.3 @@ -0,0 +1,13 @@
109.4 +a = 4
109.5 +
109.6 +def f(x):
109.7 + def g():
109.8 + def h(z):
109.9 + return x, y, z, a
109.10 + h(3) # NameError in Python
109.11 + y = 2 # not available for h, detected during inspection
109.12 + return h
109.13 + return g
109.14 +
109.15 +result = f(1)()(3)
109.16 +assert result == (1, 2, 3, 4)
110.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
110.2 +++ b/tests/nested_lambda.py Tue Aug 30 22:09:17 2016 +0200
110.3 @@ -0,0 +1,8 @@
110.4 +a = 4
110.5 +
110.6 +def f(x):
110.7 + g = lambda y: lambda z: (x, y, z, a)
110.8 + return g
110.9 +
110.10 +result = f(1)(2)(3)
110.11 +assert result == (1, 2, 3, 4)
111.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
111.2 +++ b/tests/nested_mixed.py Tue Aug 30 22:09:17 2016 +0200
111.3 @@ -0,0 +1,11 @@
111.4 +a = 4
111.5 +
111.6 +def f(x):
111.7 + def g(y):
111.8 + def h(y, z):
111.9 + return x, y, z, a # parameter y overrides outer scope
111.10 + return h
111.11 + return g
111.12 +
111.13 +result = f(1)(2)(5, 3)
111.14 +assert result == (1, 5, 3, 4)
113.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
113.2 +++ b/tests/nested_value_changed.py Tue Aug 30 22:09:17 2016 +0200
113.3 @@ -0,0 +1,13 @@
113.4 +a = 4
113.5 +
113.6 +def f(x):
113.7 + def g():
113.8 + y = 2 # used to initialise h
113.9 + def h(z):
113.10 + return x, y, z, a
113.11 + y = 5 # Python uses this value directly from g in h
113.12 + return h
113.13 + return g
113.14 +
113.15 +result = f(1)()(3)
113.16 +assert result == (1, 2, 3, 4) # (1, 5, 3, 4) in Python
114.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
114.2 +++ b/tests/operators.py Tue Aug 30 22:09:17 2016 +0200
114.3 @@ -0,0 +1,7 @@
114.4 +import operator
114.5 +
114.6 +def f(a, op, b):
114.7 + return op(a, b)
114.8 +
114.9 +f(1, operator.add, 2)
114.10 +f(1, operator.sub, 2)