Re: [pypy-dev] die cpythonobject, die!
Cc:ing pypy-dev back in, assuming it's omission was just a slip... (also why I'm not snipping the quoted material). Richard Emslie <rxe@ukshells.co.uk> writes:
Hi Michael,
On Wed, 14 Jul 2004, Michael Hudson wrote:
This surprisingly brief patch removes all uses of W_CPythonObject (though not all uses of W_BuiltinFunctionObject), by using the 'automatically faking non re-implementations' technique I've talked about before.
Second guessing here, but I reckon that within
DescrOperation.get_and_call_args()
there is a comment "special-case Functions to avoid infinite recursion" that is the start of the problems.
Bingo! Thanks.
The above line instead of -
if type(descr) is Function:
could be replace with (I think 80%)
if hasattr(descr, "call_args"):
and then have a special case for faking SlotWrapperType s called fake_function() which looks something like
def fake_function(space, cpy_func): W_FakeFunction = fake_type(space, cpy_func) W_FakeFunction.__name__ = 'W_FakeFunction(%s)'%(cpy_func.__name__)
def call_args(self, args): try: unwrappedargs = [space.unwrap(w_arg) for w_arg in args.args_w] unwrappedkwds = dict([(key, space.unwrap(w_value)) for key, w_value in args.kwds_w.items()]) except UnwrapError, e: raise UnwrapError('calling %s: %s' % (cpy_func, e)) try: assert callable(self.val), self.val result = apply(self.val, unwrappedargs, unwrappedkwds) except: wrap_exception(space) return space.wrap(result) setattr(W_FakeFunction, "call_args", call_args) return W_FakeFunction
Don't know - it's very much guess work. Hope that helps - it works for me and might at least give you some idea how to solve.
Well, I think that could work but I'd prefer a solution with less special casing. How does CPython avoid the same problem? Cheers, mwh -- -Dr. Olin Shivers, Ph.D., Cranberry-Melon School of Cucumber Science -- seen in comp.lang.scheme
Michael Hudson <mwh@python.net> writes:
Well, I think that could work but I'd prefer a solution with less special casing.
How does CPython avoid the same problem?
Well, that's fairly easy. In PyPy almost every callable is a Function or Method, hence has a __get__:
types.MethodType.im_func.__get__.__get__.__get__.__get__.__get__.__get__ <method object at 0x4062ec8c>
Hum, not sure what to do about that... Cheers, mwh -- surely, somewhere, somehow, in the history of computing, at least one manual has been written that you could at least remotely attempt to consider possibly glancing at. -- Adam Rixey
We need a sprint! :-) Think I've exhausted my pypy hacking for the week... Well, i'm not sure if this is much better than the last hack, but at least no references to SlotWrapperType anymore... ;-) Instead of fake_function() as per last mail, add to the bottom of fake_type() similar to before, but only if our ctype has __call__. def fake_type(space, cpy_type): ... # return W_Fake if hasattr(cpy_type, "__call__"): def call_args(self, args): try: unwrappedargs = [space.unwrap(w_arg) for w_arg in args.args_w] unwrappedkwds = dict([(key, space.unwrap(w_value)) for key, w_value in args.kwds_w.items()]) except UnwrapError, e: raise UnwrapError('calling %s: %s' % (cpy_type, e)) try: assert callable(self.val), self.val result = apply(self.val, unwrappedargs, unwrappedkwds) except: wrap_exception(space) return space.wrap(result) setattr(W_Fake, "call_args", call_args) return W_Fake Will also need some mods to DescrOperation() def get_and_call_args(space, w_descr, w_obj, args): descr = space.unwrap_builtin(w_descr) if hasattr(descr, "call_args"): # special-case Functions to avoid infinite recursion ## XXX Tmp comment out ## if isinstance(descr.code, BuiltinCode): ## # this sub-special case is ONLY for performance reasons ## w_result = descr.code.performance_shortcut_call_meth(space, ## w_obj, args) ## if w_result is not None: ## return w_result return descr.call_args(args.prepend(w_obj)) else: w_impl = space.get(w_descr, w_obj) return space.call_args(w_impl, args) Cheers, Richard On Wed, 14 Jul 2004, Michael Hudson wrote:
Michael Hudson <mwh@python.net> writes:
Well, I think that could work but I'd prefer a solution with less special casing.
How does CPython avoid the same problem?
Well, that's fairly easy. In PyPy almost every callable is a Function or Method, hence has a __get__:
types.MethodType.im_func.__get__.__get__.__get__.__get__.__get__.__get__ <method object at 0x4062ec8c>
Hum, not sure what to do about that...
Cheers, mwh
-- surely, somewhere, somehow, in the history of computing, at least one manual has been written that you could at least remotely attempt to consider possibly glancing at. -- Adam Rixey
_______________________________________________ pypy-dev@codespeak.net http://codespeak.net/mailman/listinfo/pypy-dev
Richard Emslie <rxe@ukshells.co.uk> writes:
We need a sprint! :-) Think I've exhausted my pypy hacking for the week...
Well, i'm not sure if this is much better than the last hack, but at least no references to SlotWrapperType anymore... ;-)
Well, I've done something a bit different... it special cases slot wrappers again, which is a bit smelly, but I'm happier with this version: http://starship.python.net/crew/mwh/fakeit3.diff (also new in this version of the patch is actually getting rid CPythonObject and associated cruft). If there are no screams of protest, I'll probably check this in pretty soon. Cheers, mwh -- If design space weren't so vast, and the good solutions so small a portion of it, programming would be a lot easier. -- maney, comp.lang.python
participants (2)
-
Michael Hudson
-
Richard Emslie