Issue2654

classification
Title: Imported modules allow access to submodules
Type: behaviour Severity: normal
Components: Core Versions: Jython 2.7
Milestone: Jython 2.7.2
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: fwierzbicki, jamesmudd, jeff.allen
Priority: high Keywords:

Created on 2018-02-08.16:55:32 by jamesmudd, last changed 2018-02-27.22:34:42 by jeff.allen.

Messages
msg11701 (view) Author: James Mudd (jamesmudd) Date: 2018-02-08.16:55:30
If you have a python module eg.

test_mod/
├── hello.py      <<<<< Contains only foo = 4
└── __init__.py   <<<<< Contains only _version__ = '1.1.1'

If you import this in cpython you will not have access to hello e.g.
>>> import test_mod
>>> dir(test_mod)
['__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__', '__version__']
>>> test_mod.hello
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'hello'

Which is correct because you didn't import test_mode.hello and the __init__.py doesn't import it.

In Jython (master)

>>> import test_mod
>>> dir(test_mod)
['__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__', '__version__'] <<<<< Looks good at this point
>>> test_mod.hello
<module 'test_mod.hello' from '/scratch/test_mod/hello.py'> <<<<< This is wrong shouldn't be able to see hello
>>> test_mod.hello.foo
4
>>> dir(test_mod)
['__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__', '__version__', 'hello'] <<<<< And now its added  to the module

I think this happens because of a change made to fix #2455 which means if you lookup an attribute on a Pyhton module and don't find it try to import it. The bug described in that ticket is when you have a mixed Python/Java package. However i'm not sure it should have been fixed and now the behaviour is wrong for Python. To fix this I think the support for the mixed Python/Java package needs to be removed which I don't see as an issue.
msg11723 (view) Author: Jeff Allen (jeff.allen) Date: 2018-02-27.22:34:41
Oh great: automatic imports. This is better than plain old Python! But seriously ... I confirm the observation and agree this is incorrect behaviour.

PS issue2654> dir test_mod
...
-a----       27/02/2018     21:55            270 Bad.class
-a----       27/02/2018     21:50             69 Bad.java
-a----       27/02/2018     07:56             28 hello.py
-a----       27/02/2018     07:56             28 __init__.py

PS issue2654> jython
Jython 2.7.2a1+ (default:d74f8c2cd56f, Feb 24 2018, 17:18:53)
[Java HotSpot(TM) 64-Bit Server VM (Oracle Corporation)] on java1.8.0_151
Type "help", "copyright", "credits" or "license" for more information.
>>> import test_mod
Executed:  test_mod\__init__.py
>>> dir(test_mod)
['__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__']
>>> test_mod.Bad.x          ### This magical import we want (I think)
42
>>> dir(test_mod)
['Bad', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__']
>>> type(test_mod.hello)    ### This magical import is not Python :(
Executed:  test_mod\hello.py
<type 'module'>

It's not as bad as at first I thought. It would still have my vote to be fixed before 2.7.2 goes out.

The business of package/module import is difficult enough in plain Python. We add Java packages to the mix, which are syntactically similar and semantically different, so it is bound to be difficult. The first thing is to be clear what behaviour we want. The Jython Book has something useful to say here:
http://www.jython.org/jythonbook/en/1.0/ModulesPackages.html#sys-path
The word "disastrous" should give us pause.

On the other hand, the Java semantics are a lot like Python 3 namespace packages (PEP 420). There the first __init__.py still defines a regular package exclusively at that location.
History
Date User Action Args
2018-02-27 22:34:42jeff.allensetpriority: high
nosy: + jeff.allen, fwierzbicki
messages: + msg11723
2018-02-08 16:55:32jamesmuddcreate