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
Labels
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
nexedi
cython
Commits
b363f41b
Commit
b363f41b
authored
Nov 19, 2010
by
Stefan Behnel
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
optimisation: do not build and test metaclass kwargs if we know the metaclass at compile time
parent
c9ff1344
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
52 additions
and
6 deletions
+52
-6
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+14
-4
Cython/Compiler/Options.py
Cython/Compiler/Options.py
+2
-2
tests/run/metaclass.pyx
tests/run/metaclass.pyx
+36
-0
No files found.
Cython/Compiler/Nodes.py
View file @
b363f41b
...
@@ -2952,16 +2952,26 @@ class PyClassDefNode(ClassDefNode):
...
@@ -2952,16 +2952,26 @@ class PyClassDefNode(ClassDefNode):
import
ExprNodes
import
ExprNodes
if
self
.
doc
and
Options
.
docstrings
:
if
self
.
doc
and
Options
.
docstrings
:
doc
=
embed_position
(
self
.
pos
,
self
.
doc
)
doc
=
embed_position
(
self
.
pos
,
self
.
doc
)
# FIXME: correct string node?
doc_node
=
ExprNodes
.
StringNode
(
pos
,
value
=
doc
)
doc_node
=
ExprNodes
.
StringNode
(
pos
,
value
=
doc
)
else
:
else
:
doc_node
=
None
doc_node
=
None
if
keyword_args
or
starstar_arg
:
if
keyword_args
or
starstar_arg
:
self
.
py3_style_class
=
True
self
.
py3_style_class
=
True
self
.
bases
=
bases
self
.
bases
=
bases
self
.
mkw
=
ExprNodes
.
KeywordArgsNode
(
pos
,
self
.
metaclass
=
None
keyword_args
=
keyword_args
,
starstar_arg
=
starstar_arg
)
if
keyword_args
and
not
starstar_arg
and
len
(
keyword_args
.
key_value_pairs
)
==
1
:
self
.
metaclass
=
ExprNodes
.
PyClassMetaclassNode
(
pos
,
mkw
=
self
.
mkw
,
bases
=
self
.
bases
)
item
=
keyword_args
.
key_value_pairs
[
0
]
if
item
.
key
.
value
==
'metaclass'
:
# special case: we already know the metaclass and
# it's the only kwarg, so we don't need to do the
# "build kwargs, find metaclass" dance at runtime
self
.
metaclass
=
item
.
value
self
.
mkw
=
ExprNodes
.
NullNode
(
pos
)
if
self
.
metaclass
is
None
:
self
.
mkw
=
ExprNodes
.
KeywordArgsNode
(
pos
,
keyword_args
=
keyword_args
,
starstar_arg
=
starstar_arg
)
self
.
metaclass
=
ExprNodes
.
PyClassMetaclassNode
(
pos
,
mkw
=
self
.
mkw
,
bases
=
self
.
bases
)
self
.
dict
=
ExprNodes
.
PyClassNamespaceNode
(
pos
,
name
=
name
,
self
.
dict
=
ExprNodes
.
PyClassNamespaceNode
(
pos
,
name
=
name
,
doc
=
doc_node
,
metaclass
=
self
.
metaclass
,
bases
=
self
.
bases
,
doc
=
doc_node
,
metaclass
=
self
.
metaclass
,
bases
=
self
.
bases
,
mkw
=
self
.
mkw
,
)
mkw
=
self
.
mkw
,
)
...
...
Cython/Compiler/Options.py
View file @
b363f41b
...
@@ -102,8 +102,8 @@ directive_scopes = { # defaults to available everywhere
...
@@ -102,8 +102,8 @@ directive_scopes = { # defaults to available everywhere
'autotestdict'
:
(
'module'
,),
'autotestdict'
:
(
'module'
,),
'autotestdict.all'
:
(
'module'
,),
'autotestdict.all'
:
(
'module'
,),
'autotestdict.cdef'
:
(
'module'
,),
'autotestdict.cdef'
:
(
'module'
,),
'test_assert_path_exists'
:
(
'function'
,),
'test_assert_path_exists'
:
(
'function'
,
'class'
,
'cclass'
),
'test_fail_if_path_exists'
:
(
'function'
,),
'test_fail_if_path_exists'
:
(
'function'
,
'class'
,
'cclass'
),
}
}
def
parse_directive_value
(
name
,
value
,
relaxed_bool
=
False
):
def
parse_directive_value
(
name
,
value
,
relaxed_bool
=
False
):
...
...
tests/run/metaclass.pyx
View file @
b363f41b
cimport
cython
class
Base
(
type
):
class
Base
(
type
):
def
__new__
(
cls
,
name
,
bases
,
attrs
):
def
__new__
(
cls
,
name
,
bases
,
attrs
):
attrs
[
'metaclass_was_here'
]
=
True
attrs
[
'metaclass_was_here'
]
=
True
return
type
.
__new__
(
cls
,
name
,
bases
,
attrs
)
return
type
.
__new__
(
cls
,
name
,
bases
,
attrs
)
@
cython
.
test_fail_if_path_exists
(
"//PyClassMetaclassNode"
,
"//Py3ClassNode"
)
class
Foo
(
object
):
class
Foo
(
object
):
"""
"""
>>> obj = Foo()
>>> obj = Foo()
...
@@ -22,6 +25,34 @@ class ODict(dict):
...
@@ -22,6 +25,34 @@ class ODict(dict):
dict
.
__setitem__
(
self
,
key
,
value
)
dict
.
__setitem__
(
self
,
key
,
value
)
self
.
_order
.
append
(
key
)
self
.
_order
.
append
(
key
)
class
Py3MetaclassPlusAttr
(
type
):
def
__new__
(
cls
,
name
,
bases
,
attrs
,
**
kwargs
):
for
key
,
value
in
kwargs
.
items
():
attrs
[
key
]
=
value
attrs
[
'metaclass_was_here'
]
=
True
return
type
.
__new__
(
cls
,
name
,
bases
,
attrs
)
def
__init__
(
self
,
cls
,
attrs
,
obj
,
**
kwargs
):
pass
@
staticmethod
def
__prepare__
(
*
args
,
**
kwargs
):
return
ODict
()
@
cython
.
test_fail_if_path_exists
(
"//PyClassMetaclassNode"
)
@
cython
.
test_assert_path_exists
(
"//Py3ClassNode"
)
class
Py3ClassMCOnly
(
object
,
metaclass
=
Py3MetaclassPlusAttr
):
"""
>>> obj = Py3ClassMCOnly()
>>> obj.bar
321
>>> obj.metaclass_was_here
True
>>> obj._order
['__module__', '__doc__', 'bar', 'metaclass_was_here']
"""
bar
=
321
class
Py3Base
(
type
):
class
Py3Base
(
type
):
def
__new__
(
cls
,
name
,
bases
,
attrs
,
**
kwargs
):
def
__new__
(
cls
,
name
,
bases
,
attrs
,
**
kwargs
):
for
key
,
value
in
kwargs
.
items
():
for
key
,
value
in
kwargs
.
items
():
...
@@ -35,6 +66,7 @@ class Py3Base(type):
...
@@ -35,6 +66,7 @@ class Py3Base(type):
def
__prepare__
(
*
args
,
**
kwargs
):
def
__prepare__
(
*
args
,
**
kwargs
):
return
ODict
()
return
ODict
()
@
cython
.
test_assert_path_exists
(
"//PyClassMetaclassNode"
,
"//Py3ClassNode"
)
class
Py3Foo
(
object
,
metaclass
=
Py3Base
,
foo
=
123
):
class
Py3Foo
(
object
,
metaclass
=
Py3Base
,
foo
=
123
):
"""
"""
>>> obj = Py3Foo()
>>> obj = Py3Foo()
...
@@ -49,6 +81,7 @@ class Py3Foo(object, metaclass=Py3Base, foo=123):
...
@@ -49,6 +81,7 @@ class Py3Foo(object, metaclass=Py3Base, foo=123):
kwargs
=
{
'foo'
:
123
,
'bar'
:
456
}
kwargs
=
{
'foo'
:
123
,
'bar'
:
456
}
@
cython
.
test_assert_path_exists
(
"//PyClassMetaclassNode"
,
"//Py3ClassNode"
)
class
Py3Mixed
(
metaclass
=
Py3Base
,
**
kwargs
):
class
Py3Mixed
(
metaclass
=
Py3Base
,
**
kwargs
):
"""
"""
>>> Py3Mixed.foo
>>> Py3Mixed.foo
...
@@ -59,6 +92,7 @@ class Py3Mixed(metaclass=Py3Base, **kwargs):
...
@@ -59,6 +92,7 @@ class Py3Mixed(metaclass=Py3Base, **kwargs):
kwargs
[
'metaclass'
]
=
Py3Base
kwargs
[
'metaclass'
]
=
Py3Base
@
cython
.
test_assert_path_exists
(
"//PyClassMetaclassNode"
)
class
Py3Kwargs
(
**
kwargs
):
class
Py3Kwargs
(
**
kwargs
):
"""
"""
>>> Py3Kwargs.foo
>>> Py3Kwargs.foo
...
@@ -81,6 +115,8 @@ class Base3(type):
...
@@ -81,6 +115,8 @@ class Base3(type):
return
{}
return
{}
kwargs
=
{
'c'
:
0
}
kwargs
=
{
'c'
:
0
}
@
cython
.
test_assert_path_exists
(
"//PyClassMetaclassNode"
,
"//Py3ClassNode"
)
class
Foo3
(
metaclass
=
Base3
,
a
=
0
,
b
=
0
,
**
kwargs
):
class
Foo3
(
metaclass
=
Base3
,
a
=
0
,
b
=
0
,
**
kwargs
):
"""
"""
>>> Foo3.kwargs
>>> Foo3.kwargs
...
...
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