Installing "dotenv" vs "load_dotenv", why?

I’m fairly new to Python. I’m using Python 3.12 on Windows 10 Pro.

I have a line in my program from dotenv import load_dotenv. So I thought when I install it in my virtual environment I would to py -m pip install dotenv. This works, but gets an error on the line with the import and my program does not run.

So to get my program to run I install it with py -m pip install load_dotenv and it runs.

I thought the module I would install would be dotenv (right after the “from”) but it’s actually load_dotenv. What am I thinking wrong here? Do I have to check the docs on every module I install to find the correct name I use in the pip installer?

Thank you.

Essentially yes. There is no guarantee of the relation between the package name and the import name, and a package name might map to any number of import names and an import name might be provided by any number of packages. But those packages are then incompatible with each other and can’t be installed at the same time, so it is strongly suggested to use the same name for both, but this isn’t enforced.

You’ve stumbled upon the difference between distribution packages and import packages. There’s a nice discussion of the differences between the two in the Packaging User Guide under Distribution package vs. import package. The fact that both use the term “package” causes no end of confusion, especially when you mix in packages for system package managers (e.g. apt), Anaconda packages, etc.

Not too long ago there was a thread collecting some common examples of distribution/import name mismatches:

If you’ve already installed a module and want to find the name of the distribution that provided it, you can use importlib.metadata.packages_distributions to do the reverse lookup. For example, if you want to know what distribution is providing PIL, you can run:

>>> importlib.metadata.packages_distributions()["PIL"]
['Pillow']

Typically a project will declare what distributions it depends on in its pyproject.toml file (or a requirements.txt or setup.py file, particularly for older projects). So if you’re trying to match the packages that some other project is using, those would be good places too look.

3 Likes

A reverse lookup is what I needed. Thanks.

Is this importlib.metadata.packages_distributions()["PIL"] ['Pillow'] a Python command I would run? I’d like to do this at the command line. I will lookup how to run a Python command at the cmd.exe prompt.

I’m having some trouble running this. When I do this in my .bat file:

py -c "importlib.metadata.packages_distributions()["%1"]"

I get this error:

Traceback (most recent call last):
  File "<string>", line 1, in <module>
NameError: name 'importlib' is not defined. Did you forget to import 'importlib'?

When I do this:

py -c "import importlib; importlib.metadata.packages_distributions()["%1"]"

I get this error.

Traceback (most recent call last):
  File "<string>", line 1, in <module>
AttributeError: module 'importlib' has no attribute 'metadata'

I mentioned I’m not an expert at Python right? :slight_smile:

And as another test I get this:

>>> import dotenv
>>> importlib.metadata.packages_distributins()['dotenv']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'importlib' is not defined. Did you forget to import 'importlib'?

importlib.metadata is a submodule of importlib which, as a rule, needs to be imported separately:

>>> import importlib
>>> importlib.metadata
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'importlib' has no attribute 'metadata'

>>> import importlib.metadata
>>> importlib.metadata
<module 'importlib.metadata' from '/usr/lib/python3.12/importlib/metadata/__init__.py'>

You can sometimes access submodules with explicitly importing them, but only if different module (often the parent module) has already imported them for you. See also:

1 Like