Skip to content

Commit c26d77b

Browse files
committed
venv: Add a command-line package for creating virtual environments.
Works like "python -m venv path" and creates a rudimentary virtual environment for the Unix port: - sets MICROPYPATH - copies the micropython binary to venv/bin/micropython which is in $PATH - installs mip & mip-cmdline in the venv Using the venv is the same as for CPython -- source the activate script to enter, and call the deactivate function to leave. This work was funded through GitHub Sponsors. Signed-off-by: Jim Mussared <[email protected]>
1 parent 143c293 commit c26d77b

File tree

2 files changed

+108
-0
lines changed

2 files changed

+108
-0
lines changed

python-stdlib/venv/manifest.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
metadata(
2+
version="0.1.0",
3+
description="Support for creating MicroPython virtual environments using `micropython -m venv`",
4+
)
5+
6+
require("argparse")
7+
require("mip-cmdline")
8+
9+
package("venv")

python-stdlib/venv/venv/__main__.py

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# Support for creating MicroPython virtual environments using `micropython -m venv`
2+
# MIT license; Copyright (c) 2022 Jim Mussared
3+
4+
import argparse
5+
import os
6+
import sys
7+
8+
9+
# If mip is not frozen into this binary, then also install it in the venv.
10+
def install_mip(venv_lib_path):
11+
need_mip = False
12+
if "mip" in sys.modules:
13+
del sys.modules["mip"]
14+
saved_sys_path = sys.path[:]
15+
try:
16+
sys.path[:] = [".frozen"]
17+
try:
18+
import mip
19+
20+
print("mip is frozen")
21+
except ImportError:
22+
need_mip = True
23+
finally:
24+
sys.path[:] = saved_sys_path
25+
26+
if need_mip:
27+
import mip
28+
29+
mip.install("mip-cmdline", target=venv_lib_path)
30+
31+
32+
def do_venv():
33+
parser = argparse.ArgumentParser(description="Create a micropython virtual environment")
34+
parser.add_argument("path", nargs=1, help="Path to create the virtual environment in")
35+
args = parser.parse_args(args=sys.argv[1:])
36+
venv_path = args.path[0]
37+
print("Creating virtual environment in:", venv_path)
38+
39+
# Equivalent to path = os.abspath(path).
40+
if not venv_path.startswith("/"):
41+
venv_path = os.getcwd() + os.sep + venv_path
42+
43+
venv_bin_path = venv_path + os.sep + "bin"
44+
venv_lib_path = venv_path + os.sep + "lib"
45+
46+
for d in (
47+
venv_path,
48+
venv_bin_path,
49+
venv_lib_path,
50+
):
51+
try:
52+
os.mkdir(d)
53+
except:
54+
pass
55+
56+
# Note the venv/lib dir goes before .frozen so that installed packages replace frozen ones.
57+
with open(venv_bin_path + os.sep + "activate", "w") as f:
58+
print(
59+
"""# Usage: source bin/activate
60+
61+
deactivate() {{
62+
PATH="$_OLD_VIRTUAL_PATH"
63+
export PATH
64+
65+
MICROPYPATH="$_OLD_VIRTUAL_MICROPYPATH"
66+
if [ -z "$MICROPYPATH" ]; then
67+
export -n MICROPYPATH
68+
else
69+
export MICROPYPATH
70+
fi
71+
72+
unset VIRTUAL_ENV
73+
74+
unset deactivate
75+
}}
76+
77+
VIRTUAL_ENV={}
78+
79+
_OLD_VIRTUAL_PATH="$PATH"
80+
PATH="$VIRTUAL_ENV/bin:$PATH"
81+
export PATH
82+
83+
_OLD_VIRTUAL_MICROPYPATH="$MICROPYPATH"
84+
MICROPYPATH="$VIRTUAL_ENV/lib:.frozen"
85+
export MICROPYPATH
86+
""".format(
87+
venv_path
88+
),
89+
file=f,
90+
)
91+
92+
# Add a `micropython` binary in $PATH pointing to this binary.
93+
if hasattr(sys, "executable"):
94+
os.system("cp {} {}".format(sys.executable, venv_bin_path + os.sep + "micropython"))
95+
96+
install_mip(venv_lib_path)
97+
98+
99+
do_venv()

0 commit comments

Comments
 (0)