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
Kirill Smelkov
cython
Commits
b3c67d1d
Commit
b3c67d1d
authored
May 08, 2008
by
Robert Bradshaw
Browse files
Options
Browse Files
Download
Plain Diff
merge __getattribut__ code
parents
45f2a56e
6b56ec73
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
221 additions
and
15 deletions
+221
-15
Cython/Compiler/ModuleNode.py
Cython/Compiler/ModuleNode.py
+34
-14
Cython/Compiler/TypeSlots.py
Cython/Compiler/TypeSlots.py
+1
-1
tests/run/__getattribute__.pyx
tests/run/__getattribute__.pyx
+60
-0
tests/run/__getattribute_subclasses__.pyx
tests/run/__getattribute_subclasses__.pyx
+126
-0
No files found.
Cython/Compiler/ModuleNode.py
View file @
b3c67d1d
...
...
@@ -666,7 +666,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
self
.
generate_ass_subscript_function
(
scope
,
code
)
if
scope
.
defines_any
([
"__setslice__"
,
"__delslice__"
]):
self
.
generate_ass_slice_function
(
scope
,
code
)
if
scope
.
defines_any
([
"__getattr__"
]):
if
scope
.
defines_any
([
"__getattr__"
,
"__getattribute__"
]):
self
.
generate_getattro_function
(
scope
,
code
)
if
scope
.
defines_any
([
"__setattr__"
,
"__delattr__"
]):
self
.
generate_setattro_function
(
scope
,
code
)
...
...
@@ -1030,27 +1030,47 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
"}"
)
def
generate_getattro_function
(
self
,
scope
,
code
):
# First try to get the attribute using PyObject_GenericGetAttr.
# If that raises an AttributeError, call the user's __getattr__
# method.
entry
=
scope
.
lookup_here
(
"__getattr__"
)
# First try to get the attribute using __getattribute__, if defined, or
# PyObject_GenericGetAttr.
#
# If that raises an AttributeError, call the __getattr__ if defined.
#
# In both cases, defined can be in this class, or any base class.
def
lookup_here_or_base
(
n
,
type
=
None
):
# Recursive lookup
if
type
is
None
:
type
=
scope
.
parent_type
r
=
type
.
scope
.
lookup_here
(
n
)
if
r
is
None
and
\
type
.
base_type
is
not
None
:
return
lookup_here_or_base
(
n
,
type
.
base_type
)
else
:
return
r
getattr_entry
=
lookup_here_or_base
(
"__getattr__"
)
getattribute_entry
=
lookup_here_or_base
(
"__getattribute__"
)
code
.
putln
(
""
)
code
.
putln
(
"static PyObject *%s(PyObject *o, PyObject *n) {"
%
scope
.
mangle_internal
(
"tp_getattro"
))
code
.
putln
(
if
getattribute_entry
is
not
None
:
code
.
putln
(
"PyObject *v = %s(o, n);"
%
getattribute_entry
.
func_cname
)
else
:
code
.
putln
(
"PyObject *v = PyObject_GenericGetAttr(o, n);"
)
code
.
putln
(
if
getattr_entry
is
not
None
:
code
.
putln
(
"if (!v && PyErr_ExceptionMatches(PyExc_AttributeError)) {"
)
code
.
putln
(
"PyErr_Clear();"
)
code
.
putln
(
"v = %s(o, n);"
%
entry
.
func_cname
)
code
.
putln
(
code
.
putln
(
"PyErr_Clear();"
)
code
.
putln
(
"v = %s(o, n);"
%
getattr_
entry
.
func_cname
)
code
.
putln
(
"}"
)
code
.
putln
(
"return v;"
)
"return v;"
)
code
.
putln
(
"}"
)
...
...
Cython/Compiler/TypeSlots.py
View file @
b3c67d1d
...
...
@@ -610,7 +610,7 @@ slot_table = (
MethodSlot
(
callfunc
,
"tp_call"
,
"__call__"
),
MethodSlot
(
reprfunc
,
"tp_str"
,
"__str__"
),
SyntheticSlot
(
"tp_getattro"
,
[
"__getattr__"
],
"0"
),
#"PyObject_GenericGetAttr"),
SyntheticSlot
(
"tp_getattro"
,
[
"__getattr__"
,
"__getattribute__"
],
"0"
),
#"PyObject_GenericGetAttr"),
SyntheticSlot
(
"tp_setattro"
,
[
"__setattr__"
,
"__delattr__"
],
"0"
),
#"PyObject_GenericSetAttr"),
SuiteSlot
(
PyBufferProcs
,
"PyBufferProcs"
,
"tp_as_buffer"
),
...
...
tests/run/__getattribute__.pyx
0 → 100644
View file @
b3c67d1d
__doc__
=
"""
__getattribute__ and __getattr__ special methods for a single class.
>>> a = just_getattribute()
>>> a.bar
'bar'
>>> a.invalid
Traceback (most recent call last):
AttributeError
>>> a = just_getattr()
>>> a.foo
10
>>> a.bar
'bar'
>>> a.invalid
Traceback (most recent call last):
AttributeError
>>> a = both()
>>> a.foo
10
>>> a.bar
'bar'
>>> a.invalid
Traceback (most recent call last):
AttributeError
"""
cdef
class
just_getattribute
:
def
__getattribute__
(
self
,
n
):
if
n
==
'bar'
:
return
n
else
:
raise
AttributeError
cdef
class
just_getattr
:
cdef
readonly
int
foo
def
__init__
(
self
):
self
.
foo
=
10
def
__getattr__
(
self
,
n
):
if
n
==
'bar'
:
return
n
else
:
raise
AttributeError
cdef
class
both
:
cdef
readonly
int
foo
def
__init__
(
self
):
self
.
foo
=
10
def
__getattribute__
(
self
,
n
):
if
n
==
'foo'
:
return
self
.
foo
else
:
raise
AttributeError
def
__getattr__
(
self
,
n
):
if
n
==
'bar'
:
return
n
else
:
raise
AttributeError
tests/run/__getattribute_subclasses__.pyx
0 → 100644
View file @
b3c67d1d
__doc__
=
"""
__getattribute__ and __getattr__ special methods and subclasses.
getattr does not override members.
>>> a = getattr_boring()
>>> a.boring_member
10
>>> a.resolved_by
'getattr_boring'
getattribute does.
>>> a = getattribute_boring()
>>> a.boring_member
Traceback (most recent call last):
AttributeError
>>> a.resolved_by
'getattribute_boring'
Is inherited.
>>> a = boring_boring_getattribute()
>>> a.boring_getattribute_member
Traceback (most recent call last):
AttributeError
>>> a.boring_boring_getattribute_member
Traceback (most recent call last):
AttributeError
>>> a.resolved_by
'_getattribute'
__getattribute__ is always tried first, then __getattr__, regardless of where
in the inheritance hiarchy they came from.
>>> a = getattribute_boring_boring_getattr()
>>> a.foo
Traceback (most recent call last):
AttributeError
>>> a.resolved_by
'getattribute_boring_boring_getattr'
>>> a.getattribute_boring_boring_getattr
True
>>> a._getattr
True
>>> a = getattr_boring_boring_getattribute()
>>> a.foo
Traceback (most recent call last):
AttributeError
>>> a.resolved_by
'_getattribute'
>>> a.getattr_boring_boring_getattribute
True
>>> a._getattribute
True
"""
cdef
class
boring
:
cdef
readonly
int
boring_member
def
__init__
(
self
):
self
.
boring_member
=
10
cdef
class
getattr_boring
(
boring
):
def
__getattr__
(
self
,
n
):
if
n
==
'resolved_by'
:
return
'getattr_boring'
elif
n
==
'getattr_boring'
:
return
True
else
:
raise
AttributeError
cdef
class
getattribute_boring
(
boring
):
def
__getattribute__
(
self
,
n
):
if
n
==
'resolved_by'
:
return
'getattribute_boring'
elif
n
==
'getattribute_boring'
:
return
True
else
:
raise
AttributeError
cdef
class
_getattr
:
def
__getattr__
(
self
,
n
):
if
n
==
'resolved_by'
:
return
'_getattr'
elif
n
==
'_getattr'
:
return
True
else
:
raise
AttributeError
cdef
class
_getattribute
(
boring
):
def
__getattribute__
(
self
,
n
):
if
n
==
'resolved_by'
:
return
'_getattribute'
elif
n
==
'_getattribute'
:
return
True
else
:
raise
AttributeError
cdef
class
boring_getattribute
(
_getattribute
):
cdef
readonly
int
boring_getattribute_member
cdef
class
boring_boring_getattribute
(
boring_getattribute
):
cdef
readonly
int
boring_boring_getattribute_member
cdef
class
boring_getattr
(
_getattr
):
cdef
readonly
int
boring_getattr_member
cdef
class
boring_boring_getattr
(
boring_getattr
):
cdef
readonly
int
boring_boring_getattr_member
cdef
class
getattribute_boring_boring_getattr
(
boring_boring_getattr
):
def
__getattribute__
(
self
,
n
):
if
n
==
'resolved_by'
:
return
'getattribute_boring_boring_getattr'
elif
n
==
'getattribute_boring_boring_getattr'
:
return
True
else
:
raise
AttributeError
cdef
class
getattr_boring_boring_getattribute
(
boring_boring_getattribute
):
def
__getattr__
(
self
,
n
):
if
n
==
'resolved_by'
:
return
'getattr_boring_boring_getattribute'
elif
n
==
'getattr_boring_boring_getattribute'
:
return
True
else
:
raise
AttributeError
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