Issue2580

classification
Title: __pyclasspath__ can break inspect.getmodule
Type: behaviour Severity: normal
Components: Core Versions: Jython 2.7
Milestone:
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: stefan.richthofer
Priority: normal Keywords:

Created on 2017-04-25.13:48:36 by stefan.richthofer, last changed 2017-04-25.22:22:20 by stefan.richthofer.

Messages
msg11322 (view) Author: Stefan Richthofer (stefan.richthofer) Date: 2017-04-25.13:48:35
This issue has a somewhat common cause with #2579.
I stumbled over this while working on https://github.com/Stewori/pytypes where I need to find the function for a given code object, so first step is to identify the module. inspect.getmodule takes an optional _filename-parameter that can enhance performance.

Consider the following code in a file - let's call it test_cp.py - located not in . but let's say in ./folder. We have jython-standalone.jar located in .

import inspect, sys, os

def func1(a, b, c):
    pass

# some debug output:
print __name__
print __file__
print func1.__code__
print func1.__code__.co_filename

# the actual issue
print inspect.getmodule(func1.__code__) # works reliably
print inspect.getmodule(func1.__code__, func1.__code__.co_filename) # can break

If I call it using

java -cp .:jython-standalone.jar:folder org.python.util.jython -c "import test_cp"

the output is

__pyclasspath__/test_cp$py.class
<code object func1 at 0x2, file "__pyclasspath__/test_cp$py.class", line 3>
__pyclasspath__/test_cp$py.class
<module 'test_cp' from '__pyclasspath__/test_cp$py.class'>
None

As you can see, inspect.getmodule returns None in this case, if the _filename parameter is given. Note that everything works fine, if I directly call it using

java -cp .:jython-standalone.jar org.python.util.jython folder/test_cp.py
or
java -jar jython-standalone.jar folder/test_cp.py

In the problematic case, one can manually fix the _filename parameter via

cfname = func1.__code__.co_filename.replace('__pyclasspath__', os.path.realpath('')+os.sep+'__pyclasspath__')
cfname = cfname.replace('$py.class', '.py')

Then calling

print inspect.getmodule(func1.__code__, cfname)

will work as expected. However IMO Jython should do this adjustment under the hood. In a similar way, __pyclasspath__ causes #2579. I will reason about a common solution.

Also, I think Jython should feature an easily accessible utility method to resolve a path or filename containing __pyclasspath__ into an actual filename usable with open(), exists() etc. or suitable to pass it to other (non-Jython-aware) scripts or programs.
msg11324 (view) Author: Stefan Richthofer (stefan.richthofer) Date: 2017-04-25.22:22:20
Note that this issue only occurs (AFAICT) if a .class file for test_cp.py exists in folder, i.e. test_cp$py.class.
History
Date User Action Args
2017-04-25 22:22:20stefan.richthofersetmessages: + msg11324
2017-04-25 13:51:51stefan.richthofersetpriority: normal
type: behaviour
components: + Core
versions: + Jython 2.7
2017-04-25 13:48:36stefan.richthofercreate