KEMBAR78
Handling module names ending with `__init__` · Issue #10329 · python/mypy · GitHub
Skip to content

Handling module names ending with __init__ #10329

@BoniLindsley

Description

@BoniLindsley

Bug Report

Attempts to find type hints that import package submodules whose names end with __init__ seem to prevented. An example being test/test__init__.py, with double underscores on both ends.

To Reproduce

I tried to create a script for this, but roughly, it does the following:

  1. Create a package directory.
  2. Create some *__init__.py and __init__.py. Some other combination of underscores and names can also be checked.
  3. Import the former from the latter, using either absolute or relative.
  4. Type check the package using mypy.

A Bash script for this:

#!/usr/bin/bash

# Create a namespace package directory.
package_name='test'
if [[ -e "${package_name}" ]]; then
  printf 'Path %s exists. Needed for tests.\n' "$package_name"
  read -n1 -r \
    -p 'Press <Y> to remove and remake. Press anything else to abort.' \
    key
  if [[ 'Y' != "$key" ]]; then
    printf 'Aborting. Pressed key was: %s\n' "$key"
    exit 1
  fi
  rm -dfr test
fi
mkdir test

# Create submodules to import.
module_names=(     \
  'test_init__'    \
  'test_init___'   \
  'test__init__'   \
  'test__init___'  \
  'test___init__'  \
  'test___init___' \
)
# Make up some variables to be imported.
for name in "${module_names[@]}"; do
  printf 'num_%s = 1' "${name}" > "${package_name}/${name}.py"
done

# Relative import of variables.
cat << EOF > "${package_name}/__init__.py"
from .test_init__ import num_test_init__
from .test_init___ import num_test_init___
from .test__init__  import num_test__init__ # Errors
from .test__init___ import num_test__init___
from .test___init__  import num_test___init__ # Errors
from .test___init___ import num_test___init___
EOF
python3 -m "${package_name}.__init__"  # Loads fine in Python.
python3 -m mypy --config-file= --package "${package_name}"
# Output:
# test/__init__.py:3: error: Skipping analyzing 'test.test__init__': found module but no type hints or library stubs
# test/__init__.py:3: note: See https://mypy.readthedocs.io/en/latest/running_mypy.html#missing-imports
# test/__init__.py:5: error: Skipping analyzing 'test.test___init__': found module but no type hints or library stubs
# Found 2 errors in 1 file (checked 5 source files)

Relative imports of modules produce slightly different errors, but they are errors nonetheless.

cat << EOF > "${package_name}/__init__.py"
from . import test_init__
from . import test_init___
from . import test__init__  # Errors
from . import test__init___
from . import test___init__  # Errors
from . import test___init___
EOF
python3 -m "${package_name}.__init__"  # Loads fine in Python.
python3 -m mypy --config-file= --package "${package_name}"
# Output:
# test/__init__.py:3: error: Module 'test' has no attribute 'test__init__'; maybe "test__init___", "test___init__", or "test_init__"?
# test/__init__.py:5: error: Module 'test' has no attribute 'test___init__'; maybe "test___init___", "test__init__", or "test__init___"?
# Found 2 errors in 1 file (checked 5 source files)

Type checking with absolute imports exhibit similar behaviours.

Expected Behavior

I expected the type checks to pass. I am not aware of module naming restrictions that might restrict this, but there might be some? Naming might be too much of an edge case to support even if not?

Actual Behavior

Output from mypy noted at the end of the Bash scripts.

Your Environment

  • Mypy version used: mypy 0.812 from python3 -m mypy --version
  • Mypy command-line flags: python3 -m mypy --config-file= --package "${package_name}"
  • Mypy configuration options from mypy.ini (and other config files): Not applicable with --config-file=.
  • Python version used: Python 3.9.2 from python3 --version
  • Operating system and version: Description: Debian GNU/Linux bullseye/sid from lsb_release --description

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugmypy got something wrong

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions