fix and tests for PY-8836 (false positive after ndarray and int multiplication) and PY-13422 (wrong return type in numpy.ones quickdoc)

Conflicts:
	python/testSrc/com/jetbrains/python/PyTypeTest.java
This commit is contained in:
Alexander Marchuk
2014-10-01 18:52:18 +04:00
committed by Andrey Vlasovskikh
parent ea0d540fff
commit 3be9fb4c44
13 changed files with 432 additions and 9 deletions
@@ -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;
}
}
@@ -0,0 +1,2 @@
def ones(shape, dtype=None, order='C')
Inferred type: (shape:&nbsp;<a href="psi_element://#typename#int">int</a>,&nbsp;dtype:&nbsp;<a href="psi_element://#typename#object">object</a>,&nbsp;order:&nbsp;<a href="psi_element://#typename#str">str</a>)&nbsp;-&gt;&nbsp;<a href="psi_element://#typename#ndarray">ndarray</a><br>
+4
View File
@@ -0,0 +1,4 @@
import numpy as np
x = np.<the_ref>ones(10)
@@ -0,0 +1,5 @@
from . import core
from .core import *
__all__ = []
__all__.extend(core.__all__)
@@ -0,0 +1,6 @@
from . import multiarray
from . import numeric
from .numeric import *
__all__ = []
__all__ += numeric.__all__
@@ -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
@@ -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
@@ -0,0 +1,5 @@
from . import core
from .core import *
__all__ = []
__all__.extend(core.__all__)
@@ -0,0 +1,6 @@
from . import multiarray
from . import numeric
from .numeric import *
__all__ = []
__all__ += numeric.__all__
@@ -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
@@ -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
@@ -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();
}
}
@@ -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);
}
}