Live data from Hacker News

Fixing the Python subprocess interface

amoffat.github.com

31–40 of 65 posts

Re: Fixing the Python subprocess interface

#31

Earlier quoted context omitted.

Irrelevant for shell-style scripts because they are entry points, not included from other modules. --And its not a "global" name space, its just the namespace of your script.--

It's a global namespace in your script. That's what it's called, I believe and it's available via globals().

Aye, they are added to "current scope's global variables", thank you for correcting.

Re: Fixing the Python subprocess interface

#33
The value/cost of a "hack" is offset by what it provides. If something can be implemented at the same cost in a less brittle and more future-proof way, then by all means label it horrible.

If you think "horrible" hacks are a slight against something that provides an amazing level of functionality to an end user, then you've lost sight of what we're coding for.

Re: Fixing the Python subprocess interface

#34
post #32
post #24

[deleted]

This is impossible. The parent bash is suspended while the python process runs. `` (not '') in Perl runs it in a child process. The equivalent is at the bottom of http://hyperpolyglot.org/scripting - or read the subprocess module documentation.

Indeed. perl does not much more than "sh -c ''".

Re: Fixing the Python subprocess interface

#36
It states that the lines

  curl("http://duckduckgo.com/", "-o page.html", "--silent")
  curl("http://duckduckgo.com/", "-o", "page.html", "--silent")
are equivalent. This worries me, I would much rather always have it be one argument corresponding to exactly one shell argument. Here it looks like in some (maybe all?) cases arguments are split on spaces, which means always having to be extremely cautious about escaping, something a good abstraction shouldn't force you to deal with.

Re: Fixing the Python subprocess interface

#37

This module is a huge hack. It's a neat hack, though :) I've written what I feel is a much better solution to this problem: Envoy. https://github.com/kennethreitz/envoy It's pythonic and makes far fewer assumptions about both your code and what you're running.

+1 for Envoy. It's a really nice replacement for subprocess (which is awful).

Clint and Requests are worth a look too.. Thanks Kenn!

Re: Fixing the Python subprocess interface

#39
This is a cute little hack, and quite possibly a very useful one. (And if it isn't useful, then it is certainly interesting and instructive.)

However:

Please, please, please don't use or recommend things like "from pbs import * ". Namespace pollution is bad enough when importing a documented collection of functions. Importing functions that are named based on whatever happens to be in my path at the moment ... that's seriously scary.

But "import pbs" looks like fun. :-) And "pbs.ls" isn't that much to type.

As The Zen of Python says:

] Namespaces are one honking great idea -- let's do more of those!

P.S. Hmmm ... but does "import pbs" work? Haven't tried it.

Re: Fixing the Python subprocess interface

#40
I use Python for shell scripting a lot. Ignoring all of the issues people have brought up here, I really like how function composition is piping:

  # sort this directory by biggest file
  print sort(du("*", "-sb"), "-rn")

  # print the number of folders and files in /etc
  print wc(ls("/etc", "-1"), "-l")
The reason that I like that method over, say, envoy's [1] method is that envoy.run('uptime | pbcopy') has what I consider code in strings. When I'm writing a script, the programs I'm calling, and how they interact, is part of the "code" to me. I would prefer that they're at the language level, and not represented as strings.

[1] I only just learned about envoy in this thread. Thanks! Sadly, one of the places where I run my Python scripts is a location where I can't install my own packages, and I don't want to deal with using my own install of Python, so I tend to just implement something like this:

  def checked_exec(seq):
    p = Popen(seq, stdout=PIPE, stderr=PIPE)
    stdout, stderr = p.communicate()
    if p.returncode != 0:
        print 'err: ' + stderr
        print "'" + seq + "' failed."
        sys.exit()
    return stdout
Post reply on HN