New submission from Jason R. Coombs <jar...@jaraco.com>:

As discovered in https://github.com/pypa/packaging-problems/issues/212, if a 
PEP 420 namespace package is represented by an implicit directory (that is, 
there's no explicit entry for the directory, only entries for the contents of 
the directory), that directory won't be picked up as a namespace package. The 
following code illustrates the issue:

```
zp $ cat make-pkgs.py                                                           
                                                                                
               
import zipfile


def make_pkgs():
    zf = zipfile.ZipFile('simple.zip', 'w')
    zf.writestr('pkg/__init__.py', b'')
    zf.close()

    zf = zipfile.ZipFile('namespace.zip', 'w')
    zf.writestr('ns/pkg/__init__.py', b'')
    zf.close()


__name__ == '__main__' and make_pkgs()
zp $ python make-pkgs.py                                                        
                                                                                
               
zp $ env PYTHONPATH=simple.zip python3.7 -c "import pkg"                        
                                                                                
               
zp $ env PYTHONPATH=namespace.zip python3.7 -c "import ns.pkg"                  
                                                                                
               
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ModuleNotFoundError: No module named 'ns'
```

As you can see, in simple.zip, the `pkg` directory is implied, but despite that 
condition, `pkg` is importable.

However, with namespace.zip, the name `ns` is not visible even though it's 
present in the zipfile and would be importable if that zipfile were extracted 
to a file system.

```
zp $ unzip namespace.zip
Archive:  namespace.zip
 extracting: ns/pkg/__init__.py
zp $ python3.7 -c "import ns.pkg" && echo done
done
```

If you were to reconstruct that zip file on the file system using standard 
tools or explicitly include 'ns/' in the zip entries, the namespace package 
becomes visible:

```
zp $ rm namespace.zip                                                           
                                                                                
               
zp $ zip -r namespace.zip ns                                                    
                                                                                
               
  adding: ns/ (stored 0%)
  adding: ns/pkg/ (stored 0%)
  adding: ns/pkg/__init__.py (stored 0%)
  adding: ns/pkg/__pycache__/ (stored 0%)
  adding: ns/pkg/__pycache__/__init__.cpython-37.pyc (deflated 23%)
zp $ rm -r ns                                                                   
                                                                                
               
zp $ env PYTHONPATH=namespace.zip python3.7 -c "import ns.pkg" && echo done     
                                                                                
               
done
```

For consistency, the zip import logic should probably honor implicit 
directories in zip files.

----------
components: Library (Lib)
messages: 340975
nosy: jaraco
priority: normal
severity: normal
status: open
title: zipimporter misses namespace packages for implicit dirs
type: behavior

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue36740>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to