Commit c37a4543 authored by Robert Bradshaw's avatar Robert Bradshaw

More merging

parents d0f03098 fb25e014
...@@ -50,7 +50,7 @@ Options: ...@@ -50,7 +50,7 @@ Options:
# transforms for the same phase will be used in the order they are given. # transforms for the same phase will be used in the order they are given.
def bad_usage(): def bad_usage():
print >>sys.stderr, usage sys.stderr.write(usage)
sys.exit(1) sys.exit(1)
def parse_command_line(args): def parse_command_line(args):
...@@ -140,14 +140,14 @@ def parse_command_line(args): ...@@ -140,14 +140,14 @@ def parse_command_line(args):
elif arg.endswith(".o"): elif arg.endswith(".o"):
options.objects.append(arg) options.objects.append(arg)
else: else:
print >>sys.stderr, \ sys.stderr.write(
"cython: %s: Unknown filename suffix" % arg "cython: %s: Unknown filename suffix\n" % arg)
if options.objects and len(sources) > 1: if options.objects and len(sources) > 1:
print >>sys.stderr, \ sys.stderr.write(
"cython: Only one source file allowed together with .o files" "cython: Only one source file allowed together with .o files\n")
if options.use_listing_file and len(sources) > 1: if options.use_listing_file and len(sources) > 1:
print >>sys.stderr, \ sys.stderr.write(
"cython: Only one source file allowed when using -o" "cython: Only one source file allowed when using -o\n")
sys.exit(1) sys.exit(1)
if len(sources) == 0 and not options.show_version: if len(sources) == 0 and not options.show_version:
bad_usage() bad_usage()
......
...@@ -18,28 +18,6 @@ from Cython.Debugging import print_call_chain ...@@ -18,28 +18,6 @@ from Cython.Debugging import print_call_chain
from DebugFlags import debug_disposal_code, debug_temp_alloc, \ from DebugFlags import debug_disposal_code, debug_temp_alloc, \
debug_coercion debug_coercion
class EncodedString(unicode):
# unicode string subclass to keep track of the original encoding.
# 'encoding' is None for unicode strings and the source encoding
# otherwise
encoding = None
def byteencode(self):
assert self.encoding is not None
return self.encode(self.encoding)
def utf8encode(self):
assert self.encoding is None
return self.encode("UTF-8")
def is_unicode(self):
return self.encoding is None
is_unicode = property(is_unicode)
# def __eq__(self, other):
# return unicode.__eq__(self, other) and \
# getattr(other, 'encoding', '') == self.encoding
class ExprNode(Node): class ExprNode(Node):
# subexprs [string] Class var holding names of subexpr node attrs # subexprs [string] Class var holding names of subexpr node attrs
...@@ -2251,7 +2229,7 @@ class SequenceNode(ExprNode): ...@@ -2251,7 +2229,7 @@ class SequenceNode(ExprNode):
self.iterator.py_result())) self.iterator.py_result()))
if debug_disposal_code: if debug_disposal_code:
print("UnpackNode.generate_assignment_code:") print("UnpackNode.generate_assignment_code:")
print("...generating disposal code for %s" % iterator) print("...generating disposal code for %s" % self.iterator)
self.iterator.generate_disposal_code(code) self.iterator.generate_disposal_code(code)
code.putln("}") code.putln("}")
...@@ -2279,7 +2257,7 @@ class TupleNode(SequenceNode): ...@@ -2279,7 +2257,7 @@ class TupleNode(SequenceNode):
def calculate_result_code(self): def calculate_result_code(self):
if len(self.args) > 0: if len(self.args) > 0:
error(pos, "Positive length tuples must be constructed.") error(self.pos, "Positive length tuples must be constructed.")
else: else:
return Naming.empty_tuple return Naming.empty_tuple
...@@ -2875,6 +2853,9 @@ class SizeofVarNode(SizeofNode): ...@@ -2875,6 +2853,9 @@ class SizeofVarNode(SizeofNode):
# #
#------------------------------------------------------------------- #-------------------------------------------------------------------
def _not_in(x, seq):
return x not in seq
compile_time_binary_operators = { compile_time_binary_operators = {
'<': operator.lt, '<': operator.lt,
'<=': operator.le, '<=': operator.le,
...@@ -2897,8 +2878,8 @@ compile_time_binary_operators = { ...@@ -2897,8 +2878,8 @@ compile_time_binary_operators = {
'-': operator.sub, '-': operator.sub,
#'/': operator.truediv, #'/': operator.truediv,
'^': operator.xor, '^': operator.xor,
'in': lambda x, y: x in y, 'in': operator.contains,
'not_in': lambda x, y: x not in y, 'not_in': _not_in,
} }
def get_compile_time_binop(node): def get_compile_time_binop(node):
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
import os, sys, re, codecs import os, sys, re, codecs
if sys.version_info[:2] < (2, 2): if sys.version_info[:2] < (2, 2):
print >>sys.stderr, "Sorry, Cython requires Python 2.2 or later" sys.stderr.write("Sorry, Cython requires Python 2.2 or later\n")
sys.exit(1) sys.exit(1)
from time import time from time import time
...@@ -146,7 +146,7 @@ class Context: ...@@ -146,7 +146,7 @@ class Context:
else: else:
filename_encoding = sys.getfilesystemencoding() filename_encoding = sys.getfilesystemencoding()
if filename_encoding is None: if filename_encoding is None:
filename_encoding = getdefaultencoding() filename_encoding = sys.getdefaultencoding()
name = source_filename.decode(filename_encoding) name = source_filename.decode(filename_encoding)
s = PyrexScanner(f, name, source_encoding = f.encoding, s = PyrexScanner(f, name, source_encoding = f.encoding,
...@@ -327,7 +327,7 @@ def main(command_line = 0): ...@@ -327,7 +327,7 @@ def main(command_line = 0):
options = default_options options = default_options
sources = args sources = args
if options.show_version: if options.show_version:
print >>sys.stderr, "Cython version %s" % Version.version sys.stderr.write("Cython version %s\n" % Version.version)
if options.working_path!="": if options.working_path!="":
os.chdir(options.working_path) os.chdir(options.working_path)
context = Context(options.include_path) context = Context(options.include_path)
...@@ -337,7 +337,7 @@ def main(command_line = 0): ...@@ -337,7 +337,7 @@ def main(command_line = 0):
if result.num_errors > 0: if result.num_errors > 0:
any_failures = 1 any_failures = 1
except PyrexError, e: except PyrexError, e:
print >>sys.stderr, e sys.stderr.write(str(e) + '\n')
any_failures = 1 any_failures = 1
if any_failures: if any_failures:
sys.exit(1) sys.exit(1)
......
...@@ -12,7 +12,7 @@ import TypeSlots ...@@ -12,7 +12,7 @@ import TypeSlots
from PyrexTypes import py_object_type, error_type, CTypedefType, CFuncType from PyrexTypes import py_object_type, error_type, CTypedefType, CFuncType
from Symtab import ModuleScope, LocalScope, \ from Symtab import ModuleScope, LocalScope, \
StructOrUnionScope, PyClassScope, CClassScope StructOrUnionScope, PyClassScope, CClassScope
from Cython.Utils import open_new_file, replace_suffix from Cython.Utils import open_new_file, replace_suffix, EncodedString
import Options import Options
import ControlFlow import ControlFlow
...@@ -41,10 +41,10 @@ def relative_position(pos): ...@@ -41,10 +41,10 @@ def relative_position(pos):
def embed_position(pos, docstring): def embed_position(pos, docstring):
if not Options.embed_pos_in_docstring: if not Options.embed_pos_in_docstring:
return docstring return docstring
pos_line = u'File: %s (starting at line %s)' % relative_position(self.pos) pos_line = u'File: %s (starting at line %s)' % relative_position(pos)
if docstring is None: if docstring is None:
# unicode string # unicode string
return ExprNodes.EncodedString(pos_line) return EncodedString(pos_line)
# make sure we can encode the filename in the docstring encoding # make sure we can encode the filename in the docstring encoding
# otherwise make the docstring a unicode string # otherwise make the docstring a unicode string
...@@ -57,13 +57,13 @@ def embed_position(pos, docstring): ...@@ -57,13 +57,13 @@ def embed_position(pos, docstring):
if not docstring: if not docstring:
# reuse the string encoding of the original docstring # reuse the string encoding of the original docstring
doc = ExprNodes.EncodedString(pos_line) doc = EncodedString(pos_line)
else: else:
doc = ExprNodes.EncodedString(pos_line + u'\\n' + docstring) doc = EncodedString(pos_line + u'\\n' + docstring)
doc.encoding = encoding doc.encoding = encoding
return doc return doc
class AttributeAccessor: class _AttributeAccessor(object):
"""Used as the result of the Node.get_children_accessors() generator""" """Used as the result of the Node.get_children_accessors() generator"""
def __init__(self, obj, attrname): def __init__(self, obj, attrname):
self.obj = obj self.obj = obj
...@@ -78,7 +78,18 @@ class AttributeAccessor: ...@@ -78,7 +78,18 @@ class AttributeAccessor:
def name(self): def name(self):
return self.attrname return self.attrname
class Node: class _AttributeIterator(object):
"""Used as the result of the Node.get_children_accessors() generator"""
def __init__(self, obj, attrnames):
self.obj = obj
self.attrnames = iter(attrnames)
def __iter__(self):
return self
def __next__(self):
return _AttributeAccessor(self.obj, self.attrnames.next())
next = __next__
class Node(object):
# pos (string, int, int) Source file position # pos (string, int, int) Source file position
# is_name boolean Is a NameNode # is_name boolean Is a NameNode
# is_literal boolean Is a ConstNode # is_literal boolean Is a ConstNode
...@@ -129,13 +140,7 @@ class Node: ...@@ -129,13 +140,7 @@ class Node:
if attrnames is None: if attrnames is None:
raise InternalError("Children access not implemented for %s" % \ raise InternalError("Children access not implemented for %s" % \
self.__class__.__name__) self.__class__.__name__)
for name in attrnames: return _AttributeIterator(self, attrnames)
a = AttributeAccessor(self, name)
yield a
# Not really needed, but one wants to enforce clients not to
# hold on to iterated objects, in case more advanced iteration
# is needed later
a.attrname = None
def get_child_attrs(self): def get_child_attrs(self):
"""Utility method for more easily implementing get_child_accessors. """Utility method for more easily implementing get_child_accessors.
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
# Pyrex Parser # Pyrex Parser
# #
import os, re, codecs import os, re
from string import join, replace from string import join, replace
from types import ListType, TupleType from types import ListType, TupleType
from Scanning import PyrexScanner from Scanning import PyrexScanner
...@@ -282,7 +282,7 @@ def p_call(s, function): ...@@ -282,7 +282,7 @@ def p_call(s, function):
if not arg.is_name: if not arg.is_name:
s.error("Expected an identifier before '='", s.error("Expected an identifier before '='",
pos = arg.pos) pos = arg.pos)
encoded_name = ExprNodes.EncodedString(arg.name) encoded_name = Utils.EncodedString(arg.name)
encoded_name.encoding = s.source_encoding encoded_name.encoding = s.source_encoding
keyword = ExprNodes.StringNode(arg.pos, keyword = ExprNodes.StringNode(arg.pos,
value = encoded_name) value = encoded_name)
...@@ -503,11 +503,11 @@ def p_name(s, name): ...@@ -503,11 +503,11 @@ def p_name(s, name):
elif isinstance(value, float): elif isinstance(value, float):
return ExprNodes.FloatNode(pos, value = rep) return ExprNodes.FloatNode(pos, value = rep)
elif isinstance(value, str): elif isinstance(value, str):
sval = ExprNodes.EncodedString(rep[1:-1]) sval = Utils.EncodedString(rep[1:-1])
sval.encoding = value.encoding sval.encoding = value.encoding
return ExprNodes.StringNode(pos, value = sval) return ExprNodes.StringNode(pos, value = sval)
elif isinstance(value, unicode): elif isinstance(value, unicode):
sval = ExprNodes.EncodedString(rep[2:-1]) sval = Utils.EncodedString(rep[2:-1])
return ExprNodes.StringNode(pos, value = sval) return ExprNodes.StringNode(pos, value = sval)
else: else:
error(pos, "Invalid type for compile-time constant: %s" error(pos, "Invalid type for compile-time constant: %s"
...@@ -523,12 +523,12 @@ def p_cat_string_literal(s): ...@@ -523,12 +523,12 @@ def p_cat_string_literal(s):
while s.sy == 'BEGIN_STRING': while s.sy == 'BEGIN_STRING':
next_kind, next_value = p_string_literal(s) next_kind, next_value = p_string_literal(s)
if next_kind == 'c': if next_kind == 'c':
self.error( error(s.position(),
"Cannot concatenate char literal with another string or char literal") "Cannot concatenate char literal with another string or char literal")
elif next_kind == 'u': elif next_kind == 'u':
kind = 'u' kind = 'u'
strings.append(next_value) strings.append(next_value)
value = ExprNodes.EncodedString( u''.join(strings) ) value = Utils.EncodedString( u''.join(strings) )
if kind != 'u': if kind != 'u':
value.encoding = s.source_encoding value.encoding = s.source_encoding
return kind, value return kind, value
...@@ -600,7 +600,7 @@ def p_string_literal(s): ...@@ -600,7 +600,7 @@ def p_string_literal(s):
"Unexpected token %r:%r in string literal" % "Unexpected token %r:%r in string literal" %
(sy, s.systring)) (sy, s.systring))
s.next() s.next()
value = ExprNodes.EncodedString( u''.join(chars) ) value = Utils.EncodedString( u''.join(chars) )
if kind != 'u': if kind != 'u':
value.encoding = s.source_encoding value.encoding = s.source_encoding
#print "p_string_literal: value =", repr(value) ### #print "p_string_literal: value =", repr(value) ###
...@@ -915,7 +915,7 @@ def p_import_statement(s): ...@@ -915,7 +915,7 @@ def p_import_statement(s):
ExprNodes.StringNode(pos, value = "*")]) ExprNodes.StringNode(pos, value = "*")])
else: else:
name_list = None name_list = None
dotted_name = ExprNodes.EncodedString(dotted_name) dotted_name = Utils.EncodedString(dotted_name)
dotted_name.encoding = s.source_encoding dotted_name.encoding = s.source_encoding
stat = Nodes.SingleAssignmentNode(pos, stat = Nodes.SingleAssignmentNode(pos,
lhs = ExprNodes.NameNode(pos, lhs = ExprNodes.NameNode(pos,
...@@ -955,7 +955,7 @@ def p_from_import_statement(s): ...@@ -955,7 +955,7 @@ def p_from_import_statement(s):
imported_name_strings = [] imported_name_strings = []
items = [] items = []
for (name_pos, name, as_name) in imported_names: for (name_pos, name, as_name) in imported_names:
encoded_name = ExprNodes.EncodedString(name) encoded_name = Utils.EncodedString(name)
encoded_name.encoding = s.source_encoding encoded_name.encoding = s.source_encoding
imported_name_strings.append( imported_name_strings.append(
ExprNodes.StringNode(name_pos, value = encoded_name)) ExprNodes.StringNode(name_pos, value = encoded_name))
...@@ -965,7 +965,7 @@ def p_from_import_statement(s): ...@@ -965,7 +965,7 @@ def p_from_import_statement(s):
name = as_name or name))) name = as_name or name)))
import_list = ExprNodes.ListNode( import_list = ExprNodes.ListNode(
imported_names[0][0], args = imported_name_strings) imported_names[0][0], args = imported_name_strings)
dotted_name = ExprNodes.EncodedString(dotted_name) dotted_name = Utils.EncodedString(dotted_name)
dotted_name.encoding = s.source_encoding dotted_name.encoding = s.source_encoding
return Nodes.FromImportStatNode(pos, return Nodes.FromImportStatNode(pos,
module = ExprNodes.ImportNode(dotted_name_pos, module = ExprNodes.ImportNode(dotted_name_pos,
...@@ -1971,7 +1971,7 @@ def p_class_statement(s): ...@@ -1971,7 +1971,7 @@ def p_class_statement(s):
# s.sy == 'class' # s.sy == 'class'
pos = s.position() pos = s.position()
s.next() s.next()
class_name = ExprNodes.EncodedString( p_ident(s) ) class_name = Utils.EncodedString( p_ident(s) )
class_name.encoding = s.source_encoding class_name.encoding = s.source_encoding
if s.sy == '(': if s.sy == '(':
s.next() s.next()
......
...@@ -59,6 +59,7 @@ def open_pickled_lexicon(expected_hash): ...@@ -59,6 +59,7 @@ def open_pickled_lexicon(expected_hash):
# Try to open pickled lexicon file and verify that # Try to open pickled lexicon file and verify that
# it matches the source file. Returns the opened # it matches the source file. Returns the opened
# file if successful, otherwise None. ??? # file if successful, otherwise None. ???
global lexicon_pickle
f = None f = None
result = None result = None
if os.path.exists(lexicon_pickle): if os.path.exists(lexicon_pickle):
......
...@@ -7,7 +7,7 @@ from Errors import warning, error, InternalError ...@@ -7,7 +7,7 @@ from Errors import warning, error, InternalError
import Options import Options
import Naming import Naming
import PyrexTypes import PyrexTypes
from PyrexTypes import * from PyrexTypes import py_object_type
import TypeSlots import TypeSlots
from TypeSlots import \ from TypeSlots import \
pyfunction_signature, pymethod_signature, \ pyfunction_signature, pymethod_signature, \
...@@ -299,7 +299,8 @@ class Scope: ...@@ -299,7 +299,8 @@ class Scope:
cname = self.mangle(Naming.type_prefix, name) cname = self.mangle(Naming.type_prefix, name)
entry = self.lookup_here(name) entry = self.lookup_here(name)
if not entry: if not entry:
type = CStructOrUnionType(name, kind, scope, typedef_flag, cname) type = PyrexTypes.CStructOrUnionType(
name, kind, scope, typedef_flag, cname)
entry = self.declare_type(name, type, pos, cname, entry = self.declare_type(name, type, pos, cname,
visibility = visibility, defining = scope is not None) visibility = visibility, defining = scope is not None)
self.sue_entries.append(entry) self.sue_entries.append(entry)
...@@ -336,7 +337,7 @@ class Scope: ...@@ -336,7 +337,7 @@ class Scope:
cname = name cname = name
else: else:
cname = self.mangle(Naming.type_prefix, name) cname = self.mangle(Naming.type_prefix, name)
type = CEnumType(name, cname, typedef_flag) type = PyrexTypes.CEnumType(name, cname, typedef_flag)
else: else:
type = PyrexTypes.c_anon_enum_type type = PyrexTypes.c_anon_enum_type
entry = self.declare_type(name, type, pos, cname = cname, entry = self.declare_type(name, type, pos, cname = cname,
...@@ -437,10 +438,10 @@ class Scope: ...@@ -437,10 +438,10 @@ class Scope:
# Add an entry for a string constant. # Add an entry for a string constant.
cname = self.new_const_cname() cname = self.new_const_cname()
if value.is_unicode: if value.is_unicode:
c_type = c_utf8_char_array_type c_type = PyrexTypes.c_utf8_char_array_type
value = value.utf8encode() value = value.utf8encode()
else: else:
c_type = c_char_array_type c_type = PyrexTypes.c_char_array_type
value = value.byteencode() value = value.byteencode()
entry = Entry("", cname, c_type, init = value) entry = Entry("", cname, c_type, init = value)
entry.used = 1 entry.used = 1
...@@ -494,16 +495,6 @@ class Scope: ...@@ -494,16 +495,6 @@ class Scope:
genv.pynum_entries.append(entry) genv.pynum_entries.append(entry)
return entry return entry
def add_py_obj(self, obj, c_prefix=''):
obj.check_const()
cname = self.new_const_cname(c_prefix)
entry = Entry("", cname, py_object_type, init = value)
entry.used = 1
entry.is_interned = 1
self.const_entries.append(entry)
self.interned_objs.append(entry)
return entry
def get_py_obj(self, obj, c_prefix=''): def get_py_obj(self, obj, c_prefix=''):
# Get entry for a generic constant. Returns an existing # Get entry for a generic constant. Returns an existing
# one if possible, otherwise creates a new one. # one if possible, otherwise creates a new one.
...@@ -513,7 +504,6 @@ class Scope: ...@@ -513,7 +504,6 @@ class Scope:
entry = genv.add_py_num(obj, c_prefix) entry = genv.add_py_num(obj, c_prefix)
genv.obj_to_entry[obj] = entry genv.obj_to_entry[obj] = entry
return entry return entry
def new_const_cname(self): def new_const_cname(self):
# Create a new globally-unique name for a constant. # Create a new globally-unique name for a constant.
...@@ -532,7 +522,7 @@ class Scope: ...@@ -532,7 +522,7 @@ class Scope:
cname = "%s%d" % (Naming.pyrex_prefix, n) cname = "%s%d" % (Naming.pyrex_prefix, n)
entry = Entry("", cname, type) entry = Entry("", cname, type)
entry.used = 1 entry.used = 1
if type.is_pyobject or type == c_py_ssize_t_type: if type.is_pyobject or type == PyrexTypes.c_py_ssize_t_type:
entry.init = "0" entry.init = "0"
self.cname_to_entry[entry.cname] = entry self.cname_to_entry[entry.cname] = entry
self.temp_entries.append(entry) self.temp_entries.append(entry)
...@@ -844,8 +834,9 @@ class ModuleScope(Scope): ...@@ -844,8 +834,9 @@ class ModuleScope(Scope):
self.default_entries.append(entry) self.default_entries.append(entry)
return entry return entry
def new_const_cname(self, prefix=''): def new_const_cname(self):
# Create a new globally-unique name for a constant. # Create a new globally-unique name for a constant.
prefix=''
n = self.const_counter n = self.const_counter
self.const_counter = n + 1 self.const_counter = n + 1
return "%s%s_%d" % (Naming.const_prefix, prefix, n) return "%s%s_%d" % (Naming.const_prefix, prefix, n)
...@@ -877,7 +868,7 @@ class ModuleScope(Scope): ...@@ -877,7 +868,7 @@ class ModuleScope(Scope):
# Make a new entry if needed # Make a new entry if needed
# #
if not entry: if not entry:
type = PyExtensionType(name, typedef_flag, base_type) type = PyrexTypes.PyExtensionType(name, typedef_flag, base_type)
type.pos = pos type.pos = pos
if visibility == 'extern': if visibility == 'extern':
type.module_name = module_name type.module_name = module_name
...@@ -1075,7 +1066,7 @@ class StructOrUnionScope(Scope): ...@@ -1075,7 +1066,7 @@ class StructOrUnionScope(Scope):
if not cname: if not cname:
cname = name cname = name
if type.is_cfunction: if type.is_cfunction:
type = CPtrType(type) type = PyrexTypes.CPtrType(type)
entry = self.declare(name, cname, type, pos) entry = self.declare(name, cname, type, pos)
entry.is_variable = 1 entry.is_variable = 1
self.var_entries.append(entry) self.var_entries.append(entry)
...@@ -1115,9 +1106,12 @@ class ClassScope(Scope): ...@@ -1115,9 +1106,12 @@ class ClassScope(Scope):
# Don't want to add a cfunction to this scope 'cause that would mess with # Don't want to add a cfunction to this scope 'cause that would mess with
# the type definition, so we just return the right entry. # the type definition, so we just return the right entry.
self.use_utility_code(classmethod_utility_code) self.use_utility_code(classmethod_utility_code)
entry = Entry("classmethod", entry = Entry(
"__Pyx_Method_ClassMethod", "classmethod",
CFuncType(py_object_type, [CFuncTypeArg("", py_object_type, None)], 0, 0)) "__Pyx_Method_ClassMethod",
PyrexTypes.CFuncType(
py_object_type,
[PyrexTypes.CFuncTypeArg("", py_object_type, None)], 0, 0))
entry.is_cfunction = 1 entry.is_cfunction = 1
return entry return entry
else: else:
......
...@@ -57,7 +57,7 @@ class Transform(object): ...@@ -57,7 +57,7 @@ class Transform(object):
parent has with child. This method should always return the node which the parent parent has with child. This method should always return the node which the parent
should use for this relation, which can either be the same node, None to remove should use for this relation, which can either be the same node, None to remove
the node, or a different node.""" the node, or a different node."""
raise InternalError("Not implemented") raise NotImplementedError("Not implemented")
class PrintTree(Transform): class PrintTree(Transform):
"""Prints a representation of the tree to standard output. """Prints a representation of the tree to standard output.
......
...@@ -85,9 +85,9 @@ class build_ext(_build_ext.build_ext): ...@@ -85,9 +85,9 @@ class build_ext(_build_ext.build_ext):
""" """
Walk the list of source files in 'sources', looking for Cython Walk the list of source files in 'sources', looking for Cython
source (.pyx) files. Run Cython on all that are found, and return source files (.pyx and .py). Run Cython on all that are
a modified 'sources' list with Cython source files replaced by the found, and return a modified 'sources' list with Cython source
generated C (or C++) files. files replaced by the generated C (or C++) files.
""" """
if PyrexError == None: if PyrexError == None:
...@@ -158,6 +158,9 @@ class build_ext(_build_ext.build_ext): ...@@ -158,6 +158,9 @@ class build_ext(_build_ext.build_ext):
newest_dependency = None newest_dependency = None
for source in sources: for source in sources:
(base, ext) = os.path.splitext(os.path.basename(source)) (base, ext) = os.path.splitext(os.path.basename(source))
if ext == ".py":
# FIXME: we might want to special case this some more
ext = '.pyx'
if ext == ".pyx": # Cython source file if ext == ".pyx": # Cython source file
output_dir = target_dir or os.path.dirname(source) output_dir = target_dir or os.path.dirname(source)
new_sources.append(os.path.join(output_dir, base + target_ext)) new_sources.append(os.path.join(output_dir, base + target_ext))
......
...@@ -258,7 +258,8 @@ class FastMachine: ...@@ -258,7 +258,8 @@ class FastMachine:
def ranges_to_string(self, range_list): def ranges_to_string(self, range_list):
return string.join(map(self.range_to_string, range_list), ",") return string.join(map(self.range_to_string, range_list), ",")
def range_to_string(self, (c1, c2)): def range_to_string(self, range_tuple):
(c1, c2) = range_tuple
if c1 == c2: if c1 == c2:
return repr(c1) return repr(c1)
else: else:
......
...@@ -122,7 +122,7 @@ class RE: ...@@ -122,7 +122,7 @@ class RE:
beginning of a line. If nocase is true, upper and lower case beginning of a line. If nocase is true, upper and lower case
letters should be treated as equivalent. letters should be treated as equivalent.
""" """
raise exceptions.UnimplementedMethod("%s.build_machine not implemented" % raise NotImplementedError("%s.build_machine not implemented" %
self.__class__.__name__) self.__class__.__name__)
def build_opt(self, m, initial_state, c): def build_opt(self, m, initial_state, c):
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
# #
#======================================================================= #=======================================================================
from Regexps import * from Regexps import Alt, Seq, Rep, Rep1, Opt, Any, AnyBut, Bol, Eol, Char
from Errors import PlexError from Errors import PlexError
class RegexpSyntaxError(PlexError): class RegexpSyntaxError(PlexError):
...@@ -104,7 +104,7 @@ class REParser: ...@@ -104,7 +104,7 @@ class REParser:
char_list.append(chr(a)) char_list.append(chr(a))
else: else:
char_list.append(c1) char_list.append(c1)
chars = string.join(char_list, "") chars = ''.join(char_list)
if invert: if invert:
return AnyBut(chars) return AnyBut(chars)
else: else:
......
...@@ -11,7 +11,7 @@ import os, sys ...@@ -11,7 +11,7 @@ import os, sys
from Cython.Utils import replace_suffix from Cython.Utils import replace_suffix
from Cython.Compiler.Errors import PyrexError from Cython.Compiler.Errors import PyrexError
version = "%s.%s" % sys.version[:2] version = "%s.%s" % sys.version_info[:2]
py_include_dirs = [ py_include_dirs = [
"%s/include/python%s" % (sys.prefix, version) "%s/include/python%s" % (sys.prefix, version)
] ]
......
...@@ -54,3 +54,25 @@ def detect_file_encoding(source_filename): ...@@ -54,3 +54,25 @@ def detect_file_encoding(source_filename):
def open_source_file(source_filename, mode="rU"): def open_source_file(source_filename, mode="rU"):
encoding = detect_file_encoding(source_filename) encoding = detect_file_encoding(source_filename)
return codecs.open(source_filename, mode=mode, encoding=encoding) return codecs.open(source_filename, mode=mode, encoding=encoding)
class EncodedString(unicode):
# unicode string subclass to keep track of the original encoding.
# 'encoding' is None for unicode strings and the source encoding
# otherwise
encoding = None
def byteencode(self):
assert self.encoding is not None
return self.encode(self.encoding)
def utf8encode(self):
assert self.encoding is None
return self.encode("UTF-8")
def is_unicode(self):
return self.encoding is None
is_unicode = property(is_unicode)
# def __eq__(self, other):
# return unicode.__eq__(self, other) and \
# getattr(other, 'encoding', '') == self.encoding
__doc__ = """
>>> l1 = Sub1([1,2,3])
>>> len(l1)
3
>>> l2 = Sub2([1,2,3])
>>> len(l2)
3
>>> isinstance(l1, list)
True
>>> isinstance(l2, list)
True
>>> isinstance(l1, Sub1)
True
>>> isinstance(l1, Sub2)
True
>>> isinstance(l2, Sub1)
False
>>> isinstance(l2, Sub2)
True
"""
cdef extern from *:
ctypedef class __builtin__.list [ object PyListObject ]:
pass
cdef class Sub2(list):
cdef char character
cdef class Sub1(Sub2):
cdef char character
## keep two lines free to make sure PEP 263 does not apply
##
##
# This file is written in UTF-8, but it has no encoding declaration,
# so it just defaults to UTF-8 (PEP 3120).
__doc__ = r"""
>>> sa
'abc'
>>> ua
u'abc'
>>> b
u'123'
>>> c
u'S\xf8k ik'
>>> d
u'\xfc\xd6\xe4'
>>> e
u'\x03g\xf8\uf8d2S\xf8k ik'
>>> f
u'\xf8'
>>> add
u'S\xf8k ik\xfc\xd6\xe4abc'
>>> null
u'\x00'
""" + """
>>> len(sa)
3
>>> len(ua)
3
>>> len(b)
3
>>> len(c)
6
>>> len(d)
3
>>> len(e)
10
>>> len(f)
1
>>> len(add)
12
>>> len(null)
1
""" + u"""
>>> sa == 'abc'
True
>>> ua == u'abc'
True
>>> b == u'123'
True
>>> c == u'Søk ik'
True
>>> d == u'üÖä'
True
>>> e == u'\x03\x67\xf8\uf8d2Søk ik' # unescaped by Cython
True
>>> e == u'\\x03\\x67\\xf8\\uf8d2Søk ik' # unescaped by Python
True
>>> f == u'\xf8' # unescaped by Cython
True
>>> f == u'\\xf8' # unescaped by Python
True
>>> add == u'Søk ik' + u'üÖä' + 'abc'
True
>>> null == u'\\x00' # unescaped by Python (required by doctest)
True
"""
sa = 'abc'
ua = u'abc'
b = u'123'
c = u'Søk ik'
d = u'üÖä'
e = u'\x03\x67\xf8\uf8d2Søk ik'
f = u'\xf8'
add = u'Søk ik' + u'üÖä' + 'abc'
null = u'\x00'
# -*- coding: latin-1 -*-
__doc__ = r"""
>>> sa
'abc'
>>> ua
u'abc'
>>> b
u'123'
>>> c
u'S\xf8k ik'
>>> d
u'\xfc\xd6\xe4'
>>> e
u'\x03g\xf8\uf8d2S\xf8k ik'
>>> f
u'\xf8'
>>> add
u'S\xf8k ik\xfc\xd6\xe4abc'
>>> null
u'\x00'
""" + """
>>> len(sa)
3
>>> len(ua)
3
>>> len(b)
3
>>> len(c)
6
>>> len(d)
3
>>> len(e)
10
>>> len(f)
1
>>> len(add)
12
>>> len(null)
1
""" + u"""
>>> sa == 'abc'
True
>>> ua == u'abc'
True
>>> b == u'123'
True
>>> c == u'Sk ik'
True
>>> d == u''
True
>>> e == u'\x03\x67\xf8\uf8d2Sk ik' # unescaped by Cython
True
>>> e == u'\\x03\\x67\\xf8\\uf8d2Sk ik' # unescaped by Python
True
>>> f == u'\xf8' # unescaped by Cython
True
>>> f == u'\\xf8' # unescaped by Python
True
>>> add == u'Sk ik' + u'' + 'abc'
True
>>> null == u'\\x00' # unescaped by Python (required by doctest)
True
"""
sa = 'abc'
ua = u'abc'
b = u'123'
c = u'Sk ik'
d = u''
e = u'\x03\x67\xf8\uf8d2Sk ik'
f = u'\xf8'
add = u'Sk ik' + u'' + 'abc'
null = u'\x00'
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