class_docstr: Test that the 'hasparent' flag gets flipped to False
  only if we're sure this object is the real parent.
  
  In ambiguous cases a stale data exception is
  raised.
class_docstr_tok: ["Test","that","the","'hasparent","'","flag","gets","flipped","to","False","only","if","we","'re","sure","this","object","is","the","real","parent",".","In","ambiguous","cases","a","stale","data","exception","is","raised","."]
docstr: Illustrate that we can't easily link a
  stale state to a fresh one if the fresh one has
  a PK change  (unless we a. tracked all the previous PKs,
  wasteful, or b. recycled states - time consuming,
  breaks lots of edge cases, destabilizes the code)
docstr_tok: ["Illustrate","that","we","ca","n't","easily","link","a","stale","state","to","a","fresh","one","if","the","fresh","one","has","a","PK","change","(","unless","we","a.","tracked","all","the","previous","PKs",",","wasteful",",","or","b.","recycled","states","-","time","consuming",",","breaks","lots","of","edge","cases",",","destabilizes","the","code",")"]
code: def test_stale_state_positive_pk_change(self):
      """Illustrate that we can't easily link a
      stale state to a fresh one if the fresh one has
      a PK change  (unless we a. tracked all the previous PKs,
      wasteful, or b. recycled states - time consuming,
      breaks lots of edge cases, destabilizes the code)
  
      """
  
      User = self.classes.User
      s, u1, a1 = self._fixture()
  
      s._expunge_states([attributes.instance_state(u1)])
  
      del u1
      gc_collect()
  
      u1 = s.query(User).first()
  
      # primary key change.  now we
      # can't rely on state.key as the
      # identifier.
      new_id = u1.id + 10
      u1.id = new_id
      a1.user_id = new_id
      s.flush()
  
      assert_raises_message(
          orm_exc.StaleDataError,
          "can't be sure this is the most recent parent.",
          u1.addresses.remove,
          a1,
      )
  
      # u1.addresses wasn't actually impacted, because the event was
      # caught before collection mutation
      eq_(u1.addresses, [a1])
  
      # expire all and we can continue
      s.expire_all()
      u1.addresses.remove(a1)
  
      self._assert_not_hasparent(a1)
  
imports: from sqlalchemy import ForeignKey
  from sqlalchemy import Integer
  from sqlalchemy import testing
  from sqlalchemy.orm import attributes
  from sqlalchemy.orm import exc
  from sqlalchemy.orm import relationship
  from sqlalchemy.testing import assert_raises_message
  from sqlalchemy.testing import eq_
  from sqlalchemy.testing import fixtures
  from sqlalchemy.testing.fixtures import fixture_session
  from sqlalchemy.testing.schema import Column
  from sqlalchemy.testing.schema import Table
  from sqlalchemy.testing.util import gc_collect
label_desc: Use image node_id 9 for calling the ParentRemovalTest obj's underlying member method code with example usage: obj.test_stale_state_positive_pk_change() without return types