prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Changing source (with xliff) can create submissions with no submitter
  # Steps to reproduce:
  
  - change source in file of existing unit
  - run update_stores
  
  # Results
  
  - submissions have no submitter
  - stuff breaks
  
  ## Expected result:
  
  - nothing breaks
  
  
  this only happens in xliff afaict - as i dont think its possible to change source of units in this way with po
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `pootle/apps/pootle_store/receivers.py`
  Content:
  ```
  1 # -*- coding: utf-8 -*-
  2 #
  3 # Copyright (C) Pootle contributors.
  4 #
  5 # This file is a part of the Pootle project. It is distributed under the GPL3
  6 # or later license. See the LICENSE file for a copy of the license and the
  7 # AUTHORS file for copyright and authorship information.
  8 
  9 from hashlib import md5
  10 
  11 from django.db.models.signals import post_save, pre_save
  12 from django.dispatch import receiver
  13 from django.utils.encoding import force_bytes
  14 
  15 from pootle.core.delegate import lifecycle, uniqueid
  16 from pootle.core.models import Revision
  17 from pootle.core.signals import update_checks, update_data
  18 
  19 from .constants import FUZZY, TRANSLATED, UNTRANSLATED
  20 from .models import Suggestion, Unit, UnitChange, UnitSource
  21 
  22 
  23 @receiver(post_save, sender=Suggestion)
  24 def handle_suggestion_added(**kwargs):
  25     created = kwargs.get("created")
  26     if not created:
  27         return
  28     store = kwargs["instance"].unit.store
  29     update_data.send(store.__class__, instance=store)
  30 
  31 
  32 @receiver(post_save, sender=Suggestion)
  33 def handle_suggestion_accepted(**kwargs):
  34     created = kwargs.get("created")
  35     suggestion = kwargs["instance"]
  36     if created or not suggestion.is_accepted:
  37         return
  38     update_data.send(
  39         suggestion.unit.store.__class__,
  40         instance=suggestion.unit.store)
  41 
  42 
  43 @receiver(pre_save, sender=UnitSource)
  44 def handle_unit_source_pre_save(**kwargs):
  45     unit_source = kwargs["instance"]
  46     created = not unit_source.pk
  47     unit = unit_source.unit
  48     if created:
  49         unit_source.creation_revision = unit.revision
  50     if created or unit.source_updated:
  51         unit_source.source_hash = md5(force_bytes(unit.source_f)).hexdigest()
  52         unit_source.source_length = len(unit.source_f)
  53         unit_source.source_wordcount = max(
  54             1, (unit.counter.count_words(unit.source_f.strings) or 0))
  55 
  56 
  57 @receiver(pre_save, sender=Unit)
  58 def handle_unit_pre_save(**kwargs):
  59     unit = kwargs["instance"]
  60     auto_translated = False
  61 
  62     if unit.source_updated:
  63         # update source related fields
  64         wc = unit.counter.count_words(unit.source_f.strings)
  65         if not wc and not bool(filter(None, unit.target_f.strings)):
  66             # auto-translate untranslated strings
  67             unit.target = unit.source
  68             unit.state = FUZZY
  69             auto_translated = True
  70     if unit.target_updated:
  71         # update target related fields
  72         unit.target_wordcount = unit.counter.count_words(
  73             unit.target_f.strings)
  74         unit.target_length = len(unit.target_f)
  75         if filter(None, unit.target_f.strings):
  76             if unit.state == UNTRANSLATED:
  77                 unit.state = TRANSLATED
  78         else:
  79             # if it was TRANSLATED then set to UNTRANSLATED
  80             if unit.state > FUZZY:
  81                 unit.state = UNTRANSLATED
  82 
  83     # Updating unit from the .po file set its revision property to
  84     # a new value (the same for all units during its store updated)
  85     # since that change doesn't require further sync but note that
  86     # auto_translated units require further sync
  87     update_revision = (
  88         unit.revision is None
  89         or (not unit.revision_updated
  90             and (unit.updated and not auto_translated)))
  91     if update_revision:
  92         unit.revision = Revision.incr()
  93 
  94     if unit.index is None:
  95         unit.index = unit.store.max_index() + 1
  96     unitid = uniqueid.get(unit.__class__)(unit)
  97     if unitid.changed:
  98         unit.setid(unitid.getid())
  99 
  100 
  101 @receiver(pre_save, sender=UnitChange)
  102 def handle_unit_pre_change(**kwargs):
  103     unit_change = kwargs["instance"]
  104     unit = unit_change.unit
  105     if unit.state == UNTRANSLATED:
  106         # clear reviewer and translator data if translation
  107         # has been deleted
  108         unit_change.submitted_by = None
  109         unit_change.submitted_on = None
  110 
  111 
  112 @receiver(post_save, sender=UnitChange)
  113 def handle_unit_change(**kwargs):
  114     unit_change = kwargs["instance"]
  115     unit = unit_change.unit
  116     created = not unit._frozen.pk
  117 
  118     if not created:
  119         lifecycle.get(Unit)(unit).change()
  120     if not unit.source_updated and not unit.target_updated:
  121         return
  122     new_untranslated = (created and unit.state == UNTRANSLATED)
  123     if not new_untranslated:
  124         update_checks.send(unit.__class__, instance=unit)
  125     if unit.istranslated():
  126         unit.update_tmserver()
  127
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/pootle/apps/pootle_store/receivers.py b/pootle/apps/pootle_store/receivers.py
  --- a/pootle/apps/pootle_store/receivers.py
  +++ b/pootle/apps/pootle_store/receivers.py
  @@ -98,17 +98,6 @@
           unit.setid(unitid.getid())
   
   
  -@receiver(pre_save, sender=UnitChange)
  -def handle_unit_pre_change(**kwargs):
  -    unit_change = kwargs["instance"]
  -    unit = unit_change.unit
  -    if unit.state == UNTRANSLATED:
  -        # clear reviewer and translator data if translation
  -        # has been deleted
  -        unit_change.submitted_by = None
  -        unit_change.submitted_on = None
  -
  -
   @receiver(post_save, sender=UnitChange)
   def handle_unit_change(**kwargs):
       unit_change = kwargs["instance"]
  
verification_info: {"golden_diff": "diff --git a/pootle/apps/pootle_store/receivers.py b/pootle/apps/pootle_store/receivers.py\n--- a/pootle/apps/pootle_store/receivers.py\n+++ b/pootle/apps/pootle_store/receivers.py\n@@ -98,17 +98,6 @@\n         unit.setid(unitid.getid())\n \n \n-@receiver(pre_save, sender=UnitChange)\n-def handle_unit_pre_change(**kwargs):\n-    unit_change = kwargs[\"instance\"]\n-    unit = unit_change.unit\n-    if unit.state == UNTRANSLATED:\n-        # clear reviewer and translator data if translation\n-        # has been deleted\n-        unit_change.submitted_by = None\n-        unit_change.submitted_on = None\n-\n-\n @receiver(post_save, sender=UnitChange)\n def handle_unit_change(**kwargs):\n     unit_change = kwargs[\"instance\"]\n", "issue": "Changing source (with xliff) can create submissions with no submitter\n# Steps to reproduce:\r\n\r\n- change source in file of existing unit\r\n- run update_stores\r\n\r\n# Results\r\n\r\n- submissions have no submitter\r\n- stuff breaks\r\n\r\n## Expected result:\r\n\r\n- nothing breaks\r\n\r\n\r\nthis only happens in xliff afaict - as i dont think its possible to change source of units in this way with po\r\n\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n#\n# Copyright (C) Pootle contributors.\n#\n# This file is a part of the Pootle project. It is distributed under the GPL3\n# or later license. See the LICENSE file for a copy of the license and the\n# AUTHORS file for copyright and authorship information.\n\nfrom hashlib import md5\n\nfrom django.db.models.signals import post_save, pre_save\nfrom django.dispatch import receiver\nfrom django.utils.encoding import force_bytes\n\nfrom pootle.core.delegate import lifecycle, uniqueid\nfrom pootle.core.models import Revision\nfrom pootle.core.signals import update_checks, update_data\n\nfrom .constants import FUZZY, TRANSLATED, UNTRANSLATED\nfrom .models import Suggestion, Unit, UnitChange, UnitSource\n\n\n@receiver(post_save, sender=Suggestion)\ndef handle_suggestion_added(**kwargs):\n    created = kwargs.get(\"created\")\n    if not created:\n        return\n    store = kwargs[\"instance\"].unit.store\n    update_data.send(store.__class__, instance=store)\n\n\n@receiver(post_save, sender=Suggestion)\ndef handle_suggestion_accepted(**kwargs):\n    created = kwargs.get(\"created\")\n    suggestion = kwargs[\"instance\"]\n    if created or not suggestion.is_accepted:\n        return\n    update_data.send(\n        suggestion.unit.store.__class__,\n        instance=suggestion.unit.store)\n\n\n@receiver(pre_save, sender=UnitSource)\ndef handle_unit_source_pre_save(**kwargs):\n    unit_source = kwargs[\"instance\"]\n    created = not unit_source.pk\n    unit = unit_source.unit\n    if created:\n        unit_source.creation_revision = unit.revision\n    if created or unit.source_updated:\n        unit_source.source_hash = md5(force_bytes(unit.source_f)).hexdigest()\n        unit_source.source_length = len(unit.source_f)\n        unit_source.source_wordcount = max(\n            1, (unit.counter.count_words(unit.source_f.strings) or 0))\n\n\n@receiver(pre_save, sender=Unit)\ndef handle_unit_pre_save(**kwargs):\n    unit = kwargs[\"instance\"]\n    auto_translated = False\n\n    if unit.source_updated:\n        # update source related fields\n        wc = unit.counter.count_words(unit.source_f.strings)\n        if not wc and not bool(filter(None, unit.target_f.strings)):\n            # auto-translate untranslated strings\n            unit.target = unit.source\n            unit.state = FUZZY\n            auto_translated = True\n    if unit.target_updated:\n        # update target related fields\n        unit.target_wordcount = unit.counter.count_words(\n            unit.target_f.strings)\n        unit.target_length = len(unit.target_f)\n        if filter(None, unit.target_f.strings):\n            if unit.state == UNTRANSLATED:\n                unit.state = TRANSLATED\n        else:\n            # if it was TRANSLATED then set to UNTRANSLATED\n            if unit.state > FUZZY:\n                unit.state = UNTRANSLATED\n\n    # Updating unit from the .po file set its revision property to\n    # a new value (the same for all units during its store updated)\n    # since that change doesn't require further sync but note that\n    # auto_translated units require further sync\n    update_revision = (\n        unit.revision is None\n        or (not unit.revision_updated\n            and (unit.updated and not auto_translated)))\n    if update_revision:\n        unit.revision = Revision.incr()\n\n    if unit.index is None:\n        unit.index = unit.store.max_index() + 1\n    unitid = uniqueid.get(unit.__class__)(unit)\n    if unitid.changed:\n        unit.setid(unitid.getid())\n\n\n@receiver(pre_save, sender=UnitChange)\ndef handle_unit_pre_change(**kwargs):\n    unit_change = kwargs[\"instance\"]\n    unit = unit_change.unit\n    if unit.state == UNTRANSLATED:\n        # clear reviewer and translator data if translation\n        # has been deleted\n        unit_change.submitted_by = None\n        unit_change.submitted_on = None\n\n\n@receiver(post_save, sender=UnitChange)\ndef handle_unit_change(**kwargs):\n    unit_change = kwargs[\"instance\"]\n    unit = unit_change.unit\n    created = not unit._frozen.pk\n\n    if not created:\n        lifecycle.get(Unit)(unit).change()\n    if not unit.source_updated and not unit.target_updated:\n        return\n    new_untranslated = (created and unit.state == UNTRANSLATED)\n    if not new_untranslated:\n        update_checks.send(unit.__class__, instance=unit)\n    if unit.istranslated():\n        unit.update_tmserver()\n", "path": "pootle/apps/pootle_store/receivers.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n#\n# Copyright (C) Pootle contributors.\n#\n# This file is a part of the Pootle project. It is distributed under the GPL3\n# or later license. See the LICENSE file for a copy of the license and the\n# AUTHORS file for copyright and authorship information.\n\nfrom hashlib import md5\n\nfrom django.db.models.signals import post_save, pre_save\nfrom django.dispatch import receiver\nfrom django.utils.encoding import force_bytes\n\nfrom pootle.core.delegate import lifecycle, uniqueid\nfrom pootle.core.models import Revision\nfrom pootle.core.signals import update_checks, update_data\n\nfrom .constants import FUZZY, TRANSLATED, UNTRANSLATED\nfrom .models import Suggestion, Unit, UnitChange, UnitSource\n\n\n@receiver(post_save, sender=Suggestion)\ndef handle_suggestion_added(**kwargs):\n    created = kwargs.get(\"created\")\n    if not created:\n        return\n    store = kwargs[\"instance\"].unit.store\n    update_data.send(store.__class__, instance=store)\n\n\n@receiver(post_save, sender=Suggestion)\ndef handle_suggestion_accepted(**kwargs):\n    created = kwargs.get(\"created\")\n    suggestion = kwargs[\"instance\"]\n    if created or not suggestion.is_accepted:\n        return\n    update_data.send(\n        suggestion.unit.store.__class__,\n        instance=suggestion.unit.store)\n\n\n@receiver(pre_save, sender=UnitSource)\ndef handle_unit_source_pre_save(**kwargs):\n    unit_source = kwargs[\"instance\"]\n    created = not unit_source.pk\n    unit = unit_source.unit\n    if created:\n        unit_source.creation_revision = unit.revision\n    if created or unit.source_updated:\n        unit_source.source_hash = md5(force_bytes(unit.source_f)).hexdigest()\n        unit_source.source_length = len(unit.source_f)\n        unit_source.source_wordcount = max(\n            1, (unit.counter.count_words(unit.source_f.strings) or 0))\n\n\n@receiver(pre_save, sender=Unit)\ndef handle_unit_pre_save(**kwargs):\n    unit = kwargs[\"instance\"]\n    auto_translated = False\n\n    if unit.source_updated:\n        # update source related fields\n        wc = unit.counter.count_words(unit.source_f.strings)\n        if not wc and not bool(filter(None, unit.target_f.strings)):\n            # auto-translate untranslated strings\n            unit.target = unit.source\n            unit.state = FUZZY\n            auto_translated = True\n    if unit.target_updated:\n        # update target related fields\n        unit.target_wordcount = unit.counter.count_words(\n            unit.target_f.strings)\n        unit.target_length = len(unit.target_f)\n        if filter(None, unit.target_f.strings):\n            if unit.state == UNTRANSLATED:\n                unit.state = TRANSLATED\n        else:\n            # if it was TRANSLATED then set to UNTRANSLATED\n            if unit.state > FUZZY:\n                unit.state = UNTRANSLATED\n\n    # Updating unit from the .po file set its revision property to\n    # a new value (the same for all units during its store updated)\n    # since that change doesn't require further sync but note that\n    # auto_translated units require further sync\n    update_revision = (\n        unit.revision is None\n        or (not unit.revision_updated\n            and (unit.updated and not auto_translated)))\n    if update_revision:\n        unit.revision = Revision.incr()\n\n    if unit.index is None:\n        unit.index = unit.store.max_index() + 1\n    unitid = uniqueid.get(unit.__class__)(unit)\n    if unitid.changed:\n        unit.setid(unitid.getid())\n\n\n@receiver(post_save, sender=UnitChange)\ndef handle_unit_change(**kwargs):\n    unit_change = kwargs[\"instance\"]\n    unit = unit_change.unit\n    created = not unit._frozen.pk\n\n    if not created:\n        lifecycle.get(Unit)(unit).change()\n    if not unit.source_updated and not unit.target_updated:\n        return\n    new_untranslated = (created and unit.state == UNTRANSLATED)\n    if not new_untranslated:\n        update_checks.send(unit.__class__, instance=unit)\n    if unit.istranslated():\n        unit.update_tmserver()\n", "path": "pootle/apps/pootle_store/receivers.py"}]}