Skip to content

reiterate version inference #1202

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 31 commits into from
Aug 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
dfadacc
Refactor version inference logic to use should_infer method for dynam…
RonnyPfannschmidt Aug 12, 2025
5cd6d2b
use PyProjectData.for_testing instead of writing to files in tests wh…
RonnyPfannschmidt Aug 12, 2025
9f6796e
enhance testability of setuptools integration points
RonnyPfannschmidt Aug 12, 2025
9d4e67e
remove the missing section km parameter
RonnyPfannschmidt Aug 12, 2025
2319a9d
migrate test_integration_function_call_order to direct pyproject data…
RonnyPfannschmidt Aug 12, 2025
869ae51
Enhance pytest report header to format package paths for better reada…
RonnyPfannschmidt Aug 12, 2025
6c335cd
Refactor PyProjectData initialization and improve error handling for …
RonnyPfannschmidt Aug 12, 2025
c2f7caf
remove the missing_file_ok hack and use exception handling instead
RonnyPfannschmidt Aug 12, 2025
b3c34c0
Refactor TOML error handling and improve pyproject reading logic
RonnyPfannschmidt Aug 12, 2025
882ef63
Enhance testing capabilities for pyproject reading and version inference
RonnyPfannschmidt Aug 12, 2025
3eb0d45
simplify version inference logic tree
RonnyPfannschmidt Aug 12, 2025
02cf5b0
add ruff/mypy back to the test
RonnyPfannschmidt Aug 12, 2025
f1ccfef
chore: pyproject_reading: add constants
RonnyPfannschmidt Aug 12, 2025
10a96fb
introduce DI for the inference config for theintegration points
RonnyPfannschmidt Aug 12, 2025
2bfc568
read version from setup.cfg
RonnyPfannschmidt Aug 12, 2025
1bea2c9
undo support for simplified enabling
RonnyPfannschmidt Aug 12, 2025
9dff8f2
update docs
RonnyPfannschmidt Aug 12, 2025
637dd75
onboard serena
RonnyPfannschmidt Aug 13, 2025
5e8feec
Add project_version property to PyProjectData to enhance readability
RonnyPfannschmidt Aug 13, 2025
de701c0
revise version inference logic
RonnyPfannschmidt Aug 13, 2025
8669af0
chore: add serena cache to gitignore
RonnyPfannschmidt Aug 13, 2025
9293e51
reiterate version inference logic again
RonnyPfannschmidt Aug 13, 2025
9e91663
introduce helpers for more compact version inference test writing
RonnyPfannschmidt Aug 13, 2025
ab097e9
partial test creation - first iteration of more pinpointed version in…
RonnyPfannschmidt Aug 13, 2025
3bfe547
drop useless test data for infer_version
RonnyPfannschmidt Aug 13, 2025
e78df43
remove integration tests that mirror version inference integration un…
RonnyPfannschmidt Aug 14, 2025
e85f66c
drop integration tests that mirror the version inference unittests
RonnyPfannschmidt Aug 14, 2025
206742a
return simplified activation with a extra to prevent regressions
RonnyPfannschmidt Aug 14, 2025
56a7a00
split version inference into the part that needs a distribution objec…
RonnyPfannschmidt Aug 16, 2025
250b5c2
add test migration plan for llms + fix changelog formatting
RonnyPfannschmidt Aug 16, 2025
b8a2920
Add simple extra to pyproject.toml
RonnyPfannschmidt Aug 16, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,5 @@ coverage.xml

# Sphinx documentation
docs/_build/

.serena/cache/
16 changes: 16 additions & 0 deletions .serena/memories/done_checklist.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
Before considering a task done

- Code quality
- Ruff clean: uv run ruff check .
- Types clean: uv run mypy
- Tests
- All tests green: uv run pytest
- New/changed behavior covered with tests (use project fixtures)
- Docs
- Update docs if user-facing behavior changed
- Build docs cleanly: uv run mkdocs build --clean --strict
- Packaging
- If relevant: uv run python -m build && uv run twine check dist/*
- Housekeeping
- Follow existing naming and module structure; keep functions focused and typed
- Update `CHANGELOG.md` when appropriate
28 changes: 28 additions & 0 deletions .serena/memories/project_overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
Project: setuptools-scm

Purpose
- Extract and infer Python package versions from SCM metadata (Git/Mercurial) at build/runtime.
- Provide setuptools integrations (dynamic version, file finders) and fallbacks for archival/PKG-INFO.

Tech Stack
- Language: Python (3.8–3.13)
- Packaging/build: setuptools (>=61), packaging; console scripts via entry points
- Tooling: uv (dependency and run), pytest, mypy (strict), ruff (lint, isort), mkdocs (docs), tox (optional/matrix), wheel/build

Codebase Structure (high level)
- src/setuptools_scm/: library code
- _cli.py, __main__.py: CLI entry (`python -m setuptools_scm`, `setuptools-scm`)
- git.py, hg.py, hg_git.py: VCS parsing
- _file_finders/: discover files for sdist
- _integration/: setuptools and pyproject integration
- version.py and helpers: version schemes/local version logic
- discover.py, fallbacks.py: inference and archival fallbacks
- testing/: pytest suite and fixtures
- docs/: mkdocs documentation
- pyproject.toml: project metadata, pytest and ruff config
- tox.ini: alternate CI/matrix, flake8 defaults
- uv.lock: locked dependencies

Conventions
- Use uv to run commands (`uv run ...`); tests live under `testing/` per pytest config.
- Type hints throughout; strict mypy enforced; ruff governs lint rules and import layout (isort in ruff).
17 changes: 17 additions & 0 deletions .serena/memories/style_and_conventions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
Style and Conventions

- Typing
- mypy strict is enabled; add precise type hints for public functions/classes.
- Prefer explicit/clear types; avoid `Any` and unsafe casts.
- Linting/Imports
- Ruff is the canonical linter (config in pyproject). Respect its rules and isort settings (single-line imports, ordered, types grouped).
- Flake8 config exists in tox.ini but ruff linting is primary.
- Formatting
- Follow ruff guidance; keep lines <= 88 where applicable (flake8 reference).
- Testing
- Pytest with `testing/` as testpath; default 5m timeout; warnings treated as errors.
- Use existing fixtures; add `@pytest.mark` markers if needed (see pyproject markers).
- Logging
- Tests run with log level info/debug; avoid noisy logs in normal library code.
- General
- Small, focused functions; early returns; explicit errors. Keep APIs documented with concise docstrings.
30 changes: 30 additions & 0 deletions .serena/memories/suggested_commands.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
Environment
- Install deps (uses default groups test, docs):
- uv sync

Core Dev
- Run tests:
- uv run pytest
- Lint (ruff):
- uv run ruff check .
- uv run ruff check . --fix # optional autofix
- Type check (mypy strict):
- uv run mypy
- Build docs:
- uv run mkdocs serve --dev-addr localhost:8000
- uv run mkdocs build --clean --strict

Entrypoints / Tooling
- CLI version/debug:
- uv run python -m setuptools_scm --help
- uv run python -m setuptools_scm
- uv run setuptools-scm --help
- Build dist and verify:
- uv run python -m build
- uv run twine check dist/*
- Optional matrix via tox:
- uv run tox -q

Git/Linux Utilities (Linux host)
- git status / git log --oneline --graph --decorate
- ls -la; find . -name "pattern"; grep -R "text" .
68 changes: 68 additions & 0 deletions .serena/project.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# language of the project (csharp, python, rust, java, typescript, go, cpp, or ruby)
# * For C, use cpp
# * For JavaScript, use typescript
# Special requirements:
# * csharp: Requires the presence of a .sln file in the project folder.
language: python

# whether to use the project's gitignore file to ignore files
# Added on 2025-04-07
ignore_all_files_in_gitignore: true
# list of additional paths to ignore
# same syntax as gitignore, so you can use * and **
# Was previously called `ignored_dirs`, please update your config if you are using that.
# Added (renamed)on 2025-04-07
ignored_paths: []

# whether the project is in read-only mode
# If set to true, all editing tools will be disabled and attempts to use them will result in an error
# Added on 2025-04-18
read_only: false


# list of tool names to exclude. We recommend not excluding any tools, see the readme for more details.
# Below is the complete list of tools for convenience.
# To make sure you have the latest list of tools, and to view their descriptions,
# execute `uv run scripts/print_tool_overview.py`.
#
# * `activate_project`: Activates a project by name.
# * `check_onboarding_performed`: Checks whether project onboarding was already performed.
# * `create_text_file`: Creates/overwrites a file in the project directory.
# * `delete_lines`: Deletes a range of lines within a file.
# * `delete_memory`: Deletes a memory from Serena's project-specific memory store.
# * `execute_shell_command`: Executes a shell command.
# * `find_referencing_code_snippets`: Finds code snippets in which the symbol at the given location is referenced.
# * `find_referencing_symbols`: Finds symbols that reference the symbol at the given location (optionally filtered by type).
# * `find_symbol`: Performs a global (or local) search for symbols with/containing a given name/substring (optionally filtered by type).
# * `get_current_config`: Prints the current configuration of the agent, including the active and available projects, tools, contexts, and modes.
# * `get_symbols_overview`: Gets an overview of the top-level symbols defined in a given file or directory.
# * `initial_instructions`: Gets the initial instructions for the current project.
# Should only be used in settings where the system prompt cannot be set,
# e.g. in clients you have no control over, like Claude Desktop.
# * `insert_after_symbol`: Inserts content after the end of the definition of a given symbol.
# * `insert_at_line`: Inserts content at a given line in a file.
# * `insert_before_symbol`: Inserts content before the beginning of the definition of a given symbol.
# * `list_dir`: Lists files and directories in the given directory (optionally with recursion).
# * `list_memories`: Lists memories in Serena's project-specific memory store.
# * `onboarding`: Performs onboarding (identifying the project structure and essential tasks, e.g. for testing or building).
# * `prepare_for_new_conversation`: Provides instructions for preparing for a new conversation (in order to continue with the necessary context).
# * `read_file`: Reads a file within the project directory.
# * `read_memory`: Reads the memory with the given name from Serena's project-specific memory store.
# * `remove_project`: Removes a project from the Serena configuration.
# * `replace_lines`: Replaces a range of lines within a file with new content.
# * `replace_symbol_body`: Replaces the full definition of a symbol.
# * `restart_language_server`: Restarts the language server, may be necessary when edits not through Serena happen.
# * `search_for_pattern`: Performs a search for a pattern in the project.
# * `summarize_changes`: Provides instructions for summarizing the changes made to the codebase.
# * `switch_modes`: Activates modes by providing a list of their names
# * `think_about_collected_information`: Thinking tool for pondering the completeness of collected information.
# * `think_about_task_adherence`: Thinking tool for determining whether the agent is still on track with the current task.
# * `think_about_whether_you_are_done`: Thinking tool for determining whether the task is truly completed.
# * `write_memory`: Writes a named memory (for future reference) to Serena's project-specific memory store.
excluded_tools: []

# initial prompt for the project. It will always be given to the LLM upon activating the project
# (contrary to the memories, which are loaded on demand).
initial_prompt: ""

project_name: "setuptools_scm"
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
# Changelog

## Unreleased

### Added

- add simplified activation via `setuptools-scm[simple]` extra

A new streamlined way to enable version inference without requiring a `[tool.setuptools_scm]` section.
When `setuptools-scm[simple]` is in `build-system.requires` and `version` is in `project.dynamic`,
version inference is automatically enabled with default settings.


### removed

- unchecked simplified activation - too many projects use setups where it would fail


## v9.1.1

### fixed
Expand Down
20 changes: 17 additions & 3 deletions docs/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,25 @@

## When is configuration needed?

Starting with setuptools-scm 8.1+, explicit configuration is **optional** in many cases:
setuptools-scm provides flexible activation options:

- **No configuration needed**: If `setuptools_scm` (or `setuptools-scm`) is in your `build-system.requires`, setuptools-scm will automatically activate with sensible defaults.
### Simplified Activation (No Configuration Needed)

- **Configuration recommended**: Use the `[tool.setuptools_scm]` section when you need to:
For basic usage, use the `simple` extra with no configuration:

```toml title="pyproject.toml"
[build-system]
requires = ["setuptools>=80", "setuptools-scm[simple]>=8"]

[project]
dynamic = ["version"]
```

This automatically enables version inference with default settings.

### Explicit Configuration (Full Control)

Use the `[tool.setuptools_scm]` section when you need to:
- Write version files (`version_file`)
- Customize version schemes (`version_scheme`, `local_scheme`)
- Set custom tag patterns (`tag_regex`)
Expand Down
21 changes: 18 additions & 3 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,36 @@ Note: `setuptools-scm>=8` intentionally doesn't depend on setuptools to ease non
Please ensure a recent version of setuptools is installed (minimum: >=61, recommended: >=80 for best compatibility).
Support for setuptools <80 is deprecated and will be removed in a future release.

**Simplified setup (recommended for basic usage):**

```toml title="pyproject.toml"
[build-system]
requires = ["setuptools>=80", "setuptools-scm>=8"]
requires = ["setuptools>=80", "setuptools-scm[simple]>=8"]
build-backend = "setuptools.build_meta"

[project]
name = "example"
# Important: Remove any existing version declaration
# version = "0.0.1"
dynamic = ["version"]
# more missing

# No additional configuration needed!
```

**With custom configuration:**

```toml title="pyproject.toml"
[build-system]
requires = ["setuptools>=80", "setuptools-scm>=8"]
build-backend = "setuptools.build_meta"

[project]
name = "example"
dynamic = ["version"]

[tool.setuptools_scm]
´´´
# Custom configuration options go here
```


!!! tip "Recommended Tag Format"
Expand Down
55 changes: 35 additions & 20 deletions docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,40 @@
Support for setuptools <80 is deprecated and will be removed in a future release.
The examples below use `setuptools>=80` as the recommended version.

There are two ways to configure `setuptools-scm` at build time, depending on your needs:
There are three ways to enable `setuptools-scm` at build time:

### Automatic Configuration (Recommended for Simple Cases)
### Simplified Activation (new)

For projects that don't need custom configuration, simply include `setuptools-scm`
in your build requirements:
For basic usage without custom configuration, use the `simple` extra:

```toml title="pyproject.toml"
[build-system]
requires = ["setuptools>=80", "setuptools-scm>=8"]
requires = ["setuptools>=80", "setuptools-scm[simple]>=8"]
build-backend = "setuptools.build_meta"

[project]
# version = "0.0.1" # Remove any existing version parameter.
dynamic = ["version"]

# No [tool.setuptools_scm] section needed for basic usage!
```

**That's it!** Starting with setuptools-scm 8.1+, if `setuptools_scm` (or `setuptools-scm`)
is present in your `build-system.requires`, setuptools-scm will automatically activate
with default settings.
This streamlined approach automatically enables version inference when:
- `setuptools-scm[simple]` is listed in `build-system.requires`
- `version` is included in `project.dynamic`

!!! tip "When to use simplified activation"

### Explicit Configuration
Use simplified activation when you:
- Want basic SCM version inference with default settings
- Don't need custom version schemes or file writing
- Prefer minimal configuration

If you need to customize setuptools-scm behavior, use the `tool.setuptools_scm` section:
Upgrade to explicit configuration if you need customization.

### Explicit Configuration (full control)

Add a `tool.setuptools_scm` section for custom configuration:

```toml title="pyproject.toml"
[build-system]
Expand All @@ -51,20 +61,25 @@ pre_parse = "fail_on_missing_submodules" # Fail if submodules are not initializ
describe_command = "git describe --dirty --tags --long --exclude *js*" # Custom describe command
```

Both approaches will work with projects that support PEP 518 ([pip](https://pypi.org/project/pip) and
[pep517](https://pypi.org/project/pep517/)).
Tools that still invoke `setup.py` must ensure build requirements are installed
Projects must support PEP 518 ([pip](https://pypi.org/project/pip) and
[pep517](https://pypi.org/project/pep517/)). Tools that still invoke `setup.py`
must ensure build requirements are installed.

### Using the setup keyword

!!! info "How Automatic Detection Works"
Alternatively, enable `setuptools-scm` via the `use_scm_version` keyword in `setup.py`.
This also counts as an explicit opt-in and does not require a tool section.

When setuptools-scm is listed in `build-system.requires`, it automatically detects this during the build process and activates with default settings. This means:
!!! note "Legacy simplified activation"

- ✅ **Automatic activation**: No `[tool.setuptools_scm]` section needed
- ✅ **Default behavior**: Uses standard version schemes and SCM detection
- ✅ **Error handling**: Provides helpful error messages if configuration is missing
- ⚙️ **Customization**: Add `[tool.setuptools_scm]` section when you need custom options
Previous versions had a "simplified" activation where listing `setuptools_scm`
in `build-system.requires` together with `project.dynamic = ["version"]` would
auto-enable version inference. This behavior was removed due to regressions and
ambiguous activation.

Both package names are detected: `setuptools_scm` and `setuptools-scm` (with dash).
The new simplified activation using the `[simple]` extra provides the same
convenience but with explicit opt-in, making it clear when version inference
should be enabled.

### Version files

Expand Down
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ dependencies = [
]
[project.optional-dependencies]
rich = ["rich"]
simple = []
toml = []

[dependency-groups]
Expand All @@ -67,6 +68,8 @@ test = [
"pytest",
"pytest-timeout", # Timeout protection for CI/CD
"rich",
"ruff",
"mypy~=1.13.0", # pinned to old for python 3.8
'typing-extensions; python_version < "3.11"',
"wheel",
"griffe",
Expand Down
Loading
Loading