简体   繁体   中英

Python site-package imports submodule from script root directory

I used to have this litte script main.py in a directory eden/ (stripped down to MVE, of course):

#!/usr/bin/env python3
# main.py
import pymongo
uri = "***"
mongo_client = pymongo.MongoClient(uri)

With a venv virtual environment (homebrew Python 3.9.6, pip 21.3.1, pymongo 3.12.1) it ran like a (py)charm. eden/ is first in the sys.path , else only Python standard lib and the site-packages from the venv , which just has pymongo in the requirements.txt .

But now I have placed a little subdirectory next to main.py like so for some completely other reason:

eden/
  +- monotonic/
  |    +- monotonic.py
  +- main.py

No __init__.py files anywhere.

With this in place main.py fails like so:

Traceback (most recent call last):
  ...
  File "****/venv/lib/python3.9/site-packages/pymongo/server_description.py", line 72, in __init__
    self._last_update_time = _time()
TypeError: 'module' object is not callable

_time comes into pymongo/server_description.py like so:

# pymongo/server_description.py
from pymongo.monotonic import time as _time

The PyCharm debugger reveals that _time is

<module 'monotonic.monotonic' from '****/eden/monotonic/monotonic.py'>

so the fix is easy (rename monotonic/ subdirectory), but I completely fail to understand what caused this import:

  • How can "my" monotonic/monotonic.py match a from pymongo.monotonic at all?

  • "My" monotonic/monotonic.py does not even offer time for import (in fact, it's an empty file in the MVE). So why won't the import in pymongo/server_description.py fail in the first place?

  • Now Python does not import time as _time from "my" monotonic/monotonic.py but the whole module ends up as _time . I cannot even state a proper question here so confused am I.

  • The bad import will happen only with monotonic/monotonic.py in place. When the subdirectory or the .py file is named differently, like tonic/monotonic.py or monotonic/tonic.py , or when monotonic.py is placed right next to main.py it will not be used. What makes <x>/<x>.py special here? Even more so, as no __init.py__ is involved in eden/ .

If you dont put a __init__.py file then the folder is considered a namespace package. Thats used to gather different folders in a same package. So when python see that, monotonic is considered a namespace package and its content to be gathered together with any other monotonic folder found in path.

At any case I dont understand how time is confused with monotonic.

The solution is to put an empty __init__.py file

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM