Recently I've been trying to learn a bit more about how to build python modules and share code amongst my personal projects. This is my first attempt and I'm running into errors and I'm having a tough time finding solutions through normal searches. I'm hoping you guys can point me in the right direction and maybe provide some insight on what's causing the issue under the hood.
I've built a super simple "card" project. It has the following layout...
And here's the contents of a few of the files from the project.
cards/setup.py
import time
from setuptools import setup, find_packages
setup(
name="pycard",
version=f"0.1.{int(time.time())}",
package_dir={"": "src"},
packages=find_packages(where="src"),
author="*****",
python_requires=">=3.12",
)
cards/src/pycard/_init_.py
from src.pycard.Cards import Card, Rank, Suit, RankSuitContext, AcesHighContext, RankSuitCard, CardContext
from src.pycard.Decks import Stack, StackContext, FiftyTwoCardDeck
Everything seems to work fine within my project. Unit tests pass, etc. To build, I run...
python setup.py sdist bdist_wheel
This creates the build, dist, and egg directories with a dist/pycard-version.whl file.
Now I create a separate project, create a new Conda environment, and run...
pip install path/to/pycard-*version*.whl
This command completes successfully and running pip list
shows pycard in my package list.
(card-games) me@computer card-games % pip list
Package Version
---------- --------------
pip 25.0
pycard 0.1.1745085939
setuptools 75.8.0
wheel 0.45.1
The problem shows up when I try to import and use the package in this new project. Here's a simple example...
from pycard.Cards import RankSuitCard, Rank, Suit
if __name__ == '__main__':
print(RankSuitCard(Rank.ACE, Suit.SPADES))
Executing this gives me the following error...
Traceback (most recent call last):
File "/Users/me/development/card-games/src/pycardgames/main.py", line 1, in <module>
from pycard.Cards import RankSuitCard, Rank, Suit
File "/Users/me/miniconda3/envs/card-games/lib/python3.12/site-packages/pycard/__init__.py", line 1, in <module>
from src.pycard.Cards import Card, Rank, Suit, RankSuitContext, AcesHighContext, RankSuitCard, CardContext
ModuleNotFoundError: No module named 'src.pycard'
What's interesting is my IDE (PyCharm) seems to understand the import, letting me reference different types, click into them and view source, etc.
My gut is it has something to do with how I'm referencing the classes in the original _init_.py (src.pycard.file), but most of the tutorials I found online use that pattern. I also haven't found much on details in terms of referencing classes in _init_.py and how that impacts importing them once you've build the package.
Any help you guys can provide would be greatly appreciated.
When you say package_dir={"": "src"}
in your setup.py
, you are saying that your root modules and packages can be found in the src
folder. That means src
should not be form part of your imports.
You are likely including src
in your imports because your test runner was not finding your source code. Instead of including src
in your imports, you could install your package as an "editable" package into your development virtual environment. This is just a fancy way to tell code running from within your venv, that when it is looking for the pycard
package, that it should look inside the src
directory. Any updates to your source code will be reflected in new test runs without having the reinstall your package. Your can do an editable install like so.
pip install --editable path/to/cards
path/to/cards
should be the path to the directory that contains your setup.py
file.
Alternatively, you could instead tell your test runner where to find your source code by using the PYTHONPATH
environment variable. This environment variable is used to tell python which directories to look in when searching for modules eg.
cd path/to/cards
export PYTHONPATH=./src
pytest tests