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
6c3f2815
Commit
6c3f2815
authored
8 years ago
by
Robert Bradshaw
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'typeid'
parents
d84f6476
eb5fc339
Changes
12
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
175 additions
and
4 deletions
+175
-4
CHANGES.rst
CHANGES.rst
+2
-0
Cython/Compiler/CythonScope.py
Cython/Compiler/CythonScope.py
+3
-1
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+73
-1
Cython/Compiler/ParseTreeTransforms.py
Cython/Compiler/ParseTreeTransforms.py
+1
-0
Cython/Includes/libcpp/typeindex.pxd
Cython/Includes/libcpp/typeindex.pxd
+15
-0
Cython/Includes/libcpp/typeinfo.pxd
Cython/Includes/libcpp/typeinfo.pxd
+10
-0
Cython/Parser/Grammar
Cython/Parser/Grammar
+1
-0
Cython/Utility/CppSupport.cpp
Cython/Utility/CppSupport.cpp
+2
-0
Cython/Utility/ModuleSetupCode.c
Cython/Utility/ModuleSetupCode.c
+3
-0
docs/src/userguide/wrapping_CPlusPlus.rst
docs/src/userguide/wrapping_CPlusPlus.rst
+23
-0
tests/run/cpp_operators.pyx
tests/run/cpp_operators.pyx
+41
-2
tests/run/cpp_operators_helper.h
tests/run/cpp_operators_helper.h
+1
-0
No files found.
CHANGES.rst
View file @
6c3f2815
...
...
@@ -42,6 +42,8 @@ Features added
* Some integer operations on Python long objects are faster in Python 2.7.
* Support for the C++ ``typeid`` operator.
Bugs fixed
----------
...
...
This diff is collapsed.
Click to expand it.
Cython/Compiler/CythonScope.py
View file @
6c3f2815
...
...
@@ -67,7 +67,9 @@ class CythonScope(ModuleScope):
name_path
=
qname
.
split
(
u'.'
)
scope
=
self
while
len
(
name_path
)
>
1
:
scope
=
scope
.
lookup_here
(
name_path
[
0
]).
as_module
scope
=
scope
.
lookup_here
(
name_path
[
0
])
if
scope
:
scope
=
scope
.
as_module
del
name_path
[
0
]
if
scope
is
None
:
return
None
...
...
This diff is collapsed.
Click to expand it.
Cython/Compiler/ExprNodes.py
View file @
6c3f2815
...
...
@@ -6241,6 +6241,7 @@ class AttributeNode(ExprNode):
needs_none_check
=
True
is_memslice_transpose
=
False
is_special_lookup
=
False
is_py_attr
=
0
def
as_cython_attribute
(
self
):
if
(
isinstance
(
self
.
obj
,
NameNode
)
and
...
...
@@ -6670,7 +6671,7 @@ class AttributeNode(ExprNode):
else
:
# result_code contains what is needed, but we may need to insert
# a check and raise an exception
if
self
.
obj
.
type
.
is_extension_type
:
if
self
.
obj
.
type
and
self
.
obj
.
type
.
is_extension_type
:
pass
elif
self
.
entry
and
self
.
entry
.
is_cmethod
:
# C method implemented as function call with utility code
...
...
@@ -10213,6 +10214,8 @@ class SizeofTypeNode(SizeofNode):
def
check_type
(
self
):
arg_type
=
self
.
arg_type
if
not
arg_type
:
return
if
arg_type
.
is_pyobject
and
not
arg_type
.
is_extension_type
:
error
(
self
.
pos
,
"Cannot take sizeof Python object"
)
elif
arg_type
.
is_void
:
...
...
@@ -10257,6 +10260,75 @@ class SizeofVarNode(SizeofNode):
def
generate_result_code
(
self
,
code
):
pass
class
TypeidNode
(
ExprNode
):
# C++ typeid operator applied to a type or variable
#
# operand ExprNode
# arg_type ExprNode
# is_variable boolean
type
=
PyrexTypes
.
error_type
subexprs
=
[
'operand'
]
arg_type
=
None
is_variable
=
None
is_temp
=
1
def
get_type_info_type
(
self
,
env
):
env_module
=
env
while
not
env_module
.
is_module_scope
:
env_module
=
env_module
.
outer_scope
typeinfo_module
=
env_module
.
find_module
(
'libcpp.typeinfo'
,
self
.
pos
)
typeinfo_entry
=
typeinfo_module
.
lookup
(
'type_info'
)
return
PyrexTypes
.
CFakeReferenceType
(
PyrexTypes
.
c_const_type
(
typeinfo_entry
.
type
))
def
analyse_types
(
self
,
env
):
type_info
=
self
.
get_type_info_type
(
env
)
if
not
type_info
:
self
.
error
(
"The 'libcpp.typeinfo' module must be cimported to use the typeid() operator"
)
return
self
self
.
type
=
type_info
as_type
=
self
.
operand
.
analyse_as_type
(
env
)
if
as_type
:
self
.
arg_type
=
as_type
self
.
is_type
=
True
else
:
self
.
arg_type
=
self
.
operand
.
analyse_types
(
env
)
self
.
is_type
=
False
if
self
.
arg_type
.
type
.
is_pyobject
:
self
.
error
(
"Cannot use typeid on a Python object"
)
return
self
elif
self
.
arg_type
.
type
.
is_void
:
self
.
error
(
"Cannot use typeid on void"
)
return
self
elif
not
self
.
arg_type
.
type
.
is_complete
():
self
.
error
(
"Cannot use typeid on incomplete type '%s'"
%
self
.
arg_type
.
type
)
return
self
env
.
use_utility_code
(
UtilityCode
.
load_cached
(
"CppExceptionConversion"
,
"CppSupport.cpp"
))
return
self
def
error
(
self
,
mess
):
error
(
self
.
pos
,
mess
)
self
.
type
=
PyrexTypes
.
error_type
self
.
result_code
=
"<error>"
def
check_const
(
self
):
return
True
def
calculate_result_code
(
self
):
return
self
.
temp_code
def
generate_result_code
(
self
,
code
):
if
self
.
is_type
:
arg_code
=
self
.
arg_type
.
empty_declaration_code
()
else
:
arg_code
=
self
.
arg_type
.
result
()
translate_cpp_exception
(
code
,
self
.
pos
,
"%s = typeid(%s);"
%
(
self
.
temp_code
,
arg_code
),
None
,
self
.
in_nogil_context
)
class
TypeofNode
(
ExprNode
):
# Compile-time type of an expression, as a string.
#
...
...
This diff is collapsed.
Click to expand it.
Cython/Compiler/ParseTreeTransforms.py
View file @
6c3f2815
...
...
@@ -635,6 +635,7 @@ class InterpretCompilerDirectives(CythonTransform, SkipDeclarations):
'operator.predecrement'
:
ExprNodes
.
inc_dec_constructor
(
True
,
'--'
),
'operator.postincrement'
:
ExprNodes
.
inc_dec_constructor
(
False
,
'++'
),
'operator.postdecrement'
:
ExprNodes
.
inc_dec_constructor
(
False
,
'--'
),
'operator.typeid'
:
ExprNodes
.
TypeidNode
,
# For backwards compatibility.
'address'
:
ExprNodes
.
AmpersandNode
,
...
...
This diff is collapsed.
Click to expand it.
Cython/Includes/libcpp/typeindex.pxd
0 → 100644
View file @
6c3f2815
from
libcpp
cimport
bool
from
.typeinfo
cimport
type_info
# This class is C++11-only
cdef
extern
from
"<typeindex>"
namespace
"std"
nogil
:
cdef
cppclass
type_index
:
type_index
(
const
type_info
&
)
const
char
*
name
()
size_t
hash_code
()
bool
operator
==
(
const
type_index
&
)
bool
operator
!=
(
const
type_index
&
)
bool
operator
<
(
const
type_index
&
)
bool
operator
<=
(
const
type_index
&
)
bool
operator
>
(
const
type_index
&
)
bool
operator
>=
(
const
type_index
&
)
This diff is collapsed.
Click to expand it.
Cython/Includes/libcpp/typeinfo.pxd
0 → 100644
View file @
6c3f2815
from
libcpp
cimport
bool
cdef
extern
from
"<typeinfo>"
namespace
"std"
nogil
:
cdef
cppclass
type_info
:
const
char
*
name
()
int
before
(
const
type_info
&
)
bool
operator
==
(
const
type_info
&
)
bool
operator
!=
(
const
type_info
&
)
# C++11-only
size_t
hash_code
()
This diff is collapsed.
Click to expand it.
Cython/Parser/Grammar
View file @
6c3f2815
...
...
@@ -167,6 +167,7 @@ memory_view_index: ':' [':'] [NUMBER]
address: '&' factor
cast: '<' type ['?'] '>' factor
size_of: 'sizeof' '(' (type) ')'
type_id: 'typeid' '(' (type) ')'
new_expr: 'new' type '(' [arglist] ')'
# TODO: Restrict cdef_stmt to "top-level" statements.
...
...
This diff is collapsed.
Click to expand it.
Cython/Utility/CppSupport.cpp
View file @
6c3f2815
...
...
@@ -18,6 +18,8 @@ static void __Pyx_CppExn2PyErr() {
PyErr_SetString
(
PyExc_MemoryError
,
exn
.
what
());
}
catch
(
const
std
::
bad_cast
&
exn
)
{
PyErr_SetString
(
PyExc_TypeError
,
exn
.
what
());
}
catch
(
const
std
::
bad_typeid
&
exn
)
{
PyErr_SetString
(
PyExc_TypeError
,
exn
.
what
());
}
catch
(
const
std
::
domain_error
&
exn
)
{
PyErr_SetString
(
PyExc_ValueError
,
exn
.
what
());
}
catch
(
const
std
::
invalid_argument
&
exn
)
{
...
...
This diff is collapsed.
Click to expand it.
Cython/Utility/ModuleSetupCode.c
View file @
6c3f2815
...
...
@@ -403,6 +403,9 @@ class __Pyx_FakeReference {
__Pyx_FakeReference
(
const
T
&
ref
)
:
ptr
(
const_cast
<
T
*>
(
&
ref
))
{
}
T
*
operator
->
()
{
return
ptr
;
}
operator
T
&
()
{
return
*
ptr
;
}
// TODO(robertwb): Delegate all operators (or auto-generate unwrapping code where needed).
template
<
typename
U
>
bool
operator
==
(
U
other
)
{
return
*
ptr
==
other
;
};
template
<
typename
U
>
bool
operator
!=
(
U
other
)
{
return
*
ptr
!=
other
;
};
private:
T
*
ptr
;
};
...
...
This diff is collapsed.
Click to expand it.
docs/src/userguide/wrapping_CPlusPlus.rst
View file @
6c3f2815
...
...
@@ -562,6 +562,8 @@ The translation is performed according to the following table
+-----------------------+---------------------+
| ``bad_cast`` | ``TypeError`` |
+-----------------------+---------------------+
| ``bad_typeid`` | ``TypeError`` |
+-----------------------+---------------------+
| ``domain_error`` | ``ValueError`` |
+-----------------------+---------------------+
| ``invalid_argument`` | ``ValueError`` |
...
...
@@ -646,6 +648,27 @@ e.g.::
(Though of course the ``for .. in`` syntax is prefered for objects supporting
the iteration protocol.)
RTTI and typeid()
=================
Cython has support for the ``typeid(...)`` operator.
from cython.operator cimport typeid
The ``typeid(...)`` operator returns an object of the type ``const type_info &``.
If you want to store a type_info value in a C variable, you will need to store it
as a pointer rather than a reference:
from libcpp.typeinfo cimport type_info
cdef const type_info* info = &typeid(MyClass)
If an invalid type is passed to ``typeid``, it will throw an ``std::bad_typeid``
exception which is converted into a ``TypeError`` exception in Python.
An additional C++11-only RTTI-related class, ``std::type_index``, is available
in ``libcpp.typeindex``.
Caveats and Limitations
========================
...
...
This diff is collapsed.
Click to expand it.
tests/run/cpp_operators.pyx
View file @
6c3f2815
...
...
@@ -4,7 +4,7 @@
from
cython
cimport
typeof
cimport
cython.operator
from
cython.operator
cimport
dereference
as
deref
from
cython.operator
cimport
typeid
,
dereference
as
deref
from
libc.string
cimport
const_char
from
libcpp
cimport
bool
...
...
@@ -50,12 +50,15 @@ cdef extern from "cpp_operators_helper.h":
const_char
*
operator
[](
int
)
const_char
*
operator
()(
int
)
cppclass
TruthClass
:
c
def
c
ppclass
TruthClass
:
TruthClass
()
TruthClass
(
bool
)
bool
operator
bool
()
bool
value
cdef
cppclass
TruthSubClass
(
TruthClass
):
pass
def
test_unops
():
"""
>>> test_unops()
...
...
@@ -182,3 +185,39 @@ def test_bool_cond():
assert
(
TruthClass
(
False
)
and
TruthClass
(
True
)).
value
==
False
assert
(
TruthClass
(
True
)
and
TruthClass
(
False
)).
value
==
False
assert
(
TruthClass
(
True
)
and
TruthClass
(
True
)).
value
==
True
ctypedef
int
*
int_ptr
def
test_typeid_op
():
"""
>>> test_typeid_op()
"""
cdef
TruthClass
*
test_1
=
new
TruthClass
()
cdef
TruthSubClass
*
test_2
=
new
TruthSubClass
()
cdef
TruthClass
*
test_3
=
<
TruthClass
*>
test_2
cdef
TruthClass
*
test_4
=
<
TruthClass
*>
0
assert
typeid
(
TruthClass
).
name
()
assert
typeid
(
test_1
).
name
()
assert
typeid
(
TruthClass
)
==
typeid
(
deref
(
test_1
))
assert
typeid
(
TruthSubClass
).
name
()
assert
typeid
(
test_2
).
name
()
assert
typeid
(
TruthSubClass
)
==
typeid
(
deref
(
test_2
))
assert
typeid
(
TruthSubClass
)
==
typeid
(
deref
(
test_3
))
assert
typeid
(
TruthClass
)
!=
typeid
(
deref
(
test_3
))
assert
typeid
(
TruthClass
).
name
()
assert
typeid
(
test_3
).
name
()
assert
typeid
(
TruthSubClass
).
name
()
assert
typeid
(
deref
(
test_2
)).
name
()
assert
typeid
(
int_ptr
).
name
()
try
:
typeid
(
deref
(
test_4
))
assert
False
except
TypeError
:
assert
True
del
test_1
,
test_2
This diff is collapsed.
Click to expand it.
tests/run/cpp_operators_helper.h
View file @
6c3f2815
...
...
@@ -50,6 +50,7 @@ class TruthClass {
public:
TruthClass
()
:
value
(
false
)
{}
TruthClass
(
bool
value
)
:
value
(
value
)
{}
virtual
~
TruthClass
()
{};
operator
bool
()
{
return
value
;
}
bool
value
;
};
This diff is collapsed.
Click to expand it.
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