diff --git a/python/src/com/jetbrains/numpy/codeInsight/NumpyDocStringTypeProvider.java b/python/src/com/jetbrains/numpy/codeInsight/NumpyDocStringTypeProvider.java
index 18786ed32ee5..1abd08650ad0 100644
--- a/python/src/com/jetbrains/numpy/codeInsight/NumpyDocStringTypeProvider.java
+++ b/python/src/com/jetbrains/numpy/codeInsight/NumpyDocStringTypeProvider.java
@@ -168,4 +168,13 @@ public class NumpyDocStringTypeProvider extends PyTypeProviderBase {
}
return null;
}
+
+ @Nullable
+ @Override
+ public PyType getReturnType(@NotNull Callable callable, @NotNull TypeEvalContext context) {
+ if (callable instanceof PyFunction) {
+ return getCallType((PyFunction)callable, null, context);
+ }
+ return null;
+ }
}
diff --git a/python/testData/quickdoc/NumPyOnesDoc.html b/python/testData/quickdoc/NumPyOnesDoc.html
new file mode 100644
index 000000000000..22c482b10807
--- /dev/null
+++ b/python/testData/quickdoc/NumPyOnesDoc.html
@@ -0,0 +1,2 @@
+def ones(shape, dtype=None, order='C')
+Inferred type: (shape: int, dtype: object, order: str) -> ndarray
diff --git a/python/testData/quickdoc/NumPyOnesDoc.py b/python/testData/quickdoc/NumPyOnesDoc.py
new file mode 100644
index 000000000000..8d2130158c9e
--- /dev/null
+++ b/python/testData/quickdoc/NumPyOnesDoc.py
@@ -0,0 +1,4 @@
+import numpy as np
+
+x = np.ones(10)
+
diff --git a/python/testData/quickdoc/NumPyOnesDoc/numpy/__init__.py b/python/testData/quickdoc/NumPyOnesDoc/numpy/__init__.py
new file mode 100644
index 000000000000..d58ac8cf7af0
--- /dev/null
+++ b/python/testData/quickdoc/NumPyOnesDoc/numpy/__init__.py
@@ -0,0 +1,5 @@
+from . import core
+from .core import *
+
+__all__ = []
+__all__.extend(core.__all__)
diff --git a/python/testData/quickdoc/NumPyOnesDoc/numpy/core/__init__.py b/python/testData/quickdoc/NumPyOnesDoc/numpy/core/__init__.py
new file mode 100644
index 000000000000..51afb32bcebe
--- /dev/null
+++ b/python/testData/quickdoc/NumPyOnesDoc/numpy/core/__init__.py
@@ -0,0 +1,6 @@
+from . import multiarray
+from . import numeric
+from .numeric import *
+
+__all__ = []
+__all__ += numeric.__all__
diff --git a/python/testData/quickdoc/NumPyOnesDoc/numpy/core/multiarray.py b/python/testData/quickdoc/NumPyOnesDoc/numpy/core/multiarray.py
new file mode 100644
index 000000000000..6eae8aed6e5d
--- /dev/null
+++ b/python/testData/quickdoc/NumPyOnesDoc/numpy/core/multiarray.py
@@ -0,0 +1,120 @@
+class ndarray(object):
+ """
+ ndarray(shape, dtype=float, buffer=None, offset=0,
+ strides=None, order=None)
+
+ An array object represents a multidimensional, homogeneous array
+ of fixed-size items. An associated data-type object describes the
+ format of each element in the array (its byte-order, how many bytes it
+ occupies in memory, whether it is an integer, a floating point number,
+ or something else, etc.)
+
+ Arrays should be constructed using `array`, `zeros` or `empty` (refer
+ to the See Also section below). The parameters given here refer to
+ a low-level method (`ndarray(...)`) for instantiating an array.
+
+ For more information, refer to the `numpy` module and examine the
+ the methods and attributes of an array.
+
+ Parameters
+ ----------
+ (for the __new__ method; see Notes below)
+
+ shape : tuple of ints
+ Shape of created array.
+ dtype : data-type, optional
+ Any object that can be interpreted as a numpy data type.
+ buffer : object exposing buffer interface, optional
+ Used to fill the array with data.
+ offset : int, optional
+ Offset of array data in buffer.
+ strides : tuple of ints, optional
+ Strides of data in memory.
+ order : {'C', 'F'}, optional
+ Row-major or column-major order.
+
+ Attributes
+ ----------
+ T : ndarray
+ Transpose of the array.
+ data : buffer
+ The array's elements, in memory.
+ dtype : dtype object
+ Describes the format of the elements in the array.
+ flags : dict
+ Dictionary containing information related to memory use, e.g.,
+ 'C_CONTIGUOUS', 'OWNDATA', 'WRITEABLE', etc.
+ flat : numpy.flatiter object
+ Flattened version of the array as an iterator. The iterator
+ allows assignments, e.g., ``x.flat = 3`` (See `ndarray.flat` for
+ assignment examples; TODO).
+ imag : ndarray
+ Imaginary part of the array.
+ real : ndarray
+ Real part of the array.
+ size : int
+ Number of elements in the array.
+ itemsize : int
+ The memory use of each array element in bytes.
+ nbytes : int
+ The total number of bytes required to store the array data,
+ i.e., ``itemsize * size``.
+ ndim : int
+ The array's number of dimensions.
+ shape : tuple of ints
+ Shape of the array.
+ strides : tuple of ints
+ The step-size required to move from one element to the next in
+ memory. For example, a contiguous ``(3, 4)`` array of type
+ ``int16`` in C-order has strides ``(8, 2)``. This implies that
+ to move from element to element in memory requires jumps of 2 bytes.
+ To move from row-to-row, one needs to jump 8 bytes at a time
+ (``2 * 4``).
+ ctypes : ctypes object
+ Class containing properties of the array needed for interaction
+ with ctypes.
+ base : ndarray
+ If the array is a view into another array, that array is its `base`
+ (unless that array is also a view). The `base` array is where the
+ array data is actually stored.
+
+ See Also
+ --------
+ array : Construct an array.
+ zeros : Create an array, each element of which is zero.
+ empty : Create an array, but leave its allocated memory unchanged (i.e.,
+ it contains "garbage").
+ dtype : Create a data-type.
+
+ Notes
+ -----
+ There are two modes of creating an array using ``__new__``:
+
+ 1. If `buffer` is None, then only `shape`, `dtype`, and `order`
+ are used.
+ 2. If `buffer` is an object exposing the buffer interface, then
+ all keywords are interpreted.
+
+ No ``__init__`` method is needed because the array is fully initialized
+ after the ``__new__`` method.
+
+ Examples
+ --------
+ These examples illustrate the low-level `ndarray` constructor. Refer
+ to the `See Also` section above for easier ways of constructing an
+ ndarray.
+
+ First mode, `buffer` is None:
+
+ >>> np.ndarray(shape=(2,2), dtype=float, order='F')
+ array([[ -1.13698227e+002, 4.25087011e-303],
+ [ 2.88528414e-306, 3.27025015e-309]]) #random
+
+ Second mode:
+
+ >>> np.ndarray((2,), buffer=np.array([1,2,3]),
+ ... offset=np.int_().itemsize,
+ ... dtype=int) # offset = 1*itemsize, i.e. skip first element
+ array([2, 3])
+ """
+ pass
diff --git a/python/testData/quickdoc/NumPyOnesDoc/numpy/core/numeric.py b/python/testData/quickdoc/NumPyOnesDoc/numpy/core/numeric.py
new file mode 100644
index 000000000000..19e7b0f6aeb2
--- /dev/null
+++ b/python/testData/quickdoc/NumPyOnesDoc/numpy/core/numeric.py
@@ -0,0 +1,51 @@
+from . import multiarray
+
+__all__ = ['ndarray', 'ones']
+
+
+ndarray = multiarray.ndarray
+
+def ones(shape, dtype=None, order='C'):
+ """
+ **Test docstring**
+ Return a new array of given shape and type, filled with ones.
+
+ Parameters
+ ----------
+ shape : int or sequence of ints
+ Shape of the new array, e.g., ``(2, 3)`` or ``2``.
+ dtype : data-type, optional
+ The desired data-type for the array, e.g., `numpy.int8`. Default is
+ `numpy.float64`.
+ order : {'C', 'F'}, optional
+ Whether to store multidimensional data in C- or Fortran-contiguous
+ (row- or column-wise) order in memory.
+
+ Returns
+ -------
+ out : ndarray
+ Array of ones with the given shape, dtype, and order.
+
+ See Also
+ --------
+ zeros, ones_like
+
+ Examples
+ --------
+ >>> np.ones(5)
+ array([ 1., 1., 1., 1., 1.])
+
+ >>> np.ones((5,), dtype=np.int)
+ array([1, 1, 1, 1, 1])
+
+ >>> np.ones((2, 1))
+ array([[ 1.],
+ [ 1.]])
+
+ >>> s = (2,2)
+ >>> np.ones(s)
+ array([[ 1., 1.],
+ [ 1., 1.]])
+
+ """
+ pass
diff --git a/python/testData/types/NumpyArrayIntMultiplicationType/numpy/__init__.py b/python/testData/types/NumpyArrayIntMultiplicationType/numpy/__init__.py
new file mode 100644
index 000000000000..d58ac8cf7af0
--- /dev/null
+++ b/python/testData/types/NumpyArrayIntMultiplicationType/numpy/__init__.py
@@ -0,0 +1,5 @@
+from . import core
+from .core import *
+
+__all__ = []
+__all__.extend(core.__all__)
diff --git a/python/testData/types/NumpyArrayIntMultiplicationType/numpy/core/__init__.py b/python/testData/types/NumpyArrayIntMultiplicationType/numpy/core/__init__.py
new file mode 100644
index 000000000000..51afb32bcebe
--- /dev/null
+++ b/python/testData/types/NumpyArrayIntMultiplicationType/numpy/core/__init__.py
@@ -0,0 +1,6 @@
+from . import multiarray
+from . import numeric
+from .numeric import *
+
+__all__ = []
+__all__ += numeric.__all__
diff --git a/python/testData/types/NumpyArrayIntMultiplicationType/numpy/core/multiarray.py b/python/testData/types/NumpyArrayIntMultiplicationType/numpy/core/multiarray.py
new file mode 100644
index 000000000000..ceb35f28b175
--- /dev/null
+++ b/python/testData/types/NumpyArrayIntMultiplicationType/numpy/core/multiarray.py
@@ -0,0 +1,129 @@
+class ndarray(object):
+ """
+ ndarray(shape, dtype=float, buffer=None, offset=0,
+ strides=None, order=None)
+
+ An array object represents a multidimensional, homogeneous array
+ of fixed-size items. An associated data-type object describes the
+ format of each element in the array (its byte-order, how many bytes it
+ occupies in memory, whether it is an integer, a floating point number,
+ or something else, etc.)
+
+ Arrays should be constructed using `array`, `zeros` or `empty` (refer
+ to the See Also section below). The parameters given here refer to
+ a low-level method (`ndarray(...)`) for instantiating an array.
+
+ For more information, refer to the `numpy` module and examine the
+ the methods and attributes of an array.
+
+ Parameters
+ ----------
+ (for the __new__ method; see Notes below)
+
+ shape : tuple of ints
+ Shape of created array.
+ dtype : data-type, optional
+ Any object that can be interpreted as a numpy data type.
+ buffer : object exposing buffer interface, optional
+ Used to fill the array with data.
+ offset : int, optional
+ Offset of array data in buffer.
+ strides : tuple of ints, optional
+ Strides of data in memory.
+ order : {'C', 'F'}, optional
+ Row-major or column-major order.
+
+ Attributes
+ ----------
+ T : ndarray
+ Transpose of the array.
+ data : buffer
+ The array's elements, in memory.
+ dtype : dtype object
+ Describes the format of the elements in the array.
+ flags : dict
+ Dictionary containing information related to memory use, e.g.,
+ 'C_CONTIGUOUS', 'OWNDATA', 'WRITEABLE', etc.
+ flat : numpy.flatiter object
+ Flattened version of the array as an iterator. The iterator
+ allows assignments, e.g., ``x.flat = 3`` (See `ndarray.flat` for
+ assignment examples; TODO).
+ imag : ndarray
+ Imaginary part of the array.
+ real : ndarray
+ Real part of the array.
+ size : int
+ Number of elements in the array.
+ itemsize : int
+ The memory use of each array element in bytes.
+ nbytes : int
+ The total number of bytes required to store the array data,
+ i.e., ``itemsize * size``.
+ ndim : int
+ The array's number of dimensions.
+ shape : tuple of ints
+ Shape of the array.
+ strides : tuple of ints
+ The step-size required to move from one element to the next in
+ memory. For example, a contiguous ``(3, 4)`` array of type
+ ``int16`` in C-order has strides ``(8, 2)``. This implies that
+ to move from element to element in memory requires jumps of 2 bytes.
+ To move from row-to-row, one needs to jump 8 bytes at a time
+ (``2 * 4``).
+ ctypes : ctypes object
+ Class containing properties of the array needed for interaction
+ with ctypes.
+ base : ndarray
+ If the array is a view into another array, that array is its `base`
+ (unless that array is also a view). The `base` array is where the
+ array data is actually stored.
+
+ See Also
+ --------
+ array : Construct an array.
+ zeros : Create an array, each element of which is zero.
+ empty : Create an array, but leave its allocated memory unchanged (i.e.,
+ it contains "garbage").
+ dtype : Create a data-type.
+
+ Notes
+ -----
+ There are two modes of creating an array using ``__new__``:
+
+ 1. If `buffer` is None, then only `shape`, `dtype`, and `order`
+ are used.
+ 2. If `buffer` is an object exposing the buffer interface, then
+ all keywords are interpreted.
+
+ No ``__init__`` method is needed because the array is fully initialized
+ after the ``__new__`` method.
+
+ Examples
+ --------
+ These examples illustrate the low-level `ndarray` constructor. Refer
+ to the `See Also` section above for easier ways of constructing an
+ ndarray.
+
+ First mode, `buffer` is None:
+
+ >>> np.ndarray(shape=(2,2), dtype=float, order='F')
+ array([[ -1.13698227e+002, 4.25087011e-303],
+ [ 2.88528414e-306, 3.27025015e-309]]) #random
+
+ Second mode:
+
+ >>> np.ndarray((2,), buffer=np.array([1,2,3]),
+ ... offset=np.int_().itemsize,
+ ... dtype=int) # offset = 1*itemsize, i.e. skip first element
+ array([2, 3])
+ """
+ pass
+
+
+ def __mul__(self, y):
+ """ x.__mul__(y) <==> x*y """
+ pass
+
+ def __rmul__(self, y):
+ """ x.__rmul__(y) <==> x*y """
+ pass
diff --git a/python/testData/types/NumpyArrayIntMultiplicationType/numpy/core/numeric.py b/python/testData/types/NumpyArrayIntMultiplicationType/numpy/core/numeric.py
new file mode 100644
index 000000000000..19e7b0f6aeb2
--- /dev/null
+++ b/python/testData/types/NumpyArrayIntMultiplicationType/numpy/core/numeric.py
@@ -0,0 +1,51 @@
+from . import multiarray
+
+__all__ = ['ndarray', 'ones']
+
+
+ndarray = multiarray.ndarray
+
+def ones(shape, dtype=None, order='C'):
+ """
+ **Test docstring**
+ Return a new array of given shape and type, filled with ones.
+
+ Parameters
+ ----------
+ shape : int or sequence of ints
+ Shape of the new array, e.g., ``(2, 3)`` or ``2``.
+ dtype : data-type, optional
+ The desired data-type for the array, e.g., `numpy.int8`. Default is
+ `numpy.float64`.
+ order : {'C', 'F'}, optional
+ Whether to store multidimensional data in C- or Fortran-contiguous
+ (row- or column-wise) order in memory.
+
+ Returns
+ -------
+ out : ndarray
+ Array of ones with the given shape, dtype, and order.
+
+ See Also
+ --------
+ zeros, ones_like
+
+ Examples
+ --------
+ >>> np.ones(5)
+ array([ 1., 1., 1., 1., 1.])
+
+ >>> np.ones((5,), dtype=np.int)
+ array([1, 1, 1, 1, 1])
+
+ >>> np.ones((2, 1))
+ array([[ 1.],
+ [ 1.]])
+
+ >>> s = (2,2)
+ >>> np.ones(s)
+ array([[ 1., 1.],
+ [ 1., 1.]])
+
+ """
+ pass
diff --git a/python/testSrc/com/jetbrains/python/PyQuickDocTest.java b/python/testSrc/com/jetbrains/python/PyQuickDocTest.java
index ec7e7eddd84a..56e023e789e1 100644
--- a/python/testSrc/com/jetbrains/python/PyQuickDocTest.java
+++ b/python/testSrc/com/jetbrains/python/PyQuickDocTest.java
@@ -27,6 +27,8 @@ import com.jetbrains.python.fixtures.LightMarkedTestCase;
import com.jetbrains.python.fixtures.PyTestCase;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.impl.PythonLanguageLevelPusher;
+import com.jetbrains.python.psi.types.PyType;
+import com.jetbrains.python.psi.types.TypeEvalContext;
import junit.framework.Assert;
import java.io.IOException;
@@ -240,7 +242,7 @@ public class PyQuickDocTest extends LightMarkedTestCase {
public void testHoverOverMethod() {
checkHover();
}
-
+
public void testHoverOverParameter() {
checkHover();
}
@@ -248,4 +250,10 @@ public class PyQuickDocTest extends LightMarkedTestCase {
public void testHoverOverControlFlowUnion() {
checkHover();
}
+
+ // PY-13422
+ public void testNumPyOnesDoc() {
+ myFixture.copyDirectoryToProject("/quickdoc/" + getTestName(false), "");
+ checkHover();
+ }
}
diff --git a/python/testSrc/com/jetbrains/python/PyTypeTest.java b/python/testSrc/com/jetbrains/python/PyTypeTest.java
index b6ed1090edad..548fe14a4458 100644
--- a/python/testSrc/com/jetbrains/python/PyTypeTest.java
+++ b/python/testSrc/com/jetbrains/python/PyTypeTest.java
@@ -194,14 +194,16 @@ public class PyTypeTest extends PyTestCase {
"def foo(*args):\n" +
" '''@rtype: C{str}'''\n" +
" return args[0]" +
- "expr = foo('')");
+ "expr = foo('')"
+ );
}
public void testEpydocParamType() {
doTest("str",
"def foo(s):\n" +
" '''@type s: C{str}'''\n" +
- " expr = s");
+ " expr = s"
+ );
}
public void testEpydocIvarType() {
@@ -385,7 +387,8 @@ public class PyTypeTest extends PyTestCase {
" return 1\n" +
"g = f\n" +
"h = g\n" +
- "expr = h()\n");
+ "expr = h()\n"
+ );
}
public void testPropertyOfUnionType() {
@@ -454,7 +457,8 @@ public class PyTypeTest extends PyTestCase {
"\n" +
" def __init__(self):\n" +
" self.foo = 3\n" +
- " expr = self.foo\n");
+ " expr = self.foo\n"
+ );
}
// PY-7215
@@ -465,7 +469,8 @@ public class PyTypeTest extends PyTestCase {
" yield 10\n" +
" return list(g())\n" +
"\n" +
- "expr = f()\n");
+ "expr = f()\n"
+ );
}
public void testGeneratorNextType() {
@@ -508,7 +513,8 @@ public class PyTypeTest extends PyTestCase {
doTest("list[list]",
"def f():\n" +
" return [f()]\n" +
- "expr = f()\n");
+ "expr = f()\n"
+ );
}
// PY-5084
@@ -519,7 +525,8 @@ public class PyTypeTest extends PyTestCase {
" if isinstance(x, int):\n" +
" print(x)\n" +
" else:\n" +
- " expr = x\n");
+ " expr = x\n"
+ );
}
// PY-5614
@@ -606,7 +613,8 @@ public class PyTypeTest extends PyTestCase {
" :rtype: T\n" +
" '''\n" +
"def bar(x):\n" +
- " expr = foo(x)\n");
+ " expr = foo(x)\n"
+ );
}
public void testIterationTypeFromGetItem() {
@@ -866,6 +874,13 @@ public class PyTypeTest extends PyTestCase {
"expr = C(10).foo()\n");
}
+ // PY-8836
+ public void testNumpyArrayIntMultiplicationType() {
+ doMultiFileTest("ndarray",
+ "import numpy as np\n" +
+ "expr = np.ones(10) * 2\n");
+ }
+
private static TypeEvalContext getTypeEvalContext(@NotNull PyExpression element) {
return TypeEvalContext.userInitiated(element.getContainingFile()).withTracing();
}
@@ -882,4 +897,16 @@ public class PyTypeTest extends PyTestCase {
final String actualType = PythonDocumentationProvider.getTypeName(actual, context);
assertEquals(expectedType, actualType);
}
+
+ public static final String TEST_DIRECTORY = "/types/";
+
+ private void doMultiFileTest(final String expectedType, final String text) {
+ final String testName = getTestName(false);
+ myFixture.copyDirectoryToProject(TEST_DIRECTORY + testName, "");
+ PyExpression expr = parseExpr(text);
+ TypeEvalContext context = getTypeEvalContext(expr);
+ PyType actual = context.getType(expr);
+ final String actualType = PythonDocumentationProvider.getTypeName(actual, context);
+ assertEquals(expectedType, actualType);
+ }
}