<div dir="ltr"><br><br><div class="gmail_quote"><div dir="ltr">On Mon, 23 Nov 2015 at 13:46 Barry Warsaw <<a href="mailto:barry@python.org">barry@python.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On Nov 20, 2015, at 09:23 PM, Brett Cannon wrote:<br>
<br>
>I have created a Jupyter Notebook to explain my thinking on what<br>
>importlib.resources() should be (at least initially).<br>
<br>
Just a few thoughts based on a review of two projects' use of pkg_resources.<br>
+1 on getting *something* into Python 3.6.<br>
<br>
Module API vs package API.  Doesn't pkg_resources actually support something<br>
similar to both, with the module function providing a convenience API?</blockquote><div><br></div><div>Yes, but that doesn't sway me. This isn't a "pkg_resources++" but a "make reading data from a package make sense in a modern import world". IOW I'm purposefully not using pkg_resources as a template but simply as a motivating factor.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">  I like<br>
that a lot because the convenience API is so darn... convenient!  You just<br>
give it the Python dotted-path and the resource and it does the rest.<br></blockquote><div><br></div><div>I don't see how that's any different than the other approach since you're still providing the exact same data; no more, no less.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Generally I don't care about caching the results of the search; these calls<br>
are almost never in performance critical code.<br></blockquote><div><br></div><div>Unfortunately for you the poll liked the other approach and TOOWTDI. So either convince me that resources.read_bytes(pkg, path) is better than resources(pkg).read_bytes(path) or consider the bike shed painted. :)</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
resource_filename().  Doesn't pkg_resources already have a strategy for the<br>
temporary file that sometimes has to be created?</blockquote><div><br></div><div>Yes and I don't like it. :) Basically you either create an instance or implicitly use a global instance of a class that stores the references and registers with atexit a cleanup function to be executed.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">  Maybe it doesn't work so<br>
well on some platforms (I've never noticed a problem on *nix).  A context<br>
manager as proposed seems like the most reasonable approach.  We definitely<br>
need this API though.  I see plenty of examples where e.g. test data files<br>
have to be shutil.copy()'d, passed to subprocess command line arguments, etc.<br></blockquote><div><br></div><div>OK, between you and Donald saying you have real needs for the API you can rest assured that it will be in the initial version, especially since I already coded up the tempfile implementation.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
read_bytes().  Thank you for the truth in advertising!  IIRC in Python 3,<br>
pkg_resource.resource_string() actually returns bytes. from-import-as to the<br>
rescue.  An actual resource_string() would have to accept an encoding argument<br>
(as would any resource-based open() method).<br></blockquote><div><br></div><div>Yes, which is why I don't think it's worth it to provide a resource_strinng() since calling decode isn't difficult (and is something you must know in Python 3).</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
resource_stream().  IIRC, the pkg_resource's version is not a context manager<br>
so it has to be closed explicitly (or wrapped in contextlib.closing()).  We<br>
can do better.<br></blockquote><div><br></div><div>I'm not convinced it's necessary to provide an equivalent open() yet; if you have an API that requires a file-like object then io.BytesIO to the rescue for read_bytes(). There is nothing tricky to get right like with a file path that may or may not be backed by a temporary file. This is a somewhat low-level API and if people want to provide convenience wrappers that's fine but I don't want to start guessing at needs beyond core APIs or ones that are hard to get right and allow for composability to higher APIs like file-like objects which others can handle.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
I do have one use of resource_listdir() which is used to find importable<br>
plugin modules at runtime.  It's handy.<br></blockquote><div><br></div><div>I'm going to punt on this for as long as possible because it's asking for trouble to get right. For example, if I do resources(pkg).listdir(), then I will end up returning relative paths, but if you disassociate those paths from pkg then you have lost proper context. You could return tuples of (pkg, relative_path), but that just doesn't seem satisfactory either. I'm just not convinced yet it is needed enough to support (at least initially).</div><div><br></div><div>-Brett</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
That's all for now.<br>
-Barry<br>
_______________________________________________<br>
Import-SIG mailing list<br>
<a href="mailto:Import-SIG@python.org" target="_blank">Import-SIG@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/import-sig" rel="noreferrer" target="_blank">https://mail.python.org/mailman/listinfo/import-sig</a><br>
</blockquote></div></div>