July 2018 Update

Most people should now use pip install setuptools (possibly with sudo).

Some may need to (re)install the python-setuptools package via their package manager (apt-get install, yum install, etc.).

This issue can be highly dependent on your OS and dev environment. See the legacy/other answers below if the above isn't working for you.

Explanation

This error message is caused by a missing/broken Python setuptools package. Per Matt M.'s comment and setuptools issue #581, the bootstrap script referred to below is no longer the recommended installation method.

The bootstrap script instructions will remain below, in case it's still helpful to anyone.

Legacy Answer

I encountered the same ImportError today while trying to use pip. Somehow the setuptools package had been deleted in my Python environment.

To fix the issue, run the setup script for setuptools:

wget https://bootstrap.pypa.io/ez_setup.py -O - | python

(or if you don't have wget installed (e.g. OS X), try

curl https://bootstrap.pypa.io/ez_setup.py | python

possibly with sudo prepended.)

If you have any version of distribute, or any setuptools below 0.6, you will have to uninstall it first.*

See Installation Instructions for further details.


* If you already have a working distribute, upgrading it to the "compatibility wrapper" that switches you over to setuptools is easier. But if things are already broken, don't try that.

Answer from cwc on Stack Overflow
Top answer
1 of 16
982

July 2018 Update

Most people should now use pip install setuptools (possibly with sudo).

Some may need to (re)install the python-setuptools package via their package manager (apt-get install, yum install, etc.).

This issue can be highly dependent on your OS and dev environment. See the legacy/other answers below if the above isn't working for you.

Explanation

This error message is caused by a missing/broken Python setuptools package. Per Matt M.'s comment and setuptools issue #581, the bootstrap script referred to below is no longer the recommended installation method.

The bootstrap script instructions will remain below, in case it's still helpful to anyone.

Legacy Answer

I encountered the same ImportError today while trying to use pip. Somehow the setuptools package had been deleted in my Python environment.

To fix the issue, run the setup script for setuptools:

wget https://bootstrap.pypa.io/ez_setup.py -O - | python

(or if you don't have wget installed (e.g. OS X), try

curl https://bootstrap.pypa.io/ez_setup.py | python

possibly with sudo prepended.)

If you have any version of distribute, or any setuptools below 0.6, you will have to uninstall it first.*

See Installation Instructions for further details.


* If you already have a working distribute, upgrading it to the "compatibility wrapper" that switches you over to setuptools is easier. But if things are already broken, don't try that.

2 of 16
153
sudo apt-get install --reinstall python-pkg-resources

fixed it for me in Debian. Seems like uninstalling some .deb packages (twisted set in my case) has broken the path python uses to find packages

🌐
ProgramCreek
programcreek.com › python › example › 32721 › pkg_resources.load_entry_point
Python Examples of pkg_resources.load_entry_point
def invoke_tool(self, cmd_line): # capture io stdout_buffer = io.StringIO() stderr_buffer = io.StringIO() old_stdout = sys.stdout old_stderr = sys.stderr sys.stdout = stdout_buffer sys.stderr = stderr_buffer args = shlex.split(cmd_line) v = pkg_resources.load_entry_point('inkfish', 'console_scripts', args[0])(args) sys.stdout = old_stdout sys.stderr = old_stderr return v, stdout_buffer.getvalue(), stderr_buffer.getvalue()
Discussions

python - How to dynamically add and load entry points? - Stack Overflow
I needed to do something similar to load a dummy plugin for test purposes. This differs slightly from your use-case in that I was specifically trying to avoid needing to define the entry points in the package (as it is just test code). I found I could dynamically insert entries into the pkg_resources ... More on stackoverflow.com
🌐 stackoverflow.com
installation error: `from pkg_resources import load_entry_point` fails
sudo pip install clf Password: Downloading/unpacking clf Downloading clf-0.4.tar.gz Running setup.py (path:/private/tmp/pip_build_root/clf/setup.py) egg_info for package clf Downloading/unpacking P... More on github.com
🌐 github.com
2
March 12, 2015
setuptools - Explain Python entry points? - Stack Overflow
It found the entry point, imported ... there, upon call to pkg_resources.load(). ... Thus, while perhaps a bit difficult to grasp at first, the entry point mechanism is actually quite simple to use. It provides an useful tool for pluggable Python software developme... More on stackoverflow.com
🌐 stackoverflow.com
use pkg_resources on each located package to find its entry points
There was an error while loading. Please reload this page. ... Use pkg_resources on each located package in the Analysis step to find its entry points and make sure those modules are collected. More on github.com
🌐 github.com
7
February 6, 2015
🌐
Bobby Hadz
bobbyhadz.com › blog › python-no-module-named-pkg-resources
No module named 'pkg_resources' in Python [Solved] | bobbyhadz
Copied!Traceback (most recent call last): File "/var/www/bin/pip", line, in <module> from pkg_resources import load_entry_point ImportError: No module named pkg_resources · Open your terminal and run the following command to install setuptools. ... If you get an error that pip is not in your PATH environment variable, try running the following commands instead. ... Copied!# python2 and Windows python -m pip install --upgrade setuptools # for Python3 on macOS or Linux python3 -m pip install --upgrade setuptools # 👇️ using an alias on Windows py -m pip install --upgrade setuptools
🌐
Readthedocs
jmchilton-galaxy.readthedocs.io › en › latest › lib › pkg_resources.html
pkg_resources Module — Galaxy Code documentation
This method returns a 2-tuple: (distributions, error_info), where distributions is a list of the distributions found in plugin_env that were loadable, along with any other distributions that are needed to resolve their dependencies. error_info is a dictionary mapping unloadable plugin distributions to an exception instance describing the error that occurred. Usually this will be a DistributionNotFound or VersionConflict instance. ... If name is None, yields all entry points in group from all distributions in the working set, otherwise only ones matching both group and name are yielded (in distribution order).
Top answer
1 of 3
14

I needed to do something similar to load a dummy plugin for test purposes. This differs slightly from your use-case in that I was specifically trying to avoid needing to define the entry points in the package (as it is just test code).

I found I could dynamically insert entries into the pkg_resources data structures as follows:

import pkg_resources
# Create the fake entry point definition
ep = pkg_resources.EntryPoint.parse('dummy = dummy_module:DummyPlugin')

# Create a fake distribution to insert into the global working_set
d = pkg_resources.Distribution()

# Add the mapping to the fake EntryPoint
d._ep_map = {'namespace': {'dummy': ep}}

# Add the fake distribution to the global working_set
pkg_resources.working_set.add(d, 'dummy')

This, at run time, added an entry point called 'dummy' to 'namespace', which would be the class 'DummyPlugin' in 'dummy_module.py'.

This was determined through use of the setuptools docs, and dir() on the objects to get more info as needed.

Docs are here: http://setuptools.readthedocs.io/en/latest/pkg_resources.html

You might especially look at http://setuptools.readthedocs.io/en/latest/pkg_resources.html#locating-plugins if all you need to do is load a plugin that you have just stored to your local filesystem.

2 of 3
3

It's more than at least 5 years, since the time when I first asked myself almost the same question, and your question now is an impulse to finally find it out.

For me it was as well interesting, if one can add entry points from the same directory as the script without installation of a package. Though I always knew that the only contents of the package might be some meta with entry points looking at some other packages.

Anyway, here is some setup of my directory:

ep_test newtover$ tree
.
├── foo-0.1.0.dist-info
│   ├── METADATA
│   └── entry_points.txt
└── foo.py

1 directory, 3 files

Here is the contents of foo.py:

ep_test newtover$ cat foo.py
def foo1():
    print 'foo1'

def foo2():
    print 'foo2'

Now let's open ipython:

In [1]: def write_ep(lines):  # a helper to update entry points file
   ...:     with open('foo-0.1.0.dist-info/entry_points.txt', 'w') as f1:
   ...:         print >> f1, '\n'.join(lines)
   ...:        

In [2]: write_ep([  # only one entry point under foo.test
   ...: "[foo.test]",
   ...: "foo_1 = foo:foo1",
   ...: ])

In [3]: !cat foo-0.1.0.dist-info/entry_points.txt
[foo.test]
foo1 = foo:foo1

In [4]: import pkg_resources

In [5]: ws = pkg_resources.WorkingSet()  # here is the answer on the question

In [6]: list(ws.iter_entry_points('foo.test'))
Out[6]: [EntryPoint.parse('foo_1 = foo:foo1')]

In [7]: write_ep([  # two entry points
   ...: "[foo.test]",
   ...: "foo_1 = foo:foo1",
   ...: "foo_2 = foo:foo2"
   ...: ])

In [8]: ws = pkg_resources.WorkingSet()  # a new instance of WorkingSet

With default parameters WorkingSet just revisits each entry in sys.path, but you can narrow the list. pkg_resources.iter_entry_points is bound to a global instance of WorkingSet.

In [9]: list(ws.iter_entry_points('foo.test'))  # both are visible
Out[9]: [EntryPoint.parse('foo_1 = foo:foo1'), EntryPoint.parse('foo_2 = foo:foo2')]

In [10]: foos = [ep.load() for ep in ws.iter_entry_points('foo.test')]

In [11]: for func in foos: print 'name is {}'.format(func.__name__); func()
name is foo1
foo1
name is foo2
foo2

And the contents of METADATA as well:

ep_test newtover$ cat foo-0.1.0.dist-info/METADATA
Metadata-Version: 1.2
Name: foo
Version: 0.1.0
Summary: entry point test

UPD1: I thought it over once again and now understand that you need an additional step before using the new plugins: you need to reload the modules.

This might be as easy as:

In [33]: modules_to_reload = {ep1.module_name for ep1 in ws.iter_entry_points('foo.test')}

In [34]: for module_name in modules_to_reload:
   ....:     reload(__import__(module_name))
   ....:

But if a new version of your plugins package is based on significant changes in other used modules, you might need a particular order of reloading and reloading of those changed modules. This might become a cumbersome task, so that restarting the bot would be the only way to go.

