I'm stumped by this

I’m sorry about the abstract title, but I can’t think what else to call this:

I’m sure that there must be a logical reason for this, but I need someone to walk me through it please.

I use this script to examine the contents of Modules.

from PIL import Image as contents

output = dir(contents)
print(output)

It just so happened to be the PIL module that I was looking at on this occasion, in relation to a recent posting on this Forum.

By coincidence, I happened to have a script named numbers.py resident in the same directory. When I execute the above, it calls and runs numbers.py, the contents of which matters not: a simple print() function call is a good working example, but I guess it can be anything you choose.

The question is why does this happen?

You’ll see that 'numbers' is present is the PIL Module, but then again so is 'preinit' (as just one example) but renaming numbers.py to preinit.py does not cause that script to run; only when it’s named numbers.py does it get called into action [I’ve not done any other testing thus far, using any other names].

I’ve tried this on two machines; one running Python3.6 and the other Python3.8 – runs just the same. The 3.8 machine is a relatively new install, with unchanged defaults, so I’m as certain as I can be that this will work on systems that I do not own or control.

OS footnote: Linux Mint 19.3 & Ubuntu 20.04.4 LTS

Python includes your current working directory in the import path,
as the highest priority location to find modules (in order for you
to be able to override modules which other modules might try to
import). Before importing from PIL, do this:

import sys
sys.path.remove('')

That should cause the importer to no longer consult your current
working directory when looking for modules to import. Longer term,
keep in mind that anything in your current working directory could
shadow similarly-named modules imported by any scripts you run, and
you might want to cd to an empty temporary directory or something
along those lines if it presents a problem. For related reasons,
never run Python scripts when you don’t trust the contents of your
current working directory (e.g. you’ve done a cd to someone’s
homedir as root).

For more information, see the Python documentation on sys.path:

https://docs.python.org/3/library/sys.html#sys.path

“numbers” is a standard library module:

https://docs.python.org/3/library/numbers.html

So what seems to be happening is that when you import from PIL, it attempts to import numbers from the stdlib but gets your numbers.py instead.

As for the “preinit” not doing the same, my guess is that whatever PIL.Image.preinit is, it isn’t a module, and so your module called “preinit.py” doesn’t get imported.

That’s the simplest explanation, there could be others.

You can get more information by doing this:

  1. Using the text editor of your choice, search the PIL library for something like import preimage and see if anything comes up.

  2. In your script, add this line:

    print(Image.preimage)

to see what sort of thing it is (a module? something else?).

My thanks to you both {the penny drops like a brick down a well}

Lesson learned: Name check my modules and be real careful when running my scripts on machines that I don’t control.