from test
.test_support
import verbose
, verify
, TestFailed
def get_more_yolks(self
):
C
= new
.classobj('Spam', (Spam
.Eggs
,), {'get_more_yolks': get_more_yolks
})
c
= new
.instance(C
, {'yolks': 3})
"new __dict__ should be empty")
o
= new
.instance(C
, None)
"new __dict__ should be empty")
self
.yolks
= self
.yolks
- 2
print 'new.instancemethod()'
im
= new
.instancemethod(break_yolks
, c
, C
)
verify(c
.get_yolks() == 3 and c
.get_more_yolks() == 6,
'Broken call of hand-crafted class instance')
verify(c
.get_yolks() == 1 and c
.get_more_yolks() == 4,
'Broken call of hand-crafted instance method')
im
= new
.instancemethod(break_yolks
, c
)
verify(c
.get_yolks() == -1)
new
.instancemethod(break_yolks
, None)
raise TestFailed
, "dangerous instance method creation allowed"
# It's unclear what the semantics should be for a code object compiled at
# module scope, but bound and run in a function. In CPython, `c' is global
# (by accident?) while in Jython, `c' is local. The intent of the test
# clearly is to make `c' global, so let's be explicit about it.
ccode
= compile(codestr
, '<string>', 'exec')
# Jython doesn't have a __builtins__, so use a portable alternative
g
= {'c': 0, '__builtins__': __builtin__
}
# this test could be more robust
func
= new
.function(ccode
, g
)
'Could not create a proper function object')
# test the various extended flavors of function.new
new
.function(f
.func_code
, {}, "blah")
g2
= new
.function(g
.func_code
, {}, "blah", (2,), g
.func_closure
)
g3
= new
.function(g
.func_code
, {}, "blah", None, g
.func_closure
)
def test_closure(func
, closure
, exc
):
new
.function(func
.func_code
, {}, "", None, closure
)
print "corrupt closure accepted"
test_closure(g
, None, TypeError) # invalid closure
test_closure(g
, (1,), TypeError) # non-cell in closure
test_closure(g
, (1, 1), ValueError) # closure is wrong size
test_closure(f
, g
.func_closure
, ValueError) # no closure needed
# bogus test of new.code()
# Note: Jython will never have new.code()
stacksize
= c
.co_stacksize
firstlineno
= c
.co_firstlineno
d
= new
.code(argcount
, nlocals
, stacksize
, flags
, codestring
,
constants
, names
, varnames
, filename
, name
,
firstlineno
, lnotab
, freevars
, cellvars
)
# test backwards-compatibility version with no freevars or cellvars
d
= new
.code(argcount
, nlocals
, stacksize
, flags
, codestring
,
constants
, names
, varnames
, filename
, name
,
try: # this used to trigger a SystemError
d
= new
.code(-argcount
, nlocals
, stacksize
, flags
, codestring
,
constants
, names
, varnames
, filename
, name
,
raise TestFailed
, "negative co_argcount didn't trigger an exception"
try: # this used to trigger a SystemError
d
= new
.code(argcount
, -nlocals
, stacksize
, flags
, codestring
,
constants
, names
, varnames
, filename
, name
,
raise TestFailed
, "negative co_nlocals didn't trigger an exception"
try: # this used to trigger a Py_FatalError!
d
= new
.code(argcount
, nlocals
, stacksize
, flags
, codestring
,
constants
, (5,), varnames
, filename
, name
,
raise TestFailed
, "non-string co_name didn't trigger an exception"
# new.code used to be a way to mutate a tuple...
d
= new
.code(argcount
, nlocals
, stacksize
, flags
, codestring
,
constants
, t
, varnames
, filename
, name
,
verify(type(t
[0]) is S
, "eek, tuple changed under us!")