## TL;DR
After an upgrade, `import ipython` is picking up a stray `ipython.py` file in your working directory or on sys.path instead of the real package, or the upgrade left a half-written install. Run `python -c "import ipython; print(ipython.__file__)"`. If it points at a local file, rename that file. If it points at site-packages, uninstall ipython twice and reinstall once.

```text
AttributeError: module 'ipython' has no attribute 'core' after upgrade
```

## Use this when
- Any `import IPython` or `import ipython` now fails with this AttributeError after an upgrade.
- The error appears in a directory where you have been writing scripts.
- The upgrade was interrupted or done with `--force` flags.

## Not for this skill when
- The error names `ipython.core.display` specifically. That is the removed re-export, a different fix.
- The kernel dies instead of raising. That is a native crash.

## Steps
1. Ask python what it imported: `python -c "import ipython; print(ipython.__file__)"`. Verify: you see the actual path being loaded.
2. If the path is a local `ipython.py` or an `ipython/` directory in your project, rename it to something non-colliding. Verify: the import now resolves to site-packages.
3. If the path is site-packages, the install is corrupt: `pip uninstall -y ipython`, run it again to catch the second copy, then `pip install ipython`. Verify: `import IPython; IPython.__version__` works.
4. Check for a second install shadowing the first: `pip list | grep -i ipython` should show exactly one. Verify: no duplicates.
5. Restart the kernel and re-run. Verify: the AttributeError is gone in a fresh kernel.

## Variant phrasings
### module ipython has no attribute core
Short form. Shadowing file is the first check.

### ipython import broken after pip upgrade
Upgrade-context phrasing. Partial install is the second suspect.

### AttributeError ipython after update
General phrasing. Same two causes.

Compatibility: All IPython versions, pip installs. Shadowing can happen with any package, but the `ipython.py` filename is the classic.

## Why it happens
Python puts the current working directory first on sys.path. A script or scratch file named `ipython.py` in the notebook's directory wins over the installed package, and the real package's submodules are then unreachable, producing this exact AttributeError.

## Edge cases / pitfalls
- The shadowing file can also be `IPython.py` on case-insensitive filesystems. Search both casings.
- A leftover `ipython.egg-link` or `.pth` file can point at a deleted source checkout. Check site-packages for strays.
- Renaming the file is not enough if a `__pycache__/ipython.*.pyc` remains and the source is gone. Clear the pycache too.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_2VN79jNexleBD4WuRmxIRQ
