Commit b978c7e0 authored by Robert Bradshaw's avatar Robert Bradshaw

merge

parents 0a0e72a7 fa55b747
...@@ -20,7 +20,7 @@ class EmbedSignature(CythonTransform): ...@@ -20,7 +20,7 @@ class EmbedSignature(CythonTransform):
try: try:
denv = self.denv # XXX denv = self.denv # XXX
ctval = default_val.compile_time_value(self.denv) ctval = default_val.compile_time_value(self.denv)
repr_val = '%r' % ctval repr_val = repr(ctval)
if isinstance(default_val, ExprNodes.UnicodeNode): if isinstance(default_val, ExprNodes.UnicodeNode):
if repr_val[:1] != 'u': if repr_val[:1] != 'u':
return u'u%s' % repr_val return u'u%s' % repr_val
...@@ -28,8 +28,8 @@ class EmbedSignature(CythonTransform): ...@@ -28,8 +28,8 @@ class EmbedSignature(CythonTransform):
if repr_val[:1] != 'b': if repr_val[:1] != 'b':
return u'b%s' % repr_val return u'b%s' % repr_val
elif isinstance(default_val, ExprNodes.StringNode): elif isinstance(default_val, ExprNodes.StringNode):
if repr_val[:1] in ('u', 'b'): if repr_val[:1] in 'ub':
repr_val[1:] return repr_val[1:]
return repr_val return repr_val
except Exception: except Exception:
try: try:
......
...@@ -637,6 +637,8 @@ class GlobalState(object): ...@@ -637,6 +637,8 @@ class GlobalState(object):
def put_cached_builtin_init(self, pos, name, cname): def put_cached_builtin_init(self, pos, name, cname):
w = self.parts['cached_builtins'] w = self.parts['cached_builtins']
interned_cname = self.get_interned_identifier(name).cname interned_cname = self.get_interned_identifier(name).cname
from ExprNodes import get_name_interned_utility_code
self.use_utility_code(get_name_interned_utility_code)
w.putln('%s = __Pyx_GetName(%s, %s); if (!%s) %s' % ( w.putln('%s = __Pyx_GetName(%s, %s); if (!%s) %s' % (
cname, cname,
Naming.builtins_cname, Naming.builtins_cname,
...@@ -667,7 +669,7 @@ class GlobalState(object): ...@@ -667,7 +669,7 @@ class GlobalState(object):
decls_writer = self.parts['decls'] decls_writer = self.parts['decls']
for _, cname, c in c_consts: for _, cname, c in c_consts:
decls_writer.putln('static char %s[] = "%s";' % ( decls_writer.putln('static char %s[] = "%s";' % (
cname, StringEncoding.split_docstring(c.escaped_value))) cname, StringEncoding.split_string_literal(c.escaped_value)))
if c.py_strings is not None: if c.py_strings is not None:
for py_string in c.py_strings.itervalues(): for py_string in c.py_strings.itervalues():
py_strings.append((c.cname, len(py_string.cname), py_string)) py_strings.append((c.cname, len(py_string.cname), py_string))
......
...@@ -1246,8 +1246,8 @@ class NameNode(AtomicExprNode): ...@@ -1246,8 +1246,8 @@ class NameNode(AtomicExprNode):
self.is_temp = 0 self.is_temp = 0
else: else:
self.is_temp = 1 self.is_temp = 1
self.is_used_as_rvalue = 1
env.use_utility_code(get_name_interned_utility_code) env.use_utility_code(get_name_interned_utility_code)
self.is_used_as_rvalue = 1
def nogil_check(self, env): def nogil_check(self, env):
if self.is_used_as_rvalue: if self.is_used_as_rvalue:
...@@ -1334,6 +1334,7 @@ class NameNode(AtomicExprNode): ...@@ -1334,6 +1334,7 @@ class NameNode(AtomicExprNode):
namespace = Naming.builtins_cname namespace = Naming.builtins_cname
else: # entry.is_pyglobal else: # entry.is_pyglobal
namespace = entry.scope.namespace_cname namespace = entry.scope.namespace_cname
code.globalstate.use_utility_code(get_name_interned_utility_code)
code.putln( code.putln(
'%s = __Pyx_GetName(%s, %s); %s' % ( '%s = __Pyx_GetName(%s, %s); %s' % (
self.result(), self.result(),
...@@ -1554,6 +1555,12 @@ class IteratorNode(ExprNode): ...@@ -1554,6 +1555,12 @@ class IteratorNode(ExprNode):
def analyse_types(self, env): def analyse_types(self, env):
self.sequence.analyse_types(env) self.sequence.analyse_types(env)
if isinstance(self.sequence, SliceIndexNode) and \
(self.sequence.base.type.is_array or self.sequence.base.type.is_ptr) \
or self.sequence.type.is_array and self.sequence.type.size is not None:
# C array iteration will be transformed later on
pass
else:
self.sequence = self.sequence.coerce_to_pyobject(env) self.sequence = self.sequence.coerce_to_pyobject(env)
self.is_temp = 1 self.is_temp = 1
...@@ -2444,6 +2451,15 @@ class CallNode(ExprNode): ...@@ -2444,6 +2451,15 @@ class CallNode(ExprNode):
self.analyse_types(env) self.analyse_types(env)
self.coerce_to(type, env) self.coerce_to(type, env)
return True return True
elif type and type.is_cpp_class:
for arg in self.args:
arg.analyse_types(env)
constructor = type.scope.lookup("<init>")
self.function = RawCNameExprNode(self.function.pos, constructor.type)
self.function.entry = constructor
self.function.set_cname(type.declaration_code(""))
self.analyse_c_function_call(env)
return True
def nogil_check(self, env): def nogil_check(self, env):
func_type = self.function_type() func_type = self.function_type()
...@@ -2490,6 +2506,8 @@ class SimpleCallNode(CallNode): ...@@ -2490,6 +2506,8 @@ class SimpleCallNode(CallNode):
def infer_type(self, env): def infer_type(self, env):
function = self.function function = self.function
func_type = function.infer_type(env) func_type = function.infer_type(env)
if isinstance(self.function, NewExprNode):
return PyrexTypes.CPtrType(self.function.class_type)
if func_type.is_ptr: if func_type.is_ptr:
func_type = func_type.base_type func_type = func_type.base_type
if func_type.is_cfunction: if func_type.is_cfunction:
...@@ -4708,7 +4726,9 @@ class BinopNode(ExprNode): ...@@ -4708,7 +4726,9 @@ class BinopNode(ExprNode):
self.operand2.analyse_types(env) self.operand2.analyse_types(env)
if self.is_py_operation(): if self.is_py_operation():
self.coerce_operands_to_pyobjects(env) self.coerce_operands_to_pyobjects(env)
self.type = py_object_type self.type = self.result_type(self.operand1.type,
self.operand2.type)
assert self.type.is_pyobject
self.is_temp = 1 self.is_temp = 1
elif self.is_cpp_operation(): elif self.is_cpp_operation():
self.analyse_cpp_operation(env) self.analyse_cpp_operation(env)
...@@ -4750,6 +4770,30 @@ class BinopNode(ExprNode): ...@@ -4750,6 +4770,30 @@ class BinopNode(ExprNode):
def result_type(self, type1, type2): def result_type(self, type1, type2):
if self.is_py_operation_types(type1, type2): if self.is_py_operation_types(type1, type2):
if type2.is_string:
type2 = Builtin.bytes_type
if type1.is_string:
type1 = Builtin.bytes_type
elif self.operator == '%' \
and type1 in (Builtin.str_type, Builtin.unicode_type):
# note that b'%s' % b'abc' doesn't work in Py3
return type1
if type1.is_builtin_type:
if type1 is type2:
if self.operator in '**%+|&^':
# FIXME: at least these operators should be safe - others?
return type1
elif self.operator == '*':
if type1 in (Builtin.bytes_type, Builtin.str_type, Builtin.unicode_type):
return type1
# multiplication of containers/numbers with an
# integer value always (?) returns the same type
if type2.is_int:
return type1
elif type2.is_builtin_type and type1.is_int and self.operator == '*':
# multiplication of containers/numbers with an
# integer value always (?) returns the same type
return type2
return py_object_type return py_object_type
else: else:
return self.compute_c_result_type(type1, type2) return self.compute_c_result_type(type1, type2)
......
...@@ -88,7 +88,7 @@ class Context(object): ...@@ -88,7 +88,7 @@ class Context(object):
from ParseTreeTransforms import AnalyseDeclarationsTransform, AnalyseExpressionsTransform from ParseTreeTransforms import AnalyseDeclarationsTransform, AnalyseExpressionsTransform
from ParseTreeTransforms import CreateClosureClasses, MarkClosureVisitor, DecoratorTransform from ParseTreeTransforms import CreateClosureClasses, MarkClosureVisitor, DecoratorTransform
from ParseTreeTransforms import InterpretCompilerDirectives, TransformBuiltinMethods from ParseTreeTransforms import InterpretCompilerDirectives, TransformBuiltinMethods
from TypeInference import MarkAssignments from TypeInference import MarkAssignments, MarkOverflowingArithmatic
from ParseTreeTransforms import AlignFunctionDefinitions, GilCheck from ParseTreeTransforms import AlignFunctionDefinitions, GilCheck
from AnalysedTreeTransforms import AutoTestDictTransform from AnalysedTreeTransforms import AutoTestDictTransform
from AutoDocTransforms import EmbedSignature from AutoDocTransforms import EmbedSignature
...@@ -135,6 +135,7 @@ class Context(object): ...@@ -135,6 +135,7 @@ class Context(object):
EmbedSignature(self), EmbedSignature(self),
EarlyReplaceBuiltinCalls(self), EarlyReplaceBuiltinCalls(self),
MarkAssignments(self), MarkAssignments(self),
MarkOverflowingArithmatic(self),
TransformBuiltinMethods(self), TransformBuiltinMethods(self),
IntroduceBufferAuxiliaryVars(self), IntroduceBufferAuxiliaryVars(self),
_check_c_declarations, _check_c_declarations,
...@@ -218,8 +219,11 @@ class Context(object): ...@@ -218,8 +219,11 @@ class Context(object):
for phase in pipeline: for phase in pipeline:
if phase is not None: if phase is not None:
if DebugFlags.debug_verbose_pipeline: if DebugFlags.debug_verbose_pipeline:
t = time()
print "Entering pipeline phase %r" % phase print "Entering pipeline phase %r" % phase
data = phase(data) data = phase(data)
if DebugFlags.debug_verbose_pipeline:
print " %.3f seconds" % (time() - t)
except CompileError, err: except CompileError, err:
# err is set # err is set
Errors.report_error(err) Errors.report_error(err)
......
...@@ -22,7 +22,7 @@ from Symtab import ModuleScope, LocalScope, GeneratorLocalScope, \ ...@@ -22,7 +22,7 @@ from Symtab import ModuleScope, LocalScope, GeneratorLocalScope, \
StructOrUnionScope, PyClassScope, CClassScope, CppClassScope StructOrUnionScope, PyClassScope, CClassScope, CppClassScope
from Cython.Utils import open_new_file, replace_suffix from Cython.Utils import open_new_file, replace_suffix
from Code import UtilityCode from Code import UtilityCode
from StringEncoding import EncodedString, escape_byte_string, split_docstring from StringEncoding import EncodedString, escape_byte_string, split_string_literal
import Options import Options
import ControlFlow import ControlFlow
import DebugFlags import DebugFlags
...@@ -661,6 +661,17 @@ class CArgDeclNode(Node): ...@@ -661,6 +661,17 @@ class CArgDeclNode(Node):
base_type = self.base_type.analyse(env, could_be_name = could_be_name) base_type = self.base_type.analyse(env, could_be_name = could_be_name)
if hasattr(self.base_type, 'arg_name') and self.base_type.arg_name: if hasattr(self.base_type, 'arg_name') and self.base_type.arg_name:
self.declarator.name = self.base_type.arg_name self.declarator.name = self.base_type.arg_name
# The parser is unable to resolve the ambiguity of [] as part of the
# type (e.g. in buffers) or empty declarator (as with arrays).
# This is only arises for empty multi-dimensional arrays.
if (base_type.is_array
and isinstance(self.base_type, TemplatedTypeNode)
and isinstance(self.declarator, CArrayDeclaratorNode)):
declarator = self.declarator
while isinstance(declarator.base, CArrayDeclaratorNode):
declarator = declarator.base
declarator.base = self.base_type.array_declarator
base_type = base_type.base_type
return self.declarator.analyse(base_type, env, nonempty = nonempty) return self.declarator.analyse(base_type, env, nonempty = nonempty)
else: else:
return self.name_declarator, self.type return self.name_declarator, self.type
...@@ -821,7 +832,7 @@ class TemplatedTypeNode(CBaseTypeNode): ...@@ -821,7 +832,7 @@ class TemplatedTypeNode(CBaseTypeNode):
else: else:
# Array # Array
empty_declarator = CNameDeclaratorNode(self.pos, name="") empty_declarator = CNameDeclaratorNode(self.pos, name="", cname=None)
if len(self.positional_args) > 1 or self.keyword_args.key_value_pairs: if len(self.positional_args) > 1 or self.keyword_args.key_value_pairs:
error(self.pos, "invalid array declaration") error(self.pos, "invalid array declaration")
self.type = PyrexTypes.error_type self.type = PyrexTypes.error_type
...@@ -832,9 +843,10 @@ class TemplatedTypeNode(CBaseTypeNode): ...@@ -832,9 +843,10 @@ class TemplatedTypeNode(CBaseTypeNode):
dimension = None dimension = None
else: else:
dimension = self.positional_args[0] dimension = self.positional_args[0]
self.type = CArrayDeclaratorNode(self.pos, self.array_declarator = CArrayDeclaratorNode(self.pos,
base = empty_declarator, base = empty_declarator,
dimension = dimension).analyse(base_type, env)[1] dimension = dimension)
self.type = self.array_declarator.analyse(base_type, env)[1]
return self.type return self.type
...@@ -2052,7 +2064,7 @@ class DefNode(FuncDefNode): ...@@ -2052,7 +2064,7 @@ class DefNode(FuncDefNode):
code.putln( code.putln(
'static char %s[] = "%s";' % ( 'static char %s[] = "%s";' % (
self.entry.doc_cname, self.entry.doc_cname,
split_docstring(escape_byte_string(docstr)))) split_string_literal(escape_byte_string(docstr))))
if with_pymethdef: if with_pymethdef:
code.put( code.put(
"static PyMethodDef %s = " % "static PyMethodDef %s = " %
...@@ -4166,7 +4178,7 @@ class ForFromStatNode(LoopNode, StatNode): ...@@ -4166,7 +4178,7 @@ class ForFromStatNode(LoopNode, StatNode):
target_node = ExprNodes.PyTempNode(self.target.pos, None) target_node = ExprNodes.PyTempNode(self.target.pos, None)
target_node.allocate(code) target_node.allocate(code)
interned_cname = code.intern_identifier(self.target.entry.name) interned_cname = code.intern_identifier(self.target.entry.name)
code.putln("/*here*/") code.globalstate.use_utility_code(ExprNodes.get_name_interned_utility_code)
code.putln("%s = __Pyx_GetName(%s, %s); %s" % ( code.putln("%s = __Pyx_GetName(%s, %s); %s" % (
target_node.result(), target_node.result(),
Naming.module_cname, Naming.module_cname,
......
...@@ -89,10 +89,12 @@ class IterationTransform(Visitor.VisitorTransform): ...@@ -89,10 +89,12 @@ class IterationTransform(Visitor.VisitorTransform):
return self._transform_dict_iteration( return self._transform_dict_iteration(
node, dict_obj=iterator, keys=True, values=False) node, dict_obj=iterator, keys=True, values=False)
# C array slice iteration? # C array (slice) iteration?
if isinstance(iterator, ExprNodes.SliceIndexNode) and \ if isinstance(iterator, ExprNodes.SliceIndexNode) and \
(iterator.base.type.is_array or iterator.base.type.is_ptr): (iterator.base.type.is_array or iterator.base.type.is_ptr):
return self._transform_carray_iteration(node, iterator) return self._transform_carray_iteration(node, iterator)
elif iterator.type.is_array:
return self._transform_carray_iteration(node, iterator)
elif not isinstance(iterator, ExprNodes.SimpleCallNode): elif not isinstance(iterator, ExprNodes.SimpleCallNode):
return node return node
...@@ -131,13 +133,26 @@ class IterationTransform(Visitor.VisitorTransform): ...@@ -131,13 +133,26 @@ class IterationTransform(Visitor.VisitorTransform):
return node return node
def _transform_carray_iteration(self, node, slice_node): def _transform_carray_iteration(self, node, slice_node):
if isinstance(slice_node, ExprNodes.SliceIndexNode):
slice_base = slice_node.base
start = slice_node.start start = slice_node.start
stop = slice_node.stop stop = slice_node.stop
step = None step = None
if not stop: if not stop:
return node return node
elif slice_node.type.is_array and slice_node.type.size is not None:
slice_base = slice_node
start = None
stop = ExprNodes.IntNode(
slice_node.pos, value=str(slice_node.type.size))
step = None
else:
return node
carray_ptr = slice_node.base.coerce_to_simple(self.current_scope) ptr_type = slice_base.type
if ptr_type.is_array:
ptr_type = ptr_type.element_ptr_type()
carray_ptr = slice_base.coerce_to_simple(self.current_scope)
if start and start.constant_result != 0: if start and start.constant_result != 0:
start_ptr_node = ExprNodes.AddNode( start_ptr_node = ExprNodes.AddNode(
...@@ -145,7 +160,7 @@ class IterationTransform(Visitor.VisitorTransform): ...@@ -145,7 +160,7 @@ class IterationTransform(Visitor.VisitorTransform):
operand1=carray_ptr, operand1=carray_ptr,
operator='+', operator='+',
operand2=start, operand2=start,
type=carray_ptr.type) type=ptr_type)
else: else:
start_ptr_node = carray_ptr start_ptr_node = carray_ptr
...@@ -154,13 +169,13 @@ class IterationTransform(Visitor.VisitorTransform): ...@@ -154,13 +169,13 @@ class IterationTransform(Visitor.VisitorTransform):
operand1=carray_ptr, operand1=carray_ptr,
operator='+', operator='+',
operand2=stop, operand2=stop,
type=carray_ptr.type type=ptr_type
).coerce_to_simple(self.current_scope) ).coerce_to_simple(self.current_scope)
counter = UtilNodes.TempHandle(carray_ptr.type) counter = UtilNodes.TempHandle(ptr_type)
counter_temp = counter.ref(node.target.pos) counter_temp = counter.ref(node.target.pos)
if slice_node.base.type.is_string and node.target.type.is_pyobject: if slice_base.type.is_string and node.target.type.is_pyobject:
# special case: char* -> bytes # special case: char* -> bytes
target_value = ExprNodes.SliceIndexNode( target_value = ExprNodes.SliceIndexNode(
node.target.pos, node.target.pos,
...@@ -181,7 +196,7 @@ class IterationTransform(Visitor.VisitorTransform): ...@@ -181,7 +196,7 @@ class IterationTransform(Visitor.VisitorTransform):
type=PyrexTypes.c_int_type), type=PyrexTypes.c_int_type),
base=counter_temp, base=counter_temp,
is_buffer_access=False, is_buffer_access=False,
type=carray_ptr.type.base_type) type=ptr_type.base_type)
if target_value.type != node.target.type: if target_value.type != node.target.type:
target_value = target_value.coerce_to(node.target.type, target_value = target_value.coerce_to(node.target.type,
...@@ -1606,20 +1621,20 @@ impl = "" ...@@ -1606,20 +1621,20 @@ impl = ""
pop_utility_code = UtilityCode( pop_utility_code = UtilityCode(
proto = """ proto = """
static CYTHON_INLINE PyObject* __Pyx_PyObject_Pop(PyObject* L) { static CYTHON_INLINE PyObject* __Pyx_PyObject_Pop(PyObject* L) {
#if PY_VERSION_HEX >= 0x02040000
if (likely(PyList_CheckExact(L)) if (likely(PyList_CheckExact(L))
/* Check that both the size is positive and no reallocation shrinking needs to be done. */ /* Check that both the size is positive and no reallocation shrinking needs to be done. */
&& likely(PyList_GET_SIZE(L) > (((PyListObject*)L)->allocated >> 1))) { && likely(PyList_GET_SIZE(L) > (((PyListObject*)L)->allocated >> 1))) {
Py_SIZE(L) -= 1; Py_SIZE(L) -= 1;
return PyList_GET_ITEM(L, PyList_GET_SIZE(L)); return PyList_GET_ITEM(L, PyList_GET_SIZE(L));
} }
else { #endif
PyObject *r, *m; PyObject *r, *m;
m = __Pyx_GetAttrString(L, "pop"); m = __Pyx_GetAttrString(L, "pop");
if (!m) return NULL; if (!m) return NULL;
r = PyObject_CallObject(m, NULL); r = PyObject_CallObject(m, NULL);
Py_DECREF(m); Py_DECREF(m);
return r; return r;
}
} }
""", """,
impl = "" impl = ""
...@@ -1632,6 +1647,7 @@ static PyObject* __Pyx_PyObject_PopIndex(PyObject* L, Py_ssize_t ix); ...@@ -1632,6 +1647,7 @@ static PyObject* __Pyx_PyObject_PopIndex(PyObject* L, Py_ssize_t ix);
impl = """ impl = """
static PyObject* __Pyx_PyObject_PopIndex(PyObject* L, Py_ssize_t ix) { static PyObject* __Pyx_PyObject_PopIndex(PyObject* L, Py_ssize_t ix) {
PyObject *r, *m, *t, *py_ix; PyObject *r, *m, *t, *py_ix;
#if PY_VERSION_HEX >= 0x02040000
if (likely(PyList_CheckExact(L))) { if (likely(PyList_CheckExact(L))) {
Py_ssize_t size = PyList_GET_SIZE(L); Py_ssize_t size = PyList_GET_SIZE(L);
if (likely(size > (((PyListObject*)L)->allocated >> 1))) { if (likely(size > (((PyListObject*)L)->allocated >> 1))) {
...@@ -1650,6 +1666,7 @@ static PyObject* __Pyx_PyObject_PopIndex(PyObject* L, Py_ssize_t ix) { ...@@ -1650,6 +1666,7 @@ static PyObject* __Pyx_PyObject_PopIndex(PyObject* L, Py_ssize_t ix) {
} }
} }
} }
#endif
py_ix = t = NULL; py_ix = t = NULL;
m = __Pyx_GetAttrString(L, "pop"); m = __Pyx_GetAttrString(L, "pop");
if (!m) goto bad; if (!m) goto bad;
......
...@@ -10,6 +10,15 @@ cython.declare(Nodes=object, ExprNodes=object, EncodedString=object) ...@@ -10,6 +10,15 @@ cython.declare(Nodes=object, ExprNodes=object, EncodedString=object)
import os import os
import re import re
import sys import sys
try:
from __builtin__ import set
except ImportError:
try:
from builtins import set
except ImportError:
from sets import Set as set
from Cython.Compiler.Scanning import PyrexScanner, FileSourceDescriptor from Cython.Compiler.Scanning import PyrexScanner, FileSourceDescriptor
import Nodes import Nodes
import ExprNodes import ExprNodes
......
...@@ -1893,6 +1893,8 @@ class CppClassType(CType): ...@@ -1893,6 +1893,8 @@ class CppClassType(CType):
def assignable_from_resolved_type(self, other_type): def assignable_from_resolved_type(self, other_type):
# TODO: handle operator=(...) here? # TODO: handle operator=(...) here?
if other_type is error_type:
return True
return other_type.is_cpp_class and other_type.is_subclass(self) return other_type.is_cpp_class and other_type.is_subclass(self)
def attributes_known(self): def attributes_known(self):
...@@ -2369,6 +2371,17 @@ def spanning_type(type1, type2): ...@@ -2369,6 +2371,17 @@ def spanning_type(type1, type2):
return widest_numeric_type(type1, c_double_type) return widest_numeric_type(type1, c_double_type)
elif type1.is_pyobject ^ type2.is_pyobject: elif type1.is_pyobject ^ type2.is_pyobject:
return py_object_type return py_object_type
elif type1.is_extension_type and type2.is_extension_type:
if type1.typeobj_is_imported() or type2.typeobj_is_imported():
return py_object_type
while True:
if type1.subtype_of(type2):
return type2
elif type2.subtype_of(type1):
return type1
type1, type2 = type1.base_type, type2.base_type
if type1 is None or type2 is None:
return py_object_type
elif type1.assignable_from(type2): elif type1.assignable_from(type2):
if type1.is_extension_type and type1.typeobj_is_imported(): if type1.is_extension_type and type1.typeobj_is_imported():
# external types are unsafe, so we use PyObject instead # external types are unsafe, so we use PyObject instead
......
...@@ -97,7 +97,10 @@ def initial_compile_time_env(): ...@@ -97,7 +97,10 @@ def initial_compile_time_env():
'UNAME_VERSION', 'UNAME_MACHINE') 'UNAME_VERSION', 'UNAME_MACHINE')
for name, value in zip(names, platform.uname()): for name, value in zip(names, platform.uname()):
benv.declare(name, value) benv.declare(name, value)
try:
import __builtin__ as builtins import __builtin__ as builtins
except ImportError:
import builtins
names = ('False', 'True', names = ('False', 'True',
'abs', 'bool', 'chr', 'cmp', 'complex', 'dict', 'divmod', 'enumerate', 'abs', 'bool', 'chr', 'cmp', 'complex', 'dict', 'divmod', 'enumerate',
'float', 'hash', 'hex', 'int', 'len', 'list', 'long', 'map', 'max', 'min', 'float', 'hash', 'hex', 'int', 'len', 'list', 'long', 'map', 'max', 'min',
......
...@@ -185,9 +185,9 @@ def escape_byte_string(s): ...@@ -185,9 +185,9 @@ def escape_byte_string(s):
append(c) append(c)
return join_bytes(l).decode('ISO-8859-1') return join_bytes(l).decode('ISO-8859-1')
def split_docstring(s): def split_string_literal(s):
# MSVC can't handle long string literals. # MSVC can't handle long string literals.
if len(s) < 2047: if len(s) < 2047:
return s return s
else: else:
return '""'.join([s[i:i+2000] for i in range(0, len(s), 2000)]) return '""'.join([s[i:i+2000] for i in range(0, len(s), 2000)]).replace(r'\""', '""\\')
...@@ -119,6 +119,8 @@ class Entry(object): ...@@ -119,6 +119,8 @@ class Entry(object):
# inline_func_in_pxd boolean Hacky special case for inline function in pxd file. # inline_func_in_pxd boolean Hacky special case for inline function in pxd file.
# Ideally this should not be necesarry. # Ideally this should not be necesarry.
# assignments [ExprNode] List of expressions that get assigned to this entry. # assignments [ExprNode] List of expressions that get assigned to this entry.
# might_overflow boolean In an arithmatic expression that could cause
# overflow (used for type inference).
inline_func_in_pxd = False inline_func_in_pxd = False
borrowed = 0 borrowed = 0
...@@ -167,6 +169,7 @@ class Entry(object): ...@@ -167,6 +169,7 @@ class Entry(object):
is_overridable = 0 is_overridable = 0
buffer_aux = None buffer_aux = None
prev_entry = None prev_entry = None
might_overflow = 0
def __init__(self, name, cname, type, pos = None, init = None): def __init__(self, name, cname, type, pos = None, init = None):
self.name = name self.name = name
...@@ -434,7 +437,7 @@ class Scope(object): ...@@ -434,7 +437,7 @@ class Scope(object):
if type.is_cpp_class and visibility != 'extern': if type.is_cpp_class and visibility != 'extern':
constructor = type.scope.lookup(u'<init>') constructor = type.scope.lookup(u'<init>')
if constructor is not None and PyrexTypes.best_match([], constructor.all_alternatives()) is None: if constructor is not None and PyrexTypes.best_match([], constructor.all_alternatives()) is None:
error(pos, "C++ class must have an empty constructor to be stack allocated") error(pos, "C++ class must have a default constructor to be stack allocated")
entry = self.declare(name, cname, type, pos, visibility) entry = self.declare(name, cname, type, pos, visibility)
entry.is_variable = 1 entry.is_variable = 1
self.control_flow.set_state((), (name, 'initalized'), False) self.control_flow.set_state((), (name, 'initalized'), False)
...@@ -1564,6 +1567,7 @@ class CppClassScope(Scope): ...@@ -1564,6 +1567,7 @@ class CppClassScope(Scope):
if name == self.name.split('::')[-1] and cname is None: if name == self.name.split('::')[-1] and cname is None:
self.check_base_default_constructor(pos) self.check_base_default_constructor(pos)
name = '<init>' name = '<init>'
type.return_type = self.lookup(self.name).type
prev_entry = self.lookup_here(name) prev_entry = self.lookup_here(name)
entry = self.declare_var(name, type, pos, cname, visibility) entry = self.declare_var(name, type, pos, cname, visibility)
if prev_entry: if prev_entry:
......
...@@ -112,6 +112,62 @@ class MarkAssignments(CythonTransform): ...@@ -112,6 +112,62 @@ class MarkAssignments(CythonTransform):
self.visitchildren(node) self.visitchildren(node)
return node return node
class MarkOverflowingArithmatic(CythonTransform):
# It may be possible to integrate this with the above for
# performance improvements (though likely not worth it).
might_overflow = False
def __call__(self, root):
self.env_stack = []
self.env = root.scope
return super(MarkOverflowingArithmatic, self).__call__(root)
def visit_safe_node(self, node):
self.might_overflow, saved = False, self.might_overflow
self.visitchildren(node)
self.might_overflow = saved
return node
def visit_neutral_node(self, node):
self.visitchildren(node)
return node
def visit_dangerous_node(self, node):
self.might_overflow, saved = True, self.might_overflow
self.visitchildren(node)
self.might_overflow = saved
return node
def visit_FuncDefNode(self, node):
self.env_stack.append(self.env)
self.env = node.local_scope
self.visit_safe_node(node)
self.env = self.env_stack.pop()
return node
def visit_NameNode(self, node):
if self.might_overflow:
entry = node.entry or self.env.lookup(node.name)
if entry:
entry.might_overflow = True
return node
def visit_BinopNode(self, node):
if node.operator in '&|^':
return self.visit_neutral_node(node)
else:
return self.visit_dangerous_node(node)
visit_UnopNode = visit_neutral_node
visit_UnaryMinusNode = visit_dangerous_node
visit_InPlaceAssignmentNode = visit_dangerous_node
visit_Node = visit_safe_node
class PyObjectTypeInferer: class PyObjectTypeInferer:
""" """
...@@ -175,7 +231,7 @@ class SimpleAssignmentTypeInferer: ...@@ -175,7 +231,7 @@ class SimpleAssignmentTypeInferer:
entry = ready_to_infer.pop() entry = ready_to_infer.pop()
types = [expr.infer_type(scope) for expr in entry.assignments] types = [expr.infer_type(scope) for expr in entry.assignments]
if types: if types:
entry.type = spanning_type(types) entry.type = spanning_type(types, entry.might_overflow)
else: else:
# FIXME: raise a warning? # FIXME: raise a warning?
# print "No assignments", entry.pos, entry # print "No assignments", entry.pos, entry
...@@ -188,9 +244,9 @@ class SimpleAssignmentTypeInferer: ...@@ -188,9 +244,9 @@ class SimpleAssignmentTypeInferer:
if len(deps) == 1 and deps == set([entry]): if len(deps) == 1 and deps == set([entry]):
types = [expr.infer_type(scope) for expr in entry.assignments if expr.type_dependencies(scope) == ()] types = [expr.infer_type(scope) for expr in entry.assignments if expr.type_dependencies(scope) == ()]
if types: if types:
entry.type = spanning_type(types) entry.type = spanning_type(types, entry.might_overflow)
types = [expr.infer_type(scope) for expr in entry.assignments] types = [expr.infer_type(scope) for expr in entry.assignments]
entry.type = spanning_type(types) # might be wider... entry.type = spanning_type(types, entry.might_overflow) # might be wider...
resolve_dependancy(entry) resolve_dependancy(entry)
del dependancies_by_entry[entry] del dependancies_by_entry[entry]
if ready_to_infer: if ready_to_infer:
...@@ -218,11 +274,11 @@ def find_spanning_type(type1, type2): ...@@ -218,11 +274,11 @@ def find_spanning_type(type1, type2):
return PyrexTypes.c_double_type return PyrexTypes.c_double_type
return result_type return result_type
def aggressive_spanning_type(types): def aggressive_spanning_type(types, might_overflow):
result_type = reduce(find_spanning_type, types) result_type = reduce(find_spanning_type, types)
return result_type return result_type
def safe_spanning_type(types): def safe_spanning_type(types, might_overflow):
result_type = reduce(find_spanning_type, types) result_type = reduce(find_spanning_type, types)
if result_type.is_pyobject: if result_type.is_pyobject:
# any specific Python type is always safe to infer # any specific Python type is always safe to infer
...@@ -235,6 +291,22 @@ def safe_spanning_type(types): ...@@ -235,6 +291,22 @@ def safe_spanning_type(types):
# find_spanning_type() only returns 'bint' for clean boolean # find_spanning_type() only returns 'bint' for clean boolean
# operations without other int types, so this is safe, too # operations without other int types, so this is safe, too
return result_type return result_type
elif result_type.is_ptr and not (result_type.is_int and result_type.rank == 0):
# Any pointer except (signed|unsigned|) char* can't implicitly
# become a PyObject.
return result_type
elif result_type.is_cpp_class:
# These can't implicitly become Python objects either.
return result_type
elif result_type.is_struct:
# Though we have struct -> object for some structs, this is uncommonly
# used, won't arise in pure Python, and there shouldn't be side
# effects, so I'm declaring this safe.
return result_type
# TODO: double complex should be OK as well, but we need
# to make sure everything is supported.
elif result_type.is_int and not might_overflow:
return result_type
return py_object_type return py_object_type
......
...@@ -7,5 +7,6 @@ ...@@ -7,5 +7,6 @@
# and keep the old one under the module name _build_ext, # and keep the old one under the module name _build_ext,
# so that *our* build_ext can make use of it. # so that *our* build_ext can make use of it.
from build_ext import build_ext from Cython.Distutils.build_ext import build_ext
# from extension import Extension # from extension import Extension
...@@ -15,16 +15,6 @@ from distutils.sysconfig import customize_compiler, get_python_version ...@@ -15,16 +15,6 @@ from distutils.sysconfig import customize_compiler, get_python_version
from distutils.dep_util import newer, newer_group from distutils.dep_util import newer, newer_group
from distutils import log from distutils import log
from distutils.dir_util import mkpath from distutils.dir_util import mkpath
try:
from Cython.Compiler.Main \
import CompilationOptions, \
default_options as pyrex_default_options, \
compile as cython_compile
from Cython.Compiler.Errors import PyrexError
except ImportError, e:
print "failed to import Cython: %s" % e
PyrexError = None
from distutils.command import build_ext as _build_ext from distutils.command import build_ext as _build_ext
extension_name_re = _build_ext.extension_name_re extension_name_re = _build_ext.extension_name_re
...@@ -83,18 +73,22 @@ class build_ext(_build_ext.build_ext): ...@@ -83,18 +73,22 @@ class build_ext(_build_ext.build_ext):
self.build_extension(ext) self.build_extension(ext)
def cython_sources(self, sources, extension): def cython_sources(self, sources, extension):
""" """
Walk the list of source files in 'sources', looking for Cython Walk the list of source files in 'sources', looking for Cython
source files (.pyx and .py). Run Cython on all that are source files (.pyx and .py). Run Cython on all that are
found, and return a modified 'sources' list with Cython source found, and return a modified 'sources' list with Cython source
files replaced by the generated C (or C++) files. files replaced by the generated C (or C++) files.
""" """
try:
if PyrexError == None: from Cython.Compiler.Main \
raise DistutilsPlatformError, \ import CompilationOptions, \
("Cython does not appear to be installed " default_options as pyrex_default_options, \
"on platform '%s'") % os.name compile as cython_compile
from Cython.Compiler.Errors import PyrexError
except ImportError:
e = sys.exc_info()[1]
print("failed to import Cython: %s" % e)
raise DistutilsPlatformError("Cython does not appear to be installed")
new_sources = [] new_sources = []
pyrex_sources = [] pyrex_sources = []
......
;;;; `Cython' mode. (add-to-list 'auto-mode-alist '("\\.pyx\\'" . cython-mode)) (define-derived-mode cython-mode python-mode "Cython" (font-lock-add-keywords nil `((,(concat "\\<\\(NULL" "\\|c\\(def\\|har\\|typedef\\)" "\\|e\\(num\\|xtern\\)" "\\|float" "\\|in\\(clude\\|t\\)" "\\|object\\|public\\|struct\\|type\\|union\\|void" "\\)\\>") 1 font-lock-keyword-face t)))) ;; Cython mode
\ No newline at end of file
(require 'python-mode)
(add-to-list 'auto-mode-alist '("\\.pyx\\'" . cython-mode))
(add-to-list 'auto-mode-alist '("\\.pxd\\'" . cython-mode))
(add-to-list 'auto-mode-alist '("\\.pxi\\'" . cython-mode))
(defun cython-compile ()
"Compile the file via Cython."
(interactive)
(let ((cy-buffer (current-buffer)))
(with-current-buffer
(compile compile-command)
(set (make-local-variable 'cython-buffer) cy-buffer)
(add-to-list (make-local-variable 'compilation-finish-functions)
'cython-compilation-finish)))
)
(defun cython-compilation-finish (buffer how)
"Called when Cython compilation finishes."
;; XXX could annotate source here
)
(defvar cython-mode-map
(let ((map (make-sparse-keymap)))
;; Will inherit from `python-mode-map' thanks to define-derived-mode.
(define-key map "\C-c\C-c" 'cython-compile)
map)
"Keymap used in `cython-mode'.")
(defvar cython-font-lock-keywords
`(;; new keywords in Cython language
(,(regexp-opt '("by" "cdef" "cimport" "cpdef" "ctypedef" "enum" "except?"
"extern" "gil" "include" "nogil" "property" "public"
"readonly" "struct" "union" "DEF" "IF" "ELIF" "ELSE") 'words)
1 font-lock-keyword-face)
;; C and Python types (highlight as builtins)
(,(regexp-opt '("NULL" "bint" "char" "dict" "double" "float" "int" "list"
"long" "object" "Py_ssize_t" "short" "size_t" "void") 'words)
1 font-lock-builtin-face)
;; cdef is used for more than functions, so simply highlighting the next
;; word is problematic. struct, enum and property work though.
("\\<\\(?:struct\\|enum\\)[ \t]+\\([a-zA-Z_]+[a-zA-Z0-9_]*\\)"
1 py-class-name-face)
("\\<property[ \t]+\\([a-zA-Z_]+[a-zA-Z0-9_]*\\)"
1 font-lock-function-name-face))
"Additional font lock keywords for Cython mode.")
(define-derived-mode cython-mode python-mode "Cython"
"Major mode for Cython development, derived from Python mode.
\\{cython-mode-map}"
(setcar font-lock-defaults
(append python-font-lock-keywords cython-font-lock-keywords))
(set (make-local-variable 'compile-command)
(concat "cython -a " buffer-file-name))
(add-to-list (make-local-variable 'compilation-finish-functions)
'cython-compilation-finish)
)
(provide 'cython-mode)
...@@ -48,8 +48,8 @@ EXT_DEP_INCLUDES = [ ...@@ -48,8 +48,8 @@ EXT_DEP_INCLUDES = [
] ]
VER_DEP_MODULES = { VER_DEP_MODULES = {
# such as: (2,4) : (operator.le, lambda x: x in ['run.extern_builtins_T258'
# (2,4) : (operator.le, lambda x: x in ['run.set']), ]),
(3,): (operator.ge, lambda x: x in ['run.non_future_division', (3,): (operator.ge, lambda x: x in ['run.non_future_division',
'compile.extsetslice', 'compile.extsetslice',
'compile.extdelslice']), 'compile.extdelslice']),
......
...@@ -25,6 +25,11 @@ if sys.platform == "darwin": ...@@ -25,6 +25,11 @@ if sys.platform == "darwin":
setup_args = {} setup_args = {}
def add_command_class(name, cls):
cmdclasses = setup_args.get('cmdclass', {})
cmdclasses[name] = cls
setup_args['cmdclass'] = cmdclasses
if sys.version_info[0] >= 3: if sys.version_info[0] >= 3:
import lib2to3.refactor import lib2to3.refactor
from distutils.command.build_py \ from distutils.command.build_py \
...@@ -34,7 +39,7 @@ if sys.version_info[0] >= 3: ...@@ -34,7 +39,7 @@ if sys.version_info[0] >= 3:
if fix.split('fix_')[-1] not in ('next',) if fix.split('fix_')[-1] not in ('next',)
] ]
build_py.fixer_names = fixers build_py.fixer_names = fixers
setup_args['cmdclass'] = {"build_py" : build_py} add_command_class("build_py", build_py)
if sys.version_info < (2,4): if sys.version_info < (2,4):
...@@ -72,14 +77,45 @@ else: ...@@ -72,14 +77,45 @@ else:
else: else:
scripts = ["cython.py"] scripts = ["cython.py"]
def compile_cython_modules():
source_root = os.path.abspath(os.path.dirname(__file__))
compiled_modules = ["Cython.Plex.Scanners",
"Cython.Compiler.Scanning",
"Cython.Compiler.Parsing",
"Cython.Compiler.Visitor",
"Cython.Runtime.refnanny"]
extensions = []
try:
if sys.version_info[0] >= 3: if sys.version_info[0] >= 3:
raise ValueError from Cython.Distutils import build_ext as build_ext_orig
sys.argv.remove("--no-cython-compile") for module in compiled_modules:
except ValueError: source_file = os.path.join(source_root, *module.split('.'))
try: if os.path.exists(source_file + ".py"):
pyx_source_file = source_file + ".py"
else:
pyx_source_file = source_file + ".pyx"
extensions.append(
Extension(module, sources = [pyx_source_file])
)
class build_ext(build_ext_orig):
def build_extensions(self):
# add path where 2to3 installed the transformed sources
# and make sure Python (re-)imports them from there
already_imported = [ module for module in sys.modules
if module == 'Cython' or module.startswith('Cython.') ]
for module in already_imported:
del sys.modules[module]
sys.path.insert(0, os.path.join(source_root, self.build_lib))
build_ext_orig.build_extensions(self)
setup_args['ext_modules'] = extensions
add_command_class("build_ext", build_ext)
else: # Python 2.x
from distutils.command.build_ext import build_ext as build_ext_orig from distutils.command.build_ext import build_ext as build_ext_orig
try:
class build_ext(build_ext_orig): class build_ext(build_ext_orig):
def build_extension(self, ext, *args, **kargs): def build_extension(self, ext, *args, **kargs):
try: try:
...@@ -89,12 +125,6 @@ except ValueError: ...@@ -89,12 +125,6 @@ except ValueError:
from Cython.Compiler.Main import compile from Cython.Compiler.Main import compile
from Cython import Utils from Cython import Utils
source_root = os.path.dirname(__file__) source_root = os.path.dirname(__file__)
compiled_modules = ["Cython.Plex.Scanners",
"Cython.Compiler.Scanning",
"Cython.Compiler.Parsing",
"Cython.Compiler.Visitor",
"Cython.Runtime.refnanny"]
extensions = []
for module in compiled_modules: for module in compiled_modules:
source_file = os.path.join(source_root, *module.split('.')) source_file = os.path.join(source_root, *module.split('.'))
if os.path.exists(source_file + ".py"): if os.path.exists(source_file + ".py"):
...@@ -116,11 +146,16 @@ except ValueError: ...@@ -116,11 +146,16 @@ except ValueError:
print("Compilation failed") print("Compilation failed")
if extensions: if extensions:
setup_args['ext_modules'] = extensions setup_args['ext_modules'] = extensions
setup_args['cmdclass'] = {"build_ext" : build_ext} add_command_class("build_ext", build_ext)
except Exception: except Exception:
print("ERROR: %s" % sys.exc_info()[1]) print("ERROR: %s" % sys.exc_info()[1])
print("Extension module compilation failed, using plain Python implementation") print("Extension module compilation failed, using plain Python implementation")
try:
sys.argv.remove("--no-cython-compile")
except ValueError:
compile_cython_modules()
setup_args.update(setuptools_extra_args) setup_args.update(setuptools_extra_args)
from Cython.Compiler.Version import version from Cython.Compiler.Version import version
......
...@@ -11,6 +11,10 @@ cdef extern int (*iapfn())[5] ...@@ -11,6 +11,10 @@ cdef extern int (*iapfn())[5]
cdef extern char *(*cpapfn())[5] cdef extern char *(*cpapfn())[5]
cdef extern int fnargfn(int ()) cdef extern int fnargfn(int ())
cdef extern int ia[]
cdef extern int iaa[][3]
cdef extern int a(int[][3], int[][3][5])
cdef void f(): cdef void f():
cdef void *p=NULL cdef void *p=NULL
global ifnp, cpa global ifnp, cpa
......
"""A long module docstring.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer sit amet
mauris mauris, sit amet venenatis nisl. Vivamus a est porta enim sollicitudin
mollis. Proin fringilla massa vel ante gravida luctus. Nunc quis nunc id quam
hendrerit posuere. Cum sociis natoque penatibus et magnis dis parturient
montes, nascetur ridiculus mus. Aliquam porttitor interdum sollicitudin. Mauris
malesuada tellus tellus. Mauris condimentum nunc et sapien pellentesque
gravida. Suspendisse sed ipsum orci. Duis ut lacus dui. Integer ac gravida sem.
Vivamus fermentum porttitor velit ac blandit. Maecenas pulvinar ullamcorper
enim, vitae aliquet tortor scelerisque et. Vestibulum ante massa, sodales et
bibendum dignissim, consectetur vitae metus. Quisque vel dui erat, vel commodo
metus. Aliquam arcu dolor, viverra sit amet porttitor a, faucibus eu augue.
Sed ornare, enim eget ultricies suscipit, nunc dui lacinia enim, vitae tempus
nunc libero vitae ligula. Nam et commodo ligula. Pellentesque tincidunt lorem
at elit aliquam at fringilla libero tempor. Donec molestie consectetur nibh, ac
varius ante dictum id. Suspendisse lectus nibh, molestie vel dapibus eget,
egestas ut eros. Mauris vel mauris turpis, vitae bibendum nunc. Vestibulum
nulla enim, vestibulum vitae tincidunt et, gravida eu metus. Nulla sagittis,
odio a placerat laoreet, arcu lectus vestibulum nunc, in hendrerit tortor quam
sit amet turpis. In et purus vel dui pellentesque tincidunt. Donec dictum nibh
sed quam luctus sit amet luctus justo dapibus. Integer nulla elit, lacinia
aliquet euismod sed, tempus vitae lectus. Fusce non sapien dolor. Suspendisse
ut est ut dui tempor ultricies id ut elit. Aenean adipiscing sollicitudin enim,
nec porttitor est porttitor eget. Proin lobortis ante ut diam sodales volutpat.
Donec urna diam, porttitor nec laoreet ut, rhoncus non diam.
Ut sed mi vitae turpis semper semper. Integer sit amet lorem sapien. Aliquam
risus diam, vulputate id sagittis et, molestie ut lectus. Aliquam erat
volutpat. Morbi aliquet venenatis metus in posuere. Cras vitae purus nunc, ut
vestibulum ipsum. Nullam vehicula dui in urna iaculis lobortis. Ut a est non
est tincidunt iaculis. Vivamus rutrum velit non nunc malesuada sed bibendum mi
iaculis. Sed id lacus in sem tempor vestibulum. Cras bibendum accumsan
suscipit. Phasellus congue nisl consectetur turpis rhoncus aliquet posuere
libero fringilla. Sed eros tellus, hendrerit nec imperdiet vitae, blandit ac
dolor. Nulla facilisi. Morbi ullamcorper libero odio, at cursus tortor. Cras
ultricies tellus eget justo cursus cursus. Donec at mi massa, auctor suscipit
sem.
Proin dolor purus, semper sed ultrices ut, iaculis at tortor. Donec risus enim,
interdum et convallis nec, aliquam eget velit. Curabitur eget lectus dolor.
Integer id turpis eu nulla euismod tincidunt. Fusce elit nibh, dapibus sit amet
tempus ac, convallis eu libero. Donec dui justo, molestie sed euismod porta,
ultricies id orci. Praesent a tellus et risus faucibus porttitor pellentesque
in purus. Fusce blandit risus ac tortor viverra vitae molestie odio convallis.
Donec rhoncus volutpat mauris, sit amet mattis libero dapibus id. Ut rhoncus
venenatis nisi ac dictum. In non nulla eget massa convallis facilisis. Praesent
nec odio id odio semper lobortis non eu erat. Proin quis gravida magna. Sed
rhoncus lectus auctor arcu posuere a auctor dui pellentesque.
Sed enim nulla, luctus quis sagittis sed, vestibulum eget metus. Mauris ornare
pretium fringilla. Proin ligula eros, fermentum in placerat sit amet, placerat
vel mauris. Nulla magna enim, luctus eget euismod ac, lacinia vel lorem. Duis
mi leo, porttitor vitae dictum ac, ultrices iaculis metus. Quisque libero mi,
aliquet quis vestibulum eget, porttitor non justo. Praesent ac metus felis.
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac
turpis egestas. Donec vel enim sit amet ante imperdiet commodo sed vel nisi.
Praesent semper viverra nulla vehicula sollicitudin. Fusce lacinia aliquet
ullamcorper. Donec vitae diam est. Integer volutpat hendrerit turpis ut
bibendum. Integer et dui augue.
Nunc ut nisl in felis feugiat semper nec sit amet purus. Proin convallis
ultrices nisl ut vehicula. Pellentesque neque mi, elementum vel placerat nec,
laoreet ac nulla. Pellentesque aliquam dui a metus iaculis posuere. Curabitur
dapibus faucibus metus. Donec quis diam dui. Proin at mi nec augue cursus
pulvinar eu vel metus. Curabitur eget turpis ac risus dignissim luctus sed id
ligula. Etiam lectus neque, varius ut euismod nec, euismod quis nulla. Ut
feugiat, quam id tempor luctus, metus eros lacinia diam, nec dapibus tellus dui
quis diam. Nam interdum, orci id fringilla mattis, ipsum eros pellentesque
turpis, hendrerit dignissim justo dui interdum ante. Curabitur aliquam nisi ut
dui lacinia tempor. Nulla lobortis tellus non sapien dignissim ut dapibus dui
aliquet. Nam scelerisque, urna a aliquam malesuada, mi tortor scelerisque
libero, quis pellentesque erat eros ut justo.
Phasellus nulla purus, suscipit vel gravida euismod, malesuada et odio.
Vestibulum non libero eget lacus venenatis auctor quis a est. Nunc id leo est.
Curabitur pulvinar viverra sapien at viverra. Cras pretium justo et lorem
lobortis id tempor nisi accumsan. Cras egestas tortor in risus hendrerit eu
varius purus suscipit. Nullam mauris eros, mattis at tempor vitae, mollis vitae
velit. Etiam at adipiscing lectus. Quisque molestie, metus id posuere pharetra,
lorem enim vehicula mauris, ut ultricies purus justo a lacus. Vivamus blandit
euismod adipiscing. Nam eu ligula at elit ultricies tempus. Nunc ac sodales
neque. Ut dui diam, porttitor a pulvinar vel, sodales sit amet turpis. Donec
vitae eros at neque luctus scelerisque. In consequat elementum iaculis. Donec
ullamcorper dolor eu quam volutpat rhoncus. Lorem ipsum dolor sit amet,
consectetur adipiscing elit. Cras laoreet ante eget dolor sagittis imperdiet.
Proin magna urna, porta id blandit nec, commodo eget lorem.
Etiam imperdiet, orci sit amet rutrum consectetur, orci augue tempus lacus, id
venenatis sapien nisl a est. Sed accumsan massa sed libero consectetur
scelerisque. Class aptent taciti sociosqu ad litora torquent per conubia
nostra, per inceptos himenaeos. Sed nunc risus, lobortis id egestas nec,
suscipit id magna. Morbi at iaculis mauris. Proin felis sem, tempus non
pellentesque congue, vehicula sit amet eros. Maecenas porttitor erat ac dolor
pharetra iaculis. Cras tincidunt, nulla eget malesuada egestas, sem diam
consequat quam, sed feugiat nulla orci at mauris. Quisque non arcu diam, ac
lacinia felis. Nunc iaculis mollis egestas. Etiam imperdiet dolor consectetur
eros feugiat fringilla sed in lacus. Nunc nec tincidunt dolor. Etiam sagittis
tortor condimentum nunc fermentum vestibulum. Vivamus lobortis, magna sit amet
scelerisque lobortis, sem eros molestie leo, eget aliquet ligula est in lectus.
Duis placerat porta pulvinar. Sed sed adipiscing ante. Vestibulum ante ipsum
primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nam accumsan
iaculis augue, sed varius dui sagittis id. Etiam sit amet eleifend augue.
Ut sit amet nibh sit amet justo tempor condimentum. Ut faucibus sagittis
volutpat. Duis vestibulum feugiat sollicitudin. Aenean cursus luctus urna at
consectetur. Nullam tincidunt, eros a iaculis sodales, tellus est imperdiet
arcu, sit amet tincidunt orci felis et tortor. Mauris rutrum venenatis nunc ut
rutrum. Phasellus nec erat magna, in tincidunt orci. Sed sit amet suscipit
tellus. Mauris ut nisi turpis. Suspendisse augue turpis, condimentum ac
bibendum in, vestibulum nec eros. Curabitur dapibus pulvinar vehicula. Fusce
consequat, erat in malesuada hendrerit, tellus urna pharetra lacus, sed euismod
nisi urna sed nisi. Etiam fermentum accumsan nunc, sed bibendum dui iaculis id.
Etiam blandit fermentum ligula nec viverra. Vivamus venenatis arcu in nulla
euismod euismod. Donec sit amet augue nec metus varius fringilla. Vivamus
pulvinar elit ac mi rhoncus in luctus diam egestas. Curabitur a felis eget arcu
pretium tempus eu sed mauris. Vestibulum ante ipsum primis in faucibus orci
luctus et ultrices posuere cubilia Curae;
Mauris malesuada, nibh ac venenatis hendrerit, ligula dui condimentum tellus,
sit amet pretium diam tortor vel risus. Suspendisse suscipit consequat eros id
dignissim. Cras interdum lorem ac massa euismod non porta enim pretium. Aliquam
ultrices nibh vitae ligula consectetur vel sollicitudin lacus volutpat.
Phasellus vulputate iaculis sem nec laoreet. Nam leo sem, tempor eu condimentum
id, imperdiet sed dolor. Donec pharetra velit non libero euismod tempor.
Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere
cubilia Curae; Sed fermentum, libero a posuere posuere, enim elit imperdiet
enim, a sollicitudin est felis non libero. Sed vel dolor ut arcu dapibus
iaculis nec a mauris. Morbi ullamcorper ultrices venenatis. Fusce luctus ante
sit amet lacus venenatis ut rutrum elit lobortis. Nulla fermentum tortor ac
sapien fringilla quis iaculis quam egestas.
Aliquam et tortor est, at elementum mauris. Morbi posuere erat nec leo
vulputate in pellentesque tortor condimentum. Vestibulum at orci augue. Aenean
pellentesque sapien id felis consequat varius. Suspendisse bibendum enim sit
amet mi imperdiet vel suscipit nisi tristique. Curabitur velit massa,
consectetur ac mattis vel, accumsan at nunc. Donec porta, nibh nec consequat
convallis, urna neque auctor erat, eu convallis lorem leo convallis turpis.
Morbi non mauris non metus ornare vulputate. Sed aliquet, dolor ut egestas
fermentum, metus purus mollis elit, nec commodo odio quam quis nisl. Aliquam
erat volutpat. Suspendisse sed faucibus urna. Integer suscipit rutrum
condimentum. Praesent dignissim libero eget metus luctus consectetur.
Vestibulum ac erat felis, vitae iaculis erat. Duis interdum lacinia arcu, non
lacinia urna luctus in. Curabitur feugiat sapien sapien, in vestibulum diam.
Phasellus lobortis massa ut metus pretium dignissim. Fusce quis sem odio.
Integer pellentesque sodales augue id tincidunt. Pellentesque habitant morbi
tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum
lorem odio, semper vel scelerisque sit amet, sagittis ac libero. Vestibulum
ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;
Nam egestas ultricies dui at gravida. Duis tristique, eros id consectetur
pellentesque, nulla arcu ultricies tortor, ut pulvinar sapien lacus in elit.
Vivamus dolor massa, pulvinar at mollis vitae, euismod ut dolor. Vivamus a
magna ante. Vestibulum vitae fringilla leo. Ut gravida magna in quam fringilla
ultricies. Mauris rhoncus enim id sem interdum blandit. Pellentesque luctus leo
sit amet felis viverra ac accumsan purus mollis. Aenean pretium fringilla quam
nec laoreet.
Nulla id mauris mauris. Nam varius bibendum tristique. Integer ante felis,
volutpat sed dignissim vel, interdum molestie nisi. Etiam mollis accumsan elit,
ut gravida eros molestie nec. Nullam quis velit ac purus imperdiet sodales.
Donec semper placerat venenatis. Cras dolor risus, sodales sed scelerisque nec,
sollicitudin pretium felis. Quisque pretium felis id turpis bibendum pulvinar
ornare id nibh. Morbi lobortis leo non mi porttitor vulputate. Vestibulum nec
odio tellus, ut blandit ligula. In pellentesque neque sit amet dui pulvinar sed
laoreet dui vehicula. In hac habitasse platea dictumst. Etiam feugiat dictum
blandit. Praesent lacinia tincidunt elit, quis consectetur tortor molestie
commodo.
Ut sit amet accumsan lorem. Cras quam nunc, malesuada tempor volutpat vitae,
aliquam eu diam. Sed sem nibh, bibendum nec sollicitudin at, interdum et magna.
Cum sociis natoque penatibus et magnis dis parturient montes, nascetur
ridiculus mus. Aliquam vitae sem non elit pharetra vestibulum et condimentum
libero. Nam egestas ultricies hendrerit. Nunc nec fringilla nulla. Aliquam
risus tellus, hendrerit non dapibus a, tincidunt vel ante. Vivamus mollis,
magna et lacinia tincidunt, dui massa porta odio, ac ornare felis massa nec
lorem. Mauris sagittis lacus sed metus mollis ac egestas lectus porttitor.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cum sociis natoque
penatibus et magnis dis parturient montes, nascetur ridiculus mus. Integer
vitae lacinia libero. Phasellus at neque enim, sit amet dictum mi.
Ut risus nisi, vestibulum vel congue eget, egestas in ipsum. Duis faucibus
tempus sodales. Duis convallis pellentesque arcu rhoncus congue. Nunc ac mauris
eu purus vestibulum congue. Praesent convallis semper augue vel volutpat.
Integer dictum varius placerat. Vestibulum convallis tortor non mi lacinia ac
aliquet dui ultricies. Donec ultrices purus eros. Maecenas venenatis posuere
massa, nec consectetur lacus cursus eget. Donec quam lacus, tempus id placerat
et, posuere sed libero. Proin auctor diam ut arcu viverra ut imperdiet tellus
dapibus.
Morbi ac mauris quis tellus porttitor eleifend. Sed et ante magna, ut sodales
sapien. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices
posuere cubilia Curae; Integer mattis venenatis mi non ullamcorper. Vestibulum
magna enim, aliquam non interdum ut, dignissim vitae ante. Praesent dignissim,
est at pretium posuere, nisl ante varius felis, vitae posuere enim nulla et
nunc. Morbi sagittis suscipit leo, eu accumsan ligula volutpat non. Donec ut
tincidunt magna. Integer ac libero mi. Sed non eros dolor, in tincidunt enim.
Curabitur iaculis erat quis felis iaculis ut volutpat augue malesuada.
Pellentesque eget arcu ligula, ut volutpat purus. Suspendisse dictum lorem quis
sapien lacinia pretium. Lorem ipsum dolor sit amet, consectetur adipiscing
elit.
Proin sagittis egestas massa et tempor. Mauris et eros ante, id porta sem. Duis
ac eros vitae ipsum ultrices malesuada eget a risus. Morbi imperdiet, est a
hendrerit tristique, mi erat molestie lacus, ac tempor risus nulla id erat.
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac
turpis egestas. Etiam congue, lacus quis ultricies consequat, diam metus
convallis enim, ut volutpat enim urna vitae erat. In quam risus, molestie et
dapibus id, elementum sit amet ligula. Nam faucibus lacus id dolor facilisis
viverra. Nullam vehicula massa ac arcu consectetur vulputate. Praesent nec
augue ac justo dapibus vehicula. Aliquam consectetur hendrerit dolor, et mollis
nisl auctor ut.
Ut sagittis risus at felis fringilla ultricies. Vestibulum non urna nibh, nec
pretium dolor. Nulla imperdiet lobortis eros at pharetra. Vivamus cursus
pellentesque ornare. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Fusce arcu quam, pulvinar at rutrum vitae, ornare vitae leo. Maecenas vehicula
magna sit amet nulla bibendum condimentum. Curabitur ultrices tempor fringilla.
Vivamus pretium suscipit molestie. Donec arcu diam, ultricies ac pellentesque
eu, venenatis et sapien.
Nam dictum orci augue, vel eleifend leo. Nam at lacus sapien, nec pretium eros.
In egestas, enim sed sagittis feugiat, purus odio tristique lectus, vel
condimentum leo turpis ac odio. Nam iaculis mi quis odio posuere et venenatis
velit ultricies. Nulla facilisi. Proin nec dolor ac quam euismod gravida quis
et eros. Nam interdum condimentum mattis. Cum sociis natoque penatibus et
magnis dis parturient montes, nascetur ridiculus mus. Praesent a nisi eu massa
mollis posuere sed a nunc. Aenean tempus enim a justo rhoncus quis ultrices
nisl commodo.
Aenean imperdiet mauris a ipsum venenatis vel scelerisque lorem rutrum. Donec
ut nunc eros, eget accumsan felis. Nullam ullamcorper porta dictum. Donec
accumsan cursus vestibulum. Aenean in sapien velit. Vivamus nec massa mi. Fusce
felis tortor, bibendum non volutpat a, fringilla quis nisi. Duis varius
bibendum erat, quis fermentum sem accumsan eget. Maecenas massa felis, porta
sed laoreet eu, luctus eu lectus. Cras id nibh vitae erat fringilla rutrum.
Maecenas eget consequat est. Vivamus viverra, felis vel faucibus rhoncus, quam
ipsum elementum libero, quis convallis urna purus ut mauris. Nam quis urna
vitae enim consequat placerat. Vivamus congue augue sit amet lectus luctus
tempor. Cras ut justo convallis est egestas pellentesque ac nec orci.
Vivamus rutrum bibendum ante, at cursus erat pulvinar ornare. Proin imperdiet
scelerisque ante eu vestibulum. Nullam ullamcorper metus nec purus auctor
lobortis. Proin sed lacus et ipsum tempor tempus. Vivamus odio dolor, vulputate
vitae semper sit amet, aliquet egestas orci. Nullam non quam eu quam sagittis
porta. Nunc in velit id erat commodo viverra. Praesent nec est augue, nec
sagittis erat. Cras sed turpis quis enim tempor sagittis. Donec in justo ac
nisl porta condimentum id vestibulum nulla. Nam elementum ultricies nunc a
bibendum.
Aenean tincidunt nisl non augue pellentesque sit amet convallis neque semper.
Cras placerat suscipit massa sed volutpat. Integer vulputate imperdiet enim,
vitae vulputate sapien mattis feugiat. Vivamus pharetra facilisis mauris a
gravida. Nulla non venenatis est. Duis lobortis consectetur sem ac aliquam. In
eget sapien odio. Vivamus pulvinar ultricies magna, quis laoreet dui porta et.
Integer tempus malesuada velit, et consequat odio ultrices sed. Aliquam
malesuada commodo diam vel posuere. Morbi porttitor, elit vitae auctor gravida,
lorem massa bibendum arcu, vel placerat nulla justo at augue.
Aliquam libero quam, mattis blandit congue sit amet, fermentum ac augue.
Aliquam malesuada molestie vulputate. Duis id porta augue. Vestibulum diam
dolor, ultrices sit amet porttitor id, convallis id lectus. Etiam ac augue
tincidunt nisi tempor molestie euismod id nisl. Nam et tortor ac arcu viverra
pulvinar. Fusce pulvinar rhoncus leo, a faucibus enim interdum non. Aliquam
vulputate mattis consectetur. Pellentesque sit amet quam sem. Cras eget arcu eu
elit volutpat volutpat. Integer sed varius enim. Integer sit amet felis orci,
id dignissim sapien. Sed vitae lorem sed libero facilisis fringilla.
Pellentesque congue tristique purus, eleifend semper risus suscipit quis.
Phasellus rutrum quam vitae arcu vulputate porta. Sed tristique arcu nec mi
porttitor lacinia.
Donec congue feugiat diam quis pretium. Vivamus at luctus nunc. Integer
vulputate laoreet mauris quis auctor. Nunc at ultrices libero. Maecenas porta
faucibus purus non vehicula. Sed sit amet metus vitae mi ultrices scelerisque
nec quis risus. Phasellus pellentesque tincidunt massa id ultricies. Aliquam
dictum arcu ac dolor interdum rutrum. Nulla facilisi. Duis nisi est, tincidunt
a sagittis id, sollicitudin at odio. Curabitur sed est eu sapien faucibus
dignissim in quis tortor.
Nunc ac elit tortor, non lobortis massa. Proin posuere ante ut metus vehicula
suscipit. Proin mattis mauris ac lectus consequat rutrum. Nam arcu lectus,
commodo non pretium a, pharetra semper dolor. Fusce eleifend hendrerit
adipiscing. Nunc et eleifend erat. Suspendisse tempus nisl ut arcu blandit ut
adipiscing nisi tristique. Suspendisse molestie facilisis risus sed fermentum.
Praesent tempor convallis ultricies. Integer et elit velit, at consectetur
risus.
Vestibulum mollis adipiscing sodales. Vestibulum ante ipsum primis in faucibus
orci luctus et ultrices posuere cubilia Curae; Mauris dictum molestie porta.
Nam convallis nisl quis lacus vulputate in convallis risus sagittis. Vivamus
accumsan faucibus cursus. Ut ultricies imperdiet ligula scelerisque blandit. In
ornare egestas purus, at convallis velit egestas laoreet. Class aptent taciti
sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nulla
quis imperdiet est. Nunc tempus magna quis lacus feugiat et posuere lacus
vehicula. Cras lacinia aliquam est at vehicula. Aenean congue elit in ante
dignissim vitae fermentum lectus aliquam. Mauris at odio magna, at interdum
dui. Cras fringilla mi velit, nec varius neque.
Fusce et volutpat lacus. Suspendisse id turpis et urna varius convallis in eu
purus. Nulla facilisi. Etiam mauris nisl, ultrices ac porttitor sit amet,
facilisis ut neque. Nullam ut velit quis velit tincidunt rhoncus. Praesent
tristique porttitor euismod. Nulla non felis ante, feugiat commodo turpis. In
nec venenatis mi. Duis tempus tempor purus, vitae consectetur mi ornare eu.
Proin sed consequat erat. Quisque nec sem dui. Nam semper, ligula facilisis
pretium interdum, diam lectus sollicitudin lorem, in elementum nisi lorem
scelerisque justo. Nullam ac fringilla nunc. Maecenas malesuada ligula in massa
sollicitudin sit amet auctor ipsum malesuada. Vestibulum ut augue in magna
lobortis varius eget in ipsum. In hac habitasse platea dictumst.
Cras vel sagittis mi. Aenean urna sapien, ultrices et tristique et, aliquam vel
libero. Nullam in consequat ante. Suspendisse libero augue, pulvinar a
dignissim vitae, fringilla malesuada dui. Phasellus augue ante, pulvinar eget
tincidunt vel, venenatis sed arcu. Pellentesque ac purus orci, vel molestie
turpis. Nulla consectetur sollicitudin dolor, sed ornare arcu accumsan
fermentum. Fusce vestibulum nisi at leo interdum eu sollicitudin lacus dictum.
Fusce malesuada consequat ipsum ut convallis. Maecenas in eros sit amet elit
consectetur fringilla nec a nibh. Ut et velit vel ligula pharetra elementum.
Nullam aliquam, tellus vel cursus lacinia, dui libero dictum turpis, nec
lacinia dolor nunc vel diam. Pellentesque convallis dui quis lacus ornare at
rutrum lorem pellentesque. Suspendisse potenti. Cum sociis natoque penatibus et
magnis dis parturient montes, nascetur ridiculus mus.
Nunc ac nibh sed mauris ornare cursus. Praesent enim mauris, tincidunt vitae
convallis ac, ultricies imperdiet sapien. Duis sodales ligula eget lorem
suscipit sed consectetur metus pretium. Nam in magna augue, quis volutpat
mauris. Quisque pretium lobortis orci quis laoreet. Nam ut nisi diam. Sed
ultrices ultrices dapibus. Integer feugiat mauris id orci pulvinar eu tempus
nibh viverra. Etiam venenatis bibendum massa a consequat. Fusce interdum velit
ac mauris rhoncus non cursus neque consectetur. Vestibulum dictum eros ac metus
fringilla venenatis. Phasellus auctor dui non nulla molestie id malesuada
mauris euismod. Aenean id tortor ac justo eleifend mollis non vel arcu. Duis ac
lorem tortor. Donec volutpat purus sed nunc luctus interdum hendrerit nulla
ullamcorper. Sed consectetur interdum aliquet. Proin ullamcorper risus ut ante
lacinia sagittis. Nunc varius eleifend purus, ac pellentesque urna viverra id.
Praesent euismod, sapien accumsan gravida dictum, massa massa euismod sapien,
ut auctor tellus arcu sed diam.
Vivamus tincidunt dolor non lorem pellentesque at tempus elit adipiscing.
Vestibulum tempor aliquam consectetur. Mauris nec dictum nisl. Donec
scelerisque ornare condimentum. Phasellus laoreet justo nec nibh convallis
convallis. Duis id orci sapien, eget pulvinar justo. Aenean id arcu felis, eu
iaculis nibh. Aenean eleifend pretium rutrum. Aliquam molestie sem quis tellus
aliquam eleifend. Mauris et purus orci. Nunc et accumsan tortor. Phasellus
semper eleifend nisi, a faucibus risus vehicula id. Lorem ipsum dolor sit amet,
consectetur adipiscing elit. Maecenas in felis et est lacinia eleifend vel sed
ipsum. Aliquam commodo molestie lorem id hendrerit. Nam sed tellus urna, sed
dignissim eros.
"""
A_LONG_STRING = """A long string.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer sit amet
mauris mauris, sit amet venenatis nisl. Vivamus a est porta enim sollicitudin
mollis. Proin fringilla massa vel ante gravida luctus. Nunc quis nunc id quam
hendrerit posuere. Cum sociis natoque penatibus et magnis dis parturient
montes, nascetur ridiculus mus. Aliquam porttitor interdum sollicitudin. Mauris
malesuada tellus tellus. Mauris condimentum nunc et sapien pellentesque
gravida. Suspendisse sed ipsum orci. Duis ut lacus dui. Integer ac gravida sem.
Vivamus fermentum porttitor velit ac blandit. Maecenas pulvinar ullamcorper
enim, vitae aliquet tortor scelerisque et. Vestibulum ante massa, sodales et
bibendum dignissim, consectetur vitae metus. Quisque vel dui erat, vel commodo
metus. Aliquam arcu dolor, viverra sit amet porttitor a, faucibus eu augue.
Sed ornare, enim eget ultricies suscipit, nunc dui lacinia enim, vitae tempus
nunc libero vitae ligula. Nam et commodo ligula. Pellentesque tincidunt lorem
at elit aliquam at fringilla libero tempor. Donec molestie consectetur nibh, ac
varius ante dictum id. Suspendisse lectus nibh, molestie vel dapibus eget,
egestas ut eros. Mauris vel mauris turpis, vitae bibendum nunc. Vestibulum
nulla enim, vestibulum vitae tincidunt et, gravida eu metus. Nulla sagittis,
odio a placerat laoreet, arcu lectus vestibulum nunc, in hendrerit tortor quam
sit amet turpis. In et purus vel dui pellentesque tincidunt. Donec dictum nibh
sed quam luctus sit amet luctus justo dapibus. Integer nulla elit, lacinia
aliquet euismod sed, tempus vitae lectus. Fusce non sapien dolor. Suspendisse
ut est ut dui tempor ultricies id ut elit. Aenean adipiscing sollicitudin enim,
nec porttitor est porttitor eget. Proin lobortis ante ut diam sodales volutpat.
Donec urna diam, porttitor nec laoreet ut, rhoncus non diam.
Ut sed mi vitae turpis semper semper. Integer sit amet lorem sapien. Aliquam
risus diam, vulputate id sagittis et, molestie ut lectus. Aliquam erat
volutpat. Morbi aliquet venenatis metus in posuere. Cras vitae purus nunc, ut
vestibulum ipsum. Nullam vehicula dui in urna iaculis lobortis. Ut a est non
est tincidunt iaculis. Vivamus rutrum velit non nunc malesuada sed bibendum mi
iaculis. Sed id lacus in sem tempor vestibulum. Cras bibendum accumsan
suscipit. Phasellus congue nisl consectetur turpis rhoncus aliquet posuere
libero fringilla. Sed eros tellus, hendrerit nec imperdiet vitae, blandit ac
dolor. Nulla facilisi. Morbi ullamcorper libero odio, at cursus tortor. Cras
ultricies tellus eget justo cursus cursus. Donec at mi massa, auctor suscipit
sem.
Proin dolor purus, semper sed ultrices ut, iaculis at tortor. Donec risus enim,
interdum et convallis nec, aliquam eget velit. Curabitur eget lectus dolor.
Integer id turpis eu nulla euismod tincidunt. Fusce elit nibh, dapibus sit amet
tempus ac, convallis eu libero. Donec dui justo, molestie sed euismod porta,
ultricies id orci. Praesent a tellus et risus faucibus porttitor pellentesque
in purus. Fusce blandit risus ac tortor viverra vitae molestie odio convallis.
Donec rhoncus volutpat mauris, sit amet mattis libero dapibus id. Ut rhoncus
venenatis nisi ac dictum. In non nulla eget massa convallis facilisis. Praesent
nec odio id odio semper lobortis non eu erat. Proin quis gravida magna. Sed
rhoncus lectus auctor arcu posuere a auctor dui pellentesque.
Sed enim nulla, luctus quis sagittis sed, vestibulum eget metus. Mauris ornare
pretium fringilla. Proin ligula eros, fermentum in placerat sit amet, placerat
vel mauris. Nulla magna enim, luctus eget euismod ac, lacinia vel lorem. Duis
mi leo, porttitor vitae dictum ac, ultrices iaculis metus. Quisque libero mi,
aliquet quis vestibulum eget, porttitor non justo. Praesent ac metus felis.
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac
turpis egestas. Donec vel enim sit amet ante imperdiet commodo sed vel nisi.
Praesent semper viverra nulla vehicula sollicitudin. Fusce lacinia aliquet
ullamcorper. Donec vitae diam est. Integer volutpat hendrerit turpis ut
bibendum. Integer et dui augue.
Nunc ut nisl in felis feugiat semper nec sit amet purus. Proin convallis
ultrices nisl ut vehicula. Pellentesque neque mi, elementum vel placerat nec,
laoreet ac nulla. Pellentesque aliquam dui a metus iaculis posuere. Curabitur
dapibus faucibus metus. Donec quis diam dui. Proin at mi nec augue cursus
pulvinar eu vel metus. Curabitur eget turpis ac risus dignissim luctus sed id
ligula. Etiam lectus neque, varius ut euismod nec, euismod quis nulla. Ut
feugiat, quam id tempor luctus, metus eros lacinia diam, nec dapibus tellus dui
quis diam. Nam interdum, orci id fringilla mattis, ipsum eros pellentesque
turpis, hendrerit dignissim justo dui interdum ante. Curabitur aliquam nisi ut
dui lacinia tempor. Nulla lobortis tellus non sapien dignissim ut dapibus dui
aliquet. Nam scelerisque, urna a aliquam malesuada, mi tortor scelerisque
libero, quis pellentesque erat eros ut justo.
Phasellus nulla purus, suscipit vel gravida euismod, malesuada et odio.
Vestibulum non libero eget lacus venenatis auctor quis a est. Nunc id leo est.
Curabitur pulvinar viverra sapien at viverra. Cras pretium justo et lorem
lobortis id tempor nisi accumsan. Cras egestas tortor in risus hendrerit eu
varius purus suscipit. Nullam mauris eros, mattis at tempor vitae, mollis vitae
velit. Etiam at adipiscing lectus. Quisque molestie, metus id posuere pharetra,
lorem enim vehicula mauris, ut ultricies purus justo a lacus. Vivamus blandit
euismod adipiscing. Nam eu ligula at elit ultricies tempus. Nunc ac sodales
neque. Ut dui diam, porttitor a pulvinar vel, sodales sit amet turpis. Donec
vitae eros at neque luctus scelerisque. In consequat elementum iaculis. Donec
ullamcorper dolor eu quam volutpat rhoncus. Lorem ipsum dolor sit amet,
consectetur adipiscing elit. Cras laoreet ante eget dolor sagittis imperdiet.
Proin magna urna, porta id blandit nec, commodo eget lorem.
Etiam imperdiet, orci sit amet rutrum consectetur, orci augue tempus lacus, id
venenatis sapien nisl a est. Sed accumsan massa sed libero consectetur
scelerisque. Class aptent taciti sociosqu ad litora torquent per conubia
nostra, per inceptos himenaeos. Sed nunc risus, lobortis id egestas nec,
suscipit id magna. Morbi at iaculis mauris. Proin felis sem, tempus non
pellentesque congue, vehicula sit amet eros. Maecenas porttitor erat ac dolor
pharetra iaculis. Cras tincidunt, nulla eget malesuada egestas, sem diam
consequat quam, sed feugiat nulla orci at mauris. Quisque non arcu diam, ac
lacinia felis. Nunc iaculis mollis egestas. Etiam imperdiet dolor consectetur
eros feugiat fringilla sed in lacus. Nunc nec tincidunt dolor. Etiam sagittis
tortor condimentum nunc fermentum vestibulum. Vivamus lobortis, magna sit amet
scelerisque lobortis, sem eros molestie leo, eget aliquet ligula est in lectus.
Duis placerat porta pulvinar. Sed sed adipiscing ante. Vestibulum ante ipsum
primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nam accumsan
iaculis augue, sed varius dui sagittis id. Etiam sit amet eleifend augue.
Ut sit amet nibh sit amet justo tempor condimentum. Ut faucibus sagittis
volutpat. Duis vestibulum feugiat sollicitudin. Aenean cursus luctus urna at
consectetur. Nullam tincidunt, eros a iaculis sodales, tellus est imperdiet
arcu, sit amet tincidunt orci felis et tortor. Mauris rutrum venenatis nunc ut
rutrum. Phasellus nec erat magna, in tincidunt orci. Sed sit amet suscipit
tellus. Mauris ut nisi turpis. Suspendisse augue turpis, condimentum ac
bibendum in, vestibulum nec eros. Curabitur dapibus pulvinar vehicula. Fusce
consequat, erat in malesuada hendrerit, tellus urna pharetra lacus, sed euismod
nisi urna sed nisi. Etiam fermentum accumsan nunc, sed bibendum dui iaculis id.
Etiam blandit fermentum ligula nec viverra. Vivamus venenatis arcu in nulla
euismod euismod. Donec sit amet augue nec metus varius fringilla. Vivamus
pulvinar elit ac mi rhoncus in luctus diam egestas. Curabitur a felis eget arcu
pretium tempus eu sed mauris. Vestibulum ante ipsum primis in faucibus orci
luctus et ultrices posuere cubilia Curae;
Mauris malesuada, nibh ac venenatis hendrerit, ligula dui condimentum tellus,
sit amet pretium diam tortor vel risus. Suspendisse suscipit consequat eros id
dignissim. Cras interdum lorem ac massa euismod non porta enim pretium. Aliquam
ultrices nibh vitae ligula consectetur vel sollicitudin lacus volutpat.
Phasellus vulputate iaculis sem nec laoreet. Nam leo sem, tempor eu condimentum
id, imperdiet sed dolor. Donec pharetra velit non libero euismod tempor.
Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere
cubilia Curae; Sed fermentum, libero a posuere posuere, enim elit imperdiet
enim, a sollicitudin est felis non libero. Sed vel dolor ut arcu dapibus
iaculis nec a mauris. Morbi ullamcorper ultrices venenatis. Fusce luctus ante
sit amet lacus venenatis ut rutrum elit lobortis. Nulla fermentum tortor ac
sapien fringilla quis iaculis quam egestas.
Aliquam et tortor est, at elementum mauris. Morbi posuere erat nec leo
vulputate in pellentesque tortor condimentum. Vestibulum at orci augue. Aenean
pellentesque sapien id felis consequat varius. Suspendisse bibendum enim sit
amet mi imperdiet vel suscipit nisi tristique. Curabitur velit massa,
consectetur ac mattis vel, accumsan at nunc. Donec porta, nibh nec consequat
convallis, urna neque auctor erat, eu convallis lorem leo convallis turpis.
Morbi non mauris non metus ornare vulputate. Sed aliquet, dolor ut egestas
fermentum, metus purus mollis elit, nec commodo odio quam quis nisl. Aliquam
erat volutpat. Suspendisse sed faucibus urna. Integer suscipit rutrum
condimentum. Praesent dignissim libero eget metus luctus consectetur.
Vestibulum ac erat felis, vitae iaculis erat. Duis interdum lacinia arcu, non
lacinia urna luctus in. Curabitur feugiat sapien sapien, in vestibulum diam.
Phasellus lobortis massa ut metus pretium dignissim. Fusce quis sem odio.
Integer pellentesque sodales augue id tincidunt. Pellentesque habitant morbi
tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum
lorem odio, semper vel scelerisque sit amet, sagittis ac libero. Vestibulum
ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;
Nam egestas ultricies dui at gravida. Duis tristique, eros id consectetur
pellentesque, nulla arcu ultricies tortor, ut pulvinar sapien lacus in elit.
Vivamus dolor massa, pulvinar at mollis vitae, euismod ut dolor. Vivamus a
magna ante. Vestibulum vitae fringilla leo. Ut gravida magna in quam fringilla
ultricies. Mauris rhoncus enim id sem interdum blandit. Pellentesque luctus leo
sit amet felis viverra ac accumsan purus mollis. Aenean pretium fringilla quam
nec laoreet.
Nulla id mauris mauris. Nam varius bibendum tristique. Integer ante felis,
volutpat sed dignissim vel, interdum molestie nisi. Etiam mollis accumsan elit,
ut gravida eros molestie nec. Nullam quis velit ac purus imperdiet sodales.
Donec semper placerat venenatis. Cras dolor risus, sodales sed scelerisque nec,
sollicitudin pretium felis. Quisque pretium felis id turpis bibendum pulvinar
ornare id nibh. Morbi lobortis leo non mi porttitor vulputate. Vestibulum nec
odio tellus, ut blandit ligula. In pellentesque neque sit amet dui pulvinar sed
laoreet dui vehicula. In hac habitasse platea dictumst. Etiam feugiat dictum
blandit. Praesent lacinia tincidunt elit, quis consectetur tortor molestie
commodo.
Ut sit amet accumsan lorem. Cras quam nunc, malesuada tempor volutpat vitae,
aliquam eu diam. Sed sem nibh, bibendum nec sollicitudin at, interdum et magna.
Cum sociis natoque penatibus et magnis dis parturient montes, nascetur
ridiculus mus. Aliquam vitae sem non elit pharetra vestibulum et condimentum
libero. Nam egestas ultricies hendrerit. Nunc nec fringilla nulla. Aliquam
risus tellus, hendrerit non dapibus a, tincidunt vel ante. Vivamus mollis,
magna et lacinia tincidunt, dui massa porta odio, ac ornare felis massa nec
lorem. Mauris sagittis lacus sed metus mollis ac egestas lectus porttitor.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cum sociis natoque
penatibus et magnis dis parturient montes, nascetur ridiculus mus. Integer
vitae lacinia libero. Phasellus at neque enim, sit amet dictum mi.
Ut risus nisi, vestibulum vel congue eget, egestas in ipsum. Duis faucibus
tempus sodales. Duis convallis pellentesque arcu rhoncus congue. Nunc ac mauris
eu purus vestibulum congue. Praesent convallis semper augue vel volutpat.
Integer dictum varius placerat. Vestibulum convallis tortor non mi lacinia ac
aliquet dui ultricies. Donec ultrices purus eros. Maecenas venenatis posuere
massa, nec consectetur lacus cursus eget. Donec quam lacus, tempus id placerat
et, posuere sed libero. Proin auctor diam ut arcu viverra ut imperdiet tellus
dapibus.
Morbi ac mauris quis tellus porttitor eleifend. Sed et ante magna, ut sodales
sapien. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices
posuere cubilia Curae; Integer mattis venenatis mi non ullamcorper. Vestibulum
magna enim, aliquam non interdum ut, dignissim vitae ante. Praesent dignissim,
est at pretium posuere, nisl ante varius felis, vitae posuere enim nulla et
nunc. Morbi sagittis suscipit leo, eu accumsan ligula volutpat non. Donec ut
tincidunt magna. Integer ac libero mi. Sed non eros dolor, in tincidunt enim.
Curabitur iaculis erat quis felis iaculis ut volutpat augue malesuada.
Pellentesque eget arcu ligula, ut volutpat purus. Suspendisse dictum lorem quis
sapien lacinia pretium. Lorem ipsum dolor sit amet, consectetur adipiscing
elit.
Proin sagittis egestas massa et tempor. Mauris et eros ante, id porta sem. Duis
ac eros vitae ipsum ultrices malesuada eget a risus. Morbi imperdiet, est a
hendrerit tristique, mi erat molestie lacus, ac tempor risus nulla id erat.
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac
turpis egestas. Etiam congue, lacus quis ultricies consequat, diam metus
convallis enim, ut volutpat enim urna vitae erat. In quam risus, molestie et
dapibus id, elementum sit amet ligula. Nam faucibus lacus id dolor facilisis
viverra. Nullam vehicula massa ac arcu consectetur vulputate. Praesent nec
augue ac justo dapibus vehicula. Aliquam consectetur hendrerit dolor, et mollis
nisl auctor ut.
Ut sagittis risus at felis fringilla ultricies. Vestibulum non urna nibh, nec
pretium dolor. Nulla imperdiet lobortis eros at pharetra. Vivamus cursus
pellentesque ornare. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Fusce arcu quam, pulvinar at rutrum vitae, ornare vitae leo. Maecenas vehicula
magna sit amet nulla bibendum condimentum. Curabitur ultrices tempor fringilla.
Vivamus pretium suscipit molestie. Donec arcu diam, ultricies ac pellentesque
eu, venenatis et sapien.
Nam dictum orci augue, vel eleifend leo. Nam at lacus sapien, nec pretium eros.
In egestas, enim sed sagittis feugiat, purus odio tristique lectus, vel
condimentum leo turpis ac odio. Nam iaculis mi quis odio posuere et venenatis
velit ultricies. Nulla facilisi. Proin nec dolor ac quam euismod gravida quis
et eros. Nam interdum condimentum mattis. Cum sociis natoque penatibus et
magnis dis parturient montes, nascetur ridiculus mus. Praesent a nisi eu massa
mollis posuere sed a nunc. Aenean tempus enim a justo rhoncus quis ultrices
nisl commodo.
Aenean imperdiet mauris a ipsum venenatis vel scelerisque lorem rutrum. Donec
ut nunc eros, eget accumsan felis. Nullam ullamcorper porta dictum. Donec
accumsan cursus vestibulum. Aenean in sapien velit. Vivamus nec massa mi. Fusce
felis tortor, bibendum non volutpat a, fringilla quis nisi. Duis varius
bibendum erat, quis fermentum sem accumsan eget. Maecenas massa felis, porta
sed laoreet eu, luctus eu lectus. Cras id nibh vitae erat fringilla rutrum.
Maecenas eget consequat est. Vivamus viverra, felis vel faucibus rhoncus, quam
ipsum elementum libero, quis convallis urna purus ut mauris. Nam quis urna
vitae enim consequat placerat. Vivamus congue augue sit amet lectus luctus
tempor. Cras ut justo convallis est egestas pellentesque ac nec orci.
Vivamus rutrum bibendum ante, at cursus erat pulvinar ornare. Proin imperdiet
scelerisque ante eu vestibulum. Nullam ullamcorper metus nec purus auctor
lobortis. Proin sed lacus et ipsum tempor tempus. Vivamus odio dolor, vulputate
vitae semper sit amet, aliquet egestas orci. Nullam non quam eu quam sagittis
porta. Nunc in velit id erat commodo viverra. Praesent nec est augue, nec
sagittis erat. Cras sed turpis quis enim tempor sagittis. Donec in justo ac
nisl porta condimentum id vestibulum nulla. Nam elementum ultricies nunc a
bibendum.
Aenean tincidunt nisl non augue pellentesque sit amet convallis neque semper.
Cras placerat suscipit massa sed volutpat. Integer vulputate imperdiet enim,
vitae vulputate sapien mattis feugiat. Vivamus pharetra facilisis mauris a
gravida. Nulla non venenatis est. Duis lobortis consectetur sem ac aliquam. In
eget sapien odio. Vivamus pulvinar ultricies magna, quis laoreet dui porta et.
Integer tempus malesuada velit, et consequat odio ultrices sed. Aliquam
malesuada commodo diam vel posuere. Morbi porttitor, elit vitae auctor gravida,
lorem massa bibendum arcu, vel placerat nulla justo at augue.
Aliquam libero quam, mattis blandit congue sit amet, fermentum ac augue.
Aliquam malesuada molestie vulputate. Duis id porta augue. Vestibulum diam
dolor, ultrices sit amet porttitor id, convallis id lectus. Etiam ac augue
tincidunt nisi tempor molestie euismod id nisl. Nam et tortor ac arcu viverra
pulvinar. Fusce pulvinar rhoncus leo, a faucibus enim interdum non. Aliquam
vulputate mattis consectetur. Pellentesque sit amet quam sem. Cras eget arcu eu
elit volutpat volutpat. Integer sed varius enim. Integer sit amet felis orci,
id dignissim sapien. Sed vitae lorem sed libero facilisis fringilla.
Pellentesque congue tristique purus, eleifend semper risus suscipit quis.
Phasellus rutrum quam vitae arcu vulputate porta. Sed tristique arcu nec mi
porttitor lacinia.
Donec congue feugiat diam quis pretium. Vivamus at luctus nunc. Integer
vulputate laoreet mauris quis auctor. Nunc at ultrices libero. Maecenas porta
faucibus purus non vehicula. Sed sit amet metus vitae mi ultrices scelerisque
nec quis risus. Phasellus pellentesque tincidunt massa id ultricies. Aliquam
dictum arcu ac dolor interdum rutrum. Nulla facilisi. Duis nisi est, tincidunt
a sagittis id, sollicitudin at odio. Curabitur sed est eu sapien faucibus
dignissim in quis tortor.
Nunc ac elit tortor, non lobortis massa. Proin posuere ante ut metus vehicula
suscipit. Proin mattis mauris ac lectus consequat rutrum. Nam arcu lectus,
commodo non pretium a, pharetra semper dolor. Fusce eleifend hendrerit
adipiscing. Nunc et eleifend erat. Suspendisse tempus nisl ut arcu blandit ut
adipiscing nisi tristique. Suspendisse molestie facilisis risus sed fermentum.
Praesent tempor convallis ultricies. Integer et elit velit, at consectetur
risus.
Vestibulum mollis adipiscing sodales. Vestibulum ante ipsum primis in faucibus
orci luctus et ultrices posuere cubilia Curae; Mauris dictum molestie porta.
Nam convallis nisl quis lacus vulputate in convallis risus sagittis. Vivamus
accumsan faucibus cursus. Ut ultricies imperdiet ligula scelerisque blandit. In
ornare egestas purus, at convallis velit egestas laoreet. Class aptent taciti
sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nulla
quis imperdiet est. Nunc tempus magna quis lacus feugiat et posuere lacus
vehicula. Cras lacinia aliquam est at vehicula. Aenean congue elit in ante
dignissim vitae fermentum lectus aliquam. Mauris at odio magna, at interdum
dui. Cras fringilla mi velit, nec varius neque.
Fusce et volutpat lacus. Suspendisse id turpis et urna varius convallis in eu
purus. Nulla facilisi. Etiam mauris nisl, ultrices ac porttitor sit amet,
facilisis ut neque. Nullam ut velit quis velit tincidunt rhoncus. Praesent
tristique porttitor euismod. Nulla non felis ante, feugiat commodo turpis. In
nec venenatis mi. Duis tempus tempor purus, vitae consectetur mi ornare eu.
Proin sed consequat erat. Quisque nec sem dui. Nam semper, ligula facilisis
pretium interdum, diam lectus sollicitudin lorem, in elementum nisi lorem
scelerisque justo. Nullam ac fringilla nunc. Maecenas malesuada ligula in massa
sollicitudin sit amet auctor ipsum malesuada. Vestibulum ut augue in magna
lobortis varius eget in ipsum. In hac habitasse platea dictumst.
Cras vel sagittis mi. Aenean urna sapien, ultrices et tristique et, aliquam vel
libero. Nullam in consequat ante. Suspendisse libero augue, pulvinar a
dignissim vitae, fringilla malesuada dui. Phasellus augue ante, pulvinar eget
tincidunt vel, venenatis sed arcu. Pellentesque ac purus orci, vel molestie
turpis. Nulla consectetur sollicitudin dolor, sed ornare arcu accumsan
fermentum. Fusce vestibulum nisi at leo interdum eu sollicitudin lacus dictum.
Fusce malesuada consequat ipsum ut convallis. Maecenas in eros sit amet elit
consectetur fringilla nec a nibh. Ut et velit vel ligula pharetra elementum.
Nullam aliquam, tellus vel cursus lacinia, dui libero dictum turpis, nec
lacinia dolor nunc vel diam. Pellentesque convallis dui quis lacus ornare at
rutrum lorem pellentesque. Suspendisse potenti. Cum sociis natoque penatibus et
magnis dis parturient montes, nascetur ridiculus mus.
Nunc ac nibh sed mauris ornare cursus. Praesent enim mauris, tincidunt vitae
convallis ac, ultricies imperdiet sapien. Duis sodales ligula eget lorem
suscipit sed consectetur metus pretium. Nam in magna augue, quis volutpat
mauris. Quisque pretium lobortis orci quis laoreet. Nam ut nisi diam. Sed
ultrices ultrices dapibus. Integer feugiat mauris id orci pulvinar eu tempus
nibh viverra. Etiam venenatis bibendum massa a consequat. Fusce interdum velit
ac mauris rhoncus non cursus neque consectetur. Vestibulum dictum eros ac metus
fringilla venenatis. Phasellus auctor dui non nulla molestie id malesuada
mauris euismod. Aenean id tortor ac justo eleifend mollis non vel arcu. Duis ac
lorem tortor. Donec volutpat purus sed nunc luctus interdum hendrerit nulla
ullamcorper. Sed consectetur interdum aliquet. Proin ullamcorper risus ut ante
lacinia sagittis. Nunc varius eleifend purus, ac pellentesque urna viverra id.
Praesent euismod, sapien accumsan gravida dictum, massa massa euismod sapien,
ut auctor tellus arcu sed diam.
Vivamus tincidunt dolor non lorem pellentesque at tempus elit adipiscing.
Vestibulum tempor aliquam consectetur. Mauris nec dictum nisl. Donec
scelerisque ornare condimentum. Phasellus laoreet justo nec nibh convallis
convallis. Duis id orci sapien, eget pulvinar justo. Aenean id arcu felis, eu
iaculis nibh. Aenean eleifend pretium rutrum. Aliquam molestie sem quis tellus
aliquam eleifend. Mauris et purus orci. Nunc et accumsan tortor. Phasellus
semper eleifend nisi, a faucibus risus vehicula id. Lorem ipsum dolor sit amet,
consectetur adipiscing elit. Maecenas in felis et est lacinia eleifend vel sed
ipsum. Aliquam commodo molestie lorem id hendrerit. Nam sed tellus urna, sed
dignissim eros.
"""
def a_function():
""""A long function docstring.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer sit amet
mauris mauris, sit amet venenatis nisl. Vivamus a est porta enim
sollicitudin mollis. Proin fringilla massa vel ante gravida luctus. Nunc
quis nunc id quam hendrerit posuere. Cum sociis natoque penatibus et magnis
dis parturient montes, nascetur ridiculus mus. Aliquam porttitor interdum
sollicitudin. Mauris malesuada tellus tellus. Mauris condimentum nunc et
sapien pellentesque gravida. Suspendisse sed ipsum orci. Duis ut lacus dui.
Integer ac gravida sem. Vivamus fermentum porttitor velit ac blandit.
Maecenas pulvinar ullamcorper enim, vitae aliquet tortor scelerisque et.
Vestibulum ante massa, sodales et bibendum dignissim, consectetur vitae
metus. Quisque vel dui erat, vel commodo metus. Aliquam arcu dolor, viverra
sit amet porttitor a, faucibus eu augue.
Sed ornare, enim eget ultricies suscipit, nunc dui lacinia enim, vitae
tempus nunc libero vitae ligula. Nam et commodo ligula. Pellentesque
tincidunt lorem at elit aliquam at fringilla libero tempor. Donec molestie
consectetur nibh, ac varius ante dictum id. Suspendisse lectus nibh,
molestie vel dapibus eget, egestas ut eros. Mauris vel mauris turpis, vitae
bibendum nunc. Vestibulum nulla enim, vestibulum vitae tincidunt et,
gravida eu metus. Nulla sagittis, odio a placerat laoreet, arcu lectus
vestibulum nunc, in hendrerit tortor quam sit amet turpis. In et purus vel
dui pellentesque tincidunt. Donec dictum nibh sed quam luctus sit amet
luctus justo dapibus. Integer nulla elit, lacinia aliquet euismod sed,
tempus vitae lectus. Fusce non sapien dolor. Suspendisse ut est ut dui
tempor ultricies id ut elit. Aenean adipiscing sollicitudin enim, nec
porttitor est porttitor eget. Proin lobortis ante ut diam sodales volutpat.
Donec urna diam, porttitor nec laoreet ut, rhoncus non diam.
Ut sed mi vitae turpis semper semper. Integer sit amet lorem sapien.
Aliquam risus diam, vulputate id sagittis et, molestie ut lectus. Aliquam
erat volutpat. Morbi aliquet venenatis metus in posuere. Cras vitae purus
nunc, ut vestibulum ipsum. Nullam vehicula dui in urna iaculis lobortis. Ut
a est non est tincidunt iaculis. Vivamus rutrum velit non nunc malesuada
sed bibendum mi iaculis. Sed id lacus in sem tempor vestibulum. Cras
bibendum accumsan suscipit. Phasellus congue nisl consectetur turpis
rhoncus aliquet posuere libero fringilla. Sed eros tellus, hendrerit nec
imperdiet vitae, blandit ac dolor. Nulla facilisi. Morbi ullamcorper libero
odio, at cursus tortor. Cras ultricies tellus eget justo cursus cursus.
Donec at mi massa, auctor suscipit sem.
Proin dolor purus, semper sed ultrices ut, iaculis at tortor. Donec risus
enim, interdum et convallis nec, aliquam eget velit. Curabitur eget lectus
dolor. Integer id turpis eu nulla euismod tincidunt. Fusce elit nibh,
dapibus sit amet tempus ac, convallis eu libero. Donec dui justo, molestie
sed euismod porta, ultricies id orci. Praesent a tellus et risus faucibus
porttitor pellentesque in purus. Fusce blandit risus ac tortor viverra
vitae molestie odio convallis. Donec rhoncus volutpat mauris, sit amet
mattis libero dapibus id. Ut rhoncus venenatis nisi ac dictum. In non nulla
eget massa convallis facilisis. Praesent nec odio id odio semper lobortis
non eu erat. Proin quis gravida magna. Sed rhoncus lectus auctor arcu
posuere a auctor dui pellentesque.
Sed enim nulla, luctus quis sagittis sed, vestibulum eget metus. Mauris
ornare pretium fringilla. Proin ligula eros, fermentum in placerat sit
amet, placerat vel mauris. Nulla magna enim, luctus eget euismod ac,
lacinia vel lorem. Duis mi leo, porttitor vitae dictum ac, ultrices iaculis
metus. Quisque libero mi, aliquet quis vestibulum eget, porttitor non
justo. Praesent ac metus felis. Pellentesque habitant morbi tristique
senectus et netus et malesuada fames ac turpis egestas. Donec vel enim sit
amet ante imperdiet commodo sed vel nisi. Praesent semper viverra nulla
vehicula sollicitudin. Fusce lacinia aliquet ullamcorper. Donec vitae diam
est. Integer volutpat hendrerit turpis ut bibendum. Integer et dui augue.
Nunc ut nisl in felis feugiat semper nec sit amet purus. Proin convallis
ultrices nisl ut vehicula. Pellentesque neque mi, elementum vel placerat
nec, laoreet ac nulla. Pellentesque aliquam dui a metus iaculis posuere.
Curabitur dapibus faucibus metus. Donec quis diam dui. Proin at mi nec
augue cursus pulvinar eu vel metus. Curabitur eget turpis ac risus
dignissim luctus sed id ligula. Etiam lectus neque, varius ut euismod nec,
euismod quis nulla. Ut feugiat, quam id tempor luctus, metus eros lacinia
diam, nec dapibus tellus dui quis diam. Nam interdum, orci id fringilla
mattis, ipsum eros pellentesque turpis, hendrerit dignissim justo dui
interdum ante. Curabitur aliquam nisi ut dui lacinia tempor. Nulla lobortis
tellus non sapien dignissim ut dapibus dui aliquet. Nam scelerisque, urna a
aliquam malesuada, mi tortor scelerisque libero, quis pellentesque erat
eros ut justo.
Phasellus nulla purus, suscipit vel gravida euismod, malesuada et odio.
Vestibulum non libero eget lacus venenatis auctor quis a est. Nunc id leo
est. Curabitur pulvinar viverra sapien at viverra. Cras pretium justo et
lorem lobortis id tempor nisi accumsan. Cras egestas tortor in risus
hendrerit eu varius purus suscipit. Nullam mauris eros, mattis at tempor
vitae, mollis vitae velit. Etiam at adipiscing lectus. Quisque molestie,
metus id posuere pharetra, lorem enim vehicula mauris, ut ultricies purus
justo a lacus. Vivamus blandit euismod adipiscing. Nam eu ligula at elit
ultricies tempus. Nunc ac sodales neque. Ut dui diam, porttitor a pulvinar
vel, sodales sit amet turpis. Donec vitae eros at neque luctus scelerisque.
In consequat elementum iaculis. Donec ullamcorper dolor eu quam volutpat
rhoncus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras
laoreet ante eget dolor sagittis imperdiet. Proin magna urna, porta id
blandit nec, commodo eget lorem.
Etiam imperdiet, orci sit amet rutrum consectetur, orci augue tempus lacus,
id venenatis sapien nisl a est. Sed accumsan massa sed libero consectetur
scelerisque. Class aptent taciti sociosqu ad litora torquent per conubia
nostra, per inceptos himenaeos. Sed nunc risus, lobortis id egestas nec,
suscipit id magna. Morbi at iaculis mauris. Proin felis sem, tempus non
pellentesque congue, vehicula sit amet eros. Maecenas porttitor erat ac
dolor pharetra iaculis. Cras tincidunt, nulla eget malesuada egestas, sem
diam consequat quam, sed feugiat nulla orci at mauris. Quisque non arcu
diam, ac lacinia felis. Nunc iaculis mollis egestas. Etiam imperdiet dolor
consectetur eros feugiat fringilla sed in lacus. Nunc nec tincidunt dolor.
Etiam sagittis tortor condimentum nunc fermentum vestibulum. Vivamus
lobortis, magna sit amet scelerisque lobortis, sem eros molestie leo, eget
aliquet ligula est in lectus. Duis placerat porta pulvinar. Sed sed
adipiscing ante. Vestibulum ante ipsum primis in faucibus orci luctus et
ultrices posuere cubilia Curae; Nam accumsan iaculis augue, sed varius dui
sagittis id. Etiam sit amet eleifend augue.
Ut sit amet nibh sit amet justo tempor condimentum. Ut faucibus sagittis
volutpat. Duis vestibulum feugiat sollicitudin. Aenean cursus luctus urna
at consectetur. Nullam tincidunt, eros a iaculis sodales, tellus est
imperdiet arcu, sit amet tincidunt orci felis et tortor. Mauris rutrum
venenatis nunc ut rutrum. Phasellus nec erat magna, in tincidunt orci. Sed
sit amet suscipit tellus. Mauris ut nisi turpis. Suspendisse augue turpis,
condimentum ac bibendum in, vestibulum nec eros. Curabitur dapibus pulvinar
vehicula. Fusce consequat, erat in malesuada hendrerit, tellus urna
pharetra lacus, sed euismod nisi urna sed nisi. Etiam fermentum accumsan
nunc, sed bibendum dui iaculis id. Etiam blandit fermentum ligula nec
viverra. Vivamus venenatis arcu in nulla euismod euismod. Donec sit amet
augue nec metus varius fringilla. Vivamus pulvinar elit ac mi rhoncus in
luctus diam egestas. Curabitur a felis eget arcu pretium tempus eu sed
mauris. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices
posuere cubilia Curae;
Mauris malesuada, nibh ac venenatis hendrerit, ligula dui condimentum
tellus, sit amet pretium diam tortor vel risus. Suspendisse suscipit
consequat eros id dignissim. Cras interdum lorem ac massa euismod non porta
enim pretium. Aliquam ultrices nibh vitae ligula consectetur vel
sollicitudin lacus volutpat. Phasellus vulputate iaculis sem nec laoreet.
Nam leo sem, tempor eu condimentum id, imperdiet sed dolor. Donec pharetra
velit non libero euismod tempor. Vestibulum ante ipsum primis in faucibus
orci luctus et ultrices posuere cubilia Curae; Sed fermentum, libero a
posuere posuere, enim elit imperdiet enim, a sollicitudin est felis non
libero. Sed vel dolor ut arcu dapibus iaculis nec a mauris. Morbi
ullamcorper ultrices venenatis. Fusce luctus ante sit amet lacus venenatis
ut rutrum elit lobortis. Nulla fermentum tortor ac sapien fringilla quis
iaculis quam egestas.
Aliquam et tortor est, at elementum mauris. Morbi posuere erat nec leo
vulputate in pellentesque tortor condimentum. Vestibulum at orci augue.
Aenean pellentesque sapien id felis consequat varius. Suspendisse bibendum
enim sit amet mi imperdiet vel suscipit nisi tristique. Curabitur velit
massa, consectetur ac mattis vel, accumsan at nunc. Donec porta, nibh nec
consequat convallis, urna neque auctor erat, eu convallis lorem leo
convallis turpis. Morbi non mauris non metus ornare vulputate. Sed aliquet,
dolor ut egestas fermentum, metus purus mollis elit, nec commodo odio quam
quis nisl. Aliquam erat volutpat. Suspendisse sed faucibus urna. Integer
suscipit rutrum condimentum. Praesent dignissim libero eget metus luctus
consectetur.
Vestibulum ac erat felis, vitae iaculis erat. Duis interdum lacinia arcu,
non lacinia urna luctus in. Curabitur feugiat sapien sapien, in vestibulum
diam. Phasellus lobortis massa ut metus pretium dignissim. Fusce quis sem
odio. Integer pellentesque sodales augue id tincidunt. Pellentesque
habitant morbi tristique senectus et netus et malesuada fames ac turpis
egestas. Vestibulum lorem odio, semper vel scelerisque sit amet, sagittis
ac libero. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices
posuere cubilia Curae; Nam egestas ultricies dui at gravida. Duis
tristique, eros id consectetur pellentesque, nulla arcu ultricies tortor,
ut pulvinar sapien lacus in elit. Vivamus dolor massa, pulvinar at mollis
vitae, euismod ut dolor. Vivamus a magna ante. Vestibulum vitae fringilla
leo. Ut gravida magna in quam fringilla ultricies. Mauris rhoncus enim id
sem interdum blandit. Pellentesque luctus leo sit amet felis viverra ac
accumsan purus mollis. Aenean pretium fringilla quam nec laoreet.
Nulla id mauris mauris. Nam varius bibendum tristique. Integer ante felis,
volutpat sed dignissim vel, interdum molestie nisi. Etiam mollis accumsan
elit, ut gravida eros molestie nec. Nullam quis velit ac purus imperdiet
sodales. Donec semper placerat venenatis. Cras dolor risus, sodales sed
scelerisque nec, sollicitudin pretium felis. Quisque pretium felis id
turpis bibendum pulvinar ornare id nibh. Morbi lobortis leo non mi
porttitor vulputate. Vestibulum nec odio tellus, ut blandit ligula. In
pellentesque neque sit amet dui pulvinar sed laoreet dui vehicula. In hac
habitasse platea dictumst. Etiam feugiat dictum blandit. Praesent lacinia
tincidunt elit, quis consectetur tortor molestie commodo.
Ut sit amet accumsan lorem. Cras quam nunc, malesuada tempor volutpat
vitae, aliquam eu diam. Sed sem nibh, bibendum nec sollicitudin at,
interdum et magna. Cum sociis natoque penatibus et magnis dis parturient
montes, nascetur ridiculus mus. Aliquam vitae sem non elit pharetra
vestibulum et condimentum libero. Nam egestas ultricies hendrerit. Nunc nec
fringilla nulla. Aliquam risus tellus, hendrerit non dapibus a, tincidunt
vel ante. Vivamus mollis, magna et lacinia tincidunt, dui massa porta odio,
ac ornare felis massa nec lorem. Mauris sagittis lacus sed metus mollis ac
egestas lectus porttitor. Lorem ipsum dolor sit amet, consectetur
adipiscing elit. Cum sociis natoque penatibus et magnis dis parturient
montes, nascetur ridiculus mus. Integer vitae lacinia libero. Phasellus at
neque enim, sit amet dictum mi.
Ut risus nisi, vestibulum vel congue eget, egestas in ipsum. Duis faucibus
tempus sodales. Duis convallis pellentesque arcu rhoncus congue. Nunc ac
mauris eu purus vestibulum congue. Praesent convallis semper augue vel
volutpat. Integer dictum varius placerat. Vestibulum convallis tortor non
mi lacinia ac aliquet dui ultricies. Donec ultrices purus eros. Maecenas
venenatis posuere massa, nec consectetur lacus cursus eget. Donec quam
lacus, tempus id placerat et, posuere sed libero. Proin auctor diam ut arcu
viverra ut imperdiet tellus dapibus.
Morbi ac mauris quis tellus porttitor eleifend. Sed et ante magna, ut
sodales sapien. Vestibulum ante ipsum primis in faucibus orci luctus et
ultrices posuere cubilia Curae; Integer mattis venenatis mi non
ullamcorper. Vestibulum magna enim, aliquam non interdum ut, dignissim
vitae ante. Praesent dignissim, est at pretium posuere, nisl ante varius
felis, vitae posuere enim nulla et nunc. Morbi sagittis suscipit leo, eu
accumsan ligula volutpat non. Donec ut tincidunt magna. Integer ac libero
mi. Sed non eros dolor, in tincidunt enim. Curabitur iaculis erat quis
felis iaculis ut volutpat augue malesuada. Pellentesque eget arcu ligula,
ut volutpat purus. Suspendisse dictum lorem quis sapien lacinia pretium.
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Proin sagittis egestas massa et tempor. Mauris et eros ante, id porta sem.
Duis ac eros vitae ipsum ultrices malesuada eget a risus. Morbi imperdiet,
est a hendrerit tristique, mi erat molestie lacus, ac tempor risus nulla id
erat. Pellentesque habitant morbi tristique senectus et netus et malesuada
fames ac turpis egestas. Etiam congue, lacus quis ultricies consequat, diam
metus convallis enim, ut volutpat enim urna vitae erat. In quam risus,
molestie et dapibus id, elementum sit amet ligula. Nam faucibus lacus id
dolor facilisis viverra. Nullam vehicula massa ac arcu consectetur
vulputate. Praesent nec augue ac justo dapibus vehicula. Aliquam
consectetur hendrerit dolor, et mollis nisl auctor ut.
Ut sagittis risus at felis fringilla ultricies. Vestibulum non urna nibh,
nec pretium dolor. Nulla imperdiet lobortis eros at pharetra. Vivamus
cursus pellentesque ornare. Lorem ipsum dolor sit amet, consectetur
adipiscing elit. Fusce arcu quam, pulvinar at rutrum vitae, ornare vitae
leo. Maecenas vehicula magna sit amet nulla bibendum condimentum. Curabitur
ultrices tempor fringilla. Vivamus pretium suscipit molestie. Donec arcu
diam, ultricies ac pellentesque eu, venenatis et sapien.
Nam dictum orci augue, vel eleifend leo. Nam at lacus sapien, nec pretium
eros. In egestas, enim sed sagittis feugiat, purus odio tristique lectus,
vel condimentum leo turpis ac odio. Nam iaculis mi quis odio posuere et
venenatis velit ultricies. Nulla facilisi. Proin nec dolor ac quam euismod
gravida quis et eros. Nam interdum condimentum mattis. Cum sociis natoque
penatibus et magnis dis parturient montes, nascetur ridiculus mus. Praesent
a nisi eu massa mollis posuere sed a nunc. Aenean tempus enim a justo
rhoncus quis ultrices nisl commodo.
Aenean imperdiet mauris a ipsum venenatis vel scelerisque lorem rutrum.
Donec ut nunc eros, eget accumsan felis. Nullam ullamcorper porta dictum.
Donec accumsan cursus vestibulum. Aenean in sapien velit. Vivamus nec massa
mi. Fusce felis tortor, bibendum non volutpat a, fringilla quis nisi. Duis
varius bibendum erat, quis fermentum sem accumsan eget. Maecenas massa
felis, porta sed laoreet eu, luctus eu lectus. Cras id nibh vitae erat
fringilla rutrum. Maecenas eget consequat est. Vivamus viverra, felis vel
faucibus rhoncus, quam ipsum elementum libero, quis convallis urna purus ut
mauris. Nam quis urna vitae enim consequat placerat. Vivamus congue augue
sit amet lectus luctus tempor. Cras ut justo convallis est egestas
pellentesque ac nec orci.
Vivamus rutrum bibendum ante, at cursus erat pulvinar ornare. Proin
imperdiet scelerisque ante eu vestibulum. Nullam ullamcorper metus nec
purus auctor lobortis. Proin sed lacus et ipsum tempor tempus. Vivamus odio
dolor, vulputate vitae semper sit amet, aliquet egestas orci. Nullam non
quam eu quam sagittis porta. Nunc in velit id erat commodo viverra.
Praesent nec est augue, nec sagittis erat. Cras sed turpis quis enim tempor
sagittis. Donec in justo ac nisl porta condimentum id vestibulum nulla. Nam
elementum ultricies nunc a bibendum.
Aenean tincidunt nisl non augue pellentesque sit amet convallis neque
semper. Cras placerat suscipit massa sed volutpat. Integer vulputate
imperdiet enim, vitae vulputate sapien mattis feugiat. Vivamus pharetra
facilisis mauris a gravida. Nulla non venenatis est. Duis lobortis
consectetur sem ac aliquam. In eget sapien odio. Vivamus pulvinar ultricies
magna, quis laoreet dui porta et. Integer tempus malesuada velit, et
consequat odio ultrices sed. Aliquam malesuada commodo diam vel posuere.
Morbi porttitor, elit vitae auctor gravida, lorem massa bibendum arcu, vel
placerat nulla justo at augue.
Aliquam libero quam, mattis blandit congue sit amet, fermentum ac augue.
Aliquam malesuada molestie vulputate. Duis id porta augue. Vestibulum diam
dolor, ultrices sit amet porttitor id, convallis id lectus. Etiam ac augue
tincidunt nisi tempor molestie euismod id nisl. Nam et tortor ac arcu
viverra pulvinar. Fusce pulvinar rhoncus leo, a faucibus enim interdum non.
Aliquam vulputate mattis consectetur. Pellentesque sit amet quam sem. Cras
eget arcu eu elit volutpat volutpat. Integer sed varius enim. Integer sit
amet felis orci, id dignissim sapien. Sed vitae lorem sed libero facilisis
fringilla. Pellentesque congue tristique purus, eleifend semper risus
suscipit quis. Phasellus rutrum quam vitae arcu vulputate porta. Sed
tristique arcu nec mi porttitor lacinia.
Donec congue feugiat diam quis pretium. Vivamus at luctus nunc. Integer
vulputate laoreet mauris quis auctor. Nunc at ultrices libero. Maecenas
porta faucibus purus non vehicula. Sed sit amet metus vitae mi ultrices
scelerisque nec quis risus. Phasellus pellentesque tincidunt massa id
ultricies. Aliquam dictum arcu ac dolor interdum rutrum. Nulla facilisi.
Duis nisi est, tincidunt a sagittis id, sollicitudin at odio. Curabitur sed
est eu sapien faucibus dignissim in quis tortor.
Nunc ac elit tortor, non lobortis massa. Proin posuere ante ut metus
vehicula suscipit. Proin mattis mauris ac lectus consequat rutrum. Nam arcu
lectus, commodo non pretium a, pharetra semper dolor. Fusce eleifend
hendrerit adipiscing. Nunc et eleifend erat. Suspendisse tempus nisl ut
arcu blandit ut adipiscing nisi tristique. Suspendisse molestie facilisis
risus sed fermentum. Praesent tempor convallis ultricies. Integer et elit
velit, at consectetur risus.
Vestibulum mollis adipiscing sodales. Vestibulum ante ipsum primis in
faucibus orci luctus et ultrices posuere cubilia Curae; Mauris dictum
molestie porta. Nam convallis nisl quis lacus vulputate in convallis risus
sagittis. Vivamus accumsan faucibus cursus. Ut ultricies imperdiet ligula
scelerisque blandit. In ornare egestas purus, at convallis velit egestas
laoreet. Class aptent taciti sociosqu ad litora torquent per conubia
nostra, per inceptos himenaeos. Nulla quis imperdiet est. Nunc tempus magna
quis lacus feugiat et posuere lacus vehicula. Cras lacinia aliquam est at
vehicula. Aenean congue elit in ante dignissim vitae fermentum lectus
aliquam. Mauris at odio magna, at interdum dui. Cras fringilla mi velit,
nec varius neque.
Fusce et volutpat lacus. Suspendisse id turpis et urna varius convallis in
eu purus. Nulla facilisi. Etiam mauris nisl, ultrices ac porttitor sit
amet, facilisis ut neque. Nullam ut velit quis velit tincidunt rhoncus.
Praesent tristique porttitor euismod. Nulla non felis ante, feugiat commodo
turpis. In nec venenatis mi. Duis tempus tempor purus, vitae consectetur mi
ornare eu. Proin sed consequat erat. Quisque nec sem dui. Nam semper,
ligula facilisis pretium interdum, diam lectus sollicitudin lorem, in
elementum nisi lorem scelerisque justo. Nullam ac fringilla nunc. Maecenas
malesuada ligula in massa sollicitudin sit amet auctor ipsum malesuada.
Vestibulum ut augue in magna lobortis varius eget in ipsum. In hac
habitasse platea dictumst.
Cras vel sagittis mi. Aenean urna sapien, ultrices et tristique et, aliquam
vel libero. Nullam in consequat ante. Suspendisse libero augue, pulvinar a
dignissim vitae, fringilla malesuada dui. Phasellus augue ante, pulvinar
eget tincidunt vel, venenatis sed arcu. Pellentesque ac purus orci, vel
molestie turpis. Nulla consectetur sollicitudin dolor, sed ornare arcu
accumsan fermentum. Fusce vestibulum nisi at leo interdum eu sollicitudin
lacus dictum. Fusce malesuada consequat ipsum ut convallis. Maecenas in
eros sit amet elit consectetur fringilla nec a nibh. Ut et velit vel ligula
pharetra elementum. Nullam aliquam, tellus vel cursus lacinia, dui libero
dictum turpis, nec lacinia dolor nunc vel diam. Pellentesque convallis dui
quis lacus ornare at rutrum lorem pellentesque. Suspendisse potenti. Cum
sociis natoque penatibus et magnis dis parturient montes, nascetur
ridiculus mus.
Nunc ac nibh sed mauris ornare cursus. Praesent enim mauris, tincidunt
vitae convallis ac, ultricies imperdiet sapien. Duis sodales ligula eget
lorem suscipit sed consectetur metus pretium. Nam in magna augue, quis
volutpat mauris. Quisque pretium lobortis orci quis laoreet. Nam ut nisi
diam. Sed ultrices ultrices dapibus. Integer feugiat mauris id orci
pulvinar eu tempus nibh viverra. Etiam venenatis bibendum massa a
consequat. Fusce interdum velit ac mauris rhoncus non cursus neque
consectetur. Vestibulum dictum eros ac metus fringilla venenatis. Phasellus
auctor dui non nulla molestie id malesuada mauris euismod. Aenean id tortor
ac justo eleifend mollis non vel arcu. Duis ac lorem tortor. Donec volutpat
purus sed nunc luctus interdum hendrerit nulla ullamcorper. Sed consectetur
interdum aliquet. Proin ullamcorper risus ut ante lacinia sagittis. Nunc
varius eleifend purus, ac pellentesque urna viverra id. Praesent euismod,
sapien accumsan gravida dictum, massa massa euismod sapien, ut auctor
tellus arcu sed diam.
Vivamus tincidunt dolor non lorem pellentesque at tempus elit adipiscing.
Vestibulum tempor aliquam consectetur. Mauris nec dictum nisl. Donec
scelerisque ornare condimentum. Phasellus laoreet justo nec nibh convallis
convallis. Duis id orci sapien, eget pulvinar justo. Aenean id arcu felis,
eu iaculis nibh. Aenean eleifend pretium rutrum. Aliquam molestie sem quis
tellus aliquam eleifend. Mauris et purus orci. Nunc et accumsan tortor.
Phasellus semper eleifend nisi, a faucibus risus vehicula id. Lorem ipsum
dolor sit amet, consectetur adipiscing elit. Maecenas in felis et est
lacinia eleifend vel sed ipsum. Aliquam commodo molestie lorem id
hendrerit. Nam sed tellus urna, sed dignissim eros.
"""
return A_LONG_STRING
...@@ -111,21 +111,84 @@ def slice_charptr_for_loop_c_enumerate(): ...@@ -111,21 +111,84 @@ def slice_charptr_for_loop_c_enumerate():
############################################################ ############################################################
# tests for int* slicing # tests for int* slicing
## cdef int cints[6] cdef int cints[6]
## for i in range(6): for i in range(6):
## cints[i] = i cints[i] = i
## @cython.test_assert_path_exists("//ForFromStatNode", @cython.test_assert_path_exists("//ForFromStatNode",
## "//ForFromStatNode//IndexNode") "//ForFromStatNode//IndexNode")
## @cython.test_fail_if_path_exists("//ForInStatNode") @cython.test_fail_if_path_exists("//ForInStatNode")
## def slice_intptr_for_loop_c(): def slice_intarray_for_loop_c():
## """ """
## >>> slice_intptr_for_loop_c() >>> slice_intarray_for_loop_c()
## [0, 1, 2] [0, 1, 2]
## [1, 2, 3, 4] [1, 2, 3, 4]
## [4, 5] [4, 5]
## """ """
## cdef int i cdef int i
## print [ i for i in cints[:3] ] print [ i for i in cints[:3] ]
## print [ i for i in cints[1:5] ] print [ i for i in cints[1:5] ]
## print [ i for i in cints[4:6] ] print [ i for i in cints[4:6] ]
@cython.test_assert_path_exists("//ForFromStatNode",
"//ForFromStatNode//IndexNode")
@cython.test_fail_if_path_exists("//ForInStatNode")
def iter_intarray_for_loop_c():
"""
>>> iter_intarray_for_loop_c()
[0, 1, 2, 3, 4, 5]
"""
cdef int i
print [ i for i in cints ]
@cython.test_assert_path_exists("//ForFromStatNode",
"//ForFromStatNode//IndexNode")
@cython.test_fail_if_path_exists("//ForInStatNode")
def slice_intptr_for_loop_c():
"""
>>> slice_intptr_for_loop_c()
[0, 1, 2]
[1, 2, 3, 4]
[4, 5]
"""
cdef int* nums = cints
cdef int i
print [ i for i in nums[:3] ]
print [ i for i in nums[1:5] ]
print [ i for i in nums[4:6] ]
############################################################
# tests for slicing other arrays
cdef double cdoubles[6]
for i in range(6):
cdoubles[i] = i + 0.5
cdef double* cdoubles_ptr = cdoubles
@cython.test_assert_path_exists("//ForFromStatNode",
"//ForFromStatNode//IndexNode")
@cython.test_fail_if_path_exists("//ForInStatNode")
def slice_doublptr_for_loop_c():
"""
>>> slice_doublptr_for_loop_c()
[0.5, 1.5, 2.5]
[1.5, 2.5, 3.5, 4.5]
[4.5, 5.5]
"""
cdef double d
print [ d for d in cdoubles_ptr[:3] ]
print [ d for d in cdoubles_ptr[1:5] ]
print [ d for d in cdoubles_ptr[4:6] ]
@cython.test_assert_path_exists("//ForFromStatNode",
"//ForFromStatNode//IndexNode")
@cython.test_fail_if_path_exists("//ForInStatNode")
def iter_doublearray_for_loop_c():
"""
>>> iter_doublearray_for_loop_c()
[0.5, 1.5, 2.5, 3.5, 4.5, 5.5]
"""
cdef double d
print [ d for d in cdoubles ]
...@@ -21,7 +21,7 @@ def test_arithmetic(double complex z, double complex w): ...@@ -21,7 +21,7 @@ def test_arithmetic(double complex z, double complex w):
>>> test_arithmetic(5-10j, 3+4j) >>> test_arithmetic(5-10j, 3+4j)
((5-10j), (-5+10j), (8-6j), (2-14j), (55-10j), (-1-2j)) ((5-10j), (-5+10j), (8-6j), (2-14j), (55-10j), (-1-2j))
""" """
return +z, -z, z+w, z-w, z*w, z/w return +z, -z+0, z+w, z-w, z*w, z/w
@cython.cdivision(False) @cython.cdivision(False)
def test_div_by_zero(double complex z): def test_div_by_zero(double complex z):
......
...@@ -21,11 +21,8 @@ def test_wrap_pair(int i, double x): ...@@ -21,11 +21,8 @@ def test_wrap_pair(int i, double x):
>>> test_wrap_pair(2, 2.25) >>> test_wrap_pair(2, 2.25)
(2, 2.25, True) (2, 2.25, True)
""" """
cdef Pair[int, double] *pair
cdef Wrap[Pair[int, double]] *wrap
try: try:
pair = new Pair[int, double](i, x) wrap = new Wrap[Pair[int, double]](Pair[int, double](i, x))
wrap = new Wrap[Pair[int, double]](deref(pair))
return wrap.get().first(), wrap.get().second(), deref(wrap) == deref(wrap) return wrap.get().first(), wrap.get().second(), deref(wrap) == deref(wrap)
finally: finally:
del pair, wrap del wrap
...@@ -21,7 +21,6 @@ def test_int(int x, int y): ...@@ -21,7 +21,6 @@ def test_int(int x, int y):
>>> test_int(100, 100) >>> test_int(100, 100)
(100, 100, True) (100, 100, True)
""" """
cdef Wrap[int] *a, *b
try: try:
a = new Wrap[int](x) a = new Wrap[int](x)
b = new Wrap[int](0) b = new Wrap[int](0)
...@@ -38,7 +37,6 @@ def test_double(double x, double y): ...@@ -38,7 +37,6 @@ def test_double(double x, double y):
>>> test_double(100, 100) >>> test_double(100, 100)
(100.0, 100.0, True) (100.0, 100.0, True)
""" """
cdef Wrap[double] *a, *b
try: try:
a = new Wrap[double](x) a = new Wrap[double](x)
b = new Wrap[double](-1) b = new Wrap[double](-1)
...@@ -54,7 +52,6 @@ def test_pair(int i, double x): ...@@ -54,7 +52,6 @@ def test_pair(int i, double x):
>>> test_pair(2, 2.25) >>> test_pair(2, 2.25)
(2, 2.25, True, False) (2, 2.25, True, False)
""" """
cdef Pair[int, double] *pair
try: try:
pair = new Pair[int, double](i, x) pair = new Pair[int, double](i, x)
return pair.first(), pair.second(), deref(pair) == deref(pair), deref(pair) != deref(pair) return pair.first(), pair.second(), deref(pair) == deref(pair), deref(pair) != deref(pair)
...@@ -68,7 +65,6 @@ def test_ptr(int i): ...@@ -68,7 +65,6 @@ def test_ptr(int i):
>>> test_ptr(5) >>> test_ptr(5)
5 5
""" """
cdef Wrap[int*] *w
try: try:
w = new Wrap[int*](&i) w = new Wrap[int*](&i)
return deref(w.get()) return deref(w.get())
...@@ -85,7 +81,6 @@ def test_func_ptr(double x): ...@@ -85,7 +81,6 @@ def test_func_ptr(double x):
>>> test_func_ptr(-1.5) >>> test_func_ptr(-1.5)
2.25 2.25
""" """
cdef Wrap[double (*)(double)] *w
try: try:
w = new Wrap[double (*)(double)](&f) w = new Wrap[double (*)(double)](&f)
return w.get()(x) return w.get()(x)
......
cdef extern from "Python.h": cdef extern from "Python.h":
ctypedef class __builtin__.str [object PyStringObject]:
cdef long ob_shash
ctypedef class __builtin__.list [object PyListObject]: ctypedef class __builtin__.list [object PyListObject]:
cdef Py_ssize_t ob_size
cdef Py_ssize_t allocated cdef Py_ssize_t allocated
ctypedef class __builtin__.dict [object PyDictObject]: ctypedef class __builtin__.dict [object PyDictObject]:
pass pass
cdef str s = "abc" cdef Py_ssize_t Py_SIZE(object o)
cdef list L = [1,2,4] cdef list L = [1,2,4]
cdef dict d = {'A': 'a'} cdef dict d = {'A': 'a'}
...@@ -23,18 +20,7 @@ def test_list(list L): ...@@ -23,18 +20,7 @@ def test_list(list L):
>>> test_list(list_subclass([1,2,3])) >>> test_list(list_subclass([1,2,3]))
True True
""" """
return L.ob_size <= L.allocated return Py_SIZE(L) <= L.allocated
def test_str(str s):
"""
>>> test_str("abc")
True
>>> class str_subclass(str): pass
>>> test_str(str_subclass("xyz"))
True
"""
cdef char* ss = s
return hash(s) == s.ob_shash
def test_tuple(tuple t): def test_tuple(tuple t):
""" """
......
...@@ -93,13 +93,49 @@ def arithmetic(): ...@@ -93,13 +93,49 @@ def arithmetic():
>>> arithmetic() >>> arithmetic()
""" """
a = 1 + 2 a = 1 + 2
assert typeof(a) == "long" assert typeof(a) == "long", typeof(a)
b = 1 + 1.5 b = 1 + 1.5
assert typeof(b) == "double" assert typeof(b) == "double", typeof(b)
c = 1 + <object>2 c = 1 + <object>2
assert typeof(c) == "Python object" assert typeof(c) == "Python object", typeof(c)
d = "abc %s" % "x" d = 1 * 1.5 ** 2
assert typeof(d) == "Python object" assert typeof(d) == "double", typeof(d)
def builtin_type_operations():
"""
>>> builtin_type_operations()
"""
b1 = b'a' * 10
b1 = 10 * b'a'
b1 = 10 * b'a' * 10
assert typeof(b1) == "bytes object", typeof(b1)
b2 = b'a' + b'b'
assert typeof(b2) == "bytes object", typeof(b2)
u1 = u'a' * 10
u1 = 10 * u'a'
assert typeof(u1) == "unicode object", typeof(u1)
u2 = u'a' + u'b'
assert typeof(u2) == "unicode object", typeof(u2)
u3 = u'a%s' % u'b'
u3 = u'a%s' % 10
assert typeof(u3) == "unicode object", typeof(u3)
s1 = "abc %s" % "x"
s1 = "abc %s" % 10
assert typeof(s1) == "str object", typeof(s1)
s2 = "abc %s" + "x"
assert typeof(s2) == "str object", typeof(s2)
s3 = "abc %s" * 10
s3 = "abc %s" * 10 * 10
s3 = 10 * "abc %s" * 10
assert typeof(s3) == "str object", typeof(s3)
L1 = [] + []
assert typeof(L1) == "list object", typeof(L1)
L2 = [] * 2
assert typeof(L2) == "list object", typeof(L2)
T1 = () + ()
assert typeof(T1) == "tuple object", typeof(T1)
T2 = () * 2
assert typeof(T2) == "tuple object", typeof(T2)
def cascade(): def cascade():
""" """
...@@ -215,10 +251,29 @@ def safe_only(): ...@@ -215,10 +251,29 @@ def safe_only():
""" """
a = 1.0 a = 1.0
assert typeof(a) == "double", typeof(c) assert typeof(a) == "double", typeof(c)
b = 1 b = 1;
assert typeof(b) == "Python object", typeof(b) assert typeof(b) == "long", typeof(b)
c = MyType() c = MyType()
assert typeof(c) == "MyType", typeof(c) assert typeof(c) == "MyType", typeof(c)
for i in range(10): pass
assert typeof(i) == "long", typeof(i)
d = 1
res = ~d
assert typeof(d) == "long", typeof(d)
# potentially overflowing arithmatic
e = 1
e += 1
assert typeof(e) == "Python object", typeof(e)
f = 1
res = f * 10
assert typeof(f) == "Python object", typeof(f)
g = 1
res = 10*(~g)
assert typeof(g) == "Python object", typeof(g)
for j in range(10):
res = -j
assert typeof(j) == "Python object", typeof(j)
@infer_types(None) @infer_types(None)
def args_tuple_keywords(*args, **kwargs): def args_tuple_keywords(*args, **kwargs):
...@@ -249,3 +304,36 @@ def args_tuple_keywords_reassign_pyobjects(*args, **kwargs): ...@@ -249,3 +304,36 @@ def args_tuple_keywords_reassign_pyobjects(*args, **kwargs):
args = [] args = []
kwargs = "test" kwargs = "test"
# / A -> AA -> AAA
# Base0 -> Base -
# \ B -> BB
# C -> CC
cdef class Base0: pass
cdef class Base(Base0): pass
cdef class A(Base): pass
cdef class AA(A): pass
cdef class AAA(AA): pass
cdef class B(Base): pass
cdef class BB(B): pass
cdef class C: pass
cdef class CC(C): pass
@infer_types(None)
def common_extension_type_base():
"""
>>> common_extension_type_base()
"""
x = A()
x = AA()
assert typeof(x) == "A", typeof(x)
y = A()
y = B()
assert typeof(y) == "Base", typeof(y)
z = AAA()
z = BB()
assert typeof(z) == "Base", typeof(z)
w = A()
w = CC()
assert typeof(w) == "Python object", typeof(w)
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