Author: Armin Rigo <[email protected]>
Branch:
Changeset: r49647:ddbc82ef4d8f
Date: 2011-11-21 20:30 +0100
http://bitbucket.org/pypy/pypy/changeset/ddbc82ef4d8f/
Log: Test and fix: instead of using a custom __setattr__ handler (and no
__getattr__, creating confusion), create a bunch of properties.
diff --git a/pypy/module/pyexpat/interp_pyexpat.py
b/pypy/module/pyexpat/interp_pyexpat.py
--- a/pypy/module/pyexpat/interp_pyexpat.py
+++ b/pypy/module/pyexpat/interp_pyexpat.py
@@ -3,9 +3,7 @@
from pypy.interpreter.gateway import NoneNotWrapped
from pypy.interpreter.gateway import interp2app, unwrap_spec
from pypy.interpreter.error import OperationError
-from pypy.objspace.descroperation import object_setattr
from pypy.rlib import rgc
-from pypy.rlib.unroll import unrolling_iterable
from pypy.rpython.lltypesystem import rffi, lltype
from pypy.rpython.tool import rffi_platform
from pypy.translator.tool.cbuild import ExternalCompilationInfo
@@ -339,8 +337,6 @@
'XML_SetUnknownEncodingHandler',
[XML_Parser, callback_type, rffi.VOIDP], lltype.Void)
-ENUMERATE_SETTERS = unrolling_iterable(SETTERS.items())
-
# Declarations of external functions
XML_ParserCreate = expat_external(
@@ -545,15 +541,19 @@
self.buffer_used = 0
return False
+ def gethandler(self, space, name, index):
+ if name == 'CharacterDataHandler':
+ return self.w_character_data_handler or space.w_None
+ return self.handlers[index]
+
def sethandler(self, space, name, w_handler, index, setter, handler):
-
if name == 'CharacterDataHandler':
self.flush_character_buffer(space)
if space.is_w(w_handler, space.w_None):
self.w_character_data_handler = None
else:
self.w_character_data_handler = w_handler
-
+ #
self.handlers[index] = w_handler
setter(self.itself, handler)
@@ -580,21 +580,29 @@
return True
- @unwrap_spec(name=str)
- def setattr(self, space, name, w_value):
- if name == "namespace_prefixes":
- XML_SetReturnNSTriplet(self.itself, space.int_w(w_value))
- return
+ @staticmethod
+ def _make_property(name):
+ index, setter, handler = SETTERS[name]
+ #
+ def descr_get_property(self, space):
+ return self.gethandler(space, name, index)
+ #
+ def descr_set_property(self, space, w_value):
+ return self.sethandler(space, name, w_value,
+ index, setter, handler)
+ #
+ return GetSetProperty(descr_get_property,
+ descr_set_property,
+ cls=W_XMLParserType)
- for handler_name, (index, setter, handler) in ENUMERATE_SETTERS:
- if name == handler_name:
- return self.sethandler(space, handler_name, w_value,
- index, setter, handler)
- # fallback to object.__setattr__()
- return space.call_function(
- object_setattr(space),
- space.wrap(self), space.wrap(name), w_value)
+ def get_namespace_prefixes(self, space):
+ raise OperationError(space.w_AttributeError,
+ space.wrap("not implemented: reading namespace_prefixes"))
+
+ @unwrap_spec(value=int)
+ def set_namespace_prefixes(self, space, value):
+ XML_SetReturnNSTriplet(self.itself, bool(value))
# Parse methods
@@ -732,10 +740,18 @@
if XML_COMBINED_VERSION >= 19505:
XMLParser_methods.append('UseForeignDTD')
+_XMLParser_extras = {}
+for name in XMLParser_methods:
+ _XMLParser_extras[name] = interp2app(getattr(W_XMLParserType, name))
+for name in SETTERS:
+ _XMLParser_extras[name] = W_XMLParserType._make_property(name)
+
W_XMLParserType.typedef = TypeDef(
"pyexpat.XMLParserType",
__doc__ = "XML parser",
- __setattr__ = interp2app(W_XMLParserType.setattr),
+ namespace_prefixes = GetSetProperty(W_XMLParserType.get_namespace_prefixes,
+ W_XMLParserType.set_namespace_prefixes,
+ cls=W_XMLParserType),
returns_unicode = bool_property('returns_unicode', W_XMLParserType),
ordered_attributes = bool_property('ordered_attributes', W_XMLParserType),
specified_attributes = bool_property('specified_attributes',
W_XMLParserType),
@@ -754,8 +770,7 @@
CurrentColumnNumber =
GetSetProperty(W_XMLParserType.descr_ErrorColumnNumber, cls=W_XMLParserType),
CurrentByteIndex = GetSetProperty(W_XMLParserType.descr_ErrorByteIndex,
cls=W_XMLParserType),
- **dict((name, interp2app(getattr(W_XMLParserType, name)))
- for name in XMLParser_methods)
+ **_XMLParser_extras
)
def ParserCreate(space, w_encoding=None, w_namespace_separator=None,
diff --git a/pypy/module/pyexpat/test/test_parser.py
b/pypy/module/pyexpat/test/test_parser.py
--- a/pypy/module/pyexpat/test/test_parser.py
+++ b/pypy/module/pyexpat/test/test_parser.py
@@ -52,6 +52,19 @@
assert res == 1
assert data == [u"\u00f6"]
+ def test_get_handler(self):
+ import pyexpat
+ p = pyexpat.ParserCreate()
+ assert p.StartElementHandler is None
+ assert p.EndElementHandler is None
+ def f(*args): pass
+ p.StartElementHandler = f
+ assert p.StartElementHandler is f
+ def g(*args): pass
+ p.EndElementHandler = g
+ assert p.StartElementHandler is f
+ assert p.EndElementHandler is g
+
def test_intern(self):
import pyexpat
p = pyexpat.ParserCreate()
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit