5.6. Replacing the standard import system 59 (continues on next page) The Python Language Reference, Release 3.9.5 5.5.2 Path entry finder protocol 5.6 Replacing the standard import system 5.7 Package Relative Imports Relative imports use leading dots. A single leading dot indicates a relative import, starting with the current package. Two or more leading dots indicate a relative import to the parent(s) of the current package, one level per dot after the first. For example, given the following package layout: package/ __init__ .py subpackage1 / __init__ .py moduleX.py moduleY.py subpackage2 / __init__ .py To selectively prevent the import of some modules from a hook early on the meta path (rather than disabling the standard import system entirely), it is sufficient to raise$_{ModuleNotFoundError}$ directly from$_{find_spec()}$ instead of returning$_{None}$ . The latter indicates that the meta path search should continue, while raising an exception terminates it immediately. If it is acceptable to only alter the behaviour of import statements without affecting other APIs that access the import system, then replacing the builtin$_{__import__()}$ function may be sufficient. This technique may also be employed at the module level to only alter the behaviour of import statements within that module. The most reliable mechanism for replacing the entire import system is to delete the default contents of sys. meta_path , replacing them entirely with a custom meta path hook. The$_{find_module()}$ method on path entry finders is deprecated, as it does not allow the path entry finder to contribute portions to namespace packages. If both$_{find_loader()}$ and$_{find_module()}$ exist on a path entry finder, the import system will always call$_{find_loader()}$ in preference to$_{find_module()}$ . For backwards compatibility with other implementations of the import protocol, many path entry finders also sup- port the same, traditional$_{find_module()}$ method that meta path finders support. However path entry finder find_module() methods are never called with a$_{path}$ argument (they are expected to record the appropriate path information from the initial call to the path hook). find_loader() takes one argument, the fully qualified name of the module being imported. find_loader() returns a 2-tuple where the first item is the loader and the second item is a namespace portion . Older path entry finders may implement one of these two deprecated methods instead of find_spec() . The methods are still respected for the sake of backward compatibility. However, if find_spec() is implemented on the path entry finder, the legacy methods are ignored. Changed in version 3.4: find_spec() replaced$_{find_loader()}$ and$_{find_module()}$ , both of which are now deprecated, but will be used if find_spec() is not defined. To indicate to the import machinery that the spec represents a namespace portion , the path entry finder sets “sub- module_search_locations” to a list containing the portion. find_spec() takes two arguments: the fully qualified name of the module being imported, and the (optional) target module. find_spec() returns a fully populated spec for the module. This spec will always have “loader” set (with one exception). In order to support imports of modules and initialized packages and also to contribute portions to namespace packages, path entry finders must implement the$_{find_spec()}$ method.