mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-19 13:02:30 +07:00
Support appending requirement to string or tuple in setup.py (PY-29153, PY-30016)
This commit is contained in:
@@ -126,15 +126,14 @@ public class PyPackageUtil {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PyListLiteralExpression findSetupPyInstallRequires(@Nullable PyCallExpression setupCall) {
|
||||
private static PsiElement findSetupPyInstallRequires(@Nullable PyCallExpression setupCall) {
|
||||
if (setupCall == null) return null;
|
||||
|
||||
return StreamEx
|
||||
.of(REQUIRES, INSTALL_REQUIRES)
|
||||
.map(setupCall::getKeywordArgument)
|
||||
.map(PyPackageUtil::resolveValue)
|
||||
.select(PyListLiteralExpression.class)
|
||||
.findFirst()
|
||||
.findFirst(Objects::nonNull)
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
@@ -435,25 +434,18 @@ public class PyPackageUtil {
|
||||
}
|
||||
|
||||
final PyFile setupPy = findSetupPy(module);
|
||||
if (setupPy == null) {
|
||||
return;
|
||||
}
|
||||
if (setupPy == null) return;
|
||||
|
||||
final PyCallExpression setupCall = findSetupCall(setupPy);
|
||||
final PyListLiteralExpression installRequires = findSetupPyInstallRequires(setupCall);
|
||||
final PyElementGenerator generator = PyElementGenerator.getInstance(module.getProject());
|
||||
if (setupCall == null) return;
|
||||
|
||||
if (installRequires != null && installRequires.isWritable()) {
|
||||
final String text = String.format("'%s'", requirementName);
|
||||
final PyExpression generated = generator.createExpressionFromText(languageLevel, text);
|
||||
installRequires.add(generated);
|
||||
|
||||
return;
|
||||
final PsiElement installRequires = findSetupPyInstallRequires(setupCall);
|
||||
if (installRequires != null) {
|
||||
addRequirementToInstallRequires(installRequires, requirementName, languageLevel);
|
||||
}
|
||||
|
||||
if (setupCall != null) {
|
||||
else {
|
||||
final PyArgumentList argumentList = setupCall.getArgumentList();
|
||||
final PyKeywordArgument requiresArg = generateRequiresKwarg(setupPy, requirementName, languageLevel, generator);
|
||||
final PyKeywordArgument requiresArg = generateRequiresKwarg(setupPy, requirementName, languageLevel);
|
||||
|
||||
if (argumentList != null && requiresArg != null) {
|
||||
argumentList.addArgument(requiresArg);
|
||||
@@ -461,14 +453,47 @@ public class PyPackageUtil {
|
||||
}
|
||||
}
|
||||
|
||||
private static void addRequirementToInstallRequires(@NotNull PsiElement installRequires,
|
||||
@NotNull String requirementName,
|
||||
@NotNull LanguageLevel languageLevel) {
|
||||
final PyElementGenerator generator = PyElementGenerator.getInstance(installRequires.getProject());
|
||||
final PyExpression newRequirement = generator.createExpressionFromText(languageLevel, "'" + requirementName + "'");
|
||||
|
||||
if (installRequires instanceof PyListLiteralExpression) {
|
||||
installRequires.add(newRequirement);
|
||||
}
|
||||
else if (installRequires instanceof PyTupleExpression) {
|
||||
final String newInstallRequiresText = StreamEx
|
||||
.of(((PyTupleExpression)installRequires).getElements())
|
||||
.append(newRequirement)
|
||||
.map(PyExpression::getText)
|
||||
.joining(",", "(", ")");
|
||||
|
||||
final PyExpression expression = generator.createExpressionFromText(languageLevel, newInstallRequiresText);
|
||||
|
||||
Optional
|
||||
.ofNullable(PyUtil.as(expression, PyParenthesizedExpression.class))
|
||||
.map(PyParenthesizedExpression::getContainedExpression)
|
||||
.map(e -> PyUtil.as(e, PyTupleExpression.class))
|
||||
.ifPresent(e -> installRequires.replace(e));
|
||||
}
|
||||
else if (installRequires instanceof PyStringLiteralExpression) {
|
||||
final PyListLiteralExpression newInstallRequires = generator.createListLiteral();
|
||||
|
||||
newInstallRequires.add(installRequires);
|
||||
newInstallRequires.add(newRequirement);
|
||||
|
||||
installRequires.replace(newInstallRequires);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PyKeywordArgument generateRequiresKwarg(@NotNull PyFile setupPy,
|
||||
@NotNull String requirementName,
|
||||
@NotNull LanguageLevel languageLevel,
|
||||
@NotNull PyElementGenerator generator) {
|
||||
@NotNull LanguageLevel languageLevel) {
|
||||
final String keyword = SetupTaskIntrospector.usesSetuptools(setupPy) ? INSTALL_REQUIRES : REQUIRES;
|
||||
final String text = String.format("foo(%s=['%s'])", keyword, requirementName);
|
||||
final PyExpression generated = generator.createExpressionFromText(languageLevel, text);
|
||||
final PyExpression generated = PyElementGenerator.getInstance(setupPy.getProject()).createExpressionFromText(languageLevel, text);
|
||||
|
||||
if (generated instanceof PyCallExpression) {
|
||||
final PyCallExpression callExpression = (PyCallExpression)generated;
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
from setuptools import setup
|
||||
|
||||
tests_require = [
|
||||
'mynose'
|
||||
]
|
||||
|
||||
setup(name='foo',
|
||||
version=0.1,
|
||||
tests_require=tests_require,
|
||||
setup_requires=[
|
||||
'numpy'
|
||||
],
|
||||
install_requires='NewDjango==1.3.1')
|
||||
@@ -0,0 +1,13 @@
|
||||
from setuptools import setup
|
||||
|
||||
tests_require = [
|
||||
'mynose'
|
||||
]
|
||||
|
||||
setup(name='foo',
|
||||
version=0.1,
|
||||
tests_require=tests_require,
|
||||
setup_requires=[
|
||||
'numpy'
|
||||
],
|
||||
install_requires=('NewDjango==1.3.1',))
|
||||
@@ -89,12 +89,20 @@ public class PyPackageUtilTest extends PyTestCase {
|
||||
doTestUselessRequirementsTxtOrSetupPyUpdating(false);
|
||||
}
|
||||
|
||||
public void testDistutilsSetupPyUpdating() {
|
||||
doTestSetupPyUpdating("requires");
|
||||
public void testDistutilsSetupPyRequiresIntroduction() {
|
||||
doTestSetupPyRequiresIntroduction("requires");
|
||||
}
|
||||
|
||||
public void testSetuptoolsSetupPyUpdating() {
|
||||
doTestSetupPyUpdating("install_requires");
|
||||
public void testSetuptoolsSetupPyRequiresIntroduction() {
|
||||
doTestSetupPyRequiresIntroduction("install_requires");
|
||||
}
|
||||
|
||||
public void testSetuptoolsSetupPyTupleRequiresAppending() {
|
||||
doTestSetupPyRequiresAppending("('NewDjango==1.3.1',)", "('NewDjango==1.3.1', 'Markdown')");
|
||||
}
|
||||
|
||||
public void testSetuptoolsSetupPyStringRequiresAppending() {
|
||||
doTestSetupPyRequiresAppending("'NewDjango==1.3.1'", "['NewDjango==1.3.1', 'Markdown']");
|
||||
}
|
||||
|
||||
public void testAbsentRequirementsTxtUpdating() {
|
||||
@@ -204,7 +212,7 @@ public class PyPackageUtilTest extends PyTestCase {
|
||||
assertEquals(expected.subList(fromIndex, expected.size()), actual);
|
||||
}
|
||||
|
||||
private void doTestSetupPyUpdating(@NotNull String keyword) {
|
||||
private void doTestSetupPyRequiresIntroduction(@NotNull String keyword) {
|
||||
final Module module = myFixture.getModule();
|
||||
|
||||
checkSetupArgumentText(module, keyword, null);
|
||||
@@ -226,6 +234,22 @@ public class PyPackageUtilTest extends PyTestCase {
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
private void doTestSetupPyRequiresAppending(@NotNull String argumentBefore, @NotNull String argumentAfter) {
|
||||
final Module module = myFixture.getModule();
|
||||
|
||||
checkSetupArgumentText(module, "install_requires", argumentBefore);
|
||||
checkRequirements(PyPackageUtil.findSetupPyRequires(module), 1);
|
||||
|
||||
final Runnable appendToRequires = () -> PyPackageUtil.addRequirementToTxtOrSetupPy(module, "Markdown", LanguageLevel.PYTHON34);
|
||||
WriteCommandAction.runWriteCommandAction(myFixture.getProject(), appendToRequires);
|
||||
|
||||
checkSetupArgumentText(module, "install_requires", argumentAfter);
|
||||
|
||||
final List<PyRequirement> actual = PyPackageUtil.findSetupPyRequires(module);
|
||||
final List<PyRequirement> expected = PyRequirementParser.fromText("NewDjango==1.3.1\nMarkdown\nnumpy\nmynose");
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
private static void checkSetupArgumentText(@NotNull Module module, @NotNull String keyword, @Nullable String text) {
|
||||
final PyCallExpression setupCall = PyPackageUtil.findSetupCall(module);
|
||||
assertNotNull(setupCall);
|
||||
|
||||
Reference in New Issue
Block a user