Skip to content

Commit 7e10fc7

Browse files
authored
Move from setup.py to pyproject.toml (#12129)
* convert setup.py to pyproject.toml * move dev requirements into pyproject.toml * with setup.py gone we can install from root * lint cleanrly state intention to remove * convert precommit to use dev deps * consolidate version to pyproject.toml * editable req get rid of editable-req * docs updates * tweak configs for builds * fix script * changelog * fixes to build * revert unnecesary changes more simplification revert linting more simplification fix don’t need it
1 parent c170211 commit 7e10fc7

File tree

9 files changed

+181
-108
lines changed

9 files changed

+181
-108
lines changed

.bumpversion.cfg

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,6 @@ first_value = 1
3232

3333
[bumpversion:part:nightly]
3434

35-
[bumpversion:file:core/setup.py]
36-
37-
[bumpversion:file:core/dbt/version.py]
35+
[bumpversion:file:core/pyproject.toml]
36+
search = version = "{current_version}"
37+
replace = version = "{new_version}"
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
kind: Under the Hood
2+
body: Move from setup.py to pyproject.toml
3+
time: 2025-10-29T13:34:50.106244-04:00
4+
custom:
5+
Author: emmyoop
6+
Issue: "5696"

ARCHITECTURE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ Each adapter plugin is a standalone python package that includes:
3939

4040
- `dbt/include/[name]`: A "sub-global" dbt project, of YAML and SQL files, that reimplements Jinja macros to use the adapter's supported SQL syntax
4141
- `dbt/adapters/[name]`: Python modules that inherit, and optionally reimplement, the base adapter classes defined in dbt-core
42-
- `setup.py`
42+
- `pyproject.toml`
4343

4444
The Postgres adapter code is the most central, and many of its implementations are used as the default defined in the dbt-core global project. The greater the distance of a data technology from Postgres, the more its adapter plugin may need to reimplement.
4545

core/dbt/version.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
import importlib.util
44
import json
55
import os
6+
import re
7+
from importlib import metadata as importlib_metadata
8+
from pathlib import Path
69
from typing import Iterator, List, Optional, Tuple
710

811
import requests
@@ -226,5 +229,21 @@ def _get_adapter_plugin_names() -> Iterator[str]:
226229
yield plugin_name
227230

228231

229-
__version__ = "1.11.0b4"
232+
def _resolve_version() -> str:
233+
try:
234+
return importlib_metadata.version("dbt-core")
235+
except importlib_metadata.PackageNotFoundError:
236+
pyproject_path = Path(__file__).resolve().parents[1] / "pyproject.toml"
237+
if not pyproject_path.exists():
238+
raise RuntimeError("Unable to locate pyproject.toml to determine dbt-core version")
239+
240+
text = pyproject_path.read_text(encoding="utf-8")
241+
match = re.search(r'^version\s*=\s*"(?P<version>[^"]+)"', text, re.MULTILINE)
242+
if match:
243+
return match.group("version")
244+
245+
raise RuntimeError("Unable to determine dbt-core version from pyproject.toml")
246+
247+
248+
__version__ = _resolve_version()
230249
installed = get_installed_version()

core/pyproject.toml

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
[tool.setuptools]
2+
package-dir = {"" = "."}
3+
include-package-data = true
4+
zip-safe = false
5+
6+
[tool.setuptools.packages.find]
7+
where = ["."]
8+
include = [
9+
"dbt",
10+
"dbt.*",
11+
]
12+
13+
# this needs to match MANIFEST.in for the wheels
14+
[tool.setuptools.package-data]
15+
"dbt" = [
16+
"include/**/*.py",
17+
"include/**/*.sql",
18+
"include/**/*.yml",
19+
"include/**/*.html",
20+
"include/**/*.md",
21+
"include/**/.gitkeep",
22+
"include/**/.gitignore",
23+
"task/docs/**/*.html",
24+
"jsonschemas/**/*.json",
25+
"py.typed",
26+
]
27+
28+
[project]
29+
name = "dbt-core"
30+
version = "1.11.0b4"
31+
description = "With dbt, data analysts and engineers can build analytics the way engineers build applications."
32+
readme = "README.md"
33+
requires-python = ">=3.10"
34+
license = "Apache-2.0"
35+
license-files = ["License.md"] # License.md copied to core/ by build script even though it lives at the root by convention
36+
keywords = []
37+
authors = [
38+
{ name = "dbt Labs", email = "[email protected]" },
39+
]
40+
maintainers = [
41+
{ name = "dbt Labs", email = "[email protected]" },
42+
]
43+
classifiers = [
44+
"Development Status :: 5 - Production/Stable",
45+
"Operating System :: Microsoft :: Windows",
46+
"Operating System :: MacOS :: MacOS X",
47+
"Operating System :: POSIX :: Linux",
48+
"Programming Language :: Python",
49+
"Programming Language :: Python :: 3.10",
50+
"Programming Language :: Python :: 3.11",
51+
"Programming Language :: Python :: 3.12",
52+
"Programming Language :: Python :: 3.13",
53+
"Programming Language :: Python :: Implementation :: CPython",
54+
"Programming Language :: Python :: Implementation :: PyPy",
55+
]
56+
dependencies = [
57+
# ----
58+
# dbt-core uses these packages deeply, throughout the codebase, and there have been breaking changes in past patch releases (even though these are major-version-one).
59+
# Pin to the patch or minor version, and bump in each new minor version of dbt-core.
60+
"agate>=1.7.0,<1.10",
61+
"Jinja2>=3.1.3,<4",
62+
"mashumaro[msgpack]>=3.9,<3.15",
63+
# ----
64+
# dbt-core uses these packages in standard ways. Pin to the major version, and check compatibility
65+
# with major versions in each new minor version of dbt-core.
66+
"click>=8.0.2,<9.0",
67+
"jsonschema>=4.19.1,<5.0",
68+
"networkx>=2.3,<4.0",
69+
"protobuf>=6.0,<7.0",
70+
"requests<3.0.0", # should match dbt-common
71+
"snowplow-tracker>=1.0.2,<2.0",
72+
# ----
73+
# These packages are major-version-0. Keep upper bounds on upcoming minor versions (which could have breaking changes)
74+
# and check compatibility / bump in each new minor version of dbt-core.
75+
"pathspec>=0.9,<0.13",
76+
"sqlparse>=0.5.0,<0.6.0",
77+
# ----
78+
# These are major-version-0 packages also maintained by dbt-labs.
79+
# Accept patches but avoid automatically updating past a set minor version range.
80+
"dbt-extractor>=0.5.0,<=0.6",
81+
"dbt-semantic-interfaces>=0.9.0,<0.10",
82+
# Minor versions for these are expected to be backwards-compatible
83+
"dbt-common>=1.27.0,<2.0",
84+
"dbt-adapters>=1.15.5,<2.0",
85+
"dbt-protos>=1.0.375,<2.0",
86+
"pydantic<3",
87+
# ----
88+
# Expect compatibility with all new versions of these packages, so lower bounds only.
89+
"packaging>20.9",
90+
"pytz>=2015.7",
91+
"pyyaml>=6.0",
92+
"daff>=1.3.46",
93+
"typing-extensions>=4.4",
94+
]
95+
96+
[project.urls]
97+
Homepage = "https://github.com/dbt-labs/dbt-core"
98+
Repository = "https://github.com/dbt-labs/dbt-core.git"
99+
Issues = "https://github.com/dbt-labs/dbt-core/issues"
100+
Changelog = "https://github.com/dbt-labs/dbt-core/blob/main/CHANGELOG.md"
101+
102+
[project.scripts]
103+
dbt = "dbt.cli.main:cli"
104+
105+
[build-system]
106+
requires = [
107+
"setuptools>=61",
108+
"wheel",
109+
]
110+
build-backend = "setuptools.build_meta"

core/setup.py

Lines changed: 21 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -1,101 +1,26 @@
11
#!/usr/bin/env python
2-
import os
3-
import sys
4-
5-
if sys.version_info < (3, 10):
6-
print("Error: dbt does not support this version of Python.")
7-
print("Please upgrade to Python 3.10 or higher.")
8-
sys.exit(1)
92

3+
"""Legacy setuptools shim retained for compatibility with existing workflows. Will be removed in a future version."""
104

115
from setuptools import setup
126

13-
try:
14-
from setuptools import find_namespace_packages
15-
except ImportError:
16-
# the user has a downlevel version of setuptools.
17-
print("Error: dbt requires setuptools v40.1.0 or higher.")
18-
print('Please upgrade setuptools with "pip install --upgrade setuptools" ' "and try again")
19-
sys.exit(1)
20-
21-
22-
this_directory = os.path.abspath(os.path.dirname(__file__))
23-
with open(os.path.join(this_directory, "README.md")) as f:
24-
long_description = f.read()
25-
26-
27-
package_name = "dbt-core"
28-
package_version = "1.11.0b4"
29-
description = """With dbt, data analysts and engineers can build analytics \
30-
the way engineers build applications."""
31-
32-
33-
setup(
34-
name=package_name,
35-
version=package_version,
36-
description=description,
37-
long_description=long_description,
38-
long_description_content_type="text/markdown",
39-
author="dbt Labs",
40-
author_email="[email protected]",
41-
url="https://github.com/dbt-labs/dbt-core",
42-
packages=find_namespace_packages(include=["dbt", "dbt.*"]),
43-
include_package_data=True,
44-
test_suite="test",
45-
entry_points={
46-
"console_scripts": ["dbt = dbt.cli.main:cli"],
47-
},
48-
install_requires=[
49-
# ----
50-
# dbt-core uses these packages deeply, throughout the codebase, and there have been breaking changes in past patch releases (even though these are major-version-one).
51-
# Pin to the patch or minor version, and bump in each new minor version of dbt-core.
52-
"agate>=1.7.0,<1.10",
53-
"Jinja2>=3.1.3,<4",
54-
"mashumaro[msgpack]>=3.9,<3.15",
55-
# ----
56-
# dbt-core uses these packages in standard ways. Pin to the major version, and check compatibility
57-
# with major versions in each new minor version of dbt-core.
58-
"click>=8.0.2,<9.0",
59-
"jsonschema>=4.19.1,<5.0",
60-
"networkx>=2.3,<4.0",
61-
"protobuf>=6.0,<7.0",
62-
"requests<3.0.0", # should match dbt-common
63-
"snowplow-tracker>=1.0.2,<2.0",
64-
# ----
65-
# These packages are major-version-0. Keep upper bounds on upcoming minor versions (which could have breaking changes)
66-
# and check compatibility / bump in each new minor version of dbt-core.
67-
"pathspec>=0.9,<0.13",
68-
"sqlparse>=0.5.0,<0.6.0",
69-
# ----
70-
# These are major-version-0 packages also maintained by dbt-labs.
71-
# Accept patches but avoid automatically updating past a set minor version range.
72-
"dbt-extractor>=0.5.0,<=0.6",
73-
"dbt-semantic-interfaces>=0.9.0,<0.10",
74-
# Minor versions for these are expected to be backwards-compatible
75-
"dbt-common>=1.27.0,<2.0",
76-
"dbt-adapters>=1.15.5,<2.0",
77-
"dbt-protos>=1.0.375,<2.0",
78-
"pydantic<3",
79-
# ----
80-
# Expect compatibility with all new versions of these packages, so lower bounds only.
81-
"packaging>20.9",
82-
"pytz>=2015.7",
83-
"pyyaml>=6.0",
84-
"daff>=1.3.46",
85-
"typing-extensions>=4.4",
86-
# ----
87-
],
88-
zip_safe=False,
89-
classifiers=[
90-
"Development Status :: 5 - Production/Stable",
91-
"License :: OSI Approved :: Apache Software License",
92-
"Operating System :: Microsoft :: Windows",
93-
"Operating System :: MacOS :: MacOS X",
94-
"Operating System :: POSIX :: Linux",
95-
"Programming Language :: Python :: 3.10",
96-
"Programming Language :: Python :: 3.11",
97-
"Programming Language :: Python :: 3.12",
98-
"Programming Language :: Python :: 3.13",
99-
],
100-
python_requires=">=3.10",
101-
)
7+
# the user has a downlevel version of setuptools.
8+
# ----
9+
# dbt-core uses these packages deeply, throughout the codebase, and there have been breaking changes in past patch releases (even though these are major-version-one).
10+
# Pin to the patch or minor version, and bump in each new minor version of dbt-core.
11+
# ----
12+
# dbt-core uses these packages in standard ways. Pin to the major version, and check compatibility
13+
# with major versions in each new minor version of dbt-core.
14+
# ----
15+
# These packages are major-version-0. Keep upper bounds on upcoming minor versions (which could have breaking changes)
16+
# and check compatibility / bump in each new minor version of dbt-core.
17+
# ----
18+
# These are major-version-0 packages also maintained by dbt-labs.
19+
# Accept patches but avoid automatically updating past a set minor version range.
20+
# Minor versions for these are expected to be backwards-compatible
21+
# ----
22+
# Expect compatibility with all new versions of these packages, so lower bounds only.
23+
# ----
24+
25+
if __name__ == "__main__":
26+
setup()

pyproject.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# Root-level pyproject.toml for tool configurations
2+
# Packaging configuration is in core/pyproject.toml
3+
# This file exists so tools like mypy and black can find their config when run from root
4+
15
[tool.mypy]
26
# TODO: widen range of files as we fix issues
37
files = 'core/dbt'

scripts/build-dist.sh

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,20 @@ set -x
1212

1313
rm -rf "$DBT_PATH"/dist
1414
rm -rf "$DBT_PATH"/build
15+
rm -rf "$DBT_PATH"/core/dist
16+
rm -rf "$DBT_PATH"/core/build
17+
1518
mkdir -p "$DBT_PATH"/dist
1619

17-
rm -rf "$DBT_PATH"/core/dist
18-
rm -rf "$DBT_PATH"core/build
20+
# Copy License.md to core/ for inclusion in distribution (required by Apache 2.0)
21+
# The license-files in pyproject.toml references it relative to core/
22+
cp "$DBT_PATH"/License.md "$DBT_PATH"/core/License.md
23+
1924
cd "$DBT_PATH"/core
20-
$PYTHON_BIN setup.py sdist bdist_wheel
21-
cp -r "$DBT_PATH"/"core"/dist/* "$DBT_PATH"/dist/
25+
$PYTHON_BIN -m pip install --upgrade build
26+
$PYTHON_BIN -m build --outdir "$DBT_PATH/dist"
2227

28+
# Clean up License.md that was copied to core/ for build
29+
rm -f "$DBT_PATH/core/License.md"
2330

2431
set +x

scripts/update_dev_packages.sh

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
#!/bin/bash -e
22
set -e
33

4+
# this is used in dbt-common for CI
5+
46
repo=$1
57
ref=$2
68
target_req_file="dev-requirements.txt"
79

810
req_sed_pattern="s|${repo}.git@main|${repo}.git@${ref}|g"
911
if [[ "$OSTYPE" == darwin* ]]; then
10-
# mac ships with a different version of sed that requires a delimiter arg
11-
sed -i "" "$req_sed_pattern" $target_req_file
12+
# mac ships with a different version of sed that requires a delimiter arg
13+
sed -i "" "$req_sed_pattern" "$target_req_file"
1214
else
13-
sed -i "$req_sed_pattern" $target_req_file
15+
sed -i "$req_sed_pattern" "$target_req_file"
1416
fi

0 commit comments

Comments
 (0)