3

Python has the ability to create a namespace packages. How do you get a list of installed packages under a namespace?

i.e. something like:

import namespace_package
dir(namespace_pageage)
shuttle87
  • 15,466
  • 11
  • 77
  • 106
MinchinWeb
  • 631
  • 1
  • 9
  • 18

2 Answers2

5

From the Python Packaging User Guide:

import pkgutil

list(
    pkgutil.iter_modules(
        namespace_package.__path__,
        namespace_package.__name__ + "."
    )
)

Note that this will not return (sub-)namespace packages within the main namespace package (i.e. if you have nested namespace packages).

MinchinWeb
  • 631
  • 1
  • 9
  • 18
  • 1
    Mhhh, any idea how to solve this for nested namespace packages as well? I guess one could cook up some self made thing with iterating over the list of paths of the namespace package and recurse into subnamespace packages ... But if there is a ready thing in `pkgutil` it would be much cleaner :) – Marti Nito Dec 09 '20 at 11:17
-1

You can use the find_packages function from setuptools. This function is often used in setup.py files but you can use it for other purposes too.

# find the folder of the package
from pathlib import Path
package_root_folder = Path(namespace_package.__file__).parent

# for that folder, detect all Python packages inside
from setuptools import find_packages
all_packages = find_packages(str(package_root_folder))
florisla
  • 12,668
  • 6
  • 40
  • 47
  • 1
    This doesn't seem to work on pure namespace projects. `namespace_project.__file__ is None` returns `True` – MinchinWeb Sep 10 '19 at 14:53
  • What do you mean by 'pure namespace projects'? You do need to have an `__init__.py` file in there, and then `namespace_package.__file__` is definitely not `None`. – florisla Sep 12 '19 at 11:01
  • 2
    Namespace packages **do not** require a `__init__.py` file, as they can group together subpackages from multiple points in the filesystem. [PEP420](https://packaging.python.org/guides/packaging-namespace-packages/#native-namespace-packages) calls them *Implicit Namespace Packages* and [Python packaging guide](https://packaging.python.org/guides/packaging-namespace-packages/#native-namespace-packages) calls them *Native namespace packages*. – MinchinWeb Sep 16 '19 at 22:25
  • Setuptools provides another method called `find_namespace_packages` that one might leverage. I'm not sure under which revision this became accessible. – Carel Apr 17 '20 at 22:56
  • @florisla indeed, pep420 states "Namespace packages cannot contain `__init__.py`" and from experience you can get in a real mess if you add one in. – Philip Couling Dec 29 '22 at 01:12