Repository: numpy/numpy
File: numpy/_core/tests/test_arrayprint.py (Python)

Code before:
            repr(a),
            'array([[array([[1., 0.],\n'
            '               [0., 1.]]), array([[1., 0., 0.],\n'
            '                                  [0., 1., 0.],\n'
            '                                  [0., 0., 1.]])],\n'
            '       [None, array([[1.],\n'
            '                     [1.],\n'
            '                     [1.]])]], dtype=object)'
        )

    @given(hynp.from_dtype(np.dtype("U")))
    @pytest.mark.thread_unsafe(reason="gives unreliable results w/ hypothesis")
    def test_any_text(self, text):
        # This test checks that, given any value that can be represented in an
        # array of dtype("U") (i.e. unicode string), ...
        a = np.array([text, text, text])
        # casting a list of them to an array does not e.g. truncate the value
        assert_equal(a[0], text)
        text = text.item()  # use raw python strings for repr below
        # and that np.array2string puts a newline in the expected location
        expected_repr = f"[{text!r} {text!r}\n {text!r}]"
        result = np.array2string(a, max_line_width=len(repr(text)) * 2 + 3)
        assert_equal(result, expected_repr)

    @pytest.mark.skipif(not HAS_REFCOUNT, reason="Python lacks refcounts")
    @pytest.mark.thread_unsafe(reason="sys.getrefcounts is thread-unsafe")
    def test_refcount(self):
        # make sure we do not hold references to the array due to a recursive
        # closure (gh-10620)
        gc.disable()
        a = np.arange(2)
        r1 = sys.getrefcount(a)
        np.array2string(a)
        np.array2string(a)
        r2 = sys.getrefcount(a)
        gc.collect()
        gc.enable()
        assert_(r1 == r2)

    def test_with_sign(self):
        # mixed negative and positive value array
        a = np.array([-2, 0, 3])
        assert_equal(
            np.array2string(a, sign='+'),
            '[-2 +0 +3]'
        )
        assert_equal(
            np.array2string(a, sign='-'),
            '[-2  0  3]'
        )
        assert_equal(

Review comment (suggestion):
It's not so much that `getrefcounts` is thread-unsafe, it's that the test depends on global state. In this case in the garbage collector, because it temporarily disables the gc for the whole process, including other threads running this test.

Code after:
            repr(a),
            'array([[array([[1., 0.],\n'
            '               [0., 1.]]), array([[1., 0., 0.],\n'
            '                                  [0., 1., 0.],\n'
            '                                  [0., 0., 1.]])],\n'
            '       [None, array([[1.],\n'
            '                     [1.],\n'
            '                     [1.]])]], dtype=object)'
        )

    @given(hynp.from_dtype(np.dtype("U")))
    @pytest.mark.thread_unsafe(
        reason="gives unreliable results w/ hypothesis (HypothesisWorks/hypothesis#4562)"
    )
    def test_any_text(self, text):
        # This test checks that, given any value that can be represented in an
        # array of dtype("U") (i.e. unicode string), ...
        a = np.array([text, text, text])
        # casting a list of them to an array does not e.g. truncate the value
        assert_equal(a[0], text)
        text = text.item()  # use raw python strings for repr below
        # and that np.array2string puts a newline in the expected location
        expected_repr = f"[{text!r} {text!r}\n {text!r}]"
        result = np.array2string(a, max_line_width=len(repr(text)) * 2 + 3)
        assert_equal(result, expected_repr)

    @pytest.mark.skipif(not HAS_REFCOUNT, reason="Python lacks refcounts")
    @pytest.mark.thread_unsafe(reason="garbage collector is global state")
    def test_refcount(self):
        # make sure we do not hold references to the array due to a recursive
        # closure (gh-10620)
        gc.disable()
        a = np.arange(2)
        r1 = sys.getrefcount(a)
        np.array2string(a)
        np.array2string(a)
        r2 = sys.getrefcount(a)
        gc.collect()
        gc.enable()
        assert_(r1 == r2)

    def test_with_sign(self):
        # mixed negative and positive value array
        a = np.array([-2, 0, 3])
        assert_equal(
            np.array2string(a, sign='+'),
            '[-2 +0 +3]'
        )
        assert_equal(
            np.array2string(a, sign='-'),
            '[-2  0  3]'