[python] refactoring: make some members used from tests public and add test-only accessors (IJPL-205216)

This is needed to avoid IllegalAccessError if tests are loaded by a different classloader and to allow enabling 'Suspicious Package-Private Access' for tests as well.

GitOrigin-RevId: ab7b1af126c6fe3060ddd75e36bdba10a93cdc01
This commit is contained in:
Nikolay Chashnikov
2025-09-02 12:09:21 +02:00
committed by intellij-monorepo-bot
parent 1b81c72b78
commit fc83a8f2fc
6 changed files with 35 additions and 13 deletions

View File

@@ -27,6 +27,7 @@ import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.psi.search.GlobalSearchScope;
import org.jdom.Element;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
@@ -207,7 +208,13 @@ public abstract class AbstractRerunFailedTestsAction extends AnAction {
protected @Nullable MyRunProfile getRunProfile(@NotNull ExecutionEnvironment environment) {
return null;
}
@TestOnly
@ApiStatus.Internal
public @Nullable RunConfiguration getRunProfileTestAccessor(@NotNull ExecutionEnvironment environment) {
return getRunProfile(environment);
}
public @Nullable TestFrameworkRunningModel getModel() {
if (myModel != null) {
return myModel;

View File

@@ -44,8 +44,10 @@ import com.jetbrains.python.psi.PyFunction;
import com.jetbrains.python.psi.PyParameterList;
import com.jetbrains.python.psi.impl.ParamHelper;
import com.jetbrains.python.refactoring.introduce.IntroduceValidator;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.VisibleForTesting;
import javax.swing.*;
import java.awt.*;
@@ -61,7 +63,7 @@ import static com.jetbrains.python.PyNames.CANONICAL_SELF;
/**
* User : ktisha
*/
@ApiStatus.Internal
public class PyChangeSignatureDialog extends
ChangeSignatureDialogBase<PyParameterInfo, PyFunction, String, PyMethodDescriptor, PyParameterTableModelItem, PyParameterTableModel> {
@@ -102,8 +104,9 @@ public class PyChangeSignatureDialog extends
return name != null && validator.isIdentifier(name, project) && !validator.isKeyword(name, project);
}
@VisibleForTesting
@Override
protected @Nullable String validateAndCommitData() {
public @Nullable String validateAndCommitData() {
final String functionName = myNameField.getText().trim();
if (!functionName.equals(myMethod.getName())) {
final boolean defined = IntroduceValidator.isDefinedInScope(functionName, myMethod.getMethod());

View File

@@ -22,8 +22,10 @@ import com.jetbrains.python.psi.resolve.PyResolveContext;
import com.jetbrains.python.psi.search.PySuperMethodsSearch;
import com.jetbrains.python.psi.types.TypeEvalContext;
import com.jetbrains.python.pyi.PyiUtil;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.VisibleForTesting;
/**
* User : ktisha
@@ -126,7 +128,9 @@ public class PyChangeSignatureHandler implements ChangeSignatureHandler {
CommonRefactoringUtil.showErrorHint(project, editor, message, RefactoringBundle.message("changeSignature.refactoring.name"), "refactoring.renameRefactorings");
}
protected static @Nullable PyFunction getSuperMethod(@Nullable PyFunction function) {
@VisibleForTesting
@ApiStatus.Internal
public static @Nullable PyFunction getSuperMethod(@Nullable PyFunction function) {
if (function == null) {
return null;
}

View File

@@ -21,8 +21,10 @@ import com.intellij.refactoring.listeners.RefactoringElementListener;
import com.jetbrains.python.PyBundle;
import com.jetbrains.python.run.configuration.PythonConfigurationFragmentedEditor;
import org.jdom.Element;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import java.io.File;
import java.util.Objects;
@@ -54,6 +56,12 @@ public class PythonRunConfiguration extends AbstractPythonRunConfiguration<Pytho
setUnbufferedEnv();
}
@TestOnly
@ApiStatus.Internal
public static PythonRunConfiguration createRunConfigurationForTests(Project project, ConfigurationFactory factory) {
return new PythonRunConfiguration(project, factory);
}
@Override
protected boolean isNewUiSupported() {
return true;

View File

@@ -2,11 +2,11 @@
package com.intellij.execution.testframework.actions;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.configurations.RunConfiguration;
import com.intellij.execution.configurations.RunProfileState;
import com.intellij.execution.executors.DefaultRunExecutor;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.runners.ExecutionEnvironmentBuilder;
import com.intellij.execution.testframework.actions.AbstractRerunFailedTestsAction.MyRunProfile;
import com.intellij.execution.ui.RunContentDescriptor;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.application.ApplicationManager;
@@ -34,7 +34,7 @@ public final class RerunFailedActionsTestTools {
*/
@Nullable
public static ExecutionEnvironment getReRunEnvironment(@NotNull final AbstractRerunFailedTestsAction runAction) {
final MyRunProfile profile = runAction.getRunProfile(new ExecutionEnvironment());
final RunConfiguration profile = runAction.getRunProfileTestAccessor(new ExecutionEnvironment());
if (profile == null) {
return null;
}

View File

@@ -11,7 +11,7 @@ class PythonConsoleScriptsTest : LightPlatform4TestCase() {
val pythonConfigurationFactory = PythonConfigurationType.getInstance().factory
SoftAssertions.assertSoftly { softly ->
PythonRunConfiguration(project, pythonConfigurationFactory).let { runConfiguration ->
PythonRunConfiguration.createRunConfigurationForTests(project, pythonConfigurationFactory).let { runConfiguration ->
runConfiguration.scriptName = "script.py"
softly
.assertThat(buildScriptWithConsoleRun(runConfiguration))
@@ -19,7 +19,7 @@ class PythonConsoleScriptsTest : LightPlatform4TestCase() {
.describedAs("Generates the line that executes the script")
}
PythonRunConfiguration(project, pythonConfigurationFactory).let { runConfiguration ->
PythonRunConfiguration.createRunConfigurationForTests(project, pythonConfigurationFactory).let { runConfiguration ->
runConfiguration.scriptName = "script name with spaces.py"
softly
.assertThat(buildScriptWithConsoleRun(runConfiguration))
@@ -27,7 +27,7 @@ class PythonConsoleScriptsTest : LightPlatform4TestCase() {
.describedAs("Generates the line that executes the script with spaces in its name")
}
PythonRunConfiguration(project, pythonConfigurationFactory).let { runConfiguration ->
PythonRunConfiguration.createRunConfigurationForTests(project, pythonConfigurationFactory).let { runConfiguration ->
runConfiguration.scriptName = "script's name.py"
softly
.assertThat(buildScriptWithConsoleRun(runConfiguration))
@@ -35,7 +35,7 @@ class PythonConsoleScriptsTest : LightPlatform4TestCase() {
.describedAs("Generates the line that executes the script with a single quotes in its name")
}
PythonRunConfiguration(project, pythonConfigurationFactory).let { runConfiguration ->
PythonRunConfiguration.createRunConfigurationForTests(project, pythonConfigurationFactory).let { runConfiguration ->
runConfiguration.scriptName = "script.py"
runConfiguration.workingDirectory = "/home/username"
softly
@@ -44,7 +44,7 @@ class PythonConsoleScriptsTest : LightPlatform4TestCase() {
.describedAs("Generates the line that executes the script with working directory specified")
}
PythonRunConfiguration(project, pythonConfigurationFactory).let { runConfiguration ->
PythonRunConfiguration.createRunConfigurationForTests(project, pythonConfigurationFactory).let { runConfiguration ->
runConfiguration.scriptName = "script.py"
runConfiguration.workingDirectory = "/home/username"
runConfiguration.scriptParameters = "simple \"one parameter in four words\" \"let's make it harder\""
@@ -55,7 +55,7 @@ class PythonConsoleScriptsTest : LightPlatform4TestCase() {
.describedAs("Generates the line that executes the script with working directory and parameters specified")
}
PythonRunConfiguration(project, pythonConfigurationFactory).let { runConfiguration ->
PythonRunConfiguration.createRunConfigurationForTests(project, pythonConfigurationFactory).let { runConfiguration ->
runConfiguration.scriptName = "user_module"
runConfiguration.isModuleMode = true
softly
@@ -64,7 +64,7 @@ class PythonConsoleScriptsTest : LightPlatform4TestCase() {
.describedAs("Generates the line that executes the module")
}
PythonRunConfiguration(project, pythonConfigurationFactory).let { runConfiguration ->
PythonRunConfiguration.createRunConfigurationForTests(project, pythonConfigurationFactory).let { runConfiguration ->
runConfiguration.scriptName = "script.py"
runConfiguration.envs["FOO"] = "BAR"
runConfiguration.envs["BAZ"] = "qux"