🌐
Python
svn.python.org › projects › sandbox › trunk › setuptools › pkg_resources.txt
pkg_resources.txt
April 30, 2007 - Most applications will use this method mainly on the master ``working_set`` instance in ``pkg_resources``, and then immediately add the returned distributions to the working set so that they are available on sys.path. This will make it possible to find any entry points, and allow any other metadata tracking and hooks to be activated.
🌐
Python
svn.python.org › projects › sandbox › branches › setuptools-0.6 › pkg_resources.py
pkg_resources.py
""" plat = get_build_platform(); ... pass # not Mac OS X return plat __all__ = [ # Basic resource access and distribution/entry point discovery 'require', 'run_script', 'get_provider', 'get_distribution', 'load_entry_point', 'get_entry_map', 'get_entry_info', ...
Find elsewhere
🌐
GitHub
github.com › pypa › setuptools › issues › 510
Avoid full path enumeration on import of setuptools or pkg_resources? · Issue #510 · pypa/setuptools
At the moment on my machine, it takes about 1.28 seconds to do a bare import pkg_resources, 1.47 seconds to do a bare import setuptools, 1.36 seconds to do a bare from pkg_resources import load_entry_point and 1.25 seconds to do a bare from pkg_resources import load_entry_point. This obviously affects all of the python scripts that are installed as console entry points, because each and every one of them starts with a line like that.
Author: pypa
🌐
GitHub
github.com › takluyver › entrypoints
GitHub - takluyver/entrypoints: Discover and load entry points from installed packages · GitHub
The entrypoints module contains functions to find and load entry points. You can install it from PyPI with pip install entrypoints. To advertise entry points when distributing a package, see entry_points in the Python Packaging User Guide.
Author: takluyver
🌐
GitHub
github.com › ncrocfer › clf › issues › 1
installation error: `from pkg_resources import load_entry_point` fails · Issue #1 · ncrocfer/clf
March 12, 2015 - $ clf Traceback (most recent call last): File "/usr/local/bin/clf", line 5, in <module> from pkg_resources import load_entry_point File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/pkg_resources.py", line 2603, in <module> working_set.require(__requires__) File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/pkg_resources.py", line 666, in require needed = self.resolve(parse_requirements(requirements)) File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/pkg_resources.py", line 565, in resolve raise DistributionNotFound(req) # XXX put more info here pkg_resources.DistributionNotFound: requests==2.5.3 ·
Author: ncrocfer
Top answer
1 of 3
297

An "entry point" is typically a function (or other callable function-like object) that a developer or user of your Python package might want to use, though a non-callable object can be supplied as an entry point as well (as correctly pointed out in the comments!).

The most popular kind of entry point is the console_scripts entry point, which points to a function that you want made available as a command-line tool to whoever installs your package. This goes into your setup.py script like:

entry_points={
    'console_scripts': [
        'cursive = cursive.tools.cmd:cursive_command',
    ],
},

I have a package I've just deployed called cursive.tools, and I wanted it to make available a "cursive" command that someone could run from the command line, like:

$ cursive --help
usage: cursive ...

The way to do this is define a function, like maybe a cursive_command function in the file cursive/tools/cmd.py that looks like:

def cursive_command():
    args = sys.argv[1:]
    if len(args) < 1:
        print "usage: ..."

and so forth; it should assume that it's been called from the command line, parse the arguments that the user has provided, and ... well, do whatever the command is designed to do.

Install the docutils package for a great example of entry-point use: it will install something like a half-dozen useful commands for converting Python documentation to other formats.

2 of 3
234

EntryPoints provide a persistent, filesystem-based object name registration and name-based direct object import mechanism (implemented by the setuptools package).

They associate names of Python objects with free-form identifiers. So any other code using the same Python installation and knowing the identifier can access an object with the associated name, no matter where the object is defined. The associated names can be any names existing in a Python module; for example name of a class, function or variable. The entry point mechanism does not care what the name refers to, as long as it is importable.

As an example, let's use (the name of) a function, and an imaginary python module with a fully-qualified name 'myns.mypkg.mymodule':

def the_function():
   "function whose name is 'the_function', in 'mymodule' module"
   print "hello from the_function"

Entry points are registered via an entry points declaration in setup.py. To register the_function under entrypoint called 'my_ep_func':

    entry_points = {
        'my_ep_group_id': [
            'my_ep_func = myns.mypkg.mymodule:the_function'
        ]
    },

As the example shows, entry points are grouped; there's corresponding API to look up all entry points belonging to a group (example below).

Upon a package installation (ie. running 'python setup.py install'), the above declaration is parsed by setuptools. It then writes the parsed information in special file. After that, the pkg_resources API (part of setuptools) can be used to look up the entry point and access the object(s) with the associated name(s):

import pkg_resources

named_objects = {}
for ep in pkg_resources.iter_entry_points(group='my_ep_group_id'):
   named_objects.update({ep.name: ep.load()})

Here, setuptools read the entry point information that was written in special files. It found the entry point, imported the module (myns.mypkg.mymodule), and retrieved the_function defined there, upon call to pkg_resources.load().

Calling the_function would then be simple:

>>> named_objects'my_ep_func'
hello from the_function

Thus, while perhaps a bit difficult to grasp at first, the entry point mechanism is actually quite simple to use. It provides an useful tool for pluggable Python software development.

🌐
Pylonsproject
docs.pylonsproject.org › projects › pylons-webframework › en › latest › advanced_pylons › entry_points_and_plugins.html
Using Entry Points to Write Plugins — Pylons Framework 1.0.2 documentation
For example: by distribution name and version requirement (such as ImagePlugins>=1.0) or by the entry point group and name (eg jpg_image). For this example we are choosing the latter, here is a simple script for loading the plugins: from pkg_resources import iter_entry_points for entry_point in iter_entry_points(group='cms.plugin', name=None): print(entry_point) from pkg_resources import iter_entry_points available_methods = [] for entry_point in iter_entry_points(group='authkit.method', name=None): available_methods.append(entry_point.load())
🌐
Ask Ubuntu
askubuntu.com › questions › 1245992 › pip3-import-error-cannot-import-name-load-entry-point-from-pkg-resources-un
virtualbox - PIP3 import error cannot import name 'load_entry_point' from 'pkg_resources' (unknown location) - Ask Ubuntu
$ sudo add-apt-repository universe $ sudo apt install python3-pip · The commands run perfectly well with no error. However when i do below to check pip version: $ pip3 -v · It gives error import error: cannot import name 'load_entry_point' from 'pkg_resources' System: Virtual box version 6.1.2, OS: Ubuntu version 20.04, Python version 3.8.2 ·
🌐
GitHub
github.com › pyinstaller › pyinstaller › issues › 1188
use pkg_resources on each located package to find its entry points · Issue #1188 · pyinstaller/pyinstaller
February 6, 2015 - As described here Use pkg_resources on each located package in the Analysis step to find its entry points and make sure those modules are collected. This approach would work for any module that uses entry_points for anything, and will in...
Author: pyinstaller
🌐
GitHub
github.com › catkin › catkin_tools › issues › 297
pkg_resources.entry_points is really slow · Issue #297 · catkin/catkin_tools
February 17, 2016 - On my 2.9Ghz i7 with an EVO850 SSD running Ubuntu 12.04: $ time python -c 'from pkg_resources import load_entry_point' python -c 'from pkg_resources import load_entry_point' 0.14s u...
Author: catkin
🌐
EasyAsLinux
easyaslinux.com › home › fix for ‘importerror: no module named pkg_resources’ error
Fix for 'ImportError: No module named pkg_resources' error » Easy as Linux
March 26, 2019 - This error message means Python setuptools is missing or broken. $sudo pip2.7 Traceback (most recent call last): File "/usr/bin/pip2.7", line 6, in from pkg_resources import load_entry_point ImportError: No module named pkg_resources #Fix1: Just re-install the Python setuptools to fix the […]
🌐
Readthedocs
entrypoints.readthedocs.io
entrypoints 0.4 — entrypoints 0.4 documentation
The entrypoints module contains functions to find and load entry points. You can install it from PyPI with pip install entrypoints. To advertise entry points when distributing a package, see entry_points in the Python Packaging User Guide. The pkg_resources module distributed with setuptools ...
🌐
Rachum
amir.rachum.com › amir rachum's blog › python entry points explained
Python Entry Points Explained - Amir Rachum's
July 28, 2017 - --- a/snek.py +++ b/snek.py @@ -31,10 +31,7 @@ fancy_snek = """\ """ def get_sneks(): - sneks = { - 'normal': normal_snek, - 'fancy': fancy_snek, - } + sneks = {} for entry_point in pkg_resources.iter_entry_points('snek_types'): sneks[entry_point.name] = entry_point.load() return sneks · And, instead, registered them like any other snek: --- a/setup.py +++ b/setup.py @@ -6,5 +6,9 @@ setup( 'console_scripts': [ 'snek = snek:main', ], + 'snek_types': [ + 'normal = snek:normal_snek', + 'fancy = snek:fancy_snek', + ], }, ) Now, you need to re-install snek for the new entry points to take: $ pytho