Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does `__import__('pkg_resources').declare_namespace(__name__)` do?

In some __init__.py files of modules I saw such single line:

__import__('pkg_resources').declare_namespace(__name__) 

What does it do and why people use it? Suppose it's related to dynamic importing and creating namespace at runtime.

like image 392
rsk Avatar asked Oct 16 '11 17:10

rsk


People also ask

What is namespace package in Python?

In Python, a namespace package allows you to spread Python code among several projects. This is useful when you want to release related libraries as separate downloads.

How do you import a namespace in Python?

Importing is a way of pulling a name from somewhere else into the desired namespace. To refer to a variable, function, or class in Python one of the following must be true: The name is in the Python built-in namespace. The name is the current module's global namespace.

How do you create a namespace in Python?

Every package, module, class, function and method occupies a Python namespace in which variable names are set. A namespace gets created automatically when a module or package starts execution. Hence, create namespace in python, all you have to do is call a function/ object or import a module/package.


2 Answers

It boils down to two things:

  1. __import__ is a Python function that will import a package using a string as the name of the package. It returns a new object that represents the imported package. So foo = __import__('bar') will import a package named bar and store a reference to its objects in a local object variable foo.

  2. From setup utils pkg_resources' documentation, declare_namespace() "Declare[s] that the dotted package name name is a "namespace package" whose contained packages and modules may be spread across multiple distributions."

So __import__('pkg_resources').declare_namespace(__name__) will import the 'pkg_resources' package into a temporary and call the declare_namespace function stored in that temporary (the __import__ function is likely used rather than the import statement so that there is no extra symbol left over named pkg_resources). If this code were in my_namespace/__init__.py, then __name__ is my_namespace and this module will be included in the my_namespace namespace package.

See the setup tools documentation for more details

See this question for discussion on the older mechanism for achieving the same effect.

See PEP 420 for the standardized mechanism that provides similar functionality beginning with Python 3.3.

like image 148
Nathan Avatar answered Sep 20 '22 19:09

Nathan


This is a way to declare the so called "namespace packages" in Python.

What are these and what is the problem:

Imagine you distribute a software product which has a lot of functionality, and not all people want all of it, so you split it into pieces and ship as optional plugins.

You want people to be able to do

import your_project.plugins.plugin1 import your_project.plugins.plugin2 ... 

Which is fine if your directory structure is exactly as above, namely

your_project/     __init__.py     plugins/         __init__.py         plugin1.py         plugin2.py 

But what if you ship those two plugins as separate python packages so they are located in two different directories? Then you might want to put __import__('pkg_resources').declare_namespace(__name__) in each package's __init__.py so that Python knows those packages are part of a bigger "namespace package", in our case it's your_project.plugins.

Please refer to the documentation for more info.

like image 34
Ivan Ivanov Avatar answered Sep 20 '22 19:09

Ivan Ivanov