mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
PY-76877 Conformance test failure: overloads_basic.py
PySliceExpression is replaced by PySubscriptionExpression in AST. PySliceItem is returned by PySubscriptionExpression.getIndexExpression(). For that purpose PySliceItem is now a PyExpression of type `builtins.slice`. GitOrigin-RevId: 9aa8de13ef7c51741e248317c5264b3a06ffb9bf
This commit is contained in:
committed by
intellij-monorepo-bot
parent
6eb1b97d67
commit
c8fb196d52
@@ -74,8 +74,7 @@ public interface PyAstAssignmentStatement extends PyAstStatement, PyAstNamedElem
|
||||
if (raw ||
|
||||
expr instanceof PyAstTargetExpression ||
|
||||
expr instanceof PyAstReferenceExpression ||
|
||||
expr instanceof PyAstSubscriptionExpression ||
|
||||
expr instanceof PyAstSliceExpression) {
|
||||
expr instanceof PyAstSubscriptionExpression) {
|
||||
targets.add(expr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
|
||||
@SuppressWarnings("MissingDeprecatedAnnotation")
|
||||
@Deprecated(forRemoval = true)
|
||||
@ApiStatus.Experimental
|
||||
public interface PyAstSliceExpression extends PyAstExpression {
|
||||
default @NotNull PyAstExpression getOperand() {
|
||||
|
||||
@@ -7,7 +7,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
|
||||
@ApiStatus.Experimental
|
||||
public interface PyAstSliceItem extends PyAstElement {
|
||||
public interface PyAstSliceItem extends PyAstExpression {
|
||||
default @Nullable PyAstExpression getLowerBound() {
|
||||
return childToPsi(PythonDialectsTokenSetProvider.getInstance().getExpressionTokens(), 0);
|
||||
}
|
||||
|
||||
@@ -73,7 +73,6 @@ public interface PyElementTypes {
|
||||
PyElementType BOOL_LITERAL_EXPRESSION = new PyElementType("BOOL_LITERAL_EXPRESSION", Companion.getINSTANCE().getBoolLiteralExpressionConstructor());
|
||||
PyElementType PARENTHESIZED_EXPRESSION = new PyElementType("PARENTHESIZED_EXPRESSION", Companion.getINSTANCE().getParenthesizedExpressionConstructor());
|
||||
PyElementType SUBSCRIPTION_EXPRESSION = new PyElementType("SUBSCRIPTION_EXPRESSION", Companion.getINSTANCE().getSubscriptionExpressionConstructor());
|
||||
PyElementType SLICE_EXPRESSION = new PyElementType("SLICE_EXPRESSION", Companion.getINSTANCE().getSliceExpressionConstructor());
|
||||
PyElementType SLICE_ITEM = new PyElementType("SLICE_ITEM", Companion.getINSTANCE().getSliceItemConstructor());
|
||||
PyElementType BINARY_EXPRESSION = new PyElementType("BINARY_EXPRESSION", Companion.getINSTANCE().getBinaryExpressionConstructor());
|
||||
PyElementType PREFIX_EXPRESSION = new PyElementType("PREFIX_EXPRESSION", Companion.getINSTANCE().getPrefixExpressionConstructor());
|
||||
|
||||
@@ -71,7 +71,6 @@ abstract class PyElementTypesFacade {
|
||||
abstract val parenthesizedExpressionConstructor: Function<in ASTNode, out PsiElement>
|
||||
abstract val subscriptionExpressionConstructor: Function<in ASTNode, out PsiElement>
|
||||
|
||||
abstract val sliceExpressionConstructor: Function<in ASTNode, out PsiElement>
|
||||
abstract val sliceItemConstructor: Function<in ASTNode, out PsiElement>
|
||||
abstract val binaryExpressionConstructor: Function<in ASTNode, out PsiElement>
|
||||
abstract val prefixExpressionConstructor: Function<in ASTNode, out PsiElement>
|
||||
|
||||
@@ -36,7 +36,7 @@ public final class PythonTokenSetContributor extends PythonDialectsTokenSetContr
|
||||
public @NotNull TokenSet getExpressionTokens() {
|
||||
return TokenSet.create(EMPTY_EXPRESSION, REFERENCE_EXPRESSION, INTEGER_LITERAL_EXPRESSION, FLOAT_LITERAL_EXPRESSION,
|
||||
IMAGINARY_LITERAL_EXPRESSION, STRING_LITERAL_EXPRESSION, PARENTHESIZED_EXPRESSION,
|
||||
SUBSCRIPTION_EXPRESSION, SLICE_EXPRESSION, BINARY_EXPRESSION, PREFIX_EXPRESSION, CALL_EXPRESSION,
|
||||
SUBSCRIPTION_EXPRESSION, SLICE_ITEM, BINARY_EXPRESSION, PREFIX_EXPRESSION, CALL_EXPRESSION,
|
||||
LIST_LITERAL_EXPRESSION, TUPLE_EXPRESSION, KEYWORD_ARGUMENT_EXPRESSION, STAR_ARGUMENT_EXPRESSION,
|
||||
LAMBDA_EXPRESSION, LIST_COMP_EXPRESSION, DICT_LITERAL_EXPRESSION, KEY_VALUE_EXPRESSION,
|
||||
REPR_EXPRESSION, GENERATOR_EXPRESSION, CONDITIONAL_EXPRESSION, YIELD_EXPRESSION,
|
||||
|
||||
@@ -601,7 +601,7 @@ public class ExpressionParsing extends Parsing {
|
||||
sliceMarker.done(PyElementTypes.EMPTY_EXPRESSION);
|
||||
sliceItemStart.done(PyElementTypes.SLICE_ITEM);
|
||||
nextToken();
|
||||
exprStart.done(PyElementTypes.SLICE_EXPRESSION);
|
||||
exprStart.done(PyElementTypes.SUBSCRIPTION_EXPRESSION);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
@@ -653,7 +653,7 @@ public class ExpressionParsing extends Parsing {
|
||||
if (sliceOrTupleStart != null) {
|
||||
sliceOrTupleStart.drop();
|
||||
}
|
||||
exprStart.done(PyElementTypes.SLICE_EXPRESSION);
|
||||
exprStart.done(PyElementTypes.SUBSCRIPTION_EXPRESSION);
|
||||
}
|
||||
return inSlice;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
|
||||
@SuppressWarnings("MissingDeprecatedAnnotation")
|
||||
@Deprecated(forRemoval = true)
|
||||
public interface PySliceExpression extends PyAstSliceExpression, PyExpression {
|
||||
@Override
|
||||
default @NotNull PyExpression getOperand() {
|
||||
|
||||
@@ -5,7 +5,7 @@ import com.jetbrains.python.ast.PyAstSliceItem;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
|
||||
public interface PySliceItem extends PyAstSliceItem, PyElement {
|
||||
public interface PySliceItem extends PyAstSliceItem, PyExpression {
|
||||
@Override
|
||||
default @Nullable PyExpression getLowerBound() {
|
||||
return (PyExpression)PyAstSliceItem.super.getLowerBound();
|
||||
|
||||
@@ -124,8 +124,6 @@ class PyElementTypesFacadeImpl : PyElementTypesFacade() {
|
||||
get() = F { node -> PyParenthesizedExpressionImpl(node) }
|
||||
override val subscriptionExpressionConstructor: F
|
||||
get() = F { node -> PySubscriptionExpressionImpl(node) }
|
||||
override val sliceExpressionConstructor: F
|
||||
get() = F { node -> PySliceExpressionImpl(node) }
|
||||
override val sliceItemConstructor: F
|
||||
get() = F { node -> PySliceItemImpl(node) }
|
||||
override val binaryExpressionConstructor: F
|
||||
|
||||
+40
-41
@@ -86,7 +86,46 @@ public final class PyStringFormatInspection extends PyInspection {
|
||||
final PyResolveContext resolveContext = PyResolveContext.defaultContext(myTypeEvalContext);
|
||||
|
||||
final String s = myFormatSpec.get("1");
|
||||
if (PsiTreeUtil.instanceOf(rightExpression, SIMPLE_RHS_EXPRESSIONS)) {
|
||||
if (rightExpression instanceof PySubscriptionExpression subscription &&
|
||||
subscription.getIndexExpression() instanceof PySliceItem sliceItem &&
|
||||
s != null) {
|
||||
final PyType type = myTypeEvalContext.getType(subscription.getOperand());
|
||||
final PyType stringType = PyBuiltinCache.getInstance(rightExpression).getStringType(LanguageLevel.forElement(rightExpression));
|
||||
final PyType listType = PyBuiltinCache.getInstance(rightExpression).getListType();
|
||||
|
||||
if (type == null) return -1;
|
||||
if (PyTypeChecker.match(listType, type, myTypeEvalContext)
|
||||
|| PyTypeChecker.match(stringType, type, myTypeEvalContext)) {
|
||||
checkTypeCompatible(problemTarget, builtinCache.getStrType(),
|
||||
PyTypeParser.getTypeByName(problemTarget, s, myTypeEvalContext));
|
||||
return 1;
|
||||
}
|
||||
PyExpression lower = sliceItem.getLowerBound();
|
||||
PyExpression upper = sliceItem.getUpperBound();
|
||||
PyExpression stride = sliceItem.getStride();
|
||||
if (upper instanceof PyNumericLiteralExpression) {
|
||||
BigInteger lowerVal;
|
||||
if (lower instanceof PyNumericLiteralExpression) {
|
||||
lowerVal = ((PyNumericLiteralExpression)lower).getBigIntegerValue();
|
||||
}
|
||||
else {
|
||||
lowerVal = BigInteger.ZERO;
|
||||
}
|
||||
int count = (((PyNumericLiteralExpression)upper).getBigIntegerValue().subtract(lowerVal)).intValue();
|
||||
int strideVal;
|
||||
if (stride instanceof PyNumericLiteralExpression) {
|
||||
strideVal = ((PyNumericLiteralExpression)stride).getBigIntegerValue().intValue();
|
||||
}
|
||||
else {
|
||||
strideVal = 1;
|
||||
}
|
||||
int res = count / strideVal;
|
||||
int residue = count % strideVal == 0 ? 0 : 1;
|
||||
return res + residue;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
else if (PsiTreeUtil.instanceOf(rightExpression, SIMPLE_RHS_EXPRESSIONS)) {
|
||||
if (s != null) {
|
||||
final PyType rightType = myTypeEvalContext.getType(rightExpression);
|
||||
if (rightType instanceof PyTupleType tupleType) {
|
||||
@@ -160,46 +199,6 @@ public final class PyStringFormatInspection extends PyInspection {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else if (rightExpression instanceof PySliceExpression && s != null) {
|
||||
final PyType type = myTypeEvalContext.getType(((PySliceExpression)rightExpression).getOperand());
|
||||
final PyType stringType = PyBuiltinCache.getInstance(rightExpression).getStringType(LanguageLevel.forElement(rightExpression));
|
||||
final PyType listType = PyBuiltinCache.getInstance(rightExpression).getListType();
|
||||
|
||||
if (type == null) return -1;
|
||||
if (PyTypeChecker.match(listType, type, myTypeEvalContext)
|
||||
|| PyTypeChecker.match(stringType, type, myTypeEvalContext)) {
|
||||
checkTypeCompatible(problemTarget, builtinCache.getStrType(),
|
||||
PyTypeParser.getTypeByName(problemTarget, s, myTypeEvalContext));
|
||||
return 1;
|
||||
}
|
||||
PySliceItem sliceItem = ((PySliceExpression)rightExpression).getSliceItem();
|
||||
if (sliceItem != null) {
|
||||
PyExpression lower = sliceItem.getLowerBound();
|
||||
PyExpression upper = sliceItem.getUpperBound();
|
||||
PyExpression stride = sliceItem.getStride();
|
||||
if (upper instanceof PyNumericLiteralExpression) {
|
||||
BigInteger lowerVal;
|
||||
if (lower instanceof PyNumericLiteralExpression) {
|
||||
lowerVal = ((PyNumericLiteralExpression)lower).getBigIntegerValue();
|
||||
}
|
||||
else {
|
||||
lowerVal = BigInteger.ZERO;
|
||||
}
|
||||
int count = (((PyNumericLiteralExpression)upper).getBigIntegerValue().subtract(lowerVal)).intValue();
|
||||
int strideVal;
|
||||
if (stride instanceof PyNumericLiteralExpression) {
|
||||
strideVal = ((PyNumericLiteralExpression)stride).getBigIntegerValue().intValue();
|
||||
}
|
||||
else {
|
||||
strideVal = 1;
|
||||
}
|
||||
int res = count / strideVal;
|
||||
int residue = count % strideVal == 0 ? 0 : 1;
|
||||
return res + residue;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
-2
@@ -73,8 +73,6 @@ public class PyTypeCheckerInspection extends PyInspection {
|
||||
|
||||
@Override
|
||||
public void visitPySubscriptionExpression(@NotNull PySubscriptionExpression node) {
|
||||
// TODO: Support slice PySliceExpressions
|
||||
|
||||
PyType operandType = myTypeEvalContext.getType(node.getOperand());
|
||||
if (operandType instanceof PyTupleType tupleType && !tupleType.isHomogeneous()) {
|
||||
PyExpression indexExpression = node.getIndexExpression();
|
||||
|
||||
@@ -45,7 +45,7 @@ import org.jetbrains.annotations.NonNls
|
||||
class PyBuiltinCache(
|
||||
val builtinsFile: PyFile? = null,
|
||||
private val myTypeshedFile: PyFile? = null,
|
||||
private val myExceptionsFile: PyFile? = null
|
||||
private val myExceptionsFile: PyFile? = null,
|
||||
) {
|
||||
/**
|
||||
* Stores the most often used types, returned by nNNType.
|
||||
@@ -199,6 +199,8 @@ class PyBuiltinCache(
|
||||
val typeType: PyClassType?
|
||||
get() = getObjectType("type")
|
||||
|
||||
val sliceType: PyClassType?
|
||||
get() = getObjectType("slice")
|
||||
|
||||
val noneType: PyClassType?
|
||||
get() {
|
||||
|
||||
@@ -24,6 +24,8 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
|
||||
@SuppressWarnings("ALL")
|
||||
@Deprecated(forRemoval = true)
|
||||
public class PySliceExpressionImpl extends PyElementImpl implements PySliceExpression {
|
||||
public PySliceExpressionImpl(ASTNode astNode) {
|
||||
super(astNode);
|
||||
|
||||
@@ -3,10 +3,19 @@ package com.jetbrains.python.psi.impl;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.jetbrains.python.psi.PySliceItem;
|
||||
import com.jetbrains.python.psi.types.PyType;
|
||||
import com.jetbrains.python.psi.types.TypeEvalContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
|
||||
public class PySliceItemImpl extends PyElementImpl implements PySliceItem {
|
||||
public PySliceItemImpl(ASTNode astNode) {
|
||||
super(astNode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable PyType getType(@NotNull TypeEvalContext context, TypeEvalContext.@NotNull Key key) {
|
||||
return PyBuiltinCache.getInstance(this).getSliceType();
|
||||
}
|
||||
}
|
||||
|
||||
+28
-18
@@ -23,6 +23,7 @@ import com.intellij.util.containers.ContainerUtil;
|
||||
import com.jetbrains.python.codeInsight.typing.PyTypingTypeProvider;
|
||||
import com.jetbrains.python.psi.PyElementVisitor;
|
||||
import com.jetbrains.python.psi.PyExpression;
|
||||
import com.jetbrains.python.psi.PySliceItem;
|
||||
import com.jetbrains.python.psi.PySubscriptionExpression;
|
||||
import com.jetbrains.python.psi.impl.references.PyOperatorReference;
|
||||
import com.jetbrains.python.psi.resolve.PyResolveContext;
|
||||
@@ -48,25 +49,34 @@ public class PySubscriptionExpressionImpl extends PyElementImpl implements PySub
|
||||
@Override
|
||||
public @Nullable PyType getType(@NotNull TypeEvalContext context, @NotNull TypeEvalContext.Key key) {
|
||||
final PyExpression indexExpression = getIndexExpression();
|
||||
final PyType type = indexExpression != null ? context.getType(getOperand()) : null;
|
||||
if (type instanceof PyTupleType tupleType) {
|
||||
List<Integer> indexPossibleValues = getIndexExpressionPossibleValues(indexExpression, context, Integer.class);
|
||||
List<@Nullable PyType> possibleTypes = ContainerUtil.map(indexPossibleValues, index -> {
|
||||
if (!tupleType.isHomogeneous() && index < 0) {
|
||||
index += tupleType.getElementCount();
|
||||
if (indexExpression != null) {
|
||||
final PyType operandType = context.getType(getOperand());
|
||||
if (indexExpression instanceof PySliceItem) {
|
||||
if (operandType instanceof PyTupleType) {
|
||||
return ((PyTupleType)operandType).isHomogeneous() ? operandType : PyBuiltinCache.getInstance(this).getTupleType();
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (operandType instanceof PyTupleType tupleType) {
|
||||
List<Integer> indexPossibleValues = getIndexExpressionPossibleValues(indexExpression, context, Integer.class);
|
||||
List<@Nullable PyType> possibleTypes = ContainerUtil.map(indexPossibleValues, index -> {
|
||||
if (!tupleType.isHomogeneous() && index < 0) {
|
||||
index += tupleType.getElementCount();
|
||||
}
|
||||
return tupleType.getElementType(index);
|
||||
});
|
||||
return PyUnionType.union(possibleTypes);
|
||||
}
|
||||
if (operandType instanceof PyTypedDictType typedDictType) {
|
||||
List<String> indexPossibleValues = getIndexExpressionPossibleValues(indexExpression, context, String.class);
|
||||
return PyUnionType.union(ContainerUtil.map(indexPossibleValues, typedDictType::getElementType));
|
||||
}
|
||||
if (operandType instanceof PyClassType) {
|
||||
PyType parameterizedType = Ref.deref(PyTypingTypeProvider.getType(this, context));
|
||||
if (parameterizedType instanceof PyCollectionType collectionType) {
|
||||
return collectionType.toClass();
|
||||
}
|
||||
}
|
||||
return tupleType.getElementType(index);
|
||||
});
|
||||
return PyUnionType.union(possibleTypes);
|
||||
}
|
||||
if (type instanceof PyTypedDictType typedDictType) {
|
||||
List<String> indexPossibleValues = getIndexExpressionPossibleValues(indexExpression, context, String.class);
|
||||
return PyUnionType.union(ContainerUtil.map(indexPossibleValues, typedDictType::getElementType));
|
||||
}
|
||||
if (type instanceof PyClassType) {
|
||||
PyType parameterizedType = Ref.deref(PyTypingTypeProvider.getType(this, context));
|
||||
if (parameterizedType instanceof PyCollectionType collectionType) {
|
||||
return collectionType.toClass();
|
||||
}
|
||||
}
|
||||
return PyCallExpressionHelper.getCallType(this, context, key);
|
||||
|
||||
+1
-2
@@ -425,7 +425,7 @@ public final class PyReplaceExpressionUtil implements PyElementTypes {
|
||||
|
||||
private static boolean isNotAssociative(final @NotNull PyBinaryExpression binaryExpression) {
|
||||
final IElementType opType = getOperationType(binaryExpression);
|
||||
return COMPARISON_OPERATIONS.contains(opType) || binaryExpression instanceof PySliceExpression ||
|
||||
return COMPARISON_OPERATIONS.contains(opType) ||
|
||||
opType == DIV || opType == FLOORDIV || opType == PERC || opType == EXP || opType == MINUS;
|
||||
}
|
||||
|
||||
@@ -433,7 +433,6 @@ public final class PyReplaceExpressionUtil implements PyElementTypes {
|
||||
int priority = 0;
|
||||
if (expr instanceof PyReferenceExpression ||
|
||||
expr instanceof PySubscriptionExpression ||
|
||||
expr instanceof PySliceExpression ||
|
||||
expr instanceof PyCallExpression) priority = 1;
|
||||
else if (expr instanceof PyPrefixExpression) {
|
||||
final IElementType opType = getOperationType(expr);
|
||||
|
||||
@@ -35,7 +35,6 @@ public final class PyEditorHandlerConfig {
|
||||
PyAstArgumentList.class,
|
||||
PyAstParameterList.class,
|
||||
PyAstDecoratorList.class,
|
||||
PyAstSliceExpression.class,
|
||||
PyAstSubscriptionExpression.class,
|
||||
PyAstGeneratorExpression.class,
|
||||
PyAstGroupPattern.class,
|
||||
|
||||
@@ -45,7 +45,6 @@ public class PyBlock implements ASTBlock {
|
||||
PyElementTypes.PARAMETER_LIST,
|
||||
PyElementTypes.TUPLE_EXPRESSION,
|
||||
PyElementTypes.PARENTHESIZED_EXPRESSION,
|
||||
PyElementTypes.SLICE_EXPRESSION,
|
||||
PyElementTypes.SUBSCRIPTION_EXPRESSION,
|
||||
PyElementTypes.GENERATOR_EXPRESSION,
|
||||
PyElementTypes.SEQUENCE_PATTERN,
|
||||
@@ -758,8 +757,9 @@ public class PyBlock implements ASTBlock {
|
||||
}
|
||||
|
||||
private boolean isSliceOperand(@NotNull ASTNode child) {
|
||||
if (myNode.getPsi() instanceof PyAstSliceExpression sliceExpression) {
|
||||
final PyAstExpression operand = sliceExpression.getOperand();
|
||||
if (myNode.getPsi() instanceof PyAstSubscriptionExpression subscription &&
|
||||
subscription.getIndexExpression() instanceof PyAstSliceItem) {
|
||||
final PyAstExpression operand = subscription.getOperand();
|
||||
return operand.getNode() == child;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -247,8 +247,7 @@ private fun getCallInnerReferenceExpression(parameters: CompletionParameters): P
|
||||
}
|
||||
|
||||
private fun getSliceSubscriptionReferenceExpression(parameters: CompletionParameters): PyExpression? {
|
||||
val expression = PsiTreeUtil.getParentOfType(parameters.position, PySubscriptionExpression::class.java) ?: PsiTreeUtil.getParentOfType(
|
||||
parameters.position, PySliceExpression::class.java)
|
||||
val expression = PsiTreeUtil.getParentOfType(parameters.position, PySubscriptionExpression::class.java)
|
||||
val result = PsiTreeUtil.getChildOfType(expression, PyReferenceExpression::class.java)
|
||||
if (result != null) {
|
||||
return PyPsiUtils.getFirstQualifier(result)
|
||||
|
||||
-1
@@ -38,7 +38,6 @@ public class PyMissingBracesFixer extends PyFixer<PyElement> {
|
||||
}
|
||||
}
|
||||
else if (psiElement instanceof PyListLiteralExpression ||
|
||||
psiElement instanceof PySliceExpression ||
|
||||
psiElement instanceof PySubscriptionExpression) {
|
||||
final PsiElement lastChild = PyPsiUtils.getPrevNonCommentSibling(psiElement.getLastChild(), false);
|
||||
if (lastChild != null && !"]".equals(lastChild.getText())) {
|
||||
|
||||
@@ -60,7 +60,6 @@ public final class PyDebugSupportUtils {
|
||||
private static boolean isSimpleEnough(final PsiElement element) {
|
||||
return element instanceof PyLiteralExpression ||
|
||||
element instanceof PyQualifiedExpression ||
|
||||
element instanceof PySliceExpression ||
|
||||
element instanceof PyNamedParameter ||
|
||||
element instanceof PyCallExpression;
|
||||
}
|
||||
|
||||
@@ -5,5 +5,6 @@
|
||||
4(5) element: PySubscriptionExpression
|
||||
5(6) READ ACCESS: foo
|
||||
6(7) element: PyDelStatement
|
||||
7(8) READ ACCESS: foo
|
||||
8() element: null
|
||||
7(8) element: PySubscriptionExpression
|
||||
8(9) READ ACCESS: foo
|
||||
9() element: null
|
||||
@@ -1,4 +1,4 @@
|
||||
def rc(s):
|
||||
return s.translate(
|
||||
'*****************************************************************TVGHEFCDIJMLKNOPQYSAUBWXRZ[\]^_`tvghefcdijmlknopqysaubwxrz*************************************************************************************************************************************')[
|
||||
::-1]
|
||||
::-1]
|
||||
|
||||
@@ -53,7 +53,7 @@ PyFile:AssignmentExpressionsInIndexes.py
|
||||
PsiComment(Py:END_OF_LINE_COMMENT)('# valid')
|
||||
PsiWhiteSpace('\n\n')
|
||||
PyExpressionStatement
|
||||
PySliceExpression
|
||||
PySubscriptionExpression
|
||||
PyReferenceExpression: s
|
||||
PsiElement(Py:IDENTIFIER)('s')
|
||||
PsiElement(Py:LBRACKET)('[')
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
PyFile:ExtendedSlices.py
|
||||
PyExpressionStatement
|
||||
PySliceExpression
|
||||
PySubscriptionExpression
|
||||
PyReferenceExpression: d
|
||||
PsiElement(Py:IDENTIFIER)('d')
|
||||
PsiElement(Py:LBRACKET)('[')
|
||||
@@ -14,7 +14,7 @@ PyFile:ExtendedSlices.py
|
||||
PsiElement(Py:RBRACKET)(']')
|
||||
PsiWhiteSpace('\n')
|
||||
PyExpressionStatement
|
||||
PySliceExpression
|
||||
PySubscriptionExpression
|
||||
PyReferenceExpression: d
|
||||
PsiElement(Py:IDENTIFIER)('d')
|
||||
PsiElement(Py:LBRACKET)('[')
|
||||
@@ -30,7 +30,7 @@ PyFile:ExtendedSlices.py
|
||||
PsiElement(Py:RBRACKET)(']')
|
||||
PsiWhiteSpace('\n')
|
||||
PyExpressionStatement
|
||||
PySliceExpression
|
||||
PySubscriptionExpression
|
||||
PyReferenceExpression: d
|
||||
PsiElement(Py:IDENTIFIER)('d')
|
||||
PsiElement(Py:LBRACKET)('[')
|
||||
@@ -44,7 +44,7 @@ PyFile:ExtendedSlices.py
|
||||
PsiElement(Py:RBRACKET)(']')
|
||||
PsiWhiteSpace('\n')
|
||||
PyExpressionStatement
|
||||
PySliceExpression
|
||||
PySubscriptionExpression
|
||||
PyReferenceExpression: d
|
||||
PsiElement(Py:IDENTIFIER)('d')
|
||||
PsiElement(Py:LBRACKET)('[')
|
||||
@@ -57,7 +57,7 @@ PyFile:ExtendedSlices.py
|
||||
PsiElement(Py:RBRACKET)(']')
|
||||
PsiWhiteSpace('\n')
|
||||
PyAssignmentStatement
|
||||
PySliceExpression
|
||||
PySubscriptionExpression
|
||||
PyReferenceExpression: d
|
||||
PsiElement(Py:IDENTIFIER)('d')
|
||||
PsiElement(Py:LBRACKET)('[')
|
||||
@@ -89,7 +89,7 @@ PyFile:ExtendedSlices.py
|
||||
PsiElement(Py:INTEGER_LITERAL)('1')
|
||||
PsiWhiteSpace('\n')
|
||||
PyExpressionStatement
|
||||
PySliceExpression
|
||||
PySubscriptionExpression
|
||||
PyReferenceExpression: d
|
||||
PsiElement(Py:IDENTIFIER)('d')
|
||||
PsiElement(Py:LBRACKET)('[')
|
||||
|
||||
@@ -10,7 +10,7 @@ PyFile:RangeAsLHS.py
|
||||
PsiElement(Py:RBRACKET)(']')
|
||||
PsiWhiteSpace('\n')
|
||||
PyAssignmentStatement
|
||||
PySliceExpression
|
||||
PySubscriptionExpression
|
||||
PyReferenceExpression: foo
|
||||
PsiElement(Py:IDENTIFIER)('foo')
|
||||
PsiElement(Py:LBRACKET)('[')
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
PyFile:SliceList.py
|
||||
PyExpressionStatement
|
||||
PySliceExpression
|
||||
PySubscriptionExpression
|
||||
PyReferenceExpression: a
|
||||
PsiElement(Py:IDENTIFIER)('a')
|
||||
PsiElement(Py:LBRACKET)('[')
|
||||
|
||||
@@ -50,7 +50,6 @@ namedtuples_define_class.py
|
||||
namedtuples_type_compat.py
|
||||
namedtuples_usage.py
|
||||
narrowing_typeis.py
|
||||
overloads_basic.py
|
||||
overloads_consistency.py
|
||||
overloads_definitions.py
|
||||
overloads_definitions_stub.pyi
|
||||
|
||||
@@ -135,13 +135,13 @@ public class Py3TypeTest extends PyTestCase {
|
||||
// doTest("int | Any",
|
||||
// """
|
||||
// from typing import Any, TypeGuard
|
||||
//
|
||||
//
|
||||
// def is_positive_integer(value: Any) -> TypeGuard[int]:
|
||||
// return isinstance(value, int) and value > 0
|
||||
//
|
||||
// def bar() -> object:
|
||||
// return 321
|
||||
//
|
||||
//
|
||||
// def foo():
|
||||
// for i in range(1, 100):
|
||||
// if i > 1:
|
||||
@@ -168,12 +168,12 @@ public class Py3TypeTest extends PyTestCase {
|
||||
// class D:
|
||||
// def bar() -> A:
|
||||
// return A()
|
||||
//
|
||||
//
|
||||
// def foo(b):
|
||||
// x = A()
|
||||
// while b:
|
||||
// x = x.bar()
|
||||
//
|
||||
//
|
||||
// expr = x""");
|
||||
//}
|
||||
|
||||
@@ -3696,6 +3696,23 @@ public class Py3TypeTest extends PyTestCase {
|
||||
});
|
||||
}
|
||||
|
||||
public void testSliceExpression() {
|
||||
doTest("int", """
|
||||
from typing import overload
|
||||
|
||||
class A[T]:
|
||||
@overload
|
||||
def __getitem__(self, s: str) -> str: ...
|
||||
|
||||
@overload
|
||||
def __getitem__(self, s: slice) -> T: ...
|
||||
|
||||
def __getitem__(self, s: str | slice) -> str | T: ...
|
||||
|
||||
expr = A[int]()[0:2]
|
||||
""");
|
||||
}
|
||||
|
||||
private void doTest(final String expectedType, final String text) {
|
||||
myFixture.configureByText(PythonFileType.INSTANCE, text);
|
||||
final PyExpression expr = myFixture.findElementByText("expr", PyExpression.class);
|
||||
|
||||
@@ -3122,7 +3122,7 @@ public class PyTypeTest extends PyTestCase {
|
||||
public void testSliceOnUnion() {
|
||||
runWithLanguageLevel(
|
||||
LanguageLevel.PYTHON36,
|
||||
() -> doTest("Union[str, Any]",
|
||||
() -> doTest("str",
|
||||
"""
|
||||
from typing import Union
|
||||
myvar: Union[str, int]
|
||||
|
||||
Reference in New Issue
Block a user