Python Forum
a special version of the python command
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
a special version of the python command
#1
i want to make a special version of the python command that has a few specific modules preloaded. it looks like more than one way to do this exists. any suggestions for the best way?
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#2
You could perhaps use a virtualenv and sitecustomize its python interpreter.
Reply
#3
can i make that into a command? i guess so if the setup can be scripted. i am wanting to use it on the #! line.

(Apr-01-2019, 07:26 AM)Gribouillis Wrote: You could perhaps use a virtualenv and sitecustomize its python interpreter.

it would need to setup that virtualenv for each process that execs that python interpreter. the idea is that what runs it has no clue.

one of the ways to do this, which i would not do, is patch the interpreter source code to do the internal calls to pre-load the modules i want. then i can use this new interpreter like any other.
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#4
I've found a very simple trick: use the PYTHONUSERBASE environment variable to specify an arbitrary directory. Here is how I do it in my linux system: I create a directory ./tmp/lib/python3.5/site-packages and in this directory I create a file
# usercustomize.py
print('HELLO FROM FAKE USERCUSTOMIZE MODULE')
# import any module you want here
Then if I run
Output:
PYTHONUSERBASE=./tmp python3
it starts python 3.5 and runs the fake usercustomize.py module. So you only need to use a shell with the proper environment.
Reply
#5
Actually, using environment variables, you could simply define a special script containing arbitrary code, then add this in your normal sitecustomize.py or usercustomize.py, add lines such as
# add this in sitecustomize.py or usercustomize.py
import os
import pathlib
special_script = os.getenv('SPECIAL_PYTHON_SCRIPT')
if special_script:
    exec(pathlib.Path(special_script).read_text())
You can then set the environment variable in bash
Output:
SPECIAL_PYTHON_SCRIPT="$HOME/foo/my_delirium.py"
and use the ordinary python3 interpreter.
Reply
#6
can you make a script that does this so that there are no manual steps? and does not require root? this would be to set it up. another script would then be run and works as if it were the special python command (can be referenced on the #! line of a script). you know what language to code these scripts in.
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#7
Skaperen Wrote:can you make a script that does this so that there are no manual steps?

Here is the install-special-python.py script. Make it executable and run it to create a new python command
#!/usr/bin/env python3
__version__ = '2019.04.06.001'
import os
from pathlib import Path
import subprocess as sp
import sys

class InstallError(RuntimeError):
    pass

def parse_args():
    """Parse command line arguments, return argparse namespace."""
    import argparse
    parser = argparse.ArgumentParser(
        description="""\
Install a special version of the python command in a new directory.\
""")
    parser.add_argument(
        'basedir', metavar='DIR',
        help="""base directory containing the new bin/python command.\
        This directory must not initially exist.""")
    return parser.parse_args()

def check_basedir_doesnt_exist(basedir):
    if basedir.exists():
        raise InstallError("Directory already exists", str(basedir))

def create_directory(dir):
    try:
        dir.mkdir(parents=True)
    except Exception as exc:
        raise InstallError("Cannot create directory", str(dir)) from exc

def get_user_site_dir(basedir):
    env = dict(os.environ)
    env['PYTHONUSERBASE'] = str(basedir)
    output = sp.check_output([
        sys.executable, '-m', 'site', '--user-site'],
        env=env).decode()
    return Path(output.strip().split('\n')[-1])

def check_is_below_basedir(dir, basedir):
    try:
        dir.relative_to(basedir)
    except ValueError as exc:
        raise InstallError(
            'Expected directory not below basedir',
            str(dir), str(basedir)) from exc

def main():
    args = parse_args()
    basedir = Path(args.basedir)
    check_basedir_doesnt_exist(basedir)
    create_directory(basedir)
    try:
        user_site_dir = get_user_site_dir(basedir)
        check_is_below_basedir(user_site_dir, basedir)
        create_directory(user_site_dir)
        (user_site_dir/"usercustomize.py").touch()
        bindir = basedir/'bin'
        create_directory(bindir)
        python = bindir/'python'
        python.write_text(
            python_contents.format(executable=sys.executable))
        python.chmod(0o774)
        print("""\
The following new command has been successfully created to invoke python:

    {python}

Customize it at startup by adding code in the usercustomize.py file.
The path to this file's parent directory is given by the command

   <interpreter> -m site --user-site
   
Its value is currently {user_site_dir}
            """.format(python=python, user_site_dir=user_site_dir))
    except InstallError:
        import shutil
        shutil.rmtree(str(basedir), ignore_errors=True)
        raise
    
python_contents="""\
#!{executable}
import os
import sys
os.environ['PYTHONUSERBASE'] = os.path.dirname(os.path.dirname(__file__))
os.execv(sys.executable, [sys.executable] + sys.argv[1:])
"""

if __name__ == '__main__':
    main()
You can even use pip with the special python by using the invoking <python> -m pip install --user ... and install specific modules. Beware that if you forget the --user argument, it will install modules for the underlying interpreter.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Query on choosing Python 3.8.6 version sureshnagarajan 0 1,789 Feb-16-2021, 05:30 AM
Last Post: sureshnagarajan
  Which Python Version? muzikman 15 5,066 Jan-19-2021, 02:16 PM
Last Post: muzikman
  Python/winrt support for python 3.8 version pbvinoth 2 3,643 Jul-08-2020, 02:03 PM
Last Post: snippsat
  Issue with 2 version of python (2.6.6 and 2.7) with pip himupant94 2 3,187 Apr-24-2020, 03:23 AM
Last Post: himupant94
  Any command to upgrade Python version 2.X to latest KarthiK 7 4,046 Feb-15-2020, 07:25 PM
Last Post: DeaD_EyE
  Default python version on Windows (3.6.x vs 3.6.y) gramakri 1 2,425 May-04-2019, 10:36 PM
Last Post: snippsat
  Old Python-version used by IDLE GeNoS 7 4,149 Apr-13-2019, 08:04 PM
Last Post: Gribouillis
  Trouble installing a old version of python - 3.4.1 alex8obrien 2 2,748 Apr-09-2019, 06:28 AM
Last Post: alex8obrien
  Distributing custom version of Python touc82 1 2,065 Mar-23-2019, 03:23 PM
Last Post: Larz60+
  Understanding Python version releases venami 3 3,075 Aug-24-2018, 09:56 PM
Last Post: venami

Forum Jump:

User Panel Messages

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