Saturday, March 5, 2022

Building packages

There are a number of techniques and tools available for creating and distributing packages. The truth is that Python does not have a great history of standardizing the packaging process. There have been multiple projects started in the first decade of the 21st century to streamline this process but not with a lot of success. In the last decade, we have had some success, thanks to the initiatives of the Python Packaging Authority (PyPA).

In this section, we will be covering techniques of building packages, accessing the packages in our program, and publishing and sharing the packages as per the guidelines provided by PyPA.

We will start with package names, followed by the use of an initialization file, and then jump into building a sample package.

Naming

Package names should follow the same rule for naming as for modules, which is lowercase with no underscores. Packages act like structured modules.

Package initialization file

A package can have an optional source file named __init__.py (or simply an init file). The presence of the init file (even a blank one) is recommended to mark folders as packages. Since Python release 3.3 or later, the use of an init file is optional (PEP 420:

Implicit Namespace Packages). There can be multiple purposes of using this init file and there is always a debate about what can go inside an init file versus what cannot go in.

A few uses of the init file are discussed here:

• Empty __init__.py: This will force developers to use explicit imports and manage the namespaces as they like. As expected, developers have to import separate modules, which can be tedious for a large package.

• Full import in __init__.py: In this case, developers can import the package and then refer to the modules directly in their code using the package name or its alias name. This provides more convenience but at the expense of maintaining the list of all imports in the __init__ file.

• Limited import: This is another approach in which the module developers can import only key functions in the init file from different modules and manage them under the package namespace. This provides the additional benefit of providing a wrapper around the underlying module's functionality. If by any chance we have to refactor the underlying modules, we have an option to keep the namespace the same, especially for API consumers. The only drawback of this approach is that it requires extra effort to manage and maintain such init files.

Sometimes, developers add code to the init file that is executed when a module is imported from a package. An example of such code is to create a session for remote systems such as a database or remote SSH server.

Share:

0 comments:

Post a Comment