Issue2510

classification
Title: TypeError when monkey-patching time.time with an unbound function
Type: Severity: normal
Components: Jythonc compiler Versions: Jython 2.7
Milestone: Jython 2.7.2
process
Status: open Resolution: remind
Dependencies: Superseder:
Assigned To: Nosy List: progval, zyasoft
Priority: Keywords:

Created on 2016-07-30.09:13:14 by progval, last changed 2017-09-10.04:28:43 by zyasoft.

Messages
msg10883 (view) Author: (progval) Date: 2016-07-30.09:13:13
Hi,

I run the following script:

import time
def fake_time():
    return 42

time.time = fake_time
print(time.time())


With CPython and Pypy, it print 42. With Jython 2.7.1b3, I get this:

Traceback (most recent call last):
  File "foo.py", line 6, in <module>
    print(time.time())
TypeError: unbound method fake_time() must be called with time instance as first argument (got nothing instead)
msg11574 (view) Author: Jim Baker (zyasoft) Date: 2017-09-06.19:12:56
The time module is implemented in Java, and it uses a old Jython scheme for registering functions. This may be causing the issue here; regardless, we should update this registration.
msg11585 (view) Author: Jim Baker (zyasoft) Date: 2017-09-10.02:59:39
So this seems to be a general problem in how we dispatch to a wide range of built-in functions. But in particular it does NOT apply to implementations that use PyBuiltinFunctionNarrow.

This can be seen in the os module, where the underlying implementation of PosixModule uses PyBuiltinFunctionNarrow for some functions, but not for others. In particular, one much like time.time that might be useful for monkey-patching/mocking is os.urandom, which cannot be so used. (At least without using functools.partial(my_urandom, os), but that's only needed for Jython.)
msg11586 (view) Author: Jim Baker (zyasoft) Date: 2017-09-10.04:28:43
I revisited PosixModule, and I believe I characterized that incorrectly with respect to os.urandom. In general, the technique used by the os module to import from a backing implementation (in this case Java-based, using ClassDictInit) seems to remove this PyMethod distinction. In particular, it can be readily done by renaming org.python.modules.time to org.python.modules._time, then adding a Lib/time.py that

from _time import *

which simply demonstrates that Python import semantics work as expected at this point.

So as with the time module, we may have other cases of unpatchable functions in other parts of the stdlib implemented by org.python.modules, but this can be readily resolved  at least two different ways.
History
Date User Action Args
2017-09-10 04:28:43zyasoftsetmessages: + msg11586
2017-09-10 02:59:40zyasoftsetmessages: + msg11585
2017-09-06 19:12:56zyasoftsetmessages: + msg11574
2017-06-23 16:56:35zyasoftsetnosy: + zyasoft
2017-06-23 16:56:29zyasoftsetresolution: remind
2016-09-14 16:19:21zyasoftsettitle: Crash after monkey-patching time.time with an unbound function -> TypeError when monkey-patching time.time with an unbound function
2016-09-14 16:18:17zyasoftsetmilestone: Jython 2.7.2
2016-07-30 09:13:14progvalcreate