<div dir="auto"><div><div class="gmail_extra"><div class="gmail_quote">On Feb 15, 2017 07:41, "Nick Coghlan" <<a href="mailto:ncoghlan@gmail.com">ncoghlan@gmail.com</a>> wrote:<blockquote class="quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="quoted-text">
>> pipenv borrows the Ruby solution to modeling this by having Pipfile<br>
>> for abstract dependency declarations and Pipfile.lock for concrete<br>
>> integration testing ones, so the idea here is to propagate that model<br>
>> to pydist.json by separating the "requires" field with abstract<br>
>> development dependencies from the "integrates" field with concrete<br>
>> deployment dependencies.<br>
><br>
> What's the benefit of putting this in pydist.json? I feel like for the<br>
> usual deployment cases (a) going straight from Pipfile.lock -> venv is<br>
> pretty much sufficient, with no need to put this into a package, but<br>
> (b) if you really do want to put it into a package, then the natural<br>
> approach would be to make an empty wheel like<br>
> "my-django-app-deploy.whl" whose dependencies were the contents of<br>
> Pipfile.lock.<br>
<br>
</div>My goal with the split is to get to a state where:<br>
<br>
- exactly zero projects on PyPI use "==" or "===" in their requires<br>
metadata (because PyPI explicitly prohibits it)<br>
- the vast majority of projects on PyPI *don't* have an "integrates" section<br>
- those projects that do have an `integrates` section have a valid<br>
reason for it (like PyObjC)<br>
<br>
For anyone making the transition from application and web service<br>
development to library and framework development, the transition from<br>
"always pin exact versions of your dependencies for deployment" to<br>
"when publishing a library or framework, only rule out the<br>
combinations that you're pretty sure *won't* work" is one of the<br>
trickiest to deal with as current tools *don't alert you to the fact<br>
that there's a difference to be learned*.<br>
<br>
Restricting what can go into requires creates an opportunity to ask<br>
users whether they're publishing a pre-integrated project or not: if<br>
yes, then they add the "integrates" field and put their pinned<br>
dependencies there; if not, then they relax the "==" constraints to<br>
"~=" or ">=".<br></blockquote></div></div></div><div dir="auto"><br></div><div dir="auto">Ah-hah, this does make sense as a problem, thanks!</div><div dir="auto"><br></div><div dir="auto">However, your solution seems very odd to me :-).</div><div dir="auto"><br></div><div dir="auto">If the goal is to put an "are you sure/yes I'm sure" UX barrier between users and certain version settings, then why make a distinction that every piece of downstream software has to be aware of and ignore? Pypi seems like a funny place in the stack to be implementing this. It would be much simpler to implement this feature at the build system level, like e.g. setuptools could require that dependencies that you think are over strict be specified in an install_requires_yes_i_really_mean_it= field, without requiring any metadata changes.</div><div dir="auto"><br></div><div dir="auto">Basically it sounds like you're saying you want to extend the metadata so that it can represent both broken and non-broken packages, so that both can be created, passed around, and checked for. And I'm saying, how about instead we do that checking when creating the package in the first place.</div><div dir="auto"><br></div><div dir="auto">(Of course I can't see any way to do any of this that won't break existing sdists, but I guess you've already decided you're OK with that. I guess I should say that I'm a bit dubious that this is so important in the first place; I feel like there are lots of legitimate use cases for == dependencies and lots of kinds of linting we might want to apply to try and improve the level of packaging quality.)</div><div dir="auto"><br></div><div dir="auto"><div class="gmail_extra"><div class="gmail_quote"><blockquote class="quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Either way, PyPI will believe your answer, it's just refusing the<br>
temptation to guess that using "==" or "===" in the requires section<br>
is sufficient to indicate that you're deliberately publishing a<br>
pre-integrated project.<br>
<div class="quoted-text"><br>
> There's certainly a distinction to be made between the abstract<br>
> dependencies and the exact locked dependencies, but to me the natural<br>
> way to model that distinction is by re-using the distinction we<br>
> already have been source packages and binary packages. The build<br>
> process for this placeholder wheel is to "compile down" the abstract<br>
> dependencies into concrete dependencies, and the resulting wheel<br>
> encodes the result of this compilation. Again, no new concepts needed.<br>
<br>
</div>Source vs binary isn't where the distinction applies, though. For<br>
example, it's legitimate for PyObjC to have pinned dependencies even<br>
when distributed in source form, as it's a metapackage used solely to<br>
integrate the various PyObjC subprojects into a single "release".<br></blockquote></div></div></div><div dir="auto"><br></div><div dir="auto">?? So that means that some packages have a loosely specified source that compiles down to a more strictly specified binary, and some have a more strictly specified source that compiles down to an equally strictly specified binary. That's... an argument in favor of my way of thinking about it, isn't it? That it can naturally express both situations?</div><div dir="auto"><br></div><div dir="auto">My point is that *for the cases where there's an important distinction between Pipfile and Pipfile.lock*, we already have a way to think about that distinction without introducing new concepts.</div><div dir="auto"><br></div><div dir="auto">-n</div></div>