Cython has moved to github.

cython-devel

view Cython/Utils.py @ 3484:b254c4dbc089

support for some Python 3 (or 2.6+) syntax features (found by test_grammar.py in Py3.1.1):
- oct/bin notation: 0o12345, 0b10101
- function annotations (only pure syntax support, not currently used)
also: allow decorators on inner functions
author Stefan Behnel <scoder@users.berlios.de>
date Thu Jan 28 23:05:39 2010 +0100 (2 years ago)
parents cd96cef90d47
children 22234d577112
line source
1 #
2 # Cython -- Things that don't belong
3 # anywhere else in particular
4 #
6 import os, sys, re, codecs
8 def replace_suffix(path, newsuf):
9 base, _ = os.path.splitext(path)
10 return base + newsuf
12 def open_new_file(path):
13 if os.path.exists(path):
14 # Make sure to create a new file here so we can
15 # safely hard link the output files.
16 os.unlink(path)
18 # we use the ISO-8859-1 encoding here because we only write pure
19 # ASCII strings or (e.g. for file names) byte encoded strings as
20 # Unicode, so we need a direct mapping from the first 256 Unicode
21 # characters to a byte sequence, which ISO-8859-1 provides
22 return codecs.open(path, "w", encoding="ISO-8859-1")
24 def castrate_file(path, st):
25 # Remove junk contents from an output file after a
26 # failed compilation.
27 # Also sets access and modification times back to
28 # those specified by st (a stat struct).
29 try:
30 f = open_new_file(path)
31 except EnvironmentError:
32 pass
33 else:
34 f.write(
35 "#error Do not use this file, it is the result of a failed Cython compilation.\n")
36 f.close()
37 if st:
38 os.utime(path, (st.st_atime, st.st_mtime-1))
40 def modification_time(path):
41 st = os.stat(path)
42 return st.st_mtime
44 def file_newer_than(path, time):
45 ftime = modification_time(path)
46 return ftime > time
48 # support for source file encoding detection
50 def encode_filename(filename):
51 if isinstance(filename, unicode):
52 return filename
53 try:
54 filename_encoding = sys.getfilesystemencoding()
55 if filename_encoding is None:
56 filename_encoding = sys.getdefaultencoding()
57 filename = filename.decode(filename_encoding)
58 except UnicodeDecodeError:
59 pass
60 return filename
62 _match_file_encoding = re.compile(u"coding[:=]\s*([-\w.]+)").search
64 def detect_file_encoding(source_filename):
65 # PEPs 263 and 3120
66 f = codecs.open(source_filename, "rU", encoding="UTF-8")
67 try:
68 chars = []
69 for i in range(2):
70 c = f.read(1)
71 while c and c != u'\n':
72 chars.append(c)
73 c = f.read(1)
74 encoding = _match_file_encoding(u''.join(chars))
75 if encoding:
76 return encoding.group(1)
77 finally:
78 f.close()
79 return "UTF-8"
81 def open_source_file(source_filename, mode="rU"):
82 encoding = detect_file_encoding(source_filename)
83 return codecs.open(source_filename, mode=mode, encoding=encoding)
85 def str_to_number(value):
86 # note: this expects a string as input that was accepted by the
87 # parser already
88 if len(value) < 2:
89 value = int(value, 0)
90 elif value[0] == '0':
91 if value[1] in 'xX':
92 # hex notation ('0x1AF')
93 value = int(value[2:], 16)
94 elif value[1] in 'oO':
95 # Py3 octal notation ('0o136')
96 value = int(value[2:], 8)
97 elif value[1] in 'bB':
98 # Py3 binary notation ('0b101')
99 value = int(value[2:], 2)
100 else:
101 # Py2 octal notation ('0136')
102 value = int(value, 8)
103 else:
104 value = int(value, 0)
105 return value
107 def long_literal(value):
108 if isinstance(value, basestring):
109 value = str_to_number(value)
110 return not -2**31 <= value < 2**31
112 def none_or_sub(s, data):
113 if s is None:
114 return s
115 else:
116 return s % data