Skip to content

Commit 7d44a24

Browse files
committed
Python scripts: Use PDM and virtualenv to manage dependencies
PDM and virtualenv are tools to manage installation of Python modules not included in the Python Standard Library. Usage: 1. Install Pipx (e.g. `brew install pipx`) - https://pipx.pypa.io/ 2. Use Pipx to install PDM (`pipx install pdm`). 3. Run `pdm install` in MuseScore's root directory. The final command creates a virtual environment (.venv folder) and installs the dependencies mentioned in MuseScore's pyproject.toml. See #23198 for details.
1 parent 3ca965e commit 7d44a24

File tree

4 files changed

+170
-0
lines changed

4 files changed

+170
-0
lines changed

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,9 @@ VERSION
6868
temp_*
6969

7070
*.local.cmake
71+
72+
# Python
73+
__pycache__/
74+
*.pyc
75+
.venv/
76+
.pdm-python

pdm.lock

Lines changed: 129 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
[project]
2+
description = "Python scripts for MuseScore Studio development."
3+
readme = "https://github.com/musescore/MuseScore/wiki"
4+
requires-python = ">=3.9"
5+
dependencies = [
6+
"requests>=2.32.3",
7+
]
8+
9+
# Useful PDM commands:
10+
# --------------------
11+
# pdm install Install all dependencies into a virtual environment (venv).
12+
# pdm run <script> Run a Python script with access to venv.
13+
# pdm add <package> Add new dependency on a PyPi package.
14+
# pdm venv remove in-project Remove the venv (e.g. to test installation from scratch).
15+
[tool.pdm]
16+
distribution = false

share/instruments/update_instruments_xml.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,25 @@
44
def eprint(*args, **kwargs):
55
print(*args, **kwargs, file=sys.stderr)
66

7+
if __name__ == '__main__' and sys.prefix == sys.base_prefix:
8+
# Not running inside a virtual environment. Let's try to load one.
9+
import os
10+
old_dir = os.path.realpath(__file__)
11+
new_dir, script_name = os.path.split(old_dir)
12+
rel_pyi = r'.venv\Scripts\python.exe' if sys.platform == 'win32' else '.venv/bin/python'
13+
while new_dir != old_dir:
14+
abs_pyi = os.path.join(new_dir, rel_pyi)
15+
if os.access(abs_pyi, os.X_OK):
16+
eprint(f'{script_name}: Loading virtual environment:\n {abs_pyi}')
17+
if sys.platform == 'win32':
18+
import subprocess
19+
raise SystemExit(subprocess.run([abs_pyi, *sys.argv]).returncode)
20+
os.execl(abs_pyi, abs_pyi, *sys.argv)
21+
old_dir = new_dir
22+
new_dir = os.path.dirname(new_dir)
23+
eprint(f'{script_name}: Not running inside a virtual environment.')
24+
del old_dir, new_dir, rel_pyi, abs_pyi, script_name
25+
726
import locale
827
if locale.getpreferredencoding().lower() != 'utf-8':
928
encoding = locale.getpreferredencoding()

0 commit comments

Comments
 (0)