Skip to content

Commit 031f8b8

Browse files
committed
support for packages built with pyproject.toml
1 parent 2809167 commit 031f8b8

File tree

6 files changed

+123
-6
lines changed

6 files changed

+123
-6
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
## 0.8.3dev
44

5+
* [Feature] Add `pkgmt new NAME --use-pyproject-toml`
6+
57
## 0.8.2 (2025-01-08)
68

79
* [Fix] Compatibility with `mistune>=3.1.0`
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
[tool.pytest.ini_options]
2+
addopts = "--pdbcls=IPython.terminal.debugger:Pdb"
3+
4+
[tool.nbqa.addopts]
5+
flake8 = [
6+
# notebooks allow non-top imports
7+
"--extend-ignore=E402",
8+
# jupysql notebooks might have "undefined name" errors
9+
# due to the << operator
10+
# W503, W504 ignore line break after/before
11+
# binary operator since they are conflicting
12+
"--ignore=F821, W503, W504",
13+
]
14+
15+
[tool.pkgmt]
16+
# used to add links to issue numbers in CHANGELOG.md
17+
github = "ploomber/$project_name"
18+
# used to check that the package is importable when running pkgmt setup
19+
package_name = "$package_name"
20+
# defines the conda environment name when using pkgmt setup, if missing,
21+
# package_name is used
22+
env_name = "$project_name"
23+
24+
[tool.pkgmt.check_links]
25+
extensions = ["md", "rst", "py", "ipynb"]
26+
27+
28+
# build settings
29+
# https://github.com/pypa/sampleproject/blob/main/pyproject.toml
30+
31+
[build-system]
32+
requires = ["setuptools"]
33+
build-backend = "setuptools.build_meta"
34+
35+
[project]
36+
name = "$project_name"
37+
version = "0.0.1"
38+
description = "A sample Python project"
39+
readme = "README.md"
40+
requires-python = ">=3.9"
41+
license = { file = "LICENSE.txt" }
42+
keywords = ["sample", "setuptools", "development"]
43+
authors = [{ name = "A. Random Developer", email = "[email protected]" }]
44+
maintainers = [
45+
{ name = "A. Great Maintainer", email = "[email protected]" },
46+
]
47+
classifiers = [
48+
"Programming Language :: Python :: 3",
49+
"Programming Language :: Python :: 3.9",
50+
"Programming Language :: Python :: 3.10",
51+
"Programming Language :: Python :: 3.11",
52+
"Programming Language :: Python :: 3.12",
53+
"Programming Language :: Python :: 3.13",
54+
"Programming Language :: Python :: 3 :: Only",
55+
]
56+
dependencies = []
57+
[project.optional-dependencies]
58+
dev = ["pytest", "flake8", "invoke", "twine"]
59+
60+
[project.urls]
61+
"Homepage" = "https://github.com/pypa/sampleproject"
62+
"Bug Reports" = "https://github.com/pypa/sampleproject/issues"
63+
"Funding" = "https://donate.pypi.org"
64+
"Say Thanks!" = "http://saythanks.io/to/example"
65+
"Source" = "https://github.com/pypa/sampleproject/"
66+
67+
[project.scripts]
68+
$project_name = "$package_name.cli:cli"
69+
70+
[tool.setuptools]
71+
package-data = { "$package_name" = ["assets/*", "*.md"] }

src/pkgmt/assets/template/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ flake8 = [
99
# due to the << operator
1010
# W503, W504 ignore line break after/before
1111
# binary operator since they are conflicting
12-
"--ignore=F821, W503, W504"
12+
"--ignore=F821, W503, W504",
1313
]
1414

1515
[tool.pkgmt]

src/pkgmt/cli.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,15 @@ def check_links(only_404):
4242

4343
@cli.command()
4444
@click.argument("name")
45-
def new(name):
45+
@click.option(
46+
"--use-pyproject-toml",
47+
is_flag=True,
48+
default=False,
49+
help="Use pyproject.toml instead of setup.py",
50+
)
51+
def new(name, use_pyproject_toml):
4652
"""Create new package"""
47-
new_.package(name)
53+
new_.package(name, use_setup_py=not use_pyproject_toml)
4854

4955

5056
@cli.command()

src/pkgmt/new.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ def render_inplace(path, **kwargs):
1212
path.write_text(template.safe_substitute(**kwargs))
1313

1414

15-
def package(name):
15+
def package(name, use_setup_py=False):
1616
"""Create a new package"""
1717
project_name = name.replace("_", "-")
1818
package_name = name.replace("-", "_")
@@ -32,6 +32,7 @@ def package(name):
3232
"tasks.py",
3333
"MANIFEST.in",
3434
"pyproject.toml",
35+
"pyproject-setup.toml",
3536
".github/workflows/ci.yml",
3637
):
3738
render_inplace(
@@ -41,3 +42,12 @@ def package(name):
4142
)
4243

4344
os.rename(root / "src" / "package_name", root / "src" / package_name)
45+
46+
if use_setup_py:
47+
(root / "pyproject-setup.toml").unlink()
48+
else:
49+
(root / "pyproject.toml").unlink()
50+
(root / "setup.py").unlink()
51+
(root / "MANIFEST.in").unlink()
52+
(root / "pyproject-setup.toml").rename(root / "pyproject.toml")
53+
(root / "src" / package_name / "__init__.py").write_text("")

tests/test_new.py

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,48 @@ def uninstall():
1111
subprocess.check_call(["pip", "uninstall", "somepkg", "-y"])
1212

1313

14-
def test_package(tmp_empty, uninstall):
15-
new.package("some-cool_pkg")
14+
def test_package_setup_py(tmp_empty, uninstall):
15+
new.package("some-cool_pkg", use_setup_py=True)
1616

1717
subprocess.check_call(["pip", "install", "some-cool-pkg/"])
1818

1919
pyproject = Path("some-cool-pkg", "pyproject.toml").read_text()
2020
setup = Path("some-cool-pkg", "setup.py").read_text()
2121
ci = Path("some-cool-pkg", ".github", "workflows", "ci.yml").read_text()
2222
manifest = Path("some-cool-pkg", "MANIFEST.in").read_text()
23+
init = Path("some-cool-pkg", "src", "some_cool_pkg", "__init__.py").read_text()
2324

25+
assert '__version__ = "0.1dev"\n' == init
2426
assert 'github = "ploomber/some-cool-pkg"' in pyproject
2527
assert 'package_name = "some_cool_pkg"' in pyproject
2628
assert 'env_name = "some-cool-pkg"' in pyproject
2729
assert 'name="some-cool-pkg"' in setup
2830
assert "src/some_cool_pkg/__init__.py" in setup
2931
assert 'python -c "import some_cool_pkg"' in ci
3032
assert "graft src/some_cool_pkg/assets" in manifest
33+
34+
35+
def test_package_pyproject_toml(tmp_empty, uninstall):
36+
new.package("some-cool_pkg", use_setup_py=False)
37+
38+
subprocess.check_call(["pip", "install", "some-cool-pkg/"])
39+
40+
pyproject = Path("some-cool-pkg", "pyproject.toml").read_text()
41+
ci = Path("some-cool-pkg", ".github", "workflows", "ci.yml").read_text()
42+
init = Path("some-cool-pkg", "src", "some_cool_pkg", "__init__.py").read_text()
43+
44+
assert not Path("some-cool-pkg", "setup.py").exists()
45+
assert not Path("some-cool-pkg", "MANIFEST.in").exists()
46+
assert not Path("some-cool-pkg", "pyproject-setup.toml").exists()
47+
48+
assert init == ""
49+
50+
assert 'github = "ploomber/some-cool-pkg"' in pyproject
51+
assert 'package_name = "some_cool_pkg"' in pyproject
52+
assert 'env_name = "some-cool-pkg"' in pyproject
53+
54+
# build settings
55+
assert 'name = "some-cool-pkg"' in pyproject
56+
assert 'package-data = { "some_cool_pkg" = ["assets/*", "*.md"] }' in pyproject
57+
58+
assert 'python -c "import some_cool_pkg"' in ci

0 commit comments

Comments
 (0)