rlsbl v0.92.0 /rlsbl.commands.check
On this page

Query package name availability across npm, PyPI, Go (pkg.go.dev), and GitHub. Detects moniker collisions via separator-insertion variants.

#rlsbl.commands.check

#rlsbl.commands.check

Check command to query package name availability across npm, PyPI, Go module proxy (pkg.go.dev), and GitHub repository namespaces.

#_request_with_backoff

python
def _request_with_backoff(url, timeout=5, max_retries=3, headers=None)

Wrap urllib.request.urlopen with retry logic for HTTP 429 responses.

On HTTP 429 (Too Many Requests): reads the Retry-After header (seconds). If present, sleeps that long. If absent, uses exponential backoff starting at 2 seconds (2, 4, 8, ...).

On other HTTP errors or non-HTTP errors (URLError, timeout): raises immediately without retrying.

Returns the response object on success, or raises the last exception after exhausting retries.

#_ultranormalize

python
def _ultranormalize(name)

Ultranormalize a package name for typosquatting detection.

Strips all separators (-, _, .), replaces visually ambiguous characters (l, L, i, I -> 1; o, O -> 0), and lowercases the result.

#_generate_ultranorm_variants

python
def _generate_ultranorm_variants(name)

Generate name variants that share the same ultranormalized form.

Starting from the PEP 503 normalized form (lowercase, separators normalized), produces all combinations of ambiguous character substitutions: l <-> 1, o <-> 0, i <-> 1 Returns (variants, capped) where variants is a list of up to 64 variants (excluding the original name) and capped is True when the total combination count exceeded the cap.

#_search_npm_similar

python
def _search_npm_similar(name)

Search the npm registry for packages with conflicting monikers.

Queries the npm search API for packages similar to name, then compares each result's normalized moniker against the candidate's. Returns a list of original package names that conflict.

Raises on failure (network, timeout). The caller is responsible for handling the exception appropriately.

#check_npm_availability

python
def check_npm_availability(name)

Check if an npm package name is available.

Returns {"status": "available"|"taken"|"error", "message"?: str}. Distinguishes 404 (truly available) from network/other errors.

#get_npm_variants

python
def get_npm_variants(name)

Generate common npm name variants for similarity checking.

npm's moniker collision algorithm strips all -, ., and _ characters and lowercases before comparing. We generate:

  1. All separator-swap variants (replace every separator with each of -._)
  2. The fully stripped form
  3. Insertion variants when the name has no separators (insert each of -._

at every interior position so we can detect existing hyphenated packages that would collide)

#check_pypi_availability

python
def check_pypi_availability(name)

Check if a PyPI package name is available.

Uses the Simple API (PEP 503) which correctly returns 200 for registered packages even if they have no releases (unlike the JSON API which 404s).

Returns {"status": "available"|"taken"|"error", "message"?: str}. Distinguishes 404 (truly available) from network/other errors.

#get_pypi_variants

python
def get_pypi_variants(name)

Generate common PyPI name variants for similarity checking.

#check_go_availability

python
def check_go_availability(name)

Check if a Go module path exists on pkg.go.dev.

Returns {"status": "not_found"|"exists"|"error", "message"?: str, "note"?: str}.

Go modules use repository paths (e.g. github.com/user/repo), not a flat claimable namespace, so we report "not found" / "exists" rather than the "available" / "taken" language used for npm and PyPI.

#check_github_availability

python
def check_github_availability(name)

Check if a repository name exists on GitHub.

Searches the GitHub API for repositories with the given name. Returns {"status": "available"|"exists"|"error", "count": int, ...}.

#_check_variants

python
def _check_variants(name, check_fn, get_variants_fn, delay_ms=0)

Check name variants for similarity using the given availability checker.

When delay_ms > 0, bypasses the thread pool and checks variants sequentially with time.sleep(delay_ms / 1000) between checks (no delay before the first check). This avoids triggering registry rate limits when many variants are generated.

Returns a list of variant names that are taken/exist.

#_classify_variant_collisions

python
def _classify_variant_collisions(name, taken_variants, registry)

Classify taken variants as hard normalization collisions or soft similar names.

Hard collisions are names the registry would reject because they normalize identically to the candidate. Soft similar names merely look alike but are distinct after normalization.

Returns (hard_collisions, soft_similar).

#_check_stdlib_collision

python
def _check_stdlib_collision(name)

Check if a name collides with a Python standard library module.

PEP 503 normalizes both the candidate and each stdlib name, then compares. Returns the stdlib module name on collision, or None.

#_check_single_name

python
def _check_single_name(name, registry, delay_ms=0)

Check a single name on a given registry, returning a structured result.

When delay_ms > 0, variant checks use sequential execution with a delay between requests instead of concurrent threads.

Returns a dict with keys: - name: the package name checked - registry: which registry was checked - status: "available", "taken", "exists", "not_found", or "error" - variants: list of similar names that are taken (npm/pypi only) - reason: why the name is taken/unavailable, or None if available/error. Values: "registered", "stdlib", "moniker", "normalized", "ultranorm" (set by _apply_ultranorm_check), or None. - error: error message if status is "error" (absent otherwise) - note: informational note (go/github only, absent otherwise) - github_count: number of GitHub repos (only when registry is "github")

#_format_single_result

python
def _format_single_result(result)

Print the verbose output for a single name check result.

Returns an exit code: 0 = available, 1 = taken/collision, 2 = error.

When status is "error", prints the error message and returns 2 immediately, skipping variant/GitHub output (same behavior as the old sys.exit(1) calls).

#_format_table_row

python
def _format_table_row(result)

Return a compact one-line dict suitable for table rendering.

Keys: name, status. The status is a short human-readable string.

#_apply_ultranorm_check

python
def _apply_ultranorm_check(result, registry, delay_ms)

Apply ultranormalization variant checking to a result dict (in-place).

Always runs for PyPI when the name was initially available. Checks each generated variant against PyPI Simple API, applying a delay between requests. Sets ultranorm_conflicts (list of taken variant names) on the result.

#run_cmd

python
def run_cmd(registry, args, flags)

Check command handler.

Checks package name availability on npm, PyPI, Go, or GitHub, and warns about similar names. Accepts one or more package names as positional arguments.