Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
switching to python3
#11
it seems lots or even most of the suggestions here tend to increase complexity, work only in a different context, and/or meet a different goal. in many cases i wish it were as simple as:
    import switchtopython3
    switchtopython3.switch_now()
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#12
Then here is your module, implementing the suggestion above. It needs to be tested in Windows and OSX
# switchtopython3.py
from __future__ import print_function
import os
import sys

# which() is copied from shutil.which() in python 3.5.2
def which(cmd, mode=os.F_OK | os.X_OK, path=None):
    """Given a command, mode, and a PATH string, return the path which
    conforms to the given mode on the PATH, or None if there is no such
    file.

    `mode` defaults to os.F_OK | os.X_OK. `path` defaults to the result
    of os.environ.get("PATH"), or can be overridden with a custom search
    path.

    """
    # Check that a given file can be accessed with the correct mode.
    # Additionally check that `file` is not a directory, as on Windows
    # directories pass the os.access check.
    def _access_check(fn, mode):
        return (os.path.exists(fn) and os.access(fn, mode)
                and not os.path.isdir(fn))

    # If we're given a path with a directory part, look it up directly rather
    # than referring to PATH directories. This includes checking relative to the
    # current directory, e.g. ./script
    if os.path.dirname(cmd):
        if _access_check(cmd, mode):
            return cmd
        return None

    if path is None:
        path = os.environ.get("PATH", os.defpath)
    if not path:
        return None
    path = path.split(os.pathsep)

    if sys.platform == "win32":
        # The current directory takes precedence on Windows.
        if not os.curdir in path:
            path.insert(0, os.curdir)

        # PATHEXT is necessary to check on Windows.
        pathext = os.environ.get("PATHEXT", "").split(os.pathsep)
        # See if the given file matches any of the expected path extensions.
        # This will allow us to short circuit when given "python.exe".
        # If it does match, only test that one, otherwise we have to try
        # others.
        if any(cmd.lower().endswith(ext.lower()) for ext in pathext):
            files = [cmd]
        else:
            files = [cmd + ext for ext in pathext]
    else:
        # On other platforms you don't have things like PATHEXT to tell you
        # what file suffixes are executable, so just pass on cmd as-is.
        files = [cmd]

    seen = set()
    for dir in path:
        normdir = os.path.normcase(dir)
        if not normdir in seen:
            seen.add(normdir)
            for thefile in files:
                name = os.path.join(dir, thefile)
                if _access_check(name, mode):
                    return name
    return None

def switch_now(verbose=False):
    if sys.version_info.major > 2:
        return
    python3 = which('python3')
    if python3 is None:
        raise RuntimeError('Cannot find python3 executable')
    if verbose:
        print('Switching to new interpreter:', python3)
    os.execl(python3, python3, *sys.argv)
You don't need to maintain which() because it is copied verbatim from python's source tree.

In Windows, I think it won't work that easily because there is usually no python3.exe executable. One can perhaps change the code
to detect the 'py' launcher, eg
if sys.platform = "win32":
    py = which('py')
    if py is not None:
        os.execl(py, py, '-3', *sys.argv)
This is only the beginning if you want a general solution, because several versions of python 3 can exist on the same machine. The complexity increases if one also wants to cover virtualenvs.
Reply
#13
i do want it to just continue if python3 is not available. my use cases are code that can run in python2 but would do better if python3 were being used. a return value may not even be needed since code that needs to know can check sys.version_info.major or the like.
    if sys.version_info.major < 3:
        switchpython.switch_now(3)
        print('Python3 is not available - expect degraded results')
if the switch is successful, execution restarts back at the top.
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  switching from notebook to pycharm enterthevoid22 1 1,653 Oct-10-2020, 05:20 PM
Last Post: perfringo

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020