<p dir="ltr"><br>
On 21 Jul 2013 04:43, "Daniel Holth" <<a href="mailto:dholth@gmail.com">dholth@gmail.com</a>> wrote:<br>
><br>
> On Sat, Jul 20, 2013 at 2:10 AM, Nick Coghlan <<a href="mailto:ncoghlan@gmail.com">ncoghlan@gmail.com</a>> wrote:<br>
> > On 20 July 2013 01:47, PJ Eby <<a href="mailto:pje@telecommunity.com">pje@telecommunity.com</a>> wrote:<br>
> >> On Fri, Jul 19, 2013 at 9:10 AM, Nick Coghlan <<a href="mailto:ncoghlan@gmail.com">ncoghlan@gmail.com</a>> wrote:<br>
> >>> Right, I think the reasonable near term solutions are for pip to either:<br>
> >>><br>
> >>> 1. generate zc.buildout style wrappers with absolute paths to avoid<br>
> >>> the implied runtime dependency<br>
> >>> 2. interpret use of script entry points as an implied dependency on<br>
> >>> setuptools and install it even if not otherwise requested<br>
> >>><br>
> >>> Either way, pip would need to do something about its *own* command<br>
> >>> line script, which heavily favours option 1<br>
> >><br>
> >> Option 1 also would address some or all of the startup performance complaint.<br>
> >><br>
> >> It occurs to me that it might actually be a good idea *not* to put the<br>
> >> script wrappers in the standard entry points file, even if that's what<br>
> >> setuptools does right now: if lots of packages use that approach,<br>
> >> it'll slow down the effective indexing for code that's scanning<br>
> >> multiple packages for something like a sqlalchemy adapter.<br>
> >><br>
> >> (Alternately, we could use something like<br>
> >> 'exports-some.group.name.json' so that each export group is a separate<br>
> >> file; this would keep scripts separate from everything else, and<br>
> >> optimize plugin searches falling in a particular group.  In fact, the<br>
> >> files needn't have any contents; it'd be okay to just parse the main<br>
> >> .json for any distribution that has exports in the group you're<br>
> >> looking for.  i.e., the real purpose of the separation of entry points<br>
> >> was always just to avoid loading metadata for distributions that don't<br>
> >> have the kind of exports you're looking for.  In the old world, few<br>
> >> distributions exported anything, so just identifying whether a<br>
> >> distribution had exports was sufficient.  In the new world, more and<br>
> >> more distributions over time will have some kind of export, so knowing<br>
> >> *which* exports they have will become more important.)<br>
> ><br>
> > A not-so-quick sketch of my current thinking:<br>
> ><br>
> > Two new fields in PEP 426: commands and exports<br>
> ><br>
> > Like the core dependency metadata, both get generated files:<br>
> > pydist-commands.json and pydist-exports.json<br>
> ><br>
> > (As far as the performance concern goes, I think longer term we'll<br>
> > probably move to a richer installation database format that includes<br>
> > an SQLite cache file managed by the installers. But near term, I like<br>
> > the idea of being able to check "has commands or not" and "has exports<br>
> > or not" with a single stat call for the appropriate file)<br>
> ><br>
> > Rather than using the "module.name:q<a href="http://ualified.name">ualified.name</a>" format (as the PEP<br>
> > currently does for the install_hooks), "export specifiers" would be<br>
> > defined as a mapping with the following subfields:<br>
> ><br>
> >     * module<br>
> >     * qualname (as per PEP 3155)<br>
> >     * extra<br>
> ><br>
> > Both qualname and extra would be optional. "extra" indicates that the<br>
> > export is only present if that extra is installed.<br>
> ><br>
> > The top level commands field would have three subfields:<br>
> > "wrap_console", "wrap_gui" and "prebuilt". The wrap_console and<br>
> > wrap_gui subfields would both be maps of command names to export<br>
> > specifiers (i.e. requests for an installer to generate the appropriate<br>
> > wrappers), while prebuilt would be a mapping of command names to paths<br>
> > relative to the scripts directory (as strings).<br>
> ><br>
> > Note that given that Python 2.7+ and 3.2+ can execute packages with a<br>
> > __main__ submodule, the export specifier for a command entry *may*<br>
> > just be the module component and it should still work.<br>
> ><br>
> > The exports field is just a rebranded and slightly rearranged<br>
> > entry_points structure: the top level keys in the hash map are "export<br>
> > groups" (defined in the same way as metadata extensions are defined)<br>
> > and the individual entries in each export group are arbitrary keys<br>
> > (meaning determined by the export group) mapping to export specifiers.<br>
> ><br>
> > With this change, I may even move the current top level<br>
> > "install_hooks" field inside the "exports" field. Even if it stay at<br>
> > the top level, the values will become export specifiers rather than<br>
> > using the entry points string format.<br>
> ><br>
> > Not sure when I'll get that tidied up and incorporated into a new<br>
> > draft of PEP 426, but I think it covers everything.<br>
> ><br>
> > For those wondering about my dividing line between "custom string<br>
> > format" and "structured data": the custom string formats in PEP 426<br>
> > should be limited to things that are likely to be passed as command<br>
> > line arguments (like requirement specifiers and their assorted<br>
> > components), or those where using structured data would be<br>
> > extraordinarily verbose (like environment markers). If I have any<br>
> > custom string formats still in there that don't fit either of those<br>
> > categories, then let me know and I'll see if I can replace them with<br>
> > structured data.<br>
> ><br>
> > Cheers,<br>
> > Nick.<br>
><br>
> It may be worth mentioning that I am not aware of any package that<br>
> uses the "entry point requires extra" feature.<br>
><br>
> IIUC pkg_resources doesn't just check whether something's installed<br>
> but attempts to add the requirements of the entry point's distribution<br>
> and any requested extras to sys.path as part of resolution.</p>
<p dir="ltr">I see it as more useful for making an executable optional by defining a "cli" extra. If your project just gets installed as a dependency, no wrapper would get generated.</p>
<p dir="ltr">Only if you went "pip install myproject[cli]" (or another project specifically depended on the cli extra) would it be installed.</p>
<p dir="ltr">Cheers,<br>
Nick.<br>
</p>