Skip to content

Instantly share code, notes, and snippets.

@TheDevMinerTV
Created February 20, 2025 14:53
Show Gist options
  • Save TheDevMinerTV/2dbd8c0708426b2adcb6d1aca2f7fc50 to your computer and use it in GitHub Desktop.
Save TheDevMinerTV/2dbd8c0708426b2adcb6d1aca2f7fc50 to your computer and use it in GitHub Desktop.
autogen pycharm interpreters
import os
import subprocess
from dataclasses import dataclass
import sys
import xml.etree.ElementTree as ET
from os.path import basename
from pathlib import Path
import random
def generate_uuid():
hex_chars = '0123456789abcdef'
uuid = ''.join(random.choice(hex_chars) for _ in range(32))
return f"{uuid[:8]}-{uuid[8:12]}-4{uuid[13:16]}-{uuid[16:20]}-{uuid[20:]}"
plugins = [
# "file://$USER_HOME$/.cache/JetBrains/PyCharm2024.3/python_stubs/1150089097",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/python-skeletons",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stdlib",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/gdb",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/six",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/boto",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/cffi",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/hvac",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/mock",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/pika",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/pytz",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/toml",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/tqdm",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/zstd",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/WebOb",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/first",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/fpdf2",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/ldap3",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/polib",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/pyjks",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/pyxdg",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/redis",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/regex",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/retry",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/uWSGI",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/ujson",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/Pillow",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/PyYAML",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/bleach",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/caldav",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/docker",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/docopt",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/flake8",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/gevent",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/hdbcli",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/ibm-db",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/nanoid",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/passpy",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/peewee",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/psutil",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/pyasn1",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/pycurl",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/pygit2",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/pynput",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/pysftp",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/qrbill",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/qrcode",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/zxcvbn",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/PyMySQL",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/WTForms",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/boltons",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/chevron",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/inifile",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/libsass",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/netaddr",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/olefile",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/passlib",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/pexpect",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/pyaudio",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/pywin32",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/seaborn",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/shapely",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/slumber",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/unidiff",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/vobject",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/ExifRead",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/Markdown",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/Pygments",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/RPi.GPIO",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/aiofiles",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/assertpy",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/capturer",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/colorama",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/croniter",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/docutils",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/greenlet",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/html5lib",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/httplib2",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/jmespath",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/keyboard",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/lzstring",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/networkx",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/oauthlib",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/openpyxl",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/paramiko",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/psycopg2",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/pyflakes",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/pyserial",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/requests",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/str2bool",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/tabulate",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/toposort",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/untangle",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/waitress",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/PyAutoGUI",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/PyScreeze",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/braintree",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/decorator",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/fanstatic",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/icalendar",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/paho-mqtt",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/playsound",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/pyOpenSSL",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/pyRFC3339",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/reportlab",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/ttkthemes",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/wurlitzer",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/xmltodict",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/Deprecated",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/Flask-Cors",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/SQLAlchemy",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/Send2Trash",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/cachetools",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/commonmark",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/dateparser",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/defusedxml",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/jsonschema",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/portpicker",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/pyfarmhash",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/setuptools",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/simplejson",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/tensorflow",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/JACK-Client",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/entrypoints",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/flake8-2020",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/mysqlclient",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/opentracing",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/pep8-naming",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/pycocotools",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/pyinstaller",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/python-jose",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/python-nmap",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/python-xlib",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/workalendar",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/aws-xray-sdk",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/console-menu",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/editdistance",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/parsimonious",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/usersettings",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/whatthepatch",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/Flask-Migrate",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/click-spinner",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/humanfriendly",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/python-gflags",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/Flask-SocketIO",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/beautifulsoup4",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/flake8-bugbear",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/python-crontab",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/python-slugify",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/singledispatch",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/flake8-builtins",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/flake8-simplify",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/influxdb-client",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/mypy-extensions",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/python-datemath",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/python-dateutil",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/Flask-SQLAlchemy",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/dockerfile-parse",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/s2clientprotocol",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/flake8-docstrings",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/requests-oauthlib",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/translationstring",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/click-default-group",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/pytest-lazy-fixture",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/flake8-rst-docstrings",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/flake8-typing-imports",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/tree-sitter-languages",
"file://$APPLICATION_HOME_DIR$/plugins/python-ce/helpers/typeshed/stubs/antlr4-python3-runtime",
"file://$APPLICATION_HOME_DIR$/plugins/python/helpers-pro/bundled_stubs",
]
home = Path.home()
base_ide_install_path = home / ".config/JetBrains"
if sys.platform.startswith("darwin"):
base_ide_install_path = home / "Library/Application Support/JetBrains"
pycharm_configs = list(base_ide_install_path.glob("PyCharm*/options/jdk.table.xml"))
projects_root = home / "d"
@dataclass
class PythonProject:
path: Path
python_binary: Path
python_version: str
name: str
def interpreter_name(self):
return f"Py venv {self.python_version} @ {self.path.relative_to(projects_root)}"
def short_python_version(self):
return '.'.join(self.python_version.split(".")[0:2])
def lib_python_name(self):
return f"python{self.short_python_version()}"
def get_python_version(python_exe: Path):
try:
result = subprocess.run([str(python_exe), "--version"], capture_output=True, text=True, check=True)
version_string = result.stdout.strip()
version = version_string.split(" ")[1]
return version
except subprocess.CalledProcessError:
return None
projects = [PythonProject(path=Path(path.parent), name=basename(path.parent), python_version=get_python_version(path / "bin/python"), python_binary=Path(os.path.realpath(path / "bin/python"))) for path in list(projects_root.glob("**/.venv"))]
def update_pycharm_jdk_table():
for config_path in pycharm_configs:
print(f"generating \"JDK\" config at {config_path}...")
tree = ET.parse(config_path)
root = tree.getroot()
components = root.find(".//component[@name='ProjectJdkTable']")
for project in projects:
venv_path = project.path / ".venv"
print(f" generating config for venv {venv_path}...")
print(f" using {project.python_binary} ({project.python_version})...")
# Create JDK entry structure
jdk_entry = ET.Element("jdk", {"version": "2"})
_ = ET.SubElement(jdk_entry, "name", {"value": project.interpreter_name()})
_ = ET.SubElement(jdk_entry, "type", {"value": "Python SDK"})
_ = ET.SubElement(jdk_entry, "version", {"value": f"Python {project.python_version}"})
_ = ET.SubElement(jdk_entry, "homePath", {"value": f"{venv_path}/bin/python"})
# Add roots section
roots = ET.SubElement(jdk_entry, "roots")
source_path_el = ET.SubElement(roots, "sourcePath")
_ = ET.SubElement(source_path_el, "root", {"type": "composite"})
python_lib_path = (project.python_binary / f"../../lib/{project.lib_python_name()}").resolve()
lib_dynload_path = python_lib_path / "lib-dynload"
add_classpath(roots, plugins + [
f"{venv_path}/lib/{project.lib_python_name()}/site-packages",
python_lib_path,
lib_dynload_path
])
additional = ET.SubElement(jdk_entry, "additional", {"SDK_UUID": generate_uuid()})
_ = ET.SubElement(additional, "setting", {"name": "FLAVOR_ID", "value": "VirtualEnvSdkFlavor"})
_ = ET.SubElement(additional, "setting", {"name": "FLAVOR_DATA", "value": "{}"})
if not any(e.find('name').attrib["value"] == project.interpreter_name() for e in root.findall('jdk')):
print(f" adding \"{project.interpreter_name()}\"...")
components.append(jdk_entry)
tree.write(config_path, encoding="UTF-8", xml_declaration=True)
def add_classpath(parent: ET.Element, paths: list[Path | str]):
classpath = ET.SubElement(parent, "classPath")
root = ET.SubElement(classpath, "root", {"type": "composite"})
for path in paths:
_ = ET.SubElement(root, "root", {
"url": f"file://{path}",
"type": "simple"
})
def update_projects():
for project in projects:
project_path = project.path
config_path = f"{project_path}/.idea/{project.name}.iml"
print(f"reconfiguring project {project.name}...")
try:
tree = ET.parse(config_path)
root = tree.getroot()
components = root.find(".//orderEntry[@type='jdk']")
print(f" setting interpreter to \"{project.interpreter_name()}\"...")
components.attrib['jdkName'] = project.interpreter_name()
tree.write(config_path, encoding="UTF-8", xml_declaration=True)
except:
pass
if __name__ == "__main__":
update_pycharm_jdk_table()
update_projects()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment