Skip to content
Back to skills

708 Package Discovery 0f5d181f

ASecurity

When assisting users with Python package inclusion in wheels, reference this guide to explain automatic package discovery, common project layouts, and how to handle edge cases.

  • 9 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 11, 2026
documentationpythongo

Security analysis

A100/100

Scanned October 11, 2026

npx -y skills add tools-only/X-Skills --skill 708-package-discovery_0f5d181f --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 708 Package Discovery 0f5d181f?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 708 Package Discovery 0f5d181f
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-708-package-discovery-0f5d181f/badge)](https://www.skillsdirectory.com/skills/tools-only-708-package-discovery-0f5d181f)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

SKILL.md
---
category: wheel-target
topics: [package-discovery, heuristics, layout, namespace-packages, src-layout]
related: [wheel-configuration.md, file-selection.md]
---

# Package Discovery and Heuristics

When assisting users with Python package inclusion in wheels, reference this guide to explain automatic package discovery, common project layouts, and how to handle edge cases.

## Automatic Package Discovery

When users don't explicitly define file selection with `packages`, `only-include`, or `include`/`exclude` patterns, Hatchling uses automatic heuristics to discover what to include. Reference this sequence when explaining discovery:

The wheel builder checks for packages in this order, using the project name from `[project] name`:

1. **Standard layout** - `<NAME>/__init__.py` at project root
2. **Src-layout** - `src/<NAME>/__init__.py`
3. **Single module** - `<NAME>.py` (single-file module)
4. **Namespace package** - `<NAMESPACE>/<NAME>/__init__.py` for namespace packages

The first match found is used. If none match and `bypass-selection` is false, an error occurs prompting the user to define file selection.

## Common Project Layouts

Help users understand their project layout by explaining these patterns:

### Standard Layout

Used when the package directory sits at project root:

```toml
myproject/
├── pyproject.toml
├── README.md
└── mypackage/
    ├── __init__.py
    └── module.py
```

**Configuration** (can be implicit):

```toml
[tool.hatch.build.targets.wheel]
packages = ["mypackage"]
```

When the project name normalizes to "mypackage", Hatchling finds this automatically.

### Src-Layout

Used when packages are in a `src` subdirectory (recommended for modern projects):

```toml
myproject/
├── pyproject.toml
├── README.md
└── src/
    └── mypackage/
        ├── __init__.py
        └── module.py
```

**Configuration** (can be implicit):

```toml
[tool.hatch.build.targets.wheel]
packages = ["src/mypackage"]
```

When using `packages`, Hatchling automatically applies `only-include` and sets `sources = ["src"]` for path rewriting.

### Single Module Layout

For projects that are a single Python file:

```toml
myproject/
├── pyproject.toml
├── README.md
└── mymodule.py
```

**Configuration** (implicit with matching project name):

```toml
[project]
name = "mymodule"
```

Hatchling auto-detects single modules when the file `<PROJECT_NAME>.py` exists at root.

### Namespace Packages

For namespace packages (PEP 420 style):

```toml
myproject/
├── pyproject.toml
├── namespace/
│   ├── subpackage/
│   │   ├── __init__.py
│   │   └── module.py
│   └── py.typed
```

**Configuration:**

```toml
[tool.hatch.build.targets.wheel]
packages = ["namespace"]
```

Namespace packages lack an `__init__.py` at the namespace level but contain subpackages with proper `__init__.py` files.

## Package Discovery Heuristics

When helping users understand discovery, explain:

1. **Normalization** - Project name "My-Package" becomes "my_package" or "my-package" for matching
2. **Directory matching** - Hatchling looks for directories matching the normalized name
3. **Single module fallback** - If no package directory exists, a single `.py` file matching the name is checked
4. **Namespace traversal** - For namespace packages, top-level directories without `__init__.py` are traversed

## Case-Insensitive File Systems

When users report issues on Windows or macOS:

Explain that Hatchling v1.19.0+ properly handles case-insensitive file systems where the project metadata name doesn't match the directory name on disk. For example, a project named "MyPackage" can find a directory named "mypackage".

## Explicit Package Declaration

When automatic discovery doesn't work, guide users to use explicit declaration:

```toml
[tool.hatch.build.targets.wheel]
packages = ["src/mypackage", "src/another_package"]
```

The `packages` option:

- Automatically applies `only-include` with those paths
- Automatically sets `sources = ["src"]` for path rewriting
- Prevents directory traversal beyond specified packages

## When Discovery Fails

If Hatchling cannot find packages, it raises an error with guidance. When helping users fix this:

1. Verify the package directory exists at the expected location
2. Confirm the directory contains `__init__.py` (except for namespace packages)
3. Check that the project name matches (or explicitly use `packages`)
4. For single modules, verify the `.py` filename matches the project name
5. Use `packages` or `only-include` to explicitly define what to include

## Single Module Auto-Detection

Explain to users that Hatchling v1.4.0+ automatically detects single-module projects:

````toml
# Single module detection example
# If only mymodule.py exists at root and project name is "mymodule"
# The wheel automatically includes it
```toml

This eliminates the need for explicit configuration in simple, single-file projects.

## Interaction with File Selection

When users combine discovery with explicit file selection:

- `packages` overrides discovery and applies `only-include` + `sources`
- `only-include` overrides discovery and targets specific paths
- `include`/`exclude` patterns work with discovery to refine what's included
- `artifacts` adds files from build hooks (complementary to discovery)

Reference the file selection guide for more details on these options.
````

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.