Commit 211a89f0 authored by Stefan Behnel's avatar Stefan Behnel

merged trunk changes

parents 138f21b3 a927b5a7
syntax: glob
*.pyc
*.swp
Cython/Compiler/Lexicon.pickle
BUILD/
.coverage
*~
*.orig
*.rej
......@@ -3,15 +3,17 @@
import os
import re
import time
import codecs
from StringIO import StringIO
import Version
from Code import CCodeWriter
from Cython import Utils
# need one-characters subsitutions (for now) so offsets aren't off
special_chars = [('<', '\xF0', '&lt;'),
('>', '\xF1', '&gt;'),
('&', '\xF2', '&amp;')]
special_chars = [(u'<', u'\xF0', u'&lt;'),
(u'>', u'\xF1', u'&gt;'),
(u'&', u'\xF2', u'&amp;')]
class AnnotationCCodeWriter(CCodeWriter):
......@@ -46,9 +48,9 @@ class AnnotationCCodeWriter(CCodeWriter):
def annotate(self, pos, item):
self.annotations.append((pos, item))
def save_annotation(self, filename):
def save_annotation(self, source_filename, target_filename):
self.mark_pos(None)
f = open(filename)
f = Utils.open_source_file(source_filename)
lines = f.readlines()
for k in range(len(lines)):
line = lines[k]
......@@ -58,12 +60,12 @@ class AnnotationCCodeWriter(CCodeWriter):
f.close()
all = []
for pos, item in self.annotations:
if pos[0] == filename:
if pos[0] == source_filename:
start = item.start()
size, end = item.end()
if size:
all.append((pos, start))
all.append(((filename, pos[1], pos[2]+size), end))
all.append(((source_filename, pos[1], pos[2]+size), end))
else:
all.append((pos, start+end))
......@@ -76,10 +78,12 @@ class AnnotationCCodeWriter(CCodeWriter):
line = lines[line_no]
lines[line_no] = line[:col] + item + line[col:]
f = open("%s.html" % filename, "w")
f.write('<html>\n')
f.write("""
html_filename = os.path.splitext(target_filename)[0] + ".html"
f = codecs.open(html_filename, "w", encoding="UTF-8")
f.write(u'<html>\n')
f.write(u"""
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type="text/css">
body { font-family: courier; font-size: 12; }
......@@ -112,16 +116,16 @@ function toggleDiv(id) {
</script>
</head>
""")
f.write('<body>\n')
f.write('<p>Generated by Cython %s on %s\n' % (Version.version, time.asctime()))
c_file = os.path.basename(filename)[:-3] + 'c'
f.write('<p>Raw output: <a href="%s">%s</a>\n' % (c_file, c_file))
f.write(u'<body>\n')
f.write(u'<p>Generated by Cython %s on %s\n' % (Version.version, time.asctime()))
c_file = Utils.encode_filename(os.path.basename(target_filename))
f.write(u'<p>Raw output: <a href="%s">%s</a>\n' % (c_file, c_file))
k = 0
py_c_api = re.compile('(Py[A-Z][a-z]+_[A-Z][a-z][A-Za-z_]+)')
pyx_api = re.compile('(__Pyx[A-Za-z_]+)\(')
py_marco_api = re.compile('(Py[A-Za-z]*_[A-Z][A-Z_]+)')
error_goto = re.compile(r'((; *if .*)? \{__pyx_filename = .*goto __pyx_L\w+;\})')
py_c_api = re.compile(u'(Py[A-Z][a-z]+_[A-Z][a-z][A-Za-z_]+)')
pyx_api = re.compile(u'(__Pyx[A-Za-z_]+)\(')
py_marco_api = re.compile(u'(Py[A-Za-z]*_[A-Z][A-Z_]+)')
error_goto = re.compile(ur'((; *if .*)? \{__pyx_filename = .*goto __pyx_L\w+;\})')
for line in lines:
......@@ -131,33 +135,33 @@ function toggleDiv(id) {
except KeyError:
code = ''
code, c_api_calls = py_c_api.subn(r"<span class='py_api'>\1</span>", code)
code, pyx_api_calls = pyx_api.subn(r"<span class='pyx_api'>\1</span>(", code)
code, macro_api_calls = py_marco_api.subn(r"<span class='py_macro_api'>\1</span>", code)
code, error_goto_calls = error_goto.subn(r"<span class='error_goto'>\1</span>", code)
code, c_api_calls = py_c_api.subn(ur"<span class='py_api'>\1</span>", code)
code, pyx_api_calls = pyx_api.subn(ur"<span class='pyx_api'>\1</span>(", code)
code, macro_api_calls = py_marco_api.subn(ur"<span class='py_macro_api'>\1</span>", code)
code, error_goto_calls = error_goto.subn(ur"<span class='error_goto'>\1</span>", code)
code = code.replace("<span class='error_goto'>;", ";<span class='error_goto'>")
code = code.replace(u"<span class='error_goto'>;", u";<span class='error_goto'>")
color = "FFFF%02x" % int(255/(1+(5*c_api_calls+2*pyx_api_calls+macro_api_calls)/10.0))
f.write("<pre class='line' style='background-color: #%s' onclick='toggleDiv(\"line%s\")'>" % (color, k))
color = u"FFFF%02x" % int(255/(1+(5*c_api_calls+2*pyx_api_calls+macro_api_calls)/10.0))
f.write(u"<pre class='line' style='background-color: #%s' onclick='toggleDiv(\"line%s\")'>" % (color, k))
f.write(" %d: " % k)
f.write(u" %d: " % k)
for c, cc, html in special_chars:
line = line.replace(cc, html)
f.write(line.rstrip())
f.write('</pre>\n')
f.write("<pre id='line%s' class='code' style='background-color: #%s'>%s</pre>" % (k, color, code))
f.write('</body></html>\n')
f.write(u'</pre>\n')
f.write(u"<pre id='line%s' class='code' style='background-color: #%s'>%s</pre>" % (k, color, code))
f.write(u'</body></html>\n')
f.close()
# TODO: make this cleaner
def escape(raw_string):
raw_string = raw_string.replace("\'", r"&#146;")
raw_string = raw_string.replace('\"', r'&quot;')
raw_string = raw_string.replace('\n', r'<br>\n')
raw_string = raw_string.replace('\t', r'\t')
raw_string = raw_string.replace(u"\'", ur"&#146;")
raw_string = raw_string.replace(u'\"', ur'&quot;')
raw_string = raw_string.replace(u'\n', ur'<br>\n')
raw_string = raw_string.replace(u'\t', ur'\t')
return raw_string
......@@ -170,7 +174,7 @@ class AnnotationItem:
self.size = size
def start(self):
return "<span class='tag %s' title='%s'>%s" % (self.style, self.text, self.tag)
return u"<span class='tag %s' title='%s'>%s" % (self.style, self.text, self.tag)
def end(self):
return self.size, "</span>"
return self.size, u"</span>"
......@@ -2741,7 +2741,7 @@ def unop_node(pos, operator, operand):
# Construct unnop node of appropriate class for
# given operator.
if isinstance(operand, IntNode) and operator == '-':
return IntNode(pos = operand.pos, value = -int(operand.value))
return IntNode(pos = operand.pos, value = str(-int(operand.value, 0)))
elif isinstance(operand, UnopNode) and operand.operator == operator:
warning(pos, "Python has no increment/decrement operator: %s%sx = %s(%sx) = x" % ((operator,)*4), 5)
return unop_node_classes[operator](pos,
......@@ -4128,7 +4128,7 @@ static void __Pyx_CppExn2PyErr() {
append_utility_code = [
"""
static inline PyObject* __Pyx_PyObject_Append(PyObject* L, PyObject* x) {
static INLINE PyObject* __Pyx_PyObject_Append(PyObject* L, PyObject* x) {
if (likely(PyList_CheckExact(L))) {
if (PyList_Append(L, x) < 0) return NULL;
Py_INCREF(Py_None);
......
......@@ -138,16 +138,7 @@ class Context:
return scope
def parse(self, source_filename, type_names, pxd, full_module_name):
try:
name = source_filename
if not isinstance(source_filename, unicode):
filename_encoding = sys.getfilesystemencoding()
if filename_encoding is None:
filename_encoding = sys.getdefaultencoding()
name = source_filename.decode(filename_encoding)
except UnicodeDecodeError:
pass
name = Utils.encode_filename(source_filename)
# Parse the given source file and return a parse tree.
try:
f = Utils.open_source_file(source_filename, "rU")
......@@ -183,6 +174,7 @@ class Context:
full_module_name = re.sub(r'[^\w.]', '_', full_module_name)
source = os.path.join(cwd, source)
result.main_source_file = source
if options.use_listing_file:
result.listing_file = replace_suffix(source, ".lis")
......@@ -295,6 +287,7 @@ class CompilationResult:
self.listing_file = None
self.object_file = None
self.extension_file = None
self.main_source_file = None
def compile(source, options = None, c_compile = 0, c_link = 0,
......@@ -360,6 +353,7 @@ default_options = dict(
obj_only = 1,
cplus = 0,
output_file = None,
annotate = False,
generate_pxi = 0,
transforms = Transform.TransformSet(),
working_path = "")
......
......@@ -209,7 +209,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
def generate_c_code(self, env, options, result):
modules = self.referenced_modules
if Options.annotate:
if Options.annotate or options.annotate:
code = Annotate.AnnotationCCodeWriter(StringIO())
else:
code = Code.CCodeWriter(StringIO())
......@@ -238,16 +238,15 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
self.generate_declarations_for_modules(env, modules, code.h)
f = open_new_file(result.c_file)
f.write(code.h.f.getvalue())
f.write("\n")
f.write(code.f.getvalue())
f.close()
result.c_file_generated = 1
if Options.annotate:
if Options.annotate or options.annotate:
self.annotate(code)
code.save_annotation(result.c_file[:-1] + "pyx") # change?
code.save_annotation(result.main_source_file, result.c_file)
def find_referenced_modules(self, env, module_list, modules_seen):
if env not in modules_seen:
......@@ -709,7 +708,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
self.generate_ass_subscript_function(scope, code)
if scope.defines_any(["__setslice__", "__delslice__"]):
self.generate_ass_slice_function(scope, code)
if scope.defines_any(["__getattr__"]):
if scope.defines_any(["__getattr__","__getattribute__"]):
self.generate_getattro_function(scope, code)
if scope.defines_any(["__setattr__", "__delattr__"]):
self.generate_setattro_function(scope, code)
......@@ -1073,23 +1072,43 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
"}")
def generate_getattro_function(self, scope, code):
# First try to get the attribute using PyObject_GenericGetAttr.
# If that raises an AttributeError, call the user's __getattr__
# method.
entry = scope.lookup_here("__getattr__")
# First try to get the attribute using __getattribute__, if defined, or
# PyObject_GenericGetAttr.
#
# If that raises an AttributeError, call the __getattr__ if defined.
#
# In both cases, defined can be in this class, or any base class.
def lookup_here_or_base(n,type=None):
# Recursive lookup
if type is None:
type = scope.parent_type
r = type.scope.lookup_here(n)
if r is None and \
type.base_type is not None:
return lookup_here_or_base(n,type.base_type)
else:
return r
getattr_entry = lookup_here_or_base("__getattr__")
getattribute_entry = lookup_here_or_base("__getattribute__")
code.putln("")
code.putln(
"static PyObject *%s(PyObject *o, PyObject *n) {"
% scope.mangle_internal("tp_getattro"))
if getattribute_entry is not None:
code.putln(
"PyObject *v = %s(o, n);" %
getattribute_entry.func_cname)
else:
code.putln(
"PyObject *v = PyObject_GenericGetAttr(o, n);")
if getattr_entry is not None:
code.putln(
"if (!v && PyErr_ExceptionMatches(PyExc_AttributeError)) {")
code.putln(
"PyErr_Clear();")
code.putln(
"v = %s(o, n);" %
entry.func_cname)
getattr_entry.func_cname)
code.putln(
"}")
code.putln(
......
......@@ -617,7 +617,7 @@ slot_table = (
MethodSlot(callfunc, "tp_call", "__call__"),
MethodSlot(reprfunc, "tp_str", "__str__"),
SyntheticSlot("tp_getattro", ["__getattr__"], "0"), #"PyObject_GenericGetAttr"),
SyntheticSlot("tp_getattro", ["__getattr__","__getattribute__"], "0"), #"PyObject_GenericGetAttr"),
SyntheticSlot("tp_setattro", ["__setattr__", "__delattr__"], "0"), #"PyObject_GenericSetAttr"),
SuiteSlot(PyBufferProcs, "PyBufferProcs", "tp_as_buffer"),
......
......@@ -28,13 +28,25 @@ def castrate_file(path, st):
f.seek(0, 0)
f.truncate()
f.write(
"#error Do not use this file, it is the result of a failed Pyrex compilation.\n")
"#error Do not use this file, it is the result of a failed Cython compilation.\n")
f.close()
if st:
os.utime(path, (st.st_atime, st.st_mtime))
# support for source file encoding detection and unicode decoding
def encode_filename(filename):
if isinstance(filename, unicode):
return filename
try:
filename_encoding = sys.getfilesystemencoding()
if filename_encoding is None:
filename_encoding = sys.getdefaultencoding()
filename = filename.decode(filename_encoding)
except UnicodeDecodeError:
pass
return filename
_match_file_encoding = re.compile(u"coding[:=]\s*([-\w.]+)").search
def detect_file_encoding(source_filename):
......
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
......@@ -2,6 +2,7 @@
import os, sys, re, shutil, unittest, doctest
from Cython.Compiler.Version import version
from Cython.Compiler.Main import \
CompilationOptions, \
default_options as pyrex_default_options, \
......@@ -36,14 +37,17 @@ class ErrorWriter(object):
return errors
class TestBuilder(object):
def __init__(self, rootdir, workdir, selectors):
def __init__(self, rootdir, workdir, selectors, annotate):
self.rootdir = rootdir
self.workdir = workdir
self.selectors = selectors
self.annotate = annotate
def build_suite(self):
suite = unittest.TestSuite()
for filename in os.listdir(self.rootdir):
filenames = os.listdir(self.rootdir)
filenames.sort()
for filename in filenames:
path = os.path.join(self.rootdir, filename)
if os.path.isdir(path) and filename in TEST_DIRS:
suite.addTest(
......@@ -53,7 +57,9 @@ class TestBuilder(object):
def handle_directory(self, path, context):
expect_errors = (context == 'errors')
suite = unittest.TestSuite()
for filename in os.listdir(path):
filenames = os.listdir(path)
filenames.sort()
for filename in filenames:
if not filename.endswith(".pyx"):
continue
module = filename[:-4]
......@@ -62,32 +68,46 @@ class TestBuilder(object):
if match(fqmodule) ]:
continue
if context in TEST_RUN_DIRS:
test = CythonRunTestCase(path, self.workdir, module)
test = CythonRunTestCase(
path, self.workdir, module, self.annotate)
else:
test = CythonCompileTestCase(
path, self.workdir, module, expect_errors)
path, self.workdir, module, expect_errors, self.annotate)
suite.addTest(test)
return suite
class CythonCompileTestCase(unittest.TestCase):
def __init__(self, directory, workdir, module, expect_errors=False):
def __init__(self, directory, workdir, module,
expect_errors=False, annotate=False):
self.directory = directory
self.workdir = workdir
self.module = module
self.expect_errors = expect_errors
self.annotate = annotate
unittest.TestCase.__init__(self)
def shortDescription(self):
return "compiling " + self.module
def setUp(self):
def tearDown(self):
if os.path.exists(self.workdir):
shutil.rmtree(self.workdir, ignore_errors=True)
for rmfile in os.listdir(self.workdir):
if self.annotate and rmfile.endswith(".html"):
continue
try:
rmfile = os.path.join(self.workdir, rmfile)
if os.path.isdir(rmfile):
shutil.rmtree(rmfile, ignore_errors=True)
else:
os.remove(rmfile)
except IOError:
pass
else:
os.makedirs(self.workdir)
def runTest(self):
self.compile(self.directory, self.module, self.workdir,
self.directory, self.expect_errors)
self.directory, self.expect_errors, self.annotate)
def split_source_and_output(self, directory, module, workdir):
source_and_output = open(os.path.join(directory, module + '.pyx'), 'rU')
......@@ -106,7 +126,7 @@ class CythonCompileTestCase(unittest.TestCase):
else:
return geterrors()
def run_cython(self, directory, module, targetdir, incdir):
def run_cython(self, directory, module, targetdir, incdir, annotate):
include_dirs = INCLUDE_DIRS[:]
if incdir:
include_dirs.append(incdir)
......@@ -116,6 +136,7 @@ class CythonCompileTestCase(unittest.TestCase):
pyrex_default_options,
include_path = include_dirs,
output_file = target,
annotate = annotate,
use_listing_file = False, cplus = False, generate_pxi = False)
cython_compile(source, options=options,
full_module_name=module)
......@@ -142,7 +163,8 @@ class CythonCompileTestCase(unittest.TestCase):
finally:
os.chdir(cwd)
def compile(self, directory, module, workdir, incdir, expect_errors):
def compile(self, directory, module, workdir, incdir,
expect_errors, annotate):
expected_errors = errors = ()
if expect_errors:
expected_errors = self.split_source_and_output(
......@@ -152,7 +174,7 @@ class CythonCompileTestCase(unittest.TestCase):
old_stderr = sys.stderr
try:
sys.stderr = ErrorWriter()
self.run_cython(directory, module, workdir, incdir)
self.run_cython(directory, module, workdir, incdir, annotate)
errors = sys.stderr.geterrors()
finally:
sys.stderr = old_stderr
......@@ -183,17 +205,26 @@ class CythonRunTestCase(CythonCompileTestCase):
result.startTest(self)
result.addError(self, sys.exc_info())
result.stopTest(self)
try:
self.tearDown()
except Exception:
pass
if __name__ == '__main__':
# RUN ALL TESTS!
ROOTDIR = os.path.join(os.getcwd(), os.path.dirname(sys.argv[0]), 'tests')
WORKDIR = os.path.join(os.getcwd(), 'BUILD')
if not os.path.exists(WORKDIR):
if os.path.exists(WORKDIR):
shutil.rmtree(WORKDIR, ignore_errors=True)
os.makedirs(WORKDIR)
if not sys.path or sys.path[0] != WORKDIR:
sys.path.insert(0, WORKDIR)
print "Running tests against Cython %s" % version
print "Python", sys.version
print
try:
sys.argv.remove("-C")
except ValueError:
......@@ -202,12 +233,19 @@ if __name__ == '__main__':
import coverage
coverage.erase()
try:
sys.argv.remove("-a")
except ValueError:
annotate_source = False
else:
annotate_source = True
import re
selectors = [ re.compile(r, re.I).search for r in sys.argv[1:] ]
if not selectors:
selectors = [ lambda x:True ]
tests = TestBuilder(ROOTDIR, WORKDIR, selectors)
tests = TestBuilder(ROOTDIR, WORKDIR, selectors, annotate_source)
test_suite = tests.build_suite()
if coverage is not None:
......
__doc__ = """
__getattribute__ and __getattr__ special methods for a single class.
>>> a = just_getattribute()
>>> a.bar
'bar'
>>> a.invalid
Traceback (most recent call last):
AttributeError
>>> a = just_getattr()
>>> a.foo
10
>>> a.bar
'bar'
>>> a.invalid
Traceback (most recent call last):
AttributeError
>>> a = both()
>>> a.foo
10
>>> a.bar
'bar'
>>> a.invalid
Traceback (most recent call last):
AttributeError
"""
cdef class just_getattribute:
def __getattribute__(self,n):
if n == 'bar':
return n
else:
raise AttributeError
cdef class just_getattr:
cdef readonly int foo
def __init__(self):
self.foo = 10
def __getattr__(self,n):
if n == 'bar':
return n
else:
raise AttributeError
cdef class both:
cdef readonly int foo
def __init__(self):
self.foo = 10
def __getattribute__(self,n):
if n == 'foo':
return self.foo
else:
raise AttributeError
def __getattr__(self,n):
if n == 'bar':
return n
else:
raise AttributeError
__doc__ = """
__getattribute__ and __getattr__ special methods and subclasses.
getattr does not override members.
>>> a = getattr_boring()
>>> a.boring_member
10
>>> a.resolved_by
'getattr_boring'
getattribute does.
>>> a = getattribute_boring()
>>> a.boring_member
Traceback (most recent call last):
AttributeError
>>> a.resolved_by
'getattribute_boring'
Is inherited.
>>> a = boring_boring_getattribute()
>>> a.boring_getattribute_member
Traceback (most recent call last):
AttributeError
>>> a.boring_boring_getattribute_member
Traceback (most recent call last):
AttributeError
>>> a.resolved_by
'_getattribute'
__getattribute__ is always tried first, then __getattr__, regardless of where
in the inheritance hiarchy they came from.
>>> a = getattribute_boring_boring_getattr()
>>> a.foo
Traceback (most recent call last):
AttributeError
>>> a.resolved_by
'getattribute_boring_boring_getattr'
>>> a.getattribute_boring_boring_getattr
True
>>> a._getattr
True
>>> a = getattr_boring_boring_getattribute()
>>> a.foo
Traceback (most recent call last):
AttributeError
>>> a.resolved_by
'_getattribute'
>>> a.getattr_boring_boring_getattribute
True
>>> a._getattribute
True
"""
cdef class boring:
cdef readonly int boring_member
def __init__(self):
self.boring_member = 10
cdef class getattr_boring(boring):
def __getattr__(self,n):
if n == 'resolved_by':
return 'getattr_boring'
elif n == 'getattr_boring':
return True
else:
raise AttributeError
cdef class getattribute_boring(boring):
def __getattribute__(self,n):
if n == 'resolved_by':
return 'getattribute_boring'
elif n == 'getattribute_boring':
return True
else:
raise AttributeError
cdef class _getattr:
def __getattr__(self,n):
if n == 'resolved_by':
return '_getattr'
elif n == '_getattr':
return True
else:
raise AttributeError
cdef class _getattribute(boring):
def __getattribute__(self,n):
if n == 'resolved_by':
return '_getattribute'
elif n == '_getattribute':
return True
else:
raise AttributeError
cdef class boring_getattribute(_getattribute):
cdef readonly int boring_getattribute_member
cdef class boring_boring_getattribute(boring_getattribute):
cdef readonly int boring_boring_getattribute_member
cdef class boring_getattr(_getattr):
cdef readonly int boring_getattr_member
cdef class boring_boring_getattr(boring_getattr):
cdef readonly int boring_boring_getattr_member
cdef class getattribute_boring_boring_getattr(boring_boring_getattr):
def __getattribute__(self,n):
if n == 'resolved_by':
return 'getattribute_boring_boring_getattr'
elif n == 'getattribute_boring_boring_getattr':
return True
else:
raise AttributeError
cdef class getattr_boring_boring_getattribute(boring_boring_getattribute):
def __getattr__(self,n):
if n == 'resolved_by':
return 'getattr_boring_boring_getattribute'
elif n == 'getattr_boring_boring_getattribute':
return True
else:
raise AttributeError
__doc__ = """
>>> c()
120
>>> i0() == -1
True
>>> i1() == 42
True
>>> i2() == 0x42
True
>>> i3() == 042
True
>>> i4() == -0x42
True
>>> l()
666
>>> f()
......@@ -27,9 +31,11 @@ DEF TUPLE = (1, 2, "buckle my shoe")
DEF TRUE_FALSE = (True, False)
DEF CHAR = c'x'
DEF INT0 = -1
DEF INT1 = 42
DEF INT2 = 0x42
DEF INT3 = 042
DEF INT4 = -0x42
DEF LONG = 666L
DEF FLOAT = 12.5
DEF STR = "spam"
......@@ -43,6 +49,11 @@ def c():
c = CHAR
return c
def i0():
cdef int i
i = INT0
return i
def i1():
cdef int i
i = INT1
......@@ -58,6 +69,11 @@ def i3():
i = INT3
return i
def i4():
cdef int i
i = INT4
return i
def l():
cdef long l
l = LONG
......
__doc__ = """
>>> test(Exception('hi'))
Raising: Exception('hi',)
Caught: <type 'exceptions.Exception'> Exception('hi',)
Caught: Exception('hi',)
"""
import sys
import sys, types
def test(obj):
print "Raising:", repr(obj)
print "Raising: %s%r" % (obj.__class__.__name__, obj.args)
try:
raise obj
except:
info = sys.exc_info()
print "Caught: %r %r" % (info[0], info[1])
if sys.version_info >= (2,5):
assert isinstance(info[0], type)
else:
assert isinstance(info[0], types.ClassType)
print "Caught: %s%r" % (info[1].__class__.__name__, info[1].args)
......@@ -10,10 +10,10 @@ __doc__ = """
>>> type(sys.maxint * 2 + 1) is long
True
>>> test(sys.maxint + 1)
2147483648L
>>> test(sys.maxint * 2 + 1)
4294967295L
>>> test(sys.maxint + 1) == sys.maxint + 1
True
>>> test(sys.maxint * 2 + 1) == sys.maxint * 2 + 1
True
>>> test(256 ** unsigned_long_size() - 1) > 0
True
......
......@@ -5,9 +5,9 @@ __doc__ = """
3
>>> test( (1,2,3) )
3
>>> testnonsense()
>>> testnonsense() # doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: 'int' object is not iterable
TypeError: ...
"""
def test1(t):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment