DEV Community

Jordan Huang
Jordan Huang

Posted on

A Fluent Import Is Not a Package: Five Myths

Have you pasted an import from a chat window?
Did pip fail only after the pull request opened?

I keep catching this pattern during otherwise careful reviews.
The helper looks tidy, and the import looks ordinary.
Nobody on the thread queried a package index.

This is not a small naming nitpick for style.
It is a supply-chain hole wearing polite syntax.

The five claims I still hear

Generated-code threads recycle the same five sentences.
They sound efficient when a deadline is close.
Each one fails under a single terminal command.

I am writing this as a myth-busting FAQ.
Every myth gets a claim, a check, a better picture.
You also get a scanner you can run locally.
That scanner never needs a model in the loop.

Myth 1: The import compiled, so the package exists

Did the transcript show a clean looking import line?
That line never called PyPI, and never called npm.

Chat cannot return a 404 for a package name.
It can only emit a string that looks installable.
I treat every generated import as an untrusted rumor.
Rumors need a registry round-trip before they become dependencies.

python -m pip index versions definitely-real-helper
npm view definitely-real-helper name version --json
Enter fullscreen mode Exit fullscreen mode

If the index stays silent, I delete that import.
I do not ask the model for a cousin name.

Better picture: import lines are only proposals today.
Existence is a registry fact, not a prose fact.
Keep those two layers apart in every review.

Would you vendor a library because a tweet named it?
Then why vendor one from a fluent paragraph?

Myth 2: The pin in chat is the pin you install

Did it write requests==2.32.3 like a lockfile?
Pins in prose are still tokens from a model.
Tokens are not a resolver, and they are not a graph.

I copy the name, then I ignore the version string.
The live index gets the next vote, not the transcript.

python -m pip index versions requests
npm view lodash version time license
Enter fullscreen mode Exit fullscreen mode

If that exact pin is missing, I refuse rounding.
I pick a published version and relock it locally.
Close enough is how drifted production graphs start.

Better picture: chat cannot freeze an install graph.
Your lockfile freezes a graph, so guard that file.
Who owns the pin if CI later drifts overnight?
You do. The transcript will not join the outage call.

Myth 3: "Just use latest" means the index head

Does "latest" feel current inside a chat answer?
Models do not watch your index. They guess a vibe.

Latest is an alias, and aliases move without warning.
Releases get yanked. Guessing is not the same as tracking.

python -m pip index versions cryptography
npm view lodash version
Enter fullscreen mode Exit fullscreen mode

I print the versions, then I choose one on purpose.
I write that choice into the lockfile with my own hands.

Better picture: latest is a moving nickname on a registry.
You want a digest, a lockfile, or both in writing.
Would you let a random blog post pick production pins?
Then do not let a transcript do that job either.

Myth 4: A green install used your private index

Did pip print Successfully installed on a rented box?
That box started with public defaults, not your Artifactory.
A green public install proves nothing about internal wheels.

This is where a scratch server still helps a little.
It helps as a clean room, not as a mirror of production.

Disclosure: This article was prepared as part of MonkeyCode's product outreach.

MonkeyCode offers free model access and a free server option.
I treat that pair as untrusted workers, never as credentialed mirrors.
I do not hand them private tokens, even for a "quick probe."

python -c "import sys; print(sys.executable)"
python -m pip config list
npm config get registry
Enter fullscreen mode Exit fullscreen mode

If the registry URL is the public default, you should stop.
Your internal wheels never entered that environment at all.

Better picture: a free server is an empty bench on purpose.
Empty is useful for public probes. Empty is not configured.
Should you install there after the index check passes?
Yes. Before the check? Never, not even once.

Myth 5: The model named a license, so legal is done

Did it answer MIT in a single confident word?
License names are short, and short answers are easy to fake.

A license is a property of a shipped artifact.
Model recall is not that artifact. Open the actual file.

python -m pip download packagename==1.2.3 -d /tmp/wheels --no-deps
npm view packagename license repository homepage
Enter fullscreen mode Exit fullscreen mode

I still read METADATA or LICENSE when the dep is load-bearing.
I am not your lawyer. I am the person who opens the tarball.

Better picture: compliance reads files, not chat labels.
Labels are a starting clue only. They are not sign-off.
Would you accept a license from a hallway conversation?
Then do not accept one from a generated paragraph either.

Artifact: extract names, then query the index

Here is the boring loop I actually want in muscle memory.
The boredom is the feature, because it is checkable.

  1. Save the generated snippet to a local file first.
  2. Extract candidate import names with a dumb scanner.
  3. Query the public index for each extracted name.
  4. Block every install on names the index does not know.
  5. Probe a throwaway venv only after that gate holds.

A small Python extractor

This helper only reads text from disk.
It does not call a model, and it is not a full module graph.
Treat unknown names as third-party until the index says otherwise.

#!/usr/bin/env python3
"""Extract top-level import names from a Python snippet.

Heuristic scanner, not a resolver and not a lockfile.
Run it on generated files before any install command.
"""
from __future__ import annotations

import ast
import sys
from pathlib import Path

STDLIB = {
    "abc", "asyncio", "collections", "contextlib", "dataclasses",
    "datetime", "functools", "hashlib", "http", "itertools", "json",
    "logging", "math", "os", "pathlib", "re", "subprocess", "sys",
    "tempfile", "threading", "time", "typing", "unittest", "uuid",
}

def top_level(name: str) -> str:
    return name.split(".")[0]

def extract(path: Path) -> set[str]:
    tree = ast.parse(path.read_text(encoding="utf-8"))
    found: set[str] = set()
    for node in ast.walk(tree):
        if isinstance(node, ast.Import):
            for alias in node.names:
                found.add(top_level(alias.name))
        elif isinstance(node, ast.ImportFrom) and node.module:
            found.add(top_level(node.module))
    return found - STDLIB

def main() -> None:
    if len(sys.argv) != 2:
        print("usage: scan_imports.py snippet.py", file=sys.stderr)
        sys.exit(2)
    names = sorted(extract(Path(sys.argv[1])))
    if not names:
        print("no third-party imports found")
        return
    for name in names:
        print(name)

if __name__ == "__main__":
    main()
Enter fullscreen mode Exit fullscreen mode

The query loop

python3 tools/scan_imports.py snippet.py | while read -r pkg; do
  echo "== $pkg =="
  python -m pip index versions "$pkg" || echo "MISSING_FROM_INDEX $pkg"
done
Enter fullscreen mode Exit fullscreen mode

Missing names never reach pip install in this loop.
That gate is the whole point of the workflow.

JavaScript snippets get a dumber first pass from me.
I still finish with npm view before any install lands.

grep -E "from |require\(" snippet.js
npm view some-name name version license --json
Enter fullscreen mode Exit fullscreen mode

Decision table

Print this beside the terminal when a generated helper arrives.
It cuts the debate short, which is the entire job.

Signal you just saw Do this next Do not do this
Name missing from the index Delete the import and rewrite the helper Ask the model for another name blindly
Name exists, suggested pin does not Pick a published version and relock Nudge the pin by one hopeful digit
Name exists, you need a private index Point pip at your index, then re-run Assume a free server already has credentials
License field is empty or cute Open the artifact; ask legal if load-bearing Trust a one-word chat answer
Install worked on a scratch server Recreate it with your lockfile locally Copy site-packages toward production

A tight loop that uses the free tools

I ask a free model for a smaller helper, not a new platform.
I save the answer as a file before any install command.
Then I run the extractor, and then I query the index.
Only after that gate may I install on a free server.

The server answers one question, and only one question.
Can this public import actually import in a clean venv?

python -m venv /tmp/probe
. /tmp/probe/bin/activate
python -m pip install -U pip
python -m pip install "$PKG==$PIN"
python -c "import $MODULE; print($MODULE.__file__)"
Enter fullscreen mode Exit fullscreen mode

If the import fails, I keep the log on disk.
I paste the log second. I do not start with "please explain."
Notice the order, because the order is the method.
Registry, pin, venv, import. Chat stays at the edges.

Limitations

This scanner misses dynamic imports on purpose.
importlib.import_module(name) will walk around the syntax check.

It also misses extras and optional dependency markers.
A real package can still be the wrong extra for your code.

PyPI distribution names are not always import names.
python-dateutil imports as dateutil. Map those pairs by hand.

pip index needs a recent pip on the machine.
Upgrade pip before you trust a confusing empty answer.

A free server will not see private indexes by default.
I will not put those credentials on a shared machine.

I am not scoring models in this article at all.
I am checking whether a name exists. Low bar. Useful bar.

Who should skip this

Do not use this as your only supply-chain control.
Finance and health teams need a real allowlist process.

Do not use it on air-gapped products with no index clone.
The commands assume you can reach a registry from here.

Do not use it to rubber-stamp licenses for counsel.
A license field can be wrong. Read the artifact anyway.

Do not point a free server at production tokens, ever.
Probe venvs are disposable. Tokens are not disposable.

If you cannot run pip index or npm view, stop here.
This FAQ depends on those tools. It does not replace them.

Keep this picture

Chat can propose an import in fluent English.
Only the registry can confirm a name is real.
Only your lockfile can confirm a pin is the one you chose.

A free model is a fast junior with no index subscription.
A free server is a clean room with public defaults.
Neither one is your release train, and neither should be.

Would you merge a dependency with no registry link attached?
Then do not merge a transcript that does the same thing.

Run the extractor.
Query the index. Then decide, not before.

Top comments (0)