Enforce explicit exports in code modules
- Usage of Python for general-purpose programming and scripting
- Usage of my_module for custom functionality or feature implementation
Non compliant code
from .my_module import *
In the above code snippet, the developer uses the wildcard operator (*) to import all functions from the
my_module.py file into the
__init__.py file. This is done in the line
from .my_module import *.
Using the wildcard operator in this way is known as a wildcard import. It's a convenient way to import all functions, classes, and variables from a module without having to specify them individually. However, this practice can lead to problems.
Firstly, it can make the code harder to understand and maintain. If there are many functions in
my_module.py, it's not immediately clear which ones are being used in
__init__.py. A developer would have to open
my_module.py and look through all the functions to figure this out.
Secondly, it can lead to namespace conflicts. If
__init__.py both have a function with the same name, the one in
__init__.py will be overwritten by the one in
my_module.py. This can lead to unexpected behavior and bugs that are hard to track down.
Lastly, it can make the code less efficient. If
my_module.py has many functions but only a few are used in
__init__.py, importing all of them wastes memory and slows down the program.
Therefore, it's recommended to avoid wildcard imports and instead import only the functions that are actually needed.
- Identify the specific functions that need to be exported from the module.
- Instead of using the wildcard operator (*), explicitly list out the functions to be exported in the import statement.
- This way, only the necessary functions are exposed, reducing the risk of misuse and making the module easier to maintain.
from .my_module import function_one, function_two
In the original code, the wildcard operator (*) was used to import all functions from
my_module. This is a bad practice as it exposes all functions, even those that are not necessary for the module's operation, which can lead to misuse and make the module harder to maintain.
In the fixed code, instead of using the wildcard operator, we explicitly list out the functions to be imported from
my_module in the import statement. Here, only
function_two are imported, and
function_three is not, as it's assumed not to be necessary for the module's operation.
This way, we are only exposing the necessary functions, reducing the risk of misuse and making the module easier to maintain. This is a better coding practice as it promotes clarity about which functions are being used and avoids potential naming conflicts.