12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879 |
- # -*- coding: utf-8 -*-
- import sys
- from uuid import uuid4
- import pytest
- from pandas.compat import PY3, intern
- from pandas.util._move import BadMove, move_into_mutable_buffer, stolenbuf
- def test_cannot_create_instance_of_stolen_buffer():
- # Stolen buffers need to be created through the smart constructor
- # "move_into_mutable_buffer," which has a bunch of checks in it.
- msg = "cannot create 'pandas.util._move.stolenbuf' instances"
- with pytest.raises(TypeError, match=msg):
- stolenbuf()
- def test_more_than_one_ref():
- # Test case for when we try to use "move_into_mutable_buffer"
- # when the object being moved has other references.
- b = b"testing"
- with pytest.raises(BadMove, match="testing") as e:
- def handle_success(type_, value, tb):
- assert value.args[0] is b
- return type(e).handle_success(e, type_, value, tb) # super
- e.handle_success = handle_success
- move_into_mutable_buffer(b)
- def test_exactly_one_ref():
- # Test case for when the object being moved has exactly one reference.
- b = b"testing"
- # We need to pass an expression on the stack to ensure that there are
- # not extra references hanging around. We cannot rewrite this test as
- # buf = b[:-3]
- # as_stolen_buf = move_into_mutable_buffer(buf)
- # because then we would have more than one reference to buf.
- as_stolen_buf = move_into_mutable_buffer(b[:-3])
- # Materialize as byte-array to show that it is mutable.
- assert bytearray(as_stolen_buf) == b"test"
- @pytest.mark.skipif(PY3, reason="bytes objects cannot be interned in PY3")
- def test_interned():
- salt = uuid4().hex
- def make_string():
- # We need to actually create a new string so that it has refcount
- # one. We use a uuid so that we know the string could not already
- # be in the intern table.
- return "".join(("testing: ", salt))
- # This should work, the string has one reference on the stack.
- move_into_mutable_buffer(make_string())
- refcount = [None] # nonlocal
- def ref_capture(ob):
- # Subtract two because those are the references owned by this frame:
- # 1. The local variables of this stack frame.
- # 2. The python data stack of this stack frame.
- refcount[0] = sys.getrefcount(ob) - 2
- return ob
- with pytest.raises(BadMove, match="testing"):
- # If we intern the string, it will still have one reference. Now,
- # it is in the intern table, so if other people intern the same
- # string while the mutable buffer holds the first string they will
- # be the same instance.
- move_into_mutable_buffer(ref_capture(intern(make_string()))) # noqa
- assert refcount[0] == 1
|