diff --git a/COPYING.txt b/COPYING.txt index 31469485007..898b2b74a7d 100644 --- a/COPYING.txt +++ b/COPYING.txt @@ -5,9 +5,9 @@ redistribute, modify and distribute modified versions." ------------------ Cython, which derives from Pyrex, is licensed under the Python -Software Foundation License. More precisely, all modifications +Software Foundation License. More precisely, all modifications made to go from Pyrex to Cython are so licensed. See LICENSE.txt for more details. - + diff --git a/Cython/Build/Dependencies.py b/Cython/Build/Dependencies.py index e4cd4fa80d8..05c5035ff97 100644 --- a/Cython/Build/Dependencies.py +++ b/Cython/Build/Dependencies.py @@ -36,7 +36,7 @@ def unquote(literal): return literals[literal[1:-1]] else: return literal - + return [unquote(item) for item in s.split(delimiter)] transitive_str = object() @@ -70,7 +70,7 @@ def line_iter(source): start = end+1 class DistutilsInfo(object): - + def __init__(self, source=None, exn=None): self.values = {} if source is not None: @@ -97,7 +97,7 @@ def __init__(self, source=None, exn=None): value = getattr(exn, key, None) if value: self.values[key] = value - + def merge(self, other): if other is None: return self @@ -114,7 +114,7 @@ def merge(self, other): else: self.values[key] = value return self - + def subs(self, aliases): if aliases is None: return self @@ -140,9 +140,9 @@ def subs(self, aliases): def strip_string_literals(code, prefix='__Pyx_L'): """ - Normalizes every string literal to be of the form '__Pyx_Lxxx', + Normalizes every string literal to be of the form '__Pyx_Lxxx', returning the normalized code and a mapping of labels to - string literals. + string literals. """ new_code = [] literals = {} @@ -156,7 +156,7 @@ def strip_string_literals(code, prefix='__Pyx_L'): double_q = code.find('"', q) q = min(single_q, double_q) if q == -1: q = max(single_q, double_q) - + # We're done. if q == -1 and hash_mark == -1: new_code.append(code[start:]) @@ -181,7 +181,7 @@ def strip_string_literals(code, prefix='__Pyx_L'): start = q else: q += 1 - + # Process comment. elif -1 != hash_mark and (hash_mark < q or q == -1): end = code.find('\n', hash_mark) @@ -212,7 +212,7 @@ def strip_string_literals(code, prefix='__Pyx_L'): new_code.append(code[start:end]) start = q q += len(in_quote) - + return "".join(new_code), literals @@ -245,16 +245,16 @@ def parse_dependencies(source_filename): class DependencyTree(object): - + def __init__(self, context): self.context = context self._transitive_cache = {} - + #@cached_method def parse_dependencies(self, source_filename): return parse_dependencies(source_filename) parse_dependencies = cached_method(parse_dependencies) - + #@cached_method def cimports_and_externs(self, filename): cimports, includes, externs = self.parse_dependencies(filename)[:3] @@ -272,10 +272,10 @@ def cimports_and_externs(self, filename): print("Unable to locate '%s' referenced from '%s'" % (filename, include)) return tuple(cimports), tuple(externs) cimports_and_externs = cached_method(cimports_and_externs) - + def cimports(self, filename): return self.cimports_and_externs(filename)[0] - + #@cached_method def package(self, filename): dir = os.path.dirname(filename) @@ -284,13 +284,13 @@ def package(self, filename): else: return () package = cached_method(package) - + #@cached_method def fully_qualifeid_name(self, filename): module = os.path.splitext(os.path.basename(filename))[0] return '.'.join(self.package(filename) + (module,)) fully_qualifeid_name = cached_method(fully_qualifeid_name) - + def find_pxd(self, module, filename=None): if module[0] == '.': raise NotImplementedError("New relative imports.") @@ -301,7 +301,7 @@ def find_pxd(self, module, filename=None): return pxd return self.context.find_pxd_file(module, None) find_pxd = cached_method(find_pxd) - + #@cached_method def cimported_files(self, filename): if filename[-4:] == '.pyx' and os.path.exists(filename[:-4] + '.pxd'): @@ -316,33 +316,33 @@ def cimported_files(self, filename): print("\n\t".join(b)) return tuple(self_pxd + filter(None, [self.find_pxd(m, filename) for m in self.cimports(filename)])) cimported_files = cached_method(cimported_files) - + def immediate_dependencies(self, filename): all = list(self.cimported_files(filename)) for extern in sum(self.cimports_and_externs(filename), ()): all.append(os.path.normpath(os.path.join(os.path.dirname(filename), extern))) return tuple(all) - + #@cached_method def timestamp(self, filename): return os.path.getmtime(filename) timestamp = cached_method(timestamp) - + def extract_timestamp(self, filename): # TODO: .h files from extern blocks return self.timestamp(filename), filename - + def newest_dependency(self, filename): return self.transitive_merge(filename, self.extract_timestamp, max) - + def distutils_info0(self, filename): return self.parse_dependencies(filename)[3] - + def distutils_info(self, filename, aliases=None, base=None): return (self.transitive_merge(filename, self.distutils_info0, DistutilsInfo.merge) .subs(aliases) .merge(base)) - + def transitive_merge(self, node, extract, merge): try: seen = self._transitive_cache[extract, merge] @@ -350,7 +350,7 @@ def transitive_merge(self, node, extract, merge): seen = self._transitive_cache[extract, merge] = {} return self.transitive_merge_helper( node, extract, merge, seen, {}, self.cimported_files)[0] - + def transitive_merge_helper(self, node, extract, merge, seen, stack, outgoing): if node in seen: return seen[node], None diff --git a/Cython/Build/Inline.py b/Cython/Build/Inline.py index e72e50953e5..eec5401eac5 100644 --- a/Cython/Build/Inline.py +++ b/Cython/Build/Inline.py @@ -88,7 +88,7 @@ def safe_type(arg, context=None): return '%s.%s' % (base_type.__module__, base_type.__name__) return 'object' -def cython_inline(code, +def cython_inline(code, get_type=unsafe_type, lib_dir=os.path.expanduser('~/.cython/inline'), cython_include_dirs=['.'], @@ -252,14 +252,14 @@ def get_body(source): else: return source[ix+1:] -# Lots to be done here... It would be especially cool if compiled functions +# Lots to be done here... It would be especially cool if compiled functions # could invoke each other quickly. class RuntimeCompiledFunction(object): def __init__(self, f): self._f = f self._body = get_body(inspect.getsource(f)) - + def __call__(self, *args, **kwds): all = getcallargs(self._f, *args, **kwds) return cython_inline(self._body, locals=self._f.func_globals, globals=self._f.func_globals, **all) diff --git a/Cython/Build/Tests/TestInline.py b/Cython/Build/Tests/TestInline.py index 4a6376934bc..b9ffade83d7 100644 --- a/Cython/Build/Tests/TestInline.py +++ b/Cython/Build/Tests/TestInline.py @@ -32,7 +32,7 @@ def test_globals(self): self.assertEquals(inline("return global_value + 1", **test_kwds), global_value + 1) if has_numpy: - + def test_numpy(self): import numpy a = numpy.ndarray((10, 20)) diff --git a/Cython/CodeWriter.py b/Cython/CodeWriter.py index 0be3881729b..da6a03c7f62 100644 --- a/Cython/CodeWriter.py +++ b/Cython/CodeWriter.py @@ -14,14 +14,14 @@ class LinesResult(object): def __init__(self): self.lines = [] self.s = u"" - + def put(self, s): self.s += s - + def newline(self): self.lines.append(self.s) self.s = u"" - + def putline(self, s): self.put(s) self.newline() @@ -29,7 +29,7 @@ def putline(self, s): class CodeWriter(TreeVisitor): indent_string = u" " - + def __init__(self, result = None): super(CodeWriter, self).__init__() if result is None: @@ -38,22 +38,22 @@ def __init__(self, result = None): self.numindents = 0 self.tempnames = {} self.tempblockindex = 0 - + def write(self, tree): self.visit(tree) - + def indent(self): self.numindents += 1 - + def dedent(self): self.numindents -= 1 - + def startline(self, s = u""): self.result.put(self.indent_string * self.numindents + s) - + def put(self, s): self.result.put(s) - + def endline(self, s = u""): self.result.putline(s) @@ -70,13 +70,13 @@ def comma_separated_list(self, items, output_rhs=False): self.visit(item.default) self.put(u", ") self.visit(items[-1]) - + def visit_Node(self, node): raise AssertionError("Node not handled by serializer: %r" % node) - + def visit_ModuleNode(self, node): self.visitchildren(node) - + def visit_StatListNode(self, node): self.visitchildren(node) @@ -87,7 +87,7 @@ def visit_FuncDefNode(self, node): self.indent() self.visit(node.body) self.dedent() - + def visit_CArgDeclNode(self, node): if node.base_type.name is not None: self.visit(node.base_type) @@ -96,10 +96,10 @@ def visit_CArgDeclNode(self, node): if node.default is not None: self.put(u" = ") self.visit(node.default) - + def visit_CNameDeclaratorNode(self, node): self.put(node.name) - + def visit_CSimpleBaseTypeNode(self, node): # See Parsing.p_sign_and_longness if node.is_basic_c_type: @@ -108,16 +108,16 @@ def visit_CSimpleBaseTypeNode(self, node): self.put("short " * -node.longness) elif node.longness > 0: self.put("long " * node.longness) - + self.put(node.name) - + def visit_SingleAssignmentNode(self, node): self.startline() self.visit(node.lhs) self.put(u" = ") self.visit(node.rhs) self.endline() - + def visit_CascadedAssignmentNode(self, node): self.startline() for lhs in node.lhs_list: @@ -125,10 +125,10 @@ def visit_CascadedAssignmentNode(self, node): self.put(u" = ") self.visit(node.rhs) self.endline() - + def visit_NameNode(self, node): self.put(node.name) - + def visit_IntNode(self, node): self.put(node.value) @@ -164,7 +164,7 @@ def visit_IfStatNode(self, node): def visit_PassStatNode(self, node): self.startline(u"pass") self.endline() - + def visit_PrintStatNode(self, node): self.startline(u"print ") self.comma_separated_list(node.arg_tuple.args) @@ -176,7 +176,7 @@ def visit_BinopNode(self, node): self.visit(node.operand1) self.put(u" %s " % node.operator) self.visit(node.operand2) - + def visit_CVarDefNode(self, node): self.startline(u"cdef ") self.visit(node.base_type) @@ -201,7 +201,7 @@ def visit_ForInStatNode(self, node): def visit_SequenceNode(self, node): self.comma_separated_list(node.args) # Might need to discover whether we need () around tuples...hmm... - + def visit_SimpleCallNode(self, node): self.visit(node.function) self.put(u"(") @@ -224,14 +224,14 @@ def visit_ExprStatNode(self, node): self.startline() self.visit(node.expr) self.endline() - + def visit_InPlaceAssignmentNode(self, node): self.startline() self.visit(node.lhs) self.put(u" %s= " % node.operator) self.visit(node.rhs) self.endline() - + def visit_WithStatNode(self, node): self.startline() self.put(u"with ") @@ -243,7 +243,7 @@ def visit_WithStatNode(self, node): self.indent() self.visit(node.body) self.dedent() - + def visit_AttributeNode(self, node): self.visit(node.obj) self.put(u".%s" % node.attribute) diff --git a/Cython/Compiler/AnalysedTreeTransforms.py b/Cython/Compiler/AnalysedTreeTransforms.py index 79a0485e282..de527e00b5a 100644 --- a/Cython/Compiler/AnalysedTreeTransforms.py +++ b/Cython/Compiler/AnalysedTreeTransforms.py @@ -11,7 +11,7 @@ class AutoTestDictTransform(ScopeTrackingTransform): # Handles autotestdict directive - blacklist = ['__cinit__', '__dealloc__', '__richcmp__', + blacklist = ['__cinit__', '__dealloc__', '__richcmp__', '__nonzero__', '__bool__', '__len__', '__contains__'] diff --git a/Cython/Compiler/Annotate.py b/Cython/Compiler/Annotate.py index 425d956e89e..fe38378b37a 100644 --- a/Cython/Compiler/Annotate.py +++ b/Cython/Compiler/Annotate.py @@ -12,9 +12,9 @@ # need one-characters subsitutions (for now) so offsets aren't off special_chars = [(u'<', u'\xF0', u'<'), - (u'>', u'\xF1', u'>'), + (u'>', u'\xF1', u'>'), (u'&', u'\xF2', u'&')] - + line_pos_comment = re.compile(r'/\*.*?<<<<<<<<<<<<<<.*?\*/\n*', re.DOTALL) class AnnotationCCodeWriter(CCodeWriter): @@ -32,14 +32,14 @@ def __init__(self, create_from=None, buffer=None, copy_formatting=True): self.annotations = create_from.annotations self.code = create_from.code self.last_pos = create_from.last_pos - + def create_new(self, create_from, buffer, copy_formatting): return AnnotationCCodeWriter(create_from, buffer, copy_formatting) def write(self, s): CCodeWriter.write(self, s) self.annotation_buffer.write(s) - + def mark_pos(self, pos): if pos is not None: CCodeWriter.mark_pos(self, pos) @@ -52,7 +52,7 @@ def mark_pos(self, pos): def annotate(self, pos, item): self.annotations.append((pos, item)) - + def save_annotation(self, source_filename, target_filename): self.mark_pos(None) f = Utils.open_source_file(source_filename) @@ -74,7 +74,7 @@ def save_annotation(self, source_filename, target_filename): all.append(((source_filename, pos[1], pos[2]+size), end)) else: all.append((pos, start+end)) - + all.sort() all.reverse() for pos, item in all: @@ -83,7 +83,7 @@ def save_annotation(self, source_filename, target_filename): col += 1 line = lines[line_no] lines[line_no] = line[:col] + item + line[col:] - + html_filename = os.path.splitext(target_filename)[0] + ".html" f = codecs.open(html_filename, "w", encoding="UTF-8") f.write(u'\n') @@ -130,14 +130,14 @@ def save_annotation(self, source_filename, target_filename): c_file = Utils.decode_filename(os.path.basename(target_filename)) f.write(u'
Raw output: %s\n' % (c_file, c_file))
k = 0
-
+
py_c_api = re.compile(u'(Py[A-Z][a-z]+_[A-Z][a-z][A-Za-z_]+)\(')
py_marco_api = re.compile(u'(Py[A-Z][a-z]+_[A-Z][A-Z_]+)\(')
pyx_c_api = re.compile(u'(__Pyx_[A-Z][a-z_][A-Za-z_]+)\(')
pyx_macro_api = re.compile(u'(__Pyx_[A-Z][A-Z_]+)\(')
error_goto = re.compile(ur'((; *if .*)? \{__pyx_filename = .*goto __pyx_L\w+;\})')
refnanny = re.compile(u'(__Pyx_X?(GOT|GIVE)REF|__Pyx_RefNanny[A-Za-z]+)')
-
+
code_source_file = self.code[source_filename]
for line in lines:
@@ -146,18 +146,18 @@ def save_annotation(self, source_filename, target_filename):
code = code_source_file[k]
except KeyError:
code = ''
-
+
code = code.replace('<', '<
')
-
+
code, py_c_api_calls = py_c_api.subn(ur"\1(", code)
code, pyx_c_api_calls = pyx_c_api.subn(ur"\1(", code)
code, py_macro_api_calls = py_marco_api.subn(ur"\1(", code)
code, pyx_macro_api_calls = pyx_macro_api.subn(ur"\1(", code)
code, refnanny_calls = refnanny.subn(ur"\1", code)
code, error_goto_calls = error_goto.subn(ur"\1", code)
-
+
code = code.replace(u";", u";")
-
+
score = 5*py_c_api_calls + 2*pyx_c_api_calls + py_macro_api_calls + pyx_macro_api_calls - refnanny_calls
color = u"FFFF%02x" % int(255/(1+score/10.0))
f.write(u"" % (color, k))
@@ -166,13 +166,13 @@ def save_annotation(self, source_filename, target_filename):
for c, cc, html in special_chars:
line = line.replace(cc, html)
f.write(line.rstrip())
-
+
f.write(u'
\n')
code = re.sub(line_pos_comment, '', code) # inline annotations are redundant
f.write(u"%s
" % (k, color, code))
f.write(u'