Skip to content
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

Add a non-package-mode #10204

Open
johnthagen opened this issue Dec 27, 2024 · 13 comments
Open

Add a non-package-mode #10204

johnthagen opened this issue Dec 27, 2024 · 13 comments
Labels
needs-design Needs discussion, investigation, or design

Comments

@johnthagen
Copy link

johnthagen commented Dec 27, 2024

Proposal

For projects that will not be published as wheels but simply want to track/lock their dependencies with uv, it would be nice to be able to omit the following lines from pyproject.toml:

[project]
name = "my-project"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"

Poetry has this feature:

[tool.poetry]
package-mode = false

Configuration Example

A straw-man proposal for how this could be configured in uv:

[project]
requires-python = ">=3.12"
dependencies = [
    "mkdocs>=1.6.1",
]

[tool.uv]
package-mode = false

Motivation

A long thread about motivation for this is in the original Poetry issue

There are many types of Projects where specifying an extra version, name, description, etc is unnecessary and extra boilerplate. For example:

  • A project that uses MkDocs to build a static site and has no Python code in it all (but the user still needs to lock the version of MkDocs and its dependencies for reproducibility)
  • A Django or FastAPI application where the execution mode is usually something like uvicorn main:app or python runserver where no package/wheel is installed
  • A collection of standalone Python files that have requirements but aren't organized into a package installed into a venv

An example referencing the boilerplate in the wild:

Our Django projects won’t really care about the name, version, description, and readme properties, so just leave them as is.

It would also be impossible to publish a non-package-mode project, which helps with the motivation for

Otherwise, someone also needs to add the Private :: Do Not Upload classifier to be extra safe.

Challenges

The complication I see with uv as compared to Poetry is that perhaps it's not technically legal to omit certain fields from the [project] field? But if a project isn't actually defining a true package/wheel perhaps that doesn't matter?

Currently if you run uv sync without these [project] fields, you get an error:

error: Failed to parse: `pyproject.toml`
  Caused by: TOML parse error at line 1, column 1
  |
1 | [project]
  | ^^^^^^^^^
`pyproject.toml` is using the `[project]` table, but the required `project.name` field is not set
@T-256
Copy link
Contributor

T-256 commented Dec 27, 2024

Configuration Example

A straw-man proposal for how this could be configured in uv:

[project]
requires-python = ">=3.12"
dependencies = [
    "mkdocs>=1.6.1",
]

[tool.uv]
package-mode = false

isn't it possible with dependency groups?

# pyproject.toml

[dependency-groups]
dev = [
    "mkdocs>=1.6.1",
]

You can use this in combination of .python-version file or with --python cli option.

@johnthagen
Copy link
Author

@T-256 Using your pyproject.toml without a [project] field, uv sync fails:

$ uv sync
error: No `project` table found in: `/pyproject.toml`

@charliermarsh
Copy link
Member

If you add [tool.uv.workspace] to it, it won't fail.

@johnthagen
Copy link
Author

johnthagen commented Dec 27, 2024

Thanks @charliermarsh! Is [tool.uv.workspace] intended to solve the use case described in this issue?

Reading the workspace docs, it seems like more of a multi-project feature rather than a "single project but I don't need the wheel project metadata" feature?

I ask because I was trying to think through how I would explain this to someone else using single Django or FastAPI application and wanting to avoid the boilerplate of extra [project] fields.

Also, when I run this way, even with a .python-version I get a warning:

warning: No `requires-python` value found in the workspace. Defaulting to `>=3.13`.

And it seems that requires-python is not allowed at the [tool.uv.workspace] level. And I think typically we'd want to steer away from needing to generate warnings.

@T-256
Copy link
Contributor

T-256 commented Dec 27, 2024

If you add [tool.uv.workspace] to it, it won't fail.

When project is not specified and workspace didn't declare, could we improve uv to treat with it as empty workspace?

I also have some environment usages where only need declared dependencies. Rye's virtual project:

If a workspace does not have a toplevel package it's recommended that it's declared as virtual.

@johnthagen
Copy link
Author

johnthagen commented Dec 27, 2024

I also have some environment usages where only need declared dependencies. Rye's virtual project:

@T-256 Oh nice. I haven't used Rye before, but that looks like it's filling the exact use case I'm referring that and the same use case as Poetry's package-mode = false.

@charliermarsh
Copy link
Member

Yeah we might improve it over time, but right now it is recommended that you create a [project] table. The example you gave would actually violate standards:

[project]
requires-python = ">=3.12"
dependencies = [
    "mkdocs>=1.6.1",
]

The standard declares that you must have at least a package name and a version (or a dynamic version) -- this isn't a uv thing, it's a standards thing.

@T-256
Copy link
Contributor

T-256 commented Dec 27, 2024

Also, when I run this way, even with a .python-version I get a warning:

You can run with --python:

> uv sync
Using CPython 3.12.3
Creating virtual environment at: .venv
warning: No `requires-python` value found in the workspace. Defaulting to `>=3.12`.
Resolved 17 packages in 5.69s
Prepared 17 packages in 12.96s
Installed 17 packages in 163ms
 + click==8.1.8
 + colorama==0.4.6
 + ghp-import==2.1.0
 + jinja2==3.1.5
 + markdown==3.7
 + markupsafe==3.0.2
 + mergedeep==1.3.4
 + mkdocs==1.6.1
 + mkdocs-get-deps==0.2.0
 + packaging==24.2
 + pathspec==0.12.1
 + platformdirs==4.3.6
 + python-dateutil==2.9.0.post0
 + pyyaml==6.0.2
 + pyyaml-env-tag==0.1
 + six==1.17.0
 + watchdog==6.0.0

> uv sync --python 3.8
Using CPython 3.8.3 interpreter at: C:\Python38\python.exe
Removed virtual environment at: .venv
Creating virtual environment at: .venv
warning: No `requires-python` value found in the workspace. Defaulting to `>=3.8`.
Resolved 22 packages in 1.02s
Prepared 5 packages in 2.19s
Installed 19 packages in 144ms
 + click==8.1.8
 + colorama==0.4.6
 + ghp-import==2.1.0
 + importlib-metadata==8.5.0
 + jinja2==3.1.5
 + markdown==3.7
 + markupsafe==2.1.5
 + mergedeep==1.3.4
 + mkdocs==1.6.1
 + mkdocs-get-deps==0.2.0
 + packaging==24.2
 + pathspec==0.12.1
 + platformdirs==4.3.6
 + python-dateutil==2.9.0.post0
 + pyyaml==6.0.2
 + pyyaml-env-tag==0.1
 + six==1.17.0
 + watchdog==4.0.2
 + zipp==3.20.2

@T-256
Copy link
Contributor

T-256 commented Dec 27, 2024

And it seems that requires-python is not allowed at the [tool.uv.workspace] level. And I think typically we'd want to steer away from needing to generate warnings.

Also, related: #4972, #4970

@johnthagen
Copy link
Author

I was curious how Rye handled this. When passing --virtual it still fills out of the [project] fields. But Rye doesn't require that you keep them (it doesn't seem to validate the [project] field, not sure if that is intentional or not). This pyproject.toml works with Rye 0.43.0:

[project]
dependencies = [
    "mkdocs<1.5",
]
requires-python = ">= 3.8"

[tool.rye]
managed = true
virtual = true
dev-dependencies = []
$ rye sync
Reusing already existing virtualenv
Generating production lockfile: /home/user/Downloads/requirements.lock
Generating dev lockfile: /home/user/Downloads/requirements-dev.lock
Installing dependencies
Resolved 13 packages in 4ms
Audited 13 packages in 0.02ms
Done!

Poetry gets around the issue (currently) because it hasn't released a version that supports [project] table, thus this works:

[tool.poetry]
package-mode = false

[tool.poetry.dependencies]
python = "^3.11"

mkdocs = "*"

I haven't tested Poetry 2.0 which supports [project] in their main branch but hasn't been released. They may run into similar problems for users wanting to use the standard [project] table and omitting unneeded boilerplate if they'd want to enforce standards-compliance.

In any case, I definitely appreciate the challenge of making this work smoothly given the current standards.

@edmorley
Copy link
Contributor

edmorley commented Dec 27, 2024

I feel like the pyproject.toml spec is more restrictive than it should be (given it states name and version are mandatory). (Particularly since the spec purports to be based on the decisions in PEP 518 and PEP 621, but neither of those peps explicitly said name and version should be mandatory.)

I wonder if upstream would be open to revising the spec to state that name and version are only required when building the project using a build backend? (Either the explicitly specified [build-system] or else the implicit one.)

Adjusting the spec in that way would actually be in keeping with other parts of the spec, which already state things like:

Tools should not require the existence of the [build-system] table. A pyproject.toml file may be used to store configuration details other than build-related data and thus lack a [build-system] table legitimately.

(from here)

@T-256
Copy link
Contributor

T-256 commented Dec 27, 2024

I feel like the pyproject.toml spec is more restrictive than it should be (given it states name and version are mandatory). (Particularly since the spec purports to be based on the decisions in PEP 518 and PEP 621, but neither of those peps explicitly said name and version should be mandatory.)

@edmorley I agree with you, to make a workaround for this standard limitation, I think we can use a clone of project and apply uv's infrastructures on it to get rid of limits. opened #10208 to discuss more there.

@charliermarsh charliermarsh added the needs-design Needs discussion, investigation, or design label Dec 28, 2024
@johnthagen
Copy link
Author

johnthagen commented Jan 13, 2025

For reference, Poetry 2.0.1 also took the same stance as uv and (unlike Rye) requires the requires [project] fields (name and version) to exist

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs-design Needs discussion, investigation, or design
Projects
None yet
Development

No branches or pull requests

4 participants