PEP 735: Dependency Groups in pyproject.toml

In the poetry orbit, we do allow dependencies to be installed in an editable way. You’ll never hear complaints about something that works, and people use. We do hear people wanting a way to switch between regular installs and editable installs however. For that, we’d probably want to store multiple ways to install a dependency, and ``switch’’ between them. This completely breaks poetry workflow though, as the dependency graph of the stable install (probably a wheel) would be completely different to the editable install (probably a git checkout). That’s not an insurmountable problem though, and recalculating the dependency graph on a (hypothetical) command like `poetry install --develop=dep1,dep2’ is…probably OK? This is not at all how it currently works however, if you specify a dep as editable in pyproject.toml, that’s how it’s installed.

1 Like

I don’t think editable absolutely has to be standardized. To clarify, I didn’t mean that we need an answer that works for every tool, or some plan for how all tools support such cases.

I only mean that for the tools which already care to support this (I’m thinking of Poetry and PDM here primarily), we should make it possible.

For nox, tox and hatch I don’t think that any really allows me to configure things in precisely the way that I want for this. The problem is that they attach tasks to environments. With hatch you can define an environment like test-env and then tasks (“scripts”) within that environment like run-tests or run-slow-tests and then you can perform the tasks in the environment like:

hatch run test-env:run-tests

With nox there is no clear distinction between environments and tasks so you just have “sessions” and you can make a session called test that both builds the environment and runs the tests like

nox -s test

What I actually want is to be able to reuse the defined task “run the tests” but with a different environment that I created perhaps using completely different tools like:

nox --env=../my-env -s test

I’m not sure if this could work with nox because the first thing that the test session does is likely session.install("pytest", dep1", "dep2==2.3", ...) i.e. the session begins by building an environment. Since tox is configured statically it could make more sense to have tox --env=.... With hatch it could potentially make sense if you could create a variant of a particular environment like:

hatch env create my-env --variant-of test-env --editable=dep1:../dep1.git
hatch run my-env:run-tests

I need the environment to be a variant of test-env primarily because test-env owns the run-tests task but it might also be convenient to inherit the dependencies from test-env as long as you can override some with e.g. --editable.

For my use cases I don’t really want this environment to be something that is described persistently in pyproject.toml/noxfile/tox.ini. This is usually an environment that I will create temporarily and locally so that I can do something like bisect a bug that is triggered by a change in dep1 or prepare a pull request for dep1 while checking against the test suite from the current project. It also does not really make sense to share this configuration with anyone else because this needs to be configured with the local paths to the projects in my system.

More generally I would want to be able to perform tasks using an arbitrary environment that I created using completely different tools outside of the project like:

virtualenv myenv
source myenv/bin/activate

# Install proj1 and proj2 in editable mode
# and install their test dependencies
pip install -e ./proj1 -e ./proj2 -G ./proj1:test -G ./proj2:test

# Run tests for proj1/proj2 in *this* environment:
cd proj1 && nox --env=../myenv -s test
cd proj2 && hatch run --env=../myenv test-env:run-tests

I don’t necessarily want nox/hatch to create this environment but as long as they own the configuration for things like running the tests then I want them to cooperate with me if I have created my own environment without them somehow. Potentially what would be best is if nox/hatch did not own the configuration for how to run the tests in the first place and then I would not need to use either nox or hatch at all in this situation. In fact ideally there would be a single way to say “run the tests in the current environment” for either proj1 or proj2 without needing to know whether the projects use hatch or nox.

1 Like

Taking a very reductionist view, how is this different from myenv\Scripts\python.exe run_tests.py (with a suitable run_tests.py script, of course)?

I see what you’re asking for, but if you want environments and tasks to be this decoupled, it’s not completely clear to me what added value a “workflow manager” tool offers.

It is not much different except that a project that uses nox might not have such a script and also you would want an associated requirements.txt.

I’m not sure what you mean by a “workflow manager”. Do you mean like nox and hatch or something else?

I think that nox and hatch are useful for the common case of a developer working on the project running a bunch of tasks in a defined set of environments. These tools just get in the way when you want to do something that is not in their defined set of environments.

I presume that this is why projects end up doing things like persistently configuring an environment in which some dependencies are specified to be editable: if you do not have a defined environment in which the dependency is editable then the environment manager makes it difficult to create or use such an environment. A better solution though is often just to get the environment management tool out of the way but that means that you want access to their config (dependency groups, task commands, etc) from outside.

Note that there are other situations where you would want to have the tasks be decoupled e.g. a downstream packager would want to do things like run the tests but in their own environment so again nox/hatch would just get in the way for them.

1 Like

I understand that viewpoint, and while I appreciate the work that they do, I will never limit capabilities of our ecosystem or preclude experimentation just to make their lives easier.

I care almost exclusively about the user (myself included) and in that sense the only external tool I care much about interoperating with is IDEs like Visual Studio Code. And for that, like I mentioned earlier in the thread, Brett’s proposal is the right approach.

2 Likes

I believe path, VCS, and editable dependencies could be standardized (nice to have, but kind of must have since hatch, poetry, and so on already have it) but they should be left out of pyproject.toml. I think we might need some kind of “override” file for this kind of info (concrete dependencies). This file could be committed to the git repository but tools should probably not take it into account by default, it should be opt-in.

tool run --group='docs' --task='build-pdf'

and

tool run --group='docs' --task='build-pdf' --override='my-overrides.mp3'

where my-overrides.mp3 contains the info to install sphinx from my own GitHub fork at some specific branch.

I think your situation is significantly different from the two use cases which I want to support.

For me, the ones which I know about are:

  • I want to run tests with the current package (.) installed as editable
  • the monorepo case

I’m going to try to sketch out the monorepo situation as a quick user story here…


Angela and her team work at $COMPANY , where they maintain an application which consists of a web API and two distinct worker processes. All three components talk to the same database, and they additionally communicate with one another using a wire protocol (could be protobuf, messagepack, or maybe something custom). As such, they need to have a synchronized copy of some core code.

Angela’s team decides to structure their code as a monorepo so that they will ship and version “the whole application”, rather than moving the parts independently. The monorepo will also allow them to share code between the API and the workers by having repo-local dependencies. Their repo structure is:

+ company-product/
  +- api/
  +- worker1/
  +- worker2/
  +- common-core/

All three of api/, worker1/, and worker2/ are full packages, as is common-core/. And all three of api/, worker1/, and worker2/ depend on common-core/.

Angela wants to ensure that all of her team members get an editable install of common-core/ in their test environments for the three main application pieces. Frequently, she finds that without this, less experienced python developers are making changes in common-core/ and then having difficulty understanding why their changes are not showing up when they run the tests for the API or workers.

How should Angela make sure that the environments are constructed correctly for these dependencies?

3 Likes

It doesn’t need to be evicted from pyproject.toml: the [tool] tables exist to take this on.

One way to semi-standardize these options is to say something like “PEP 735 does not make an effort to standardize these types[1] of dependencies, but workflow managers may define configuration to augment specific dependency-groups in their [tool] config”

The idea being to punt on standardizing this bit of configuration, but allow existing tools to support it while still standardizing on what can be agreed on today.


  1. potentially all three types, or just the editable deps, or whatever ↩︎

2 Likes

Could be both. The important bit is the opt-in. There could be 1 or 2 sets of overrides in pyproject.toml, for example in the case of a monorepo because there is one obvious development setup that everyone can agree on (or it is the policy in the team or whatever). But one should also be able to provide their own set of overrides easily, something that might work for them only and there is not point in committing it to the shared repository.

I’m fully okay with making that kind of move if we can explain how the dependency group data could be augmented in a [tool] config.

Taking the monorepo story I laid out, a likely desirable config for each of the applications is

[dependency-groups]
production = [{path = "."}, {path = "../common-core"}]
test = [
  "pytest",
  {path = ".", editable = true},
  {path = "../common-core", editable = true}
]

Suppose we remove editable from the spec. How should a tool support recording, in pyproject.toml or its own separate config, that under test the path dependencies should be installed as editable?

It’s very easy to say “some config” or “some flag”, but I’d like to be much more concrete. Maybe it’s trivial to specify such config – if so, then it should be trivial to do it in this thread.

1 Like

I agree but I think that part is outside of a dependency-group PEP, right? Tools will define external overrides or config files if they need to.

Hm I realized while writing up a strawman example that I misremembered the spec you’ve written. This is a little simpler when everything is a table. But one possible path: tools could include their own dependency-groups table and merge the two tables with dict-update semantics: the tool-specific table overrides/adds to the main table.

I would tweak one aspect of your current examples: I think something like name should be required, even for local installs.

[dependency-groups]
production = [{name = "mypackage", path = "."}, {name = "core", path = "../common-core"}]
test = [
  "pytest", "[production]",  # assuming this is still allowed
]

# tool specific overrides for the test group
[tool.mytool.dependency-groups.test]
pytest = { editable = true }
mypackage = { editable = true }
core = { editable = true }

Implicit here is the requirement that an array of dependencies is converted into a table of dependency objects–so the tool must read the test group and creates {name = "pytest"} and expands [production] into its component pieces. Then when it reads the tool specific table it can merge in those settings.

That might get a little confusing, and it could be simpler to say “it’s all tables”, but I’m not sure.

A sneaky bit here is that mytool could be written to support editable = true in the [dependency-group] table itself–but this wouldn’t be standardized across tools and might lead to confusing behavior. So perhaps it’d be better to say “no undefined fields in the main table, you must use an override table” in the PEP.

[dependency-groups]
# `.` is the only path-like value accepted and it stands for the current project 
production = ["."]
test = ["pytest", "."]
index-url = "https://corporate-repo.test/simple/"

[mypackage]
editable = true

[common-core]
path = "../commone-core"
editable = true

[pytest]
version = "<7.4"

Basically it is this idea.

Maybe we can play with having one set of default “overrides” (i.e. concrete dependencies) per dependency group, as long as it is easy to opt-out of those defaults and use another set of overrides instead.

1 Like

In fairness, it has gone through two major revisions since the initial post! I’ve tried to communicate that well, but it’s hard to make sure everyone sees the update messages when the thread is active.

One of the reasons I won’t remove editable too quickly is to keep the draft PEP more stable during discussion. (A lesson I’ve learned in the past week, more or less.) If we reach a point in which there’s consensus that it should be removed, additionally meeting the constraint that we have a palatable solution for PDM and Poetry, then we can remove it.

To some degree it’s outside of this PEP, but there are three main ways in which it is involved:

  1. Poetry and PDM already allow dependencies specified in their dependency group implementations to be declared as editable.

Any dependency group spec which wants to support these usages needs a plan for how these tools will adapt, and I believe that there needs to be buy-in from the Poetry and/or PDM maintainers.
You could ignore Poetry and PDM – say it’s the tool authors’ job to handle how the new feature will play with their implementations – that is very much not the approach I’m taking with this PEP. If it doesn’t have the support or acceptance of the Poetry and PDM devs, I think we need to stop what we’re doing. My belief is that failing to incorporate the needs of these tools will fracture the ecosystem further, rather than unify it with a common spec.

  1. requirements.txt files support -e.

You can choose to color those cases as outside of what we’re seeking to support or not.
It’s a similar situation to the Poetry & PDM one.
Again, my current belief is that without a clear notion of how use-cases which are relying on -e ../foo in a requirements file will be supported, we’ll be going in the wrong direction – adding options without sufficiently unifying the current community use cases and needs.

  1. The current PEP, as written, is very careful to allow tools to control editable installs via overrides (without specifying a mechanism).

That is, if the spec includes editable and wants to support overriding that setting, it is written differently from a spec which treats the editable value as strictly enforced (SHOULD vs MUST).


To pick one thing out, I don’t think this is sufficient.
Extras, sibling directories, and only_deps are all important inclusions in the current spec.

Paul has already said that as a pip maintainer, he doesn’t want to implement both the --only-deps flag and Dependency Groups. (And I’m not sure if my slicing this issue down the middle by proposing a control in Dependency Groups which mirrors the flag is sufficient!)

I need to think more about the rest of what you’re suggesting, and how that would be usable for Poetry and PDM. It’s worth noting that we’ve already had the PDM author chime in in this thread to say that

  • the spec isn’t useful without a solution for editable local path dependencies
  • we need to be formulating some common approach for complex dependency data (which I took to mean that we need to look beyond PEP 508 strings), rather than each tool solving this from scratch

I agree on the second point, which is a matter of opinion. The first is more or less an implementation telling us about their situation, so I treat it more as a statement of fact than opinion.

It’s okay for the solution offered to be something which sits alongside the PEP, but PDM and/or Poetry would need to be onboard. (I haven’t considered yet what it would mean if one tool likes the solution and the other doesn’t. Frankly, I’m hoping that I never need to confront that possibility.) So is your proposal that each tool has a table for dependency group augmentation? e.g.

[dependency-groups]
production = [{path = "."}, {path = "../common-core"}]
test = ["pytest", {include = "production"}]

[tool.pdm.dependency-groups]
use_editable = ["test"]

?

This is very similar to @jamestwebber’s suggestion above, but limited to a subset of the current proposed syntax.

Regarding that…

Why should we require a name field? Is it only to reference the path dependency in a later config? If you need to refer to a path dependency later, why not use the package name or the path string? Would you require the name to match the package name?

This would be a relatively easy addition to the spec, but I don’t understand why we would include it.


I think something that I’m missing is why, exactly, editable seems to be a major point of contention. Some tools want it included in the spec.

Several people seem to have some high-level concerns that this is the wrong level of abstraction for that information. But would its inclusion be a deal breaker for someone? Is there a practical negative consequence of having editable in the spec?

I’m aware that Hatch doesn’t support editable installs today. This is the only place where I see clear negative impact. I’ve written things such that Hatch would be free to always ignore editable = true (and could emit a warning upon seeing it). It’s not an ideal outcome, but I think it’s livable.
Hatch could also ignore dependency groups and rely on the ability of users to invoke pip when setting up an environment (which is the current solution for having editable installs in a Hatch environment, as I understand it) to provide support.

1 Like

I didn’t communicate well there. It’s definitely useful for there to be a clear solution for extension by these tools, but I don’t think the specification for how that works need be in the PEP. As long as a proof-of-concept exists and is agreed to be viable.

Buy-in from maintainers is certainly key as well.

It feels a little weird to have unnamed dependencies (“install whatever package you find at this path”) although I guess there’s no real issue with it. I do worry a bit about naming collisions if the package name is dynamic data. On the other hand I didn’t like needing to type it out, even in that small example.

I guess that just a cheat toward the idea of having it all be tables, and the package name is the table name. This is more like Cargo.toml, with the difference that they always have at least the version to store. It isn’t simple to add an empty table[1], which is what we’d want for basic dependencies.


  1. you can do it with pytest = {} but that’s ugly ↩︎

By configuring the creation of the test environments at the level of the monorepo rather than in each individual project?

Marking dependencies as editable in pyproject.toml sounds to me like using project-level configuration and tooling for things that would be more appropriately handled at the monorepo level.

Rather than doing

cd worker1 && nox

they could do

mono-nox worker1

Here mono-nox is a hypothetical nox like tool for monorepos. It knows because of the mono-nox.ini configuration file which of the dependencies of worker1 should be installed from the local directory in the monorepo rather than from PyPI or a local index. This might use editable installs or it might build fresh environments depending on configuration in mono-nox.ini. Also mono-nox could be used to choose which project’s test suite should be run based on which have changed e.g. if common-core is changed then you should probably run its test suite and test all of its dependents as well.

It would not be difficult to support both project-level nox and also monorepo level mono-nox if the configuration of tasks and dependencies were separated as I described above. Ideally mono-nox could reach into each project and extract dependency groups as well as commands for running the tests, etc. This way the project lists its dependency groups without reference to whether or not they should be editable but it is the mono-nox configuration that understands if you want to use all local versions from the monorepo.

In the situation I described I essentially want a mono-nox like tool as well: the main difference is just that since I don’t have a monorepo I don’t have an obvious place to store mono-nox.ini.

2 Likes

My belief is somewhat contrary - without a clear notion of what people want in the way of editable support, we should refuse the temptation to guess. If people are currently using existing mechanisms, and they aren’t engaging with the PEP process, then (assuming we’ve done sufficient outreach to ensure they are aware that their opinions are being sought) we can reasonably assume that they don’t have strong views, and we’d be better off keeping editable installs out of scope until there’s sufficient interest.

The monorepo example is interesting but I still feel that there’s a bit of an XY problem involved. The problem that editable installs are solving feels to me very much like it’s being framed in a way that assumes that editable installs are the solution, so we’re not understanding the real issue yet. For example,

Sure, but Angela also gets regular complaints from other developers that their tests randomly stop working because someone has changed the common-core code without communicating with the consumers of that code. Using non-editable installs would isolate the tests from such unexpected changes.

So editable installs are choosing one trade-off over another, rather than solving the underlying issue (whatever that issue is).

I’ve just skimmed this section of the proposal and no, it isn’t. Pip would allow pip install --only-deps requests, but your proposal only allows only_deps on path dependencies. To me, this indicates that there’s a fundamental misunderstanding here - dependency groups and --only-deps are two fundamentally different solutions to the underlying problem, with different trade-offs, different strengths and different weaknesses. You can’t simply merge the two of them by adding a flag like this. And yes, I know I said earlier that --only-deps was a strict superset of dependency groups - that was in the context of a very specific constraint, that we were only talking about projects which are intended to build a wheel, and we were OK with using extras (and hence including the group in the package metadata). That constraint is precisely what I mean by trade-offs.

I really don’t have a strong opinion yet on whether --only-deps or dependency groups is the better solution here. I’m still struggling to get a proper feel for either of them in terms of a useful set of use cases. But I am still of the opinion that we should pick one and implement it, not try to merge them. And if we can’t decide which approach is best, we’ve not understood the problem well enough yet, and we should hold off on both.

On the first point, as I said, I think we need to know more about why the spec isn’t useful to PDM without support for editables. They have practical experience of people needing/using editable install support, so can they share it? Otherwise, point one is little more than PDM stating their preference, and while that’s valuable, so is everyone else’s preference. (And you’re unlikely to be able to please everyone…)

On the second point, I agree in principle, but does it need to happen in this PEP? Like PEP 508, maybe we should standardise the language for describing this “more complex dependency data” before we try to define functionality that uses the data.

For the same reason that URL dependencies have the name @ portion, I assume - to refer to the dependency by name. And I would expect that the name would be required to match the project name, but for that requirement to be of the form “your data is incorrect if it doesn’t” rather than “tools should check this and give an error if it doesn’t”.

For me, I want to understand why people want it. Yes, I’d like to consider whether there are other ways of addressing the underlying requirement, but fundamentally, I just want to know why it’s so important. People ask for support for hashes, and for the ability to specify index URLs, and those features just got declared out of scope. I guess I’m missing why editables are so different.

The main cost for me is just added complexity, in terms of implementation and in terms of teaching the feature to new users. How do we explain to a newcomer when to use editable and when not to? Not all build backends support editable installs, so how does that affect things? Setuptools has multiple ways of implementing editable installs, how would a user choose a particular one? If you can’t, what does the user do?

That, for me, is the most important negative of supporting editable installs, and I’m not yet personally convinced that the benefits (which frankly aren’t very clear to me) justify that cost.

4 Likes

Yes I would say that the concern is because that approach attempts to standardize a concept that no Python tool in existence does properly. PDM and Poetry treat that the same way as pip and just guarantees the source code is updated in real time, not dependencies. That is not what users want but rather they want a guarantee for the source code and dependencies.

For example, pretend you are writing Rust or Go and you depend on a path to a local project. If you told a user that a build would incorporate changes to that directory’s source code but not dependencies/metadata they would be bewildered.

Unfortunately, I keep saying that but it’s not having an effect so I will gracefully bow out of this discussion now :slightly_smiling_face:

6 Likes

Not completely lacking in effect - I agree with this concern, and you’ve stated it better than I’d managed to do.

Editable installs are fundamentally incomplete. They do not correctly implement the idea of “an installed package that I can modify in-place”. The fact that setuptools has multiple implementations of editable installs, with different trade-offs, emphasises the fact that there’s no complete and correct solution here.

Using an editable install should therefore, IMO, always be a choice for the individual developer, who is the only person who can evaluate the trade-offs involved. Project-level configuration should (again IMO) only state what is to be installed, and not how it should be installed.

At this point, I don’t have anything further to say myself (with my “individual developer” or “pip maintainer” hat on), so I’ll leave it at that. And with my PEP delegate hat[1] on, I’ll simply say that the PEP needs to acknowledge and address these concerns before I’ll be happy accepting it as a fair representation of the discussion here.


  1. I have too many hats! :tophat: :billed_cap: ↩︎

7 Likes

I may need to reduce my engagement on this thread. Writing replies here is taking the time I have allocated in my schedule for working on the PEP, which means that I’m behind where I want to be.

In fact, I wanted to put the whole debate around editable on ice earlier, to focus on other things. But then the conversation barrelled ahead here and I got sucked in. I’m not criticizing anyone here – it’s just very hard to wrangle a thread with this many participants and I may have been foolish in requesting that we temporarily table editable.

We’re still missing a solid write-up of the two things which we agreed upon earlier:

  • Use Cases
  • Prior Art

There are some additions in-thread which I can take for content to try to document these systematically.

Regardless of the outcome, I will try to make sure I capture the debate accurately.

Either it will be in Rejected Ideas or not, but some part of the document needs to reckon with this.

I think this is correct. My grasp of the monorepo case is based on the observation of how people are using editable installs to handle monorepos – very much derived from users exploring the available tools and finding what works best for them today.

I’ll try to turn this into a use case which is stated in the abstract, without presupposing that editable = true is the right solution.

It seems that I misunderstood significantly. Or perhaps I tried to take what looked like an “easy” solution without adequately considering the impact.

The request which prompts --only-deps is a user who wants to install project.dependencies, potentially with some segment of project.optional-dependencies (extras), but without building and installing the relevant package. I’ll focus only on project.dependencies for the moment, with the expectation that a good solution for that can be extended to optional-dependencies.
A build may be required for dynamic dependency data.

If those same dependencies are represented in a dependency group, then the user would need a way to refer to them in project.dependencies. e.g. via dynamic metadata:

[dependency-groups]
production = ["foo"]
[project]
dynamic = ["dependencies"]
[tool.my-build-tool.dynamic]
dependencies = {group = "production"}

If the package dependencies are instead represented in a concrete [project.dependencies] table, it would be necessary to have a way for a dependency group to refer to that table.

I can easily understand how the dynamic dependencies solution would work. I’m not sure how a dependency group can refer to project.dependencies other than something equivalent to {path = ".", only_deps = True}.
I can imagine things like {toml_path = "pyproject.toml:project.dependencies"}, but is that really what’s wanted here? It seems oddly specific for this scenario and wouldn’t handle dynamic dependencies at all.

For these cases, I want to try to understand, are we looking at dependency groups as a fully orthogonal feature with no built-in support for getting at project.dependencies? Or are we looking for some alternative way for a dependency group to implicitly include project.dependencies?

From your reply, it feels like omitting only_deps as a flag on path dependencies and suggesting the dynamic metadata approach – as an example of how implementations can combine the data – would have been closer to your expectations.

I’m still missing a deeper grasp of the usage here. But I’d like to make sure I understand your comment properly.

Granted, we should try to understand this better. But I think such a line of investigation is quite likely to end up back at the same point as the monorepo example: users request and use editables to solve some (ill-specified) problems. So the tool supports it, in order to support those users.

That is to say:
PDM and Poetry developers might not have a full grasp of the usages, other than the fact that users have requested and use the flag, and would be upset if it were removed.

Operating on that assumption that there’s limited information for us to gain (I’m not giving up but I am pessimistic), Poetry and PDM will both want to be able to adopt the new feature and support their existing users who are using editables. If I’m right, we won’t learn much more than that.

I’ve looked a bit at the main request for editable support in Hatch, and the users there seem to be entirely of the monorepo class. I’d love to hear if there are other editable-install usage scenarios which people know about. I only know of the two which I mentioned earlier, monorepos and pip install -e ..

This is why I put so much weight on having a complete proposal for how these tools will “post-apply” the editable=true setting for a given set of dependencies, if editable is removed. My assumption is that regardless of how well or how poorly we understand the use cases, PDM and Poetry will see this feature as a requirement for them to support dependency groups.

I mostly followed this line of thinking by proposing the use of objects for specifications that are not PEP 508 specifiers.

I think we need path dependencies and extras. That covers ., .[dev], ../foo, and ../foo[bar] (all valid in requirements.txt). This could have been allowed as string data, but I much prefer that we explicitly tag these as paths.

More than one person has requested the ability to include one dependency group in another, a la -r. I think this is reasonable, but debates about syntax left me feeling that extending PEP 508 was, again, trying to bake complexity and information into a string which simply didn’t need to be tackled there. So I introduced {include = "foo"}.

Basically, I don’t see a good reason to force all of our data into strings when the spec is only laying out TOML content.
Either we need to describe the data in some explicit way (as objects) or we need to devise a DSL which extends PEP 508 such that its specifiers are unambiguously not PEP 508.

The choice between extending PEP 508 with some augmented string syntax and objects for dependency specifiers seems somewhat independent from knowing exactly what the non-PEP 508 data are.

It’s not possible to write this PEP without some way to specify these as-yet-non-standardized ideas, unless we exclude -r and paths from the PEP. We could cut those features, which neatly sidesteps editable and only_deps, and declare that PEP 735 only contains PEP 508 specifiers. However, at that point, I expect that we’re leaving too much on the table and reception of the PEP would be tepid at best.

I need to read up on this. I’m not clear on why URL dependencies need to be named either. (Sorry for my ignorance, but it’s the truth! :sweat_smile: )

To some degree, I’m inclined to compare {path = "foo"} to foo/ in a requirements.txt. So if it needs to be {name = "foo", path = "foo"}, I want to make sure I fully grasp why the path dependency in the PEP needs more information than pip needs to install.

I hate giving this answer, but “because PDM and Poetry support it” is part of the reasoning here. I’m very, very concerned about putting forth something which inadequately covers the existing solution space, and ending up playing directly into the criticism that packaging is too disparate and has too many different ways of doing similar things.
So that answers part of what you’re asking: why so much spilled ink over editables? Because I’ve made it a requirement of the PEP that it has a clear gameplan for these two tools, and this is a sticking point.

But to the other part of the question, that harder part, why do people really want editables in the first place, such that Poetry and PDM have implemented support and tox has limited (.-only) support? I think I need to take some time off of the forum and try to write up the scenarios which I’ve seen.

Hashes are primarily of importance for lockfiles, which is why I put them firmly out of scope. Poetry and PDM use distinct lockfile formats, outside of pyproject.toml, and including locked dependency data in pyproject.toml is – I think we have general agreement? – not desirable.

My first draft laid claim to a table above the dependency-groups data, and my intent was to allow for index URLs to be specified as part of that table in a future PEP. I removed that as part of trying to solve the (hard) problem of naming this table, but index URLs weren’t outside of the scope which was considered – I just expected/intended that they would be separately solvable in the future.

I apologize if you feel like you’ve been saying this repeatedly. In some way or another, I did not fully follow until this last, most stark declaration of the issue.


There’s quite a lot of information here to synthesize. Several things interrelate.

For example, @jamestwebber’s earlier suggested way of declaring (in a tool-specific way) that certain path dependencies are editable is predicated on those dependencies being individually named. That works best if we incorporate the suggestion that name be required – which, by my own admission, I don’t fully understand vis-a-vis PEP 508’s requirement for URLs.

As I said at the top of this post, I really want to spend less time staying on top of this thread so that I can work on documenting the things which we’re missing. I will post back here when I intend to do another round of edits other than fleshing out the appendices, which are currently stubs.

9 Likes