Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Gwenaël Samain
cython
Commits
70ea30b6
Commit
70ea30b6
authored
Apr 22, 2008
by
Stefan Behnel
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
source code encoding support (PEP 263) and UTF-8 default source encoding (PEP 3120)
parent
2986d78b
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
162 additions
and
82 deletions
+162
-82
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+27
-3
Cython/Compiler/Main.py
Cython/Compiler/Main.py
+20
-4
Cython/Compiler/ModuleNode.py
Cython/Compiler/ModuleNode.py
+1
-1
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+11
-7
Cython/Compiler/Parsing.py
Cython/Compiler/Parsing.py
+33
-58
Cython/Compiler/PyrexTypes.py
Cython/Compiler/PyrexTypes.py
+57
-3
Cython/Compiler/Scanning.py
Cython/Compiler/Scanning.py
+2
-1
Cython/Compiler/Symtab.py
Cython/Compiler/Symtab.py
+11
-5
No files found.
Cython/Compiler/ExprNodes.py
View file @
70ea30b6
...
@@ -18,6 +18,29 @@ from Cython.Debugging import print_call_chain
...
@@ -18,6 +18,29 @@ 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
# type PyrexType Type of the result
# type PyrexType Type of the result
...
@@ -696,15 +719,16 @@ class StringNode(ConstNode):
...
@@ -696,15 +719,16 @@ class StringNode(ConstNode):
type
=
PyrexTypes
.
c_char_ptr_type
type
=
PyrexTypes
.
c_char_ptr_type
def
compile_time_value
(
self
,
denv
):
def
compile_time_value
(
self
,
denv
):
return
eval
(
'"%s"'
%
self
.
value
)
return
self
.
value
def
analyse_types
(
self
,
env
):
def
analyse_types
(
self
,
env
):
self
.
entry
=
env
.
add_string_const
(
self
.
value
)
self
.
entry
=
env
.
add_string_const
(
self
.
value
)
def
coerce_to
(
self
,
dst_type
,
env
):
def
coerce_to
(
self
,
dst_type
,
env
):
if
dst_type
.
is_int
:
if
dst_type
.
is_int
:
if
not
self
.
type
.
is_pyobject
and
len
(
self
.
value
)
==
1
:
if
not
self
.
type
.
is_pyobject
and
len
(
self
.
entry
.
init
)
==
1
:
return
CharNode
(
self
.
pos
,
value
=
self
.
value
)
# we use the *encoded* value here
return
CharNode
(
self
.
pos
,
value
=
self
.
entry
.
init
)
else
:
else
:
error
(
self
.
pos
,
"Only coerce single-character ascii strings can be used as ints."
)
error
(
self
.
pos
,
"Only coerce single-character ascii strings can be used as ints."
)
return
self
return
self
...
...
Cython/Compiler/Main.py
View file @
70ea30b6
...
@@ -2,12 +2,11 @@
...
@@ -2,12 +2,11 @@
# Cython Top Level
# Cython Top Level
#
#
import
os
,
sys
,
re
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"
print
>>
sys
.
stderr
,
"Sorry, Cython requires Python 2.2 or later"
sys
.
exit
(
1
)
sys
.
exit
(
1
)
import
os
from
time
import
time
from
time
import
time
import
Version
import
Version
from
Scanning
import
PyrexScanner
from
Scanning
import
PyrexScanner
...
@@ -138,10 +137,27 @@ class Context:
...
@@ -138,10 +137,27 @@ class Context:
self
.
modules
[
name
]
=
scope
self
.
modules
[
name
]
=
scope
return
scope
return
scope
match_file_encoding
=
re
.
compile
(
"coding[:=]
\
s*([-
\
w.]+)"
).
search
def
detect_file_encoding
(
self
,
source_filename
):
# PEPs 263 and 3120
f
=
codecs
.
open
(
source_filename
,
"rU"
,
encoding
=
"UTF-8"
)
try
:
for
line_no
,
line
in
enumerate
(
f
):
encoding
=
self
.
match_file_encoding
(
line
)
if
encoding
:
return
encoding
.
group
(
1
)
if
line_no
==
1
:
break
finally
:
f
.
close
()
return
"UTF-8"
def
parse
(
self
,
source_filename
,
type_names
,
pxd
,
full_module_name
):
def
parse
(
self
,
source_filename
,
type_names
,
pxd
,
full_module_name
):
# Parse the given source file and return a parse tree.
# Parse the given source file and return a parse tree.
f
=
open
(
source_filename
,
"rU"
)
encoding
=
self
.
detect_file_encoding
(
source_filename
)
s
=
PyrexScanner
(
f
,
source_filename
,
f
=
codecs
.
open
(
source_filename
,
"rU"
,
encoding
=
encoding
)
s
=
PyrexScanner
(
f
,
source_filename
,
source_encoding
=
encoding
,
type_names
=
type_names
,
context
=
self
)
type_names
=
type_names
,
context
=
self
)
try
:
try
:
tree
=
Parsing
.
p_module
(
s
,
pxd
,
full_module_name
)
tree
=
Parsing
.
p_module
(
s
,
pxd
,
full_module_name
)
...
...
Cython/Compiler/ModuleNode.py
View file @
70ea30b6
...
@@ -1270,7 +1270,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -1270,7 +1270,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
entry
.
pystring_cname
,
entry
.
pystring_cname
,
entry
.
cname
,
entry
.
cname
,
entry
.
cname
,
entry
.
cname
,
isinstance
(
entry
.
init
,
unicode
)
entry
.
type
.
is_unicode
))
))
code
.
putln
(
code
.
putln
(
"{0, 0, 0, 0}"
)
"{0, 0, 0, 0}"
)
...
...
Cython/Compiler/Nodes.py
View file @
70ea30b6
...
@@ -1199,7 +1199,7 @@ class DefNode(FuncDefNode):
...
@@ -1199,7 +1199,7 @@ class DefNode(FuncDefNode):
# args [CArgDeclNode] formal arguments
# args [CArgDeclNode] formal arguments
# star_arg PyArgDeclNode or None * argument
# star_arg PyArgDeclNode or None * argument
# starstar_arg PyArgDeclNode or None ** argument
# starstar_arg PyArgDeclNode or None ** argument
# doc
s
tring or None
# doc
EncodedS
tring or None
# body StatListNode
# body StatListNode
#
#
# The following subnode is constructed internally
# The following subnode is constructed internally
...
@@ -1358,12 +1358,15 @@ class DefNode(FuncDefNode):
...
@@ -1358,12 +1358,15 @@ class DefNode(FuncDefNode):
entry
.
pymethdef_cname
=
\
entry
.
pymethdef_cname
=
\
Naming
.
pymethdef_prefix
+
prefix
+
name
Naming
.
pymethdef_prefix
+
prefix
+
name
if
not
Options
.
docstrings
:
if
not
Options
.
docstrings
:
self
.
entry
.
doc
=
None
entry
.
doc
=
None
else
:
else
:
if
Options
.
embed_pos_in_docstring
:
if
Options
.
embed_pos_in_docstring
:
entry
.
doc
=
'File: %s (starting at line %s)'
%
relative_position
(
self
.
pos
)
doc
=
u
'File: %s (starting at line %s)'
%
relative_position
(
self
.
pos
)
if
not
self
.
doc
is
None
:
if
not
self
.
doc
is
None
:
entry
.
doc
=
entry
.
doc
+
'
\
\
n'
+
self
.
doc
doc
=
doc
+
u'
\
\
n'
+
self
.
doc
doc
=
ExprNodes
.
EncodedString
(
doc
)
doc
.
encoding
=
self
.
doc
.
encoding
entry
.
doc
=
doc
else
:
else
:
entry
.
doc
=
self
.
doc
entry
.
doc
=
self
.
doc
entry
.
doc_cname
=
\
entry
.
doc_cname
=
\
...
@@ -1920,8 +1923,9 @@ class PyClassDefNode(StatNode, BlockNode):
...
@@ -1920,8 +1923,9 @@ class PyClassDefNode(StatNode, BlockNode):
self
.
dict
=
ExprNodes
.
DictNode
(
pos
,
key_value_pairs
=
[])
self
.
dict
=
ExprNodes
.
DictNode
(
pos
,
key_value_pairs
=
[])
if
self
.
doc
and
Options
.
docstrings
:
if
self
.
doc
and
Options
.
docstrings
:
if
Options
.
embed_pos_in_docstring
:
if
Options
.
embed_pos_in_docstring
:
doc
=
'File: %s (starting at line %s)'
%
relative_position
(
self
.
pos
)
doc
=
u'File: %s (starting at line %s)'
%
relative_position
(
self
.
pos
)
doc
=
doc
+
'
\
\
n'
+
self
.
doc
doc
=
ExprNodes
.
EncodedString
(
doc
+
'u
\
\
n'
+
self
.
doc
)
doc
.
encoding
=
self
.
doc
.
encoding
doc_node
=
ExprNodes
.
StringNode
(
pos
,
value
=
doc
)
doc_node
=
ExprNodes
.
StringNode
(
pos
,
value
=
doc
)
else
:
else
:
doc_node
=
None
doc_node
=
None
...
@@ -2073,7 +2077,7 @@ class PropertyNode(StatNode):
...
@@ -2073,7 +2077,7 @@ class PropertyNode(StatNode):
# Definition of a property in an extension type.
# Definition of a property in an extension type.
#
#
# name string
# name string
# doc
s
tring or None Doc string
# doc
EncodedS
tring or None Doc string
# body StatListNode
# body StatListNode
child_attrs
=
[
"body"
]
child_attrs
=
[
"body"
]
...
...
Cython/Compiler/Parsing.py
View file @
70ea30b6
...
@@ -281,8 +281,10 @@ def p_call(s, function):
...
@@ -281,8 +281,10 @@ 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
.
encoding
=
s
.
source_encoding
keyword
=
ExprNodes
.
StringNode
(
arg
.
pos
,
keyword
=
ExprNodes
.
StringNode
(
arg
.
pos
,
value
=
arg
.
name
)
value
=
encoded_
name
)
arg
=
p_simple_expr
(
s
)
arg
=
p_simple_expr
(
s
)
keyword_args
.
append
((
keyword
,
arg
))
keyword_args
.
append
((
keyword
,
arg
))
else
:
else
:
...
@@ -459,7 +461,7 @@ def p_atom(s):
...
@@ -459,7 +461,7 @@ def p_atom(s):
value
=
s
.
systring
[:
-
1
]
value
=
s
.
systring
[:
-
1
]
s
.
next
()
s
.
next
()
return
ExprNodes
.
ImagNode
(
pos
,
value
=
value
)
return
ExprNodes
.
ImagNode
(
pos
,
value
=
value
)
elif
sy
==
'
STRING'
or
sy
==
'
BEGIN_STRING'
:
elif
sy
==
'BEGIN_STRING'
:
kind
,
value
=
p_cat_string_literal
(
s
)
kind
,
value
=
p_cat_string_literal
(
s
)
if
kind
==
'c'
:
if
kind
==
'c'
:
return
ExprNodes
.
CharNode
(
pos
,
value
=
value
)
return
ExprNodes
.
CharNode
(
pos
,
value
=
value
)
...
@@ -500,7 +502,12 @@ def p_name(s, name):
...
@@ -500,7 +502,12 @@ 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
):
return
ExprNodes
.
StringNode
(
pos
,
value
=
rep
[
1
:
-
1
])
sval
=
ExprNodes
.
EncodedString
(
rep
[
1
:
-
1
])
sval
.
encoding
=
value
.
encoding
return
ExprNodes
.
StringNode
(
pos
,
value
=
sval
)
elif
isinstance
(
value
,
unicode
):
sval
=
ExprNodes
.
EncodedString
(
rep
[
2
:
-
1
])
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"
%
value
.
__class__
.
__name__
)
%
value
.
__class__
.
__name__
)
...
@@ -508,21 +515,25 @@ def p_name(s, name):
...
@@ -508,21 +515,25 @@ def p_name(s, name):
def
p_cat_string_literal
(
s
):
def
p_cat_string_literal
(
s
):
# A sequence of one or more adjacent string literals.
# A sequence of one or more adjacent string literals.
# Returns (kind, value) where kind in ('', 'c', 'r')
# Returns (kind, value) where kind in ('', 'c', 'r'
, 'u'
)
kind
,
value
=
p_string_literal
(
s
)
kind
,
value
=
p_string_literal
(
s
)
if
kind
!=
'c'
:
if
kind
!=
'c'
:
strings
=
[
value
]
strings
=
[
value
]
while
s
.
sy
==
'
STRING'
or
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
(
self
.
error
(
"Cannot concatenate char literal with another string or char literal"
)
"Cannot concatenate char literal with another string or char literal"
)
elif
next_kind
==
'u'
:
kind
=
'u'
strings
.
append
(
next_value
)
strings
.
append
(
next_value
)
value
=
''
.
join
(
strings
)
value
=
ExprNodes
.
EncodedString
(
u''
.
join
(
strings
)
)
if
kind
!=
'u'
:
value
.
encoding
=
s
.
source_encoding
return
kind
,
value
return
kind
,
value
def
p_opt_string_literal
(
s
):
def
p_opt_string_literal
(
s
):
if
s
.
sy
==
'
STRING'
or
s
.
sy
==
'
BEGIN_STRING'
:
if
s
.
sy
==
'BEGIN_STRING'
:
return
p_string_literal
(
s
)
return
p_string_literal
(
s
)
else
:
else
:
return
None
return
None
...
@@ -530,10 +541,6 @@ def p_opt_string_literal(s):
...
@@ -530,10 +541,6 @@ def p_opt_string_literal(s):
def
p_string_literal
(
s
):
def
p_string_literal
(
s
):
# A single string or char literal.
# A single string or char literal.
# Returns (kind, value) where kind in ('', 'c', 'r', 'u')
# Returns (kind, value) where kind in ('', 'c', 'r', 'u')
if
s
.
sy
==
'STRING'
:
value
=
unquote
(
s
.
systring
)
s
.
next
()
return
value
# s.sy == 'BEGIN_STRING'
# s.sy == 'BEGIN_STRING'
pos
=
s
.
position
()
pos
=
s
.
position
()
#is_raw = s.systring[:1].lower() == "r"
#is_raw = s.systring[:1].lower() == "r"
...
@@ -549,8 +556,6 @@ def p_string_literal(s):
...
@@ -549,8 +556,6 @@ def p_string_literal(s):
systr
=
s
.
systring
systr
=
s
.
systring
if
len
(
systr
)
==
1
and
systr
in
"'
\
"
\
n
"
:
if
len
(
systr
)
==
1
and
systr
in
"'
\
"
\
n
"
:
chars
.
append
(
'
\
\
'
)
chars
.
append
(
'
\
\
'
)
if
kind
==
'u'
and
not
isinstance
(
systr
,
unicode
):
systr
=
systr
.
decode
(
"UTF-8"
)
chars
.
append
(
systr
)
chars
.
append
(
systr
)
elif
sy
==
'ESCAPE'
:
elif
sy
==
'ESCAPE'
:
systr
=
s
.
systring
systr
=
s
.
systring
...
@@ -572,7 +577,8 @@ def p_string_literal(s):
...
@@ -572,7 +577,8 @@ def p_string_literal(s):
elif
c
in
'ux'
:
elif
c
in
'ux'
:
if
kind
==
'u'
:
if
kind
==
'u'
:
try
:
try
:
chars
.
append
(
systr
.
decode
(
'unicode_escape'
))
chars
.
append
(
systr
.
encode
(
"ASCII"
).
decode
(
'unicode_escape'
))
except
UnicodeDecodeError
:
except
UnicodeDecodeError
:
s
.
error
(
"Invalid unicode escape '%s'"
%
systr
,
s
.
error
(
"Invalid unicode escape '%s'"
%
systr
,
pos
=
pos
)
pos
=
pos
)
...
@@ -593,50 +599,12 @@ def p_string_literal(s):
...
@@ -593,50 +599,12 @@ 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
=
''
.
join
(
chars
)
value
=
ExprNodes
.
EncodedString
(
u''
.
join
(
chars
)
)
if
kind
!=
'u'
:
value
.
encoding
=
s
.
source_encoding
#print "p_string_literal: value =", repr(value) ###
#print "p_string_literal: value =", repr(value) ###
return
kind
,
value
return
kind
,
value
def
unquote
(
s
):
is_raw
=
0
if
s
[:
1
].
lower
()
==
"r"
:
is_raw
=
1
s
=
s
[
1
:]
q
=
s
[:
3
]
if
q
==
'"""'
or
q
==
"'''"
:
s
=
s
[
3
:
-
3
]
else
:
s
=
s
[
1
:
-
1
]
if
is_raw
:
s
=
s
.
replace
(
'
\
\
'
,
'
\
\
\
\
'
)
s
=
s
.
replace
(
'
\
n
'
,
'
\
\
\
n
'
)
else
:
# Split into double quotes, newlines, escape sequences
# and spans of regular chars
l1
=
re
.
split
(
r'((?:\\[0-7]{1,3})|(?:\\x[0-9A-Fa-f]{2})|(?:\\.)|(?:\\\n)|(?:\n)|")'
,
s
)
#print "unquote: l1 =", l1 ###
l2
=
[]
for
item
in
l1
:
if
item
==
'"'
or
item
==
'
\
n
'
:
l2
.
append
(
'
\
\
'
+
item
)
elif
item
==
'
\
\
\
n
'
:
pass
elif
item
[:
1
]
==
'
\
\
'
:
if
len
(
item
)
==
2
:
if
item
[
1
]
in
'"
\
\
abfnrtv'
:
l2
.
append
(
item
)
else
:
l2
.
append
(
item
[
1
])
elif
item
[
1
:
2
]
==
'x'
:
l2
.
append
(
'
\
\
x0'
+
item
[
2
:])
else
:
# octal escape
l2
.
append
(
item
)
else
:
l2
.
append
(
item
)
s
=
""
.
join
(
l2
)
return
s
# list_display ::= "[" [listmaker] "]"
# list_display ::= "[" [listmaker] "]"
# listmaker ::= expression ( list_for | ( "," expression )* [","] )
# listmaker ::= expression ( list_for | ( "," expression )* [","] )
# list_iter ::= list_for | list_if
# list_iter ::= list_for | list_if
...
@@ -946,6 +914,8 @@ def p_import_statement(s):
...
@@ -946,6 +914,8 @@ 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
.
encoding
=
s
.
source_encoding
stat
=
Nodes
.
SingleAssignmentNode
(
pos
,
stat
=
Nodes
.
SingleAssignmentNode
(
pos
,
lhs
=
ExprNodes
.
NameNode
(
pos
,
lhs
=
ExprNodes
.
NameNode
(
pos
,
name
=
as_name
or
target_name
),
name
=
as_name
or
target_name
),
...
@@ -984,14 +954,18 @@ def p_from_import_statement(s):
...
@@ -984,14 +954,18 @@ 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
.
encoding
=
s
.
source_encoding
imported_name_strings
.
append
(
imported_name_strings
.
append
(
ExprNodes
.
StringNode
(
name_pos
,
value
=
name
))
ExprNodes
.
StringNode
(
name_pos
,
value
=
encoded_
name
))
items
.
append
(
items
.
append
(
(
name
,
(
name
,
ExprNodes
.
NameNode
(
name_pos
,
ExprNodes
.
NameNode
(
name_pos
,
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
.
encoding
=
s
.
source_encoding
return
Nodes
.
FromImportStatNode
(
pos
,
return
Nodes
.
FromImportStatNode
(
pos
,
module
=
ExprNodes
.
ImportNode
(
dotted_name_pos
,
module
=
ExprNodes
.
ImportNode
(
dotted_name_pos
,
module_name
=
ExprNodes
.
StringNode
(
dotted_name_pos
,
module_name
=
ExprNodes
.
StringNode
(
dotted_name_pos
,
...
@@ -1996,7 +1970,8 @@ def p_class_statement(s):
...
@@ -1996,7 +1970,8 @@ def p_class_statement(s):
# s.sy == 'class'
# s.sy == 'class'
pos
=
s
.
position
()
pos
=
s
.
position
()
s
.
next
()
s
.
next
()
class_name
=
p_ident
(
s
)
class_name
=
ExprNodes
.
EncodedString
(
p_ident
(
s
)
)
class_name
.
encoding
=
s
.
source_encoding
if
s
.
sy
==
'('
:
if
s
.
sy
==
'('
:
s
.
next
()
s
.
next
()
base_list
=
p_simple_expr_list
(
s
)
base_list
=
p_simple_expr_list
(
s
)
...
@@ -2113,7 +2088,7 @@ def p_property_decl(s):
...
@@ -2113,7 +2088,7 @@ def p_property_decl(s):
return
Nodes
.
PropertyNode
(
pos
,
name
=
name
,
doc
=
doc
,
body
=
body
)
return
Nodes
.
PropertyNode
(
pos
,
name
=
name
,
doc
=
doc
,
body
=
body
)
def
p_doc_string
(
s
):
def
p_doc_string
(
s
):
if
s
.
sy
==
'
STRING'
or
s
.
sy
==
'
BEGIN_STRING'
:
if
s
.
sy
==
'BEGIN_STRING'
:
_
,
result
=
p_cat_string_literal
(
s
)
_
,
result
=
p_cat_string_literal
(
s
)
if
s
.
sy
!=
'EOF'
:
if
s
.
sy
!=
'EOF'
:
s
.
expect_newline
(
"Syntax error in doc string"
)
s
.
expect_newline
(
"Syntax error in doc string"
)
...
...
Cython/Compiler/PyrexTypes.py
View file @
70ea30b6
...
@@ -37,6 +37,7 @@ class PyrexType(BaseType):
...
@@ -37,6 +37,7 @@ class PyrexType(BaseType):
# is_enum boolean Is a C enum type
# is_enum boolean Is a C enum type
# is_typedef boolean Is a typedef type
# is_typedef boolean Is a typedef type
# is_string boolean Is a C char * type
# is_string boolean Is a C char * type
# is_unicode boolean Is a UTF-8 encoded C char * type
# is_returncode boolean Is used only to signal exceptions
# is_returncode boolean Is used only to signal exceptions
# is_error boolean Is the dummy error type
# is_error boolean Is the dummy error type
# has_attributes boolean Has C dot-selectable attributes
# has_attributes boolean Has C dot-selectable attributes
...
@@ -83,6 +84,7 @@ class PyrexType(BaseType):
...
@@ -83,6 +84,7 @@ class PyrexType(BaseType):
is_enum
=
0
is_enum
=
0
is_typedef
=
0
is_typedef
=
0
is_string
=
0
is_string
=
0
is_unicode
=
0
is_returncode
=
0
is_returncode
=
0
is_error
=
0
is_error
=
0
has_attributes
=
0
has_attributes
=
0
...
@@ -875,19 +877,49 @@ class CEnumType(CType):
...
@@ -875,19 +877,49 @@ class CEnumType(CType):
return
self
.
base_declaration_code
(
public_decl
(
base
,
dll_linkage
),
entity_code
)
return
self
.
base_declaration_code
(
public_decl
(
base
,
dll_linkage
),
entity_code
)
def
_escape_byte_string
(
s
):
try
:
s
.
decode
(
"ASCII"
)
return
s
except
UnicodeDecodeError
:
pass
l
=
[]
append
=
l
.
append
for
c
in
s
:
o
=
ord
(
c
)
if
o
>=
128
:
append
(
'
\
\
x%X'
%
o
)
else
:
append
(
c
)
return
''
.
join
(
l
)
class
CStringType
:
class
CStringType
:
# Mixin class for C string types.
# Mixin class for C string types.
is_string
=
1
is_string
=
1
is_unicode
=
0
to_py_function
=
"PyString_FromString"
to_py_function
=
"PyString_FromString"
from_py_function
=
"PyString_AsString"
from_py_function
=
"PyString_AsString"
exception_value
=
"NULL"
exception_value
=
"NULL"
def
literal_code
(
self
,
value
):
def
literal_code
(
self
,
value
):
if
isinstance
(
value
,
unicode
):
assert
isinstance
(
value
,
str
)
value
=
value
.
encode
(
"UTF-8"
)
return
'"%s"'
%
_escape_byte_string
(
value
)
return
'"%s"'
%
value
class
CUTF8StringType
:
# Mixin class for C unicode types.
is_string
=
1
is_unicode
=
1
to_py_function
=
"PyUnicode_DecodeUTF8"
exception_value
=
"NULL"
def
literal_code
(
self
,
value
):
assert
isinstance
(
value
,
str
)
return
'"%s"'
%
_escape_byte_string
(
value
)
class
CCharArrayType
(
CStringType
,
CArrayType
):
class
CCharArrayType
(
CStringType
,
CArrayType
):
...
@@ -900,6 +932,16 @@ class CCharArrayType(CStringType, CArrayType):
...
@@ -900,6 +932,16 @@ class CCharArrayType(CStringType, CArrayType):
CArrayType
.
__init__
(
self
,
c_char_type
,
size
)
CArrayType
.
__init__
(
self
,
c_char_type
,
size
)
class
CUTF8CharArrayType
(
CUTF8StringType
,
CArrayType
):
# C 'char []' type.
parsetuple_format
=
"s"
pymemberdef_typecode
=
"T_STRING_INPLACE"
def
__init__
(
self
,
size
):
CArrayType
.
__init__
(
self
,
c_char_type
,
size
)
class
CCharPtrType
(
CStringType
,
CPtrType
):
class
CCharPtrType
(
CStringType
,
CPtrType
):
# C 'char *' type.
# C 'char *' type.
...
@@ -910,6 +952,16 @@ class CCharPtrType(CStringType, CPtrType):
...
@@ -910,6 +952,16 @@ class CCharPtrType(CStringType, CPtrType):
CPtrType
.
__init__
(
self
,
c_char_type
)
CPtrType
.
__init__
(
self
,
c_char_type
)
class
CUTF8CharPtrType
(
CUTF8StringType
,
CPtrType
):
# C 'char *' type, encoded in UTF-8.
parsetuple_format
=
"s"
pymemberdef_typecode
=
"T_STRING"
def
__init__
(
self
):
CPtrType
.
__init__
(
self
,
c_char_type
)
class
ErrorType
(
PyrexType
):
class
ErrorType
(
PyrexType
):
# Used to prevent propagation of error messages.
# Used to prevent propagation of error messages.
...
@@ -974,7 +1026,9 @@ c_longdouble_type = CFloatType(8)
...
@@ -974,7 +1026,9 @@ c_longdouble_type = CFloatType(8)
c_null_ptr_type
=
CNullPtrType
(
c_void_type
)
c_null_ptr_type
=
CNullPtrType
(
c_void_type
)
c_char_array_type
=
CCharArrayType
(
None
)
c_char_array_type
=
CCharArrayType
(
None
)
c_utf8_char_array_type
=
CUTF8CharArrayType
(
None
)
c_char_ptr_type
=
CCharPtrType
()
c_char_ptr_type
=
CCharPtrType
()
c_utf8_char_ptr_type
=
CUTF8CharPtrType
()
c_char_ptr_ptr_type
=
CPtrType
(
c_char_ptr_type
)
c_char_ptr_ptr_type
=
CPtrType
(
c_char_ptr_type
)
c_int_ptr_type
=
CPtrType
(
c_int_type
)
c_int_ptr_type
=
CPtrType
(
c_int_type
)
...
...
Cython/Compiler/Scanning.py
View file @
70ea30b6
...
@@ -212,7 +212,7 @@ class PyrexScanner(Scanner):
...
@@ -212,7 +212,7 @@ class PyrexScanner(Scanner):
resword_dict
=
build_resword_dict
()
resword_dict
=
build_resword_dict
()
def
__init__
(
self
,
file
,
filename
,
parent_scanner
=
None
,
def
__init__
(
self
,
file
,
filename
,
parent_scanner
=
None
,
type_names
=
None
,
context
=
None
):
type_names
=
None
,
context
=
None
,
source_encoding
=
None
):
Scanner
.
__init__
(
self
,
get_lexicon
(),
file
,
filename
)
Scanner
.
__init__
(
self
,
get_lexicon
(),
file
,
filename
)
if
parent_scanner
:
if
parent_scanner
:
self
.
context
=
parent_scanner
.
context
self
.
context
=
parent_scanner
.
context
...
@@ -226,6 +226,7 @@ class PyrexScanner(Scanner):
...
@@ -226,6 +226,7 @@ class PyrexScanner(Scanner):
self
.
compile_time_env
=
initial_compile_time_env
()
self
.
compile_time_env
=
initial_compile_time_env
()
self
.
compile_time_eval
=
1
self
.
compile_time_eval
=
1
self
.
compile_time_expr
=
0
self
.
compile_time_expr
=
0
self
.
source_encoding
=
source_encoding
self
.
trace
=
trace_scanner
self
.
trace
=
trace_scanner
self
.
indentation_stack
=
[
0
]
self
.
indentation_stack
=
[
0
]
self
.
indentation_char
=
None
self
.
indentation_char
=
None
...
...
Cython/Compiler/Symtab.py
View file @
70ea30b6
...
@@ -438,7 +438,13 @@ class Scope:
...
@@ -438,7 +438,13 @@ class Scope:
def
add_string_const
(
self
,
value
):
def
add_string_const
(
self
,
value
):
# Add an entry for a string constant.
# Add an entry for a string constant.
cname
=
self
.
new_const_cname
()
cname
=
self
.
new_const_cname
()
entry
=
Entry
(
""
,
cname
,
c_char_array_type
,
init
=
value
)
if
value
.
is_unicode
:
c_type
=
c_utf8_char_array_type
value
=
value
.
utf8encode
()
else
:
c_type
=
c_char_array_type
value
=
value
.
byteencode
()
entry
=
Entry
(
""
,
cname
,
c_type
,
init
=
value
)
entry
.
used
=
1
entry
.
used
=
1
self
.
const_entries
.
append
(
entry
)
self
.
const_entries
.
append
(
entry
)
return
entry
return
entry
...
@@ -460,7 +466,7 @@ class Scope:
...
@@ -460,7 +466,7 @@ class Scope:
# Python identifier, it will be interned.
# Python identifier, it will be interned.
if
not
entry
.
pystring_cname
:
if
not
entry
.
pystring_cname
:
value
=
entry
.
init
value
=
entry
.
init
if
identifier_pattern
.
match
(
value
)
and
isinstance
(
value
,
str
):
if
not
entry
.
type
.
is_unicode
and
identifier_pattern
.
match
(
value
):
entry
.
pystring_cname
=
self
.
intern
(
value
)
entry
.
pystring_cname
=
self
.
intern
(
value
)
entry
.
is_interned
=
1
entry
.
is_interned
=
1
else
:
else
:
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment