Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make environments more user friendly #1

Open
pfmoore opened this issue Oct 19, 2017 · 1 comment
Open

Make environments more user friendly #1

pfmoore opened this issue Oct 19, 2017 · 1 comment

Comments

@pfmoore
Copy link

pfmoore commented Oct 19, 2017

I'm not 100% clear what the role of an environment is. They seem to be read/write, although I'm not sure what the use case is for writing them. And getting useful information out of them when reading involves understanding the internals.

What I'd like is for an environment to have the following (read-only) properties:

  • install_path - the InstallPath value, which is the root of the installation
  • executable - the executable, which may be None.
  • gui_executable - the GUI mode executable (again may be None).

I don't know what the use case is for ExecutableArguments in the PEP (maybe the expectation is that Jython might use it as something like executable="java", args = "-jar jython.jar"?) but I'd be 100% fine with having the executable property be None if they are present. The use case for this API is programs like virtualenv, tox, and nox, that all want to translate something like 3.6 into C:\Path\To\python.exe, and have never supported anything more complex than an unadorned executable, so I'd like to optimise for that use case.

The intention here being that tools can do something like

def run_interpreter(version, argv):
    interpreters = [env for env in pep514tools.findall(version) if env.executable]
    if not interpreters:
        raise ValueError(f"Python {version} not found")
    if len(interpreters) > 1:
        raise ValueError(f"Version {version} is ambiguous")
    return subprocess.run([interpreters[0].executable] + argv)

I'm happy to create a PR if you think this is a reasonable API. Thoughts?

@zooba
Copy link
Owner

zooba commented Jun 14, 2018

@pfmoore Apologies for missing this issue...

Without docs, it's not obvious that the way to get this info is to look at env.info.install_path.executable_path (and similar for associated keys). These aren't meant to be internals, hence the lack of leading underscores. And if executable_arguments exists it should be appended to the executable path, precisely for cases like you mention, and I put it in to try to avoid tools like tox/VS/etc. excluding such interpreters because they don't fit the argv[0] model (though VS still doesn't support it... my bad).

A nicer API would be a top-level property that returns the subprocess argument list with 1 or more arguments based on what keys are available. (It's also implied that when executable_path is missing but install_path is present, it should refer to python.exe in that path.)

And the use case for writing is to enable interpreters to register themselves or others. For example, in VS we put custom environments under Software\Python\VisualStudio\... following the same spec, so we can use the same PEP 514 parsing code to load them later on. Any distro could also just bundle pep514tools and use it to [de]register themselves on [un]installation.

Feel free to add an API along these lines:

class Enviroment:
    @property
    def command_line(self):
        return self.info.install_path.executable_path or ... #etc. with error handling and all that

I'd also be totally okay with an API like this if it's convenient:

class Environment:
    def Popen(self, args, **kwargs):
        import subprocess
        return subprocess.Popen(self.command_line + args, **kwargs)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants