<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Sat, Jan 28, 2017 at 5:26 AM, Paul Moore <span dir="ltr"><<a href="mailto:p.f.moore@gmail.com" target="_blank">p.f.moore@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On 28 January 2017 at 02:11, C Anthony Risinger <<a href="mailto:anthony@xtfx.me">anthony@xtfx.me</a>> wrote:<br>
> I can't articulate it we'll, or even fully isolate the reasons for it. All I<br>
> really know is how I feel when peers ask me about Python or the reading I<br>
> get when others speak about their experience using it. Python is absolutely<br>
> one of my favorite languages to write, yet I find myself recommending<br>
> against it, and watching others do the same. Python comes with caveats and<br>
> detailed explanations out the gate and people simply perceive higher<br>
> barriers and more chores.<br>
<br>
Picking up on this and the comment you made in the original post<br>
<br>
> With a still difficult distribution/compatibility story, I've watched dozens of instances<br>
> where people choose something else, usually Node or Golang.<br>
<br>
Can you explain why you recommend against Python, in a bit more<br>
detail? If you are an enthusiastic Python user, but you are steering<br>
people away from Python, then it would be worth understanding why.<br>
<br>
As you mention end user applications and distribution, one of my first<br>
questions would be what platform you work on. Following on from that,<br>
what sort of end user applications are you looking at? If we're<br>
talking here about games for iOS, then that's a much different<br>
situation than GUI apps for Windows or command line tools for Linux.<br></blockquote><div> </div><div><div>I'm working on Linux myself, with my typical audience being other developers or occasionally leadership. Builds usually include Windows, but always Linux and OSX. I'd like a one-click solution to:</div><div><br></div><div>How do I redistribute and successfully install Python, dependencies, and an application with the least possible steps for the end user? For any platform or persona?</div><div><br></div><div>I prefer dynamic applications redistribute their runtime, and not depend on the system in any significant way aside from major libraries or support files. It's more obnoxious sometimes but I believe it lowers the number of unexpected incidents. I also don't want to setup support infrastructure (pypi proxy cache or self hosted pypi) myself or require coordination with ops teams. Simple authenticated download for publishing is ideal, and direct execution of that download is even better.</div><div><br></div><div>Containers are have greatly impacted how people think about distribution. There is a trend to use fast/small containers as CLI tools. I think there is still benefit to empowering a way to "remix python" with your local environment and produce a redistributable binary for downstream users. I have far less experience with Go but I like how easy it is to generate such executables.</div></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
My personal feeling is that Python happily works in the "Command line<br>
tools for Linux" area (except possibly with regard to C extensions<br>
where the plethora of Linux ABIs makes things hard). But other areas<br>
less so. I've been having good experiences making standalone<br>
applications with the new Windows "embedded" distributions, but that<br>
is relatively new, and still has a lot of rough edges. I'm working on<br>
a project to bundle a working zipapp with the embedded distribution to<br>
make a standalone exe - would having something like that make any<br>
difference in your environment?<br></blockquote></div><div class="gmail_extra"><br></div><div class="gmail_extra">Yes I believe it would. I implemented something to this end for Linux (defunct, no Python 3, uses abandoned PEP 425):</div><div class="gmail_extra"><br></div><div class="gmail_extra"><a href="https://github.com/anthonyrisinger/zippy">https://github.com/anthonyrisinger/zippy</a></div><div class="gmail_extra"><br></div><div class="gmail_extra">about 4-5 years ago for this purpose, before similar technologies such as PEX and zipapp existed. It worked well for the time it was used.</div><div class="gmail_extra"><br></div><div class="gmail_extra">The project is dead, but it had a few ideas I think might be worth further exploration. In a nutshell, "zippy" was a build tool (waf and distlib because no interface to pip) that always output a single python binary built from source. All python code (stdlib, deps, app) was appended in a zipfile. All C-extensions (including dotted) were observed during .so generation and re-linked statically into the binary as builtins instead (more on this below).</div><div class="gmail_extra"><br></div><div class="gmail_extra">The end result was a self-contained executable that would only recognize it's own stdlib and could properly run embedded C-modules. The implementation also changed entrypoints based on argv[0], so this could thing could perform as a multicall binary like BusyBox (the symlink name was resolved to an entrypoint). It was easy to send this to other developers where they could unpack it for development or use it as-is. A future goal was to allow respinning an unpacked environment into a new redistributable.</div><div class="gmail_extra"><br></div><div class="gmail_extra">To make this work, I changed python in a few specific ways:</div><div class="gmail_extra"><br></div><div class="gmail_extra">Set LANDMARK file at build time to something other than `os.py`. Python uses this file to recognize the stdlib during early boot. Customizing it [zippy-SOMEHASH.json] ensures a different unpacked build's stdlib is unrecognizable (this happens *often* if you've "installed" a build by unpacking to the default path, then do another build).</div><div class="gmail_extra"><br></div><div class="gmail_extra">Add `sys.executable` to the default search path. This ensures python first scans the filesystem for an unpacked environment but always falls back to its own appended zipfile. Combined with custom LANDMARK this made the python installation executable from any on-disk location.</div><div class="gmail_extra"><br></div><div class="gmail_extra">Build python locally, install app and all deps into the local build, re-link all C-extensions statically, append zipfile to python binary. I *may* have went overboard, but I generalized a method for statically linking numpy into python, I believe originally described at <a href="http://yt.enzotools.org/wiki/CrayXT5Installation">http://yt.enzotools.org/wiki/CrayXT5Installation</a> . In short, distutils is monkeypatched to trace calls to `unixccompiler.UnixCCompiler.link_shared_object`. A normal object file with strict symbol exports, similar to a shared object, is written alongside the shared object, and Modules/Setup is updated. After deps are installed from pypi, python is re-linked with all the newly traced C-ext static objects. The process exposed a few interesting bugs in python and elsewhere (possibly since fixed) but was known to work for all stdlib C-extensions and every popular library we used throughout the company (psycopg2, librabbitmq, sqlite3, and dozens others were all successfully linked into the same process).</div><div class="gmail_extra"><br></div><div class="gmail_extra">This is approximately when Golang starting looking attractive to me. The past few years have seen serious improvements to this space for Python but I think there is a ways to go yet. Python has different challenges and advantages because it's older and dynamic, but I think some activity around all this might make it easier to customize Python builds.</div><div><br></div>-- <br><div class="gmail_signature"><br>C Anthony</div>
</div></div>