Skip to content

Commit 5f2c10d

Browse files
committed
PythonLib/min added, missing .pyd files for PythonLib/full
1 parent e4b2481 commit 5f2c10d

331 files changed

Lines changed: 142888 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

PythonLib/full/bz2.pyd

190 KB
Binary file not shown.

PythonLib/full/pyexpat.pyd

208 KB
Binary file not shown.

PythonLib/full/select.pyd

93.5 KB
Binary file not shown.

PythonLib/full/unicodedata.pyd

776 KB
Binary file not shown.

PythonLib/full/winsound.pyd

42.5 KB
Binary file not shown.

PythonLib/min/BaseHTTPServer.py

Lines changed: 603 additions & 0 deletions
Large diffs are not rendered by default.

PythonLib/min/Bastion.py

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
"""Bastionification utility.
2+
3+
A bastion (for another object -- the 'original') is an object that has
4+
the same methods as the original but does not give access to its
5+
instance variables. Bastions have a number of uses, but the most
6+
obvious one is to provide code executing in restricted mode with a
7+
safe interface to an object implemented in unrestricted mode.
8+
9+
The bastionification routine has an optional second argument which is
10+
a filter function. Only those methods for which the filter method
11+
(called with the method name as argument) returns true are accessible.
12+
The default filter method returns true unless the method name begins
13+
with an underscore.
14+
15+
There are a number of possible implementations of bastions. We use a
16+
'lazy' approach where the bastion's __getattr__() discipline does all
17+
the work for a particular method the first time it is used. This is
18+
usually fastest, especially if the user doesn't call all available
19+
methods. The retrieved methods are stored as instance variables of
20+
the bastion, so the overhead is only occurred on the first use of each
21+
method.
22+
23+
Detail: the bastion class has a __repr__() discipline which includes
24+
the repr() of the original object. This is precomputed when the
25+
bastion is created.
26+
27+
"""
28+
from warnings import warnpy3k
29+
warnpy3k("the Bastion module has been removed in Python 3.0", stacklevel=2)
30+
del warnpy3k
31+
32+
__all__ = ["BastionClass", "Bastion"]
33+
34+
from types import MethodType
35+
36+
37+
class BastionClass:
38+
39+
"""Helper class used by the Bastion() function.
40+
41+
You could subclass this and pass the subclass as the bastionclass
42+
argument to the Bastion() function, as long as the constructor has
43+
the same signature (a get() function and a name for the object).
44+
45+
"""
46+
47+
def __init__(self, get, name):
48+
"""Constructor.
49+
50+
Arguments:
51+
52+
get - a function that gets the attribute value (by name)
53+
name - a human-readable name for the original object
54+
(suggestion: use repr(object))
55+
56+
"""
57+
self._get_ = get
58+
self._name_ = name
59+
60+
def __repr__(self):
61+
"""Return a representation string.
62+
63+
This includes the name passed in to the constructor, so that
64+
if you print the bastion during debugging, at least you have
65+
some idea of what it is.
66+
67+
"""
68+
return "<Bastion for %s>" % self._name_
69+
70+
def __getattr__(self, name):
71+
"""Get an as-yet undefined attribute value.
72+
73+
This calls the get() function that was passed to the
74+
constructor. The result is stored as an instance variable so
75+
that the next time the same attribute is requested,
76+
__getattr__() won't be invoked.
77+
78+
If the get() function raises an exception, this is simply
79+
passed on -- exceptions are not cached.
80+
81+
"""
82+
attribute = self._get_(name)
83+
self.__dict__[name] = attribute
84+
return attribute
85+
86+
87+
def Bastion(object, filter = lambda name: name[:1] != '_',
88+
name=None, bastionclass=BastionClass):
89+
"""Create a bastion for an object, using an optional filter.
90+
91+
See the Bastion module's documentation for background.
92+
93+
Arguments:
94+
95+
object - the original object
96+
filter - a predicate that decides whether a function name is OK;
97+
by default all names are OK that don't start with '_'
98+
name - the name of the object; default repr(object)
99+
bastionclass - class used to create the bastion; default BastionClass
100+
101+
"""
102+
103+
raise RuntimeError, "This code is not secure in Python 2.2 and later"
104+
105+
# Note: we define *two* ad-hoc functions here, get1 and get2.
106+
# Both are intended to be called in the same way: get(name).
107+
# It is clear that the real work (getting the attribute
108+
# from the object and calling the filter) is done in get1.
109+
# Why can't we pass get1 to the bastion? Because the user
110+
# would be able to override the filter argument! With get2,
111+
# overriding the default argument is no security loophole:
112+
# all it does is call it.
113+
# Also notice that we can't place the object and filter as
114+
# instance variables on the bastion object itself, since
115+
# the user has full access to all instance variables!
116+
117+
def get1(name, object=object, filter=filter):
118+
"""Internal function for Bastion(). See source comments."""
119+
if filter(name):
120+
attribute = getattr(object, name)
121+
if type(attribute) == MethodType:
122+
return attribute
123+
raise AttributeError, name
124+
125+
def get2(name, get1=get1):
126+
"""Internal function for Bastion(). See source comments."""
127+
return get1(name)
128+
129+
if name is None:
130+
name = repr(object)
131+
return bastionclass(get2, name)
132+
133+
134+
def _test():
135+
"""Test the Bastion() function."""
136+
class Original:
137+
def __init__(self):
138+
self.sum = 0
139+
def add(self, n):
140+
self._add(n)
141+
def _add(self, n):
142+
self.sum = self.sum + n
143+
def total(self):
144+
return self.sum
145+
o = Original()
146+
b = Bastion(o)
147+
testcode = """if 1:
148+
b.add(81)
149+
b.add(18)
150+
print "b.total() =", b.total()
151+
try:
152+
print "b.sum =", b.sum,
153+
except:
154+
print "inaccessible"
155+
else:
156+
print "accessible"
157+
try:
158+
print "b._add =", b._add,
159+
except:
160+
print "inaccessible"
161+
else:
162+
print "accessible"
163+
try:
164+
print "b._get_.func_defaults =", map(type, b._get_.func_defaults),
165+
except:
166+
print "inaccessible"
167+
else:
168+
print "accessible"
169+
\n"""
170+
exec testcode
171+
print '='*20, "Using rexec:", '='*20
172+
import rexec
173+
r = rexec.RExec()
174+
m = r.add_module('__main__')
175+
m.b = b
176+
r.r_exec(testcode)
177+
178+
179+
if __name__ == '__main__':
180+
_test()

0 commit comments

Comments
 (0)