mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
PY-57566 Support PEP 660 editable installs.
GitOrigin-RevId: cca68d9504ae4f10a774cfbdd03c38f5176f88fd
This commit is contained in:
committed by
intellij-monorepo-bot
parent
9d1b9721f4
commit
33673afd98
@@ -4,8 +4,48 @@ import sys
|
||||
_helpers_root = os.path.dirname(os.path.abspath(__file__))
|
||||
_working_dir = os.getcwd()
|
||||
|
||||
for root in sys.path:
|
||||
# The current working dir is not automatically included but can be if PYTHONPATH
|
||||
# contains an empty entry.
|
||||
if root != _helpers_root and root != os.curdir and root != _working_dir:
|
||||
print(root)
|
||||
|
||||
def get_pep660_editable_roots_from_metadata():
|
||||
try:
|
||||
# importlib.metadata was added in 3.8
|
||||
from importlib.metadata import distributions, Distribution
|
||||
except ImportError:
|
||||
return []
|
||||
|
||||
def read_from_direct_url_json(dist):
|
||||
# type: (Distribution) -> str | None
|
||||
|
||||
import json
|
||||
direct_url_file = dist._path / 'direct_url.json'
|
||||
if direct_url_file.exists():
|
||||
with direct_url_file.open() as f:
|
||||
data = json.load(f)
|
||||
if data.get('dir_info', {}).get('editable'):
|
||||
return data.get('url', '')
|
||||
return None
|
||||
|
||||
editable_roots = []
|
||||
for dist in distributions():
|
||||
url = None # type: str | None
|
||||
try:
|
||||
# 'origin' was added in Python 3.13
|
||||
if dist.origin.dir_info.editable:
|
||||
url = dist.origin.url
|
||||
except AttributeError:
|
||||
url = read_from_direct_url_json(dist)
|
||||
|
||||
FILE_PREFIX = "file://"
|
||||
if url and url.startswith(FILE_PREFIX):
|
||||
editable_roots.append(url[len(FILE_PREFIX):])
|
||||
return editable_roots
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
for root in sys.path:
|
||||
# The current working dir is not automatically included but can be if PYTHONPATH
|
||||
# contains an empty entry.
|
||||
if root != _helpers_root and root != os.curdir and root != _working_dir:
|
||||
print(root)
|
||||
|
||||
for editable_root in get_pep660_editable_roots_from_metadata():
|
||||
print(editable_root)
|
||||
|
||||
@@ -237,8 +237,10 @@ class Args(vararg initialArgs: String) {
|
||||
return this
|
||||
}
|
||||
|
||||
fun addArgs(args: List<String>): Args = addArgs(*args.toTypedArray())
|
||||
|
||||
/**
|
||||
* This file will be copied to remote machine and its remote name will be added to the list of arguments.
|
||||
* This file will be copied to remote machine, and its remote name will be added to the list of arguments.
|
||||
* Use [argGenerator] to modify name
|
||||
*/
|
||||
fun addLocalFile(localFile: Path, argGenerator: FileArgGenerator = FileArgGenerator { it }): Args {
|
||||
@@ -267,5 +269,3 @@ class Args(vararg initialArgs: String) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun Args.addArgs(args: List<String>): Args = addArgs(*args.toTypedArray())
|
||||
@@ -0,0 +1,22 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.jetbrains.python
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.roots.AdditionalLibraryRootsProvider
|
||||
import com.intellij.openapi.roots.SyntheticLibrary
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import org.jetbrains.annotations.Unmodifiable
|
||||
|
||||
// Notes (please do not remove):
|
||||
// - If you think you want to add library roots here: Consider extending file community/python/helpers/syspath.py instead.
|
||||
// - If used, this file needs to be added to community/python/python-psi-impl/resources/intellij.python.psi.impl.xml.
|
||||
@Suppress("unused")
|
||||
internal class PyAdditionalLibraryRootsProvider : AdditionalLibraryRootsProvider() {
|
||||
override fun getRootsToWatch(project: Project): @Unmodifiable Collection<VirtualFile> {
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
override fun getAdditionalProjectLibraries(project: Project): Collection<SyntheticLibrary> {
|
||||
return emptyList()
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,7 @@ public interface RootVisitor {
|
||||
* @param root what we're visiting.
|
||||
* @param module the module to which the root belongs, or null
|
||||
* @param sdk the SDK to which the root belongs, or null
|
||||
* @param isModuleSource true iff the root belongs to the module in case both module and sdk are present
|
||||
*
|
||||
* @return false when visiting must stop.
|
||||
*/
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.jetbrains.python.packaging.management
|
||||
|
||||
import com.intellij.openapi.util.NlsSafe
|
||||
import com.jetbrains.python.packaging.common.PythonRepositoryPackageSpecification
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import java.net.URI
|
||||
|
||||
@ApiStatus.Internal
|
||||
sealed class PythonPackageInstallRequest(val title: String) {
|
||||
sealed class PythonPackageInstallRequest(val title: @NlsSafe String) {
|
||||
data class ByLocation(val location: URI) : PythonPackageInstallRequest(location.toString())
|
||||
data class ByRepositoryPythonPackageSpecifications(val specifications: List<PythonRepositoryPackageSpecification>) : PythonPackageInstallRequest(
|
||||
specifications.joinToString(", ") { it.nameWithVersionSpec })
|
||||
|
||||
@@ -103,10 +103,10 @@ class PipPackageManagerEngine(
|
||||
runPackagingTool(operation, Args(*arguments.toTypedArray()))
|
||||
|
||||
|
||||
private fun partitionPackagesBySource(installRequest: PythonPackageInstallRequest): List<List<String>> {
|
||||
private fun partitionPackagesBySource(installRequest: PythonPackageInstallRequest): List<Args> {
|
||||
when (installRequest) {
|
||||
is PythonPackageInstallRequest.ByLocation -> {
|
||||
return listOf(listOf(installRequest.location.toString()))
|
||||
return listOf(Args(installRequest.location.toString()))
|
||||
}
|
||||
is PythonPackageInstallRequest.ByRepositoryPythonPackageSpecifications -> {
|
||||
return partitionPackagesBySource(installRequest.specifications)
|
||||
@@ -114,7 +114,7 @@ class PipPackageManagerEngine(
|
||||
}
|
||||
}
|
||||
|
||||
private fun partitionPackagesBySource(specifications: List<PythonRepositoryPackageSpecification>): List<List<String>> {
|
||||
private fun partitionPackagesBySource(specifications: List<PythonRepositoryPackageSpecification>): List<Args> {
|
||||
val (pypiSpecs, nonPypi) = specifications.partition {
|
||||
val url = it.repository.urlForInstallation?.toString()
|
||||
url == null || url == PyPIPackageUtil.PYPI_LIST_URL
|
||||
@@ -127,25 +127,27 @@ class PipPackageManagerEngine(
|
||||
return@mapNotNull null
|
||||
}
|
||||
|
||||
listOf(
|
||||
val argsStr = listOf(
|
||||
"--index-url",
|
||||
url
|
||||
) + specs.map { it.nameWithVersionSpec }
|
||||
|
||||
Args().addArgs(argsStr)
|
||||
}
|
||||
|
||||
val pypi = mutableListOf<List<String>>()
|
||||
val pypi = mutableListOf<Args>()
|
||||
if (pypiSpecs.isNotEmpty()) {
|
||||
pypi.add(pypiSpecs.map { it.nameWithVersionsSpec })
|
||||
pypi.add(Args().addArgs(pypiSpecs.map { it.nameWithVersionsSpec }))
|
||||
}
|
||||
|
||||
return pypi + byRepository
|
||||
}
|
||||
|
||||
suspend fun performInstall(argumentsGroups: List<List<String>>, options: List<String>): PyResult<Unit> {
|
||||
suspend fun performInstall(argumentsGroups: List<Args>, options: List<String>): PyResult<Unit> {
|
||||
for (argumentsGroup in argumentsGroups) {
|
||||
val result = runPackagingTool(
|
||||
operation = "install",
|
||||
arguments = argumentsGroup + options
|
||||
arguments = argumentsGroup.addArgs(options)
|
||||
)
|
||||
|
||||
result.onFailure {
|
||||
|
||||
+3
-2
@@ -10,6 +10,7 @@ import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.roots.ModuleRootManager;
|
||||
import com.intellij.openapi.roots.OrderRootType;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.jetbrains.python.PyNames;
|
||||
import com.jetbrains.python.sdk.legacy.PythonSdkUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -38,9 +39,9 @@ public class PythonSpellcheckerGenerateDictionariesAction extends AnAction {
|
||||
if (root.getName().equals("Lib")) {
|
||||
generator.addFolder("python", root);
|
||||
generator.excludeFolder(root.findChild("test"));
|
||||
generator.excludeFolder(root.findChild("site-packages"));
|
||||
generator.excludeFolder(root.findChild(PyNames.SITE_PACKAGES));
|
||||
}
|
||||
else if (root.getName().equals("site-packages")) {
|
||||
else if (root.getName().equals(PyNames.SITE_PACKAGES)) {
|
||||
VirtualFile djangoRoot = root.findChild("django");
|
||||
if (djangoRoot != null) {
|
||||
generator.addFolder("django", djangoRoot);
|
||||
|
||||
Reference in New Issue
Block a user