three dots aka ellipsis in import statement before package name - python

I would like to know the purpose of a three-dots symbol aka ellipsis put before the package name in an import statement.
Examples:
sklearn/metrics/_plot/det_curve.py:
import scipy as sp
from .base import _get_response
from .. import det_curve
from .._base import _check_pos_label_consistency
from ...utils import check_matplotlib_support
or this Github issue, where they call it an "ellipsis import" and where the three dots are followed by a space:
from ... import MyContentContentType as __MyContentContentType__
from ... import MyDetectionDetectionGender as __MyDetectionDetectionGender__

Three dots is not the Ellipsis object.
According to the documentation, three dots in a relative import statement means "up two levels" (in other words, an equivalent for ../.. in shell):
7.11. The import statement
When specifying what module to import you do not have to specify the absolute name of the module. When a module or package is contained within another package it is possible to make a relative import within the same top package without having to mention the package name. By using leading dots in the specified module or package after from you can specify how high to traverse up the current package hierarchy without specifying exact names. One leading dot means the current package where the module making the import exists. Two dots means up one package level. Three dots is up two levels, etc. So if you execute from . import mod from a module in the pkg package then you will end up importing pkg.mod. If you execute from ..subpkg2 import mod from within pkg.subpkg1 you will import pkg.subpkg2.mod. The specification for relative imports is contained in the Package Relative Imports section.

Related

result of pycharm optimize imports

I used "code/optimize imports" in Pycharm and it resulted in this
import logging
import os
import re
import subprocess
from getpass import getpass
from pathlib import Path
import requests
import sys
import time
from bs4 import BeautifulSoup
why is it in this order? why is there a blank line?
Maybe it uses isort (https://pypi.org/project/isort/):
import is before from x import y
Than the imports are sorted alphabetically.
And lastly the imports are grouped by the type of the import. The blank line between your imports is the separator between Python Standard Library imports and Third Party imports.
isort parses specified files for global level import lines (imports
outside of try / except blocks, functions, etc..) and puts them all at
the top of the file grouped together by the type of import:
Future
Python Standard Library
Third Party
Current Python Project
Explicitly Local (. before import, as in: from . import x)
Custom Separate Sections (Defined by forced_separate list in configuration file)
Custom Sections (Defined by sections list in configuration file)
Inside of each section the imports are sorted alphabetically. isort
automatically removes duplicate python imports, and wraps long from
imports to the specified line length (defaults to 79).
Edit:
Group imports by type is recommended also in PEP8 (https://www.python.org/dev/peps/pep-0008/#imports)

What does a dot denote in an import statement?

Could anyone please explains what from .object import object means?
I know that everything extends object just like in Java.But what does .object means?
I saw this piece of code in the source code in psycopg2:
from .object import object
class cursor(object):
pass
That's the new syntax for explicit relative imports. It means import from the current package.
Without the ., if you had a file _object.py for some indecipherable reason next to your main script, object would break. With the ., it ensures it gets its own module.
The thing that defines what a "current package" is that it should say from where the importing package is. It basically means the current namespace or package directory.
Hope this helps!
From the docs:
One leading dot means the current package where the module making the import exists. Two dots means up one package level. Three dots is up two levels, etc. So if you execute from . import mod from a module in the pkg package then you will end up importing pkg.mod. If you execute from ..subpkg2 import mod from within pkg.subpkg1 you will import pkg.subpkg2.mod. The specification for relative imports is contained within PEP 328.
The dot is basically telling the program to search in the current directory before looking at the files in your python path. If object exists in both the current directory and your python path, only the one from the former will be imported.

PyCharm doesn't recognize imports for py files in the same directory with python3.7 interpreter [duplicate]

I don't understand the following from pep-0404
In Python 3, implicit relative imports within packages are no longer
available - only absolute imports and explicit relative imports are
supported. In addition, star imports (e.g. from x import *) are only
permitted in module level code.
What is a relative import?
In what other places star import was allowed in python2?
Please explain with examples.
Relative import happens whenever you are importing a package relative to the current script/package.
Consider the following tree for example:
mypkg
├── base.py
└── derived.py
Now, your derived.py requires something from base.py. In Python 2, you could do it like this (in derived.py):
from base import BaseThing
Python 3 no longer supports that since it's not explicit whether you want the 'relative' or 'absolute' base. In other words, if there was a Python package named base installed in the system, you'd get the wrong one.
Instead it requires you to use explicit imports which explicitly specify location of a module on a path-alike basis. Your derived.py would look like:
from .base import BaseThing
The leading . says 'import base from module directory'; in other words, .base maps to ./base.py.
Similarly, there is .. prefix which goes up the directory hierarchy like ../ (with ..mod mapping to ../mod.py), and then ... which goes two levels up (../../mod.py) and so on.
Please however note that the relative paths listed above were relative to directory where current module (derived.py) resides in, not the current working directory.
#BrenBarn has already explained the star import case. For completeness, I will have to say the same ;).
For example, you need to use a few math functions but you use them only in a single function. In Python 2 you were permitted to be semi-lazy:
def sin_degrees(x):
from math import *
return sin(degrees(x))
Note that it already triggers a warning in Python 2:
a.py:1: SyntaxWarning: import * only allowed at module level
def sin_degrees(x):
In modern Python 2 code you should and in Python 3 you have to do either:
def sin_degrees(x):
from math import sin, degrees
return sin(degrees(x))
or:
from math import *
def sin_degrees(x):
return sin(degrees(x))
For relative imports see the documentation. A relative import is when you import from a module relative to that module's location, instead of absolutely from sys.path.
As for import *, Python 2 allowed star imports within functions, for instance:
>>> def f():
... from math import *
... print sqrt
A warning is issued for this in Python 2 (at least recent versions). In Python 3 it is no longer allowed and you can only do star imports at the top level of a module (not inside functions or classes).
To support both Python 2 and Python 3, use explicit relative imports as below. They are relative to the current module. They have been supported starting from 2.5.
from .sister import foo
from . import brother
from ..aunt import bar
from .. import uncle
Added another case to Michał Górny's answer:
Note that relative imports are based on the name of the current module. Since the name of the main module is always "__main__", modules intended for use as the main module of a Python application must always use absolute imports.

Python relative import with more than two dots

Is it ok to use a module referencing with more than two dots in a path? Like in this example:
# Project structure:
# sound
# __init__.py
# codecs
# __init__.py
# echo
# __init__.py
# nix
# __init__.py
# way1.py
# way2.py
# way2.py source code
from .way1 import echo_way1
from ...codecs import cool_codec
# Do something with echo_way1 and cool_codec.
UPD: Changed the example. And I know, this will work in a practice. But is it a common method of importing or not?
update Nov. 24,2020
If you wanna dig deeper in python's relative-import, I strongly recommend you this answer.
Is it ok to use a module referencing with more than two dots in a path?
Yes. You can use multiple dots in relative import path, but it is only feasible when using from xxx import yyy syntax, not import xxx syntax. Moreover, single dot, two dots and three dots mean current directory, parent directory and grandparent directory respectively, and so on.
And I know, this will work in a practice. But is it a common method of importing or not?
It depends. If your project has complex directory structure, using absolute import would be "disgusting". For example,
from sub1.sub2.sub3.sub4.sub5 import yourmethod
. In this case, using relative import will make your code clean and neat. Maybe look like
from ...sub5 import yourmethod
From PEP8:
Absolute imports are recommended, as they are usually more readable and tend to be better behaved (or at least give better error messages) if the import system is incorrectly configured (such as when a directory inside a package ends up on sys.path):
import mypkg.sibling
from mypkg import sibling
from mypkg.sibling import example
However, explicit relative imports are an acceptable alternative to absolute imports, especially when dealing with complex package layouts where using absolute imports would be unnecessarily verbose:
from . import sibling
from .sibling import example
Standard library code should avoid complex package layouts and always use absolute imports.

Import Python file from within executing script

I am attempting to import a python file(called test.py that resides in the parent directory) from within the currently executing python file(I'll call it a.py). All my directories involved have a file in it called init.py(with 2 underscores each side of init)
My Problem: When I attempt to import the desired file I get the following error
Attempted relative import in non-package
My code inside a.py:
try:
from .linkIO can_follow # error occurs here
except Exception,e:
print e
print success
Note: I know that if I were to create a file called b.py and import a.py(which in itself imports the desired python file) it all works, so whats going wrong?
For eg:
b.py:
import a
print "success 2"
As stated in PEP 328 all import must be absolute to prevent modules masking each other. Absolute means the module/package must be in the module-path sys.path. Relative imports (thats the dot for) are only allowed intra-packages wise, meaning if modules from the same package want to import each other.
So this leave you with following possibilities:
You make a package (which you seem to have made already) and add the package-path to sys. path
you just adjust sys.path for each module
you put all your custom modules into the same directory as the start-script/main-application
for 1. and 2. you may add a package/module to sys.path like this:
import sys
from os.path import dirname, join
sys.path.append(dirname(__file__)) #package-root-directory
or
module_dir = 'mymodules'
sys.path.append(join(dirname(__file__), module_dir)) # in the main-file
BTW:
from .linkIO can_follow
can't work! The import statement is missing!
As a reminder: if using relative imports you MUST use the from-version: from .relmodule import xyz. An import .XYZ without the from isn't allowed!

Categories

Resources