prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  add_translation_dirs behaves the wrong way around
  This is a follow-up to #1473. See the reproducer and notes there.
  
  I would propose an API change that changes behaviour of add_translation_dirs to append specs at the end of existing specs instead of prepending it. That way, API users simply need to understand "last spec wins". This matches much closer to the mental model of "add".
  
  It matches the current documented behaviour of how the method is to _behave_ in case of multiple calls.
  
  
  </issue>
  <code>
  [start of pyramid/config/i18n.py]
  1 from pyramid.interfaces import (
  2     ILocaleNegotiator,
  3     ITranslationDirectories,
  4     )
  5 
  6 from pyramid.exceptions import ConfigurationError
  7 from pyramid.path import AssetResolver
  8 from pyramid.util import action_method
  9 
  10 class I18NConfiguratorMixin(object):
  11     @action_method
  12     def set_locale_negotiator(self, negotiator):
  13         """
  14         Set the :term:`locale negotiator` for this application.  The
  15         :term:`locale negotiator` is a callable which accepts a
  16         :term:`request` object and which returns a :term:`locale
  17         name`.  The ``negotiator`` argument should be the locale
  18         negotiator implementation or a :term:`dotted Python name`
  19         which refers to such an implementation.
  20 
  21         Later calls to this method override earlier calls; there can
  22         be only one locale negotiator active at a time within an
  23         application.  See :ref:`activating_translation` for more
  24         information.
  25 
  26         .. note::
  27 
  28            Using the ``locale_negotiator`` argument to the
  29            :class:`pyramid.config.Configurator` constructor can be used to
  30            achieve the same purpose.
  31         """
  32         def register():
  33             self._set_locale_negotiator(negotiator)
  34         intr = self.introspectable('locale negotiator', None,
  35                                    self.object_description(negotiator),
  36                                    'locale negotiator')
  37         intr['negotiator'] = negotiator
  38         self.action(ILocaleNegotiator, register, introspectables=(intr,))
  39 
  40     def _set_locale_negotiator(self, negotiator):
  41         locale_negotiator = self.maybe_dotted(negotiator)
  42         self.registry.registerUtility(locale_negotiator, ILocaleNegotiator)
  43 
  44     @action_method
  45     def add_translation_dirs(self, *specs):
  46         """ Add one or more :term:`translation directory` paths to the
  47         current configuration state.  The ``specs`` argument is a
  48         sequence that may contain absolute directory paths
  49         (e.g. ``/usr/share/locale``) or :term:`asset specification`
  50         names naming a directory path (e.g. ``some.package:locale``)
  51         or a combination of the two.
  52 
  53         Example:
  54 
  55         .. code-block:: python
  56 
  57            config.add_translation_dirs('/usr/share/locale',
  58                                        'some.package:locale')
  59 
  60         The translation directories are defined as a list in which
  61         translations defined later have precedence over translations defined
  62         earlier.
  63 
  64         If multiple specs are provided in a single call to
  65         ``add_translation_dirs``, the directories will be inserted in the
  66         order they're provided (earlier items are trumped by later items).
  67 
  68         .. warning::
  69 
  70            Consecutive calls to ``add_translation_dirs`` will sort the
  71            directories such that the later calls will add folders with
  72            lower precedence than earlier calls.
  73 
  74         """
  75         introspectables = []
  76 
  77         def register():
  78             directories = []
  79             resolver = AssetResolver(self.package_name)
  80 
  81             # defer spec resolution until register to allow for asset
  82             # overrides to take place in an earlier config phase
  83             for spec in specs[::-1]:  # reversed
  84                 # the trailing slash helps match asset overrides for folders
  85                 if not spec.endswith('/'):
  86                     spec += '/'
  87                 asset = resolver.resolve(spec)
  88                 directory = asset.abspath()
  89                 if not asset.isdir():
  90                     raise ConfigurationError('"%s" is not a directory' %
  91                                             directory)
  92                 intr = self.introspectable('translation directories', directory,
  93                                         spec, 'translation directory')
  94                 intr['directory'] = directory
  95                 intr['spec'] = spec
  96                 introspectables.append(intr)
  97                 directories.append(directory)
  98 
  99             tdirs = self.registry.queryUtility(ITranslationDirectories)
  100             if tdirs is None:
  101                 tdirs = []
  102                 self.registry.registerUtility(tdirs, ITranslationDirectories)
  103             for directory in directories:
  104                 tdirs.insert(0, directory)
  105 
  106         self.action(None, register, introspectables=introspectables)
  107 
  108
  [end of pyramid/config/i18n.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/pyramid/config/i18n.py b/pyramid/config/i18n.py
  --- a/pyramid/config/i18n.py
  +++ b/pyramid/config/i18n.py
  @@ -42,7 +42,7 @@
           self.registry.registerUtility(locale_negotiator, ILocaleNegotiator)
   
       @action_method
  -    def add_translation_dirs(self, *specs):
  +    def add_translation_dirs(self, *specs, **kw):
           """ Add one or more :term:`translation directory` paths to the
           current configuration state.  The ``specs`` argument is a
           sequence that may contain absolute directory paths
  @@ -61,18 +61,27 @@
           translations defined later have precedence over translations defined
           earlier.
   
  +        By default, consecutive calls to ``add_translation_dirs`` will add
  +        directories to the start of the list. This means later calls to
  +        ``add_translation_dirs`` will have their translations trumped by
  +        earlier calls. If you explicitly need this call to trump an earlier
  +        call then you may set ``override`` to ``True``.
  +
           If multiple specs are provided in a single call to
           ``add_translation_dirs``, the directories will be inserted in the
           order they're provided (earlier items are trumped by later items).
   
  -        .. warning::
  +        .. versionchanged:: 1.8
   
  -           Consecutive calls to ``add_translation_dirs`` will sort the
  -           directories such that the later calls will add folders with
  -           lower precedence than earlier calls.
  +           The ``override`` parameter was added to allow a later call
  +           to ``add_translation_dirs`` to override an earlier call, inserting
  +           folders at the beginning of the translation directory list.
   
           """
           introspectables = []
  +        override = kw.pop('override', False)
  +        if kw:
  +            raise TypeError('invalid keyword arguments: %s', sorted(kw.keys()))
   
           def register():
               directories = []
  @@ -80,7 +89,7 @@
   
               # defer spec resolution until register to allow for asset
               # overrides to take place in an earlier config phase
  -            for spec in specs[::-1]:  # reversed
  +            for spec in specs:
                   # the trailing slash helps match asset overrides for folders
                   if not spec.endswith('/'):
                       spec += '/'
  @@ -100,8 +109,11 @@
               if tdirs is None:
                   tdirs = []
                   self.registry.registerUtility(tdirs, ITranslationDirectories)
  -            for directory in directories:
  -                tdirs.insert(0, directory)
  +            if override:
  +                tdirs.extend(directories)
  +            else:
  +                for directory in reversed(directories):
  +                    tdirs.insert(0, directory)
   
           self.action(None, register, introspectables=introspectables)
  
verification_info: {"golden_diff": "diff --git a/pyramid/config/i18n.py b/pyramid/config/i18n.py\n--- a/pyramid/config/i18n.py\n+++ b/pyramid/config/i18n.py\n@@ -42,7 +42,7 @@\n         self.registry.registerUtility(locale_negotiator, ILocaleNegotiator)\n \n     @action_method\n-    def add_translation_dirs(self, *specs):\n+    def add_translation_dirs(self, *specs, **kw):\n         \"\"\" Add one or more :term:`translation directory` paths to the\n         current configuration state.  The ``specs`` argument is a\n         sequence that may contain absolute directory paths\n@@ -61,18 +61,27 @@\n         translations defined later have precedence over translations defined\n         earlier.\n \n+        By default, consecutive calls to ``add_translation_dirs`` will add\n+        directories to the start of the list. This means later calls to\n+        ``add_translation_dirs`` will have their translations trumped by\n+        earlier calls. If you explicitly need this call to trump an earlier\n+        call then you may set ``override`` to ``True``.\n+\n         If multiple specs are provided in a single call to\n         ``add_translation_dirs``, the directories will be inserted in the\n         order they're provided (earlier items are trumped by later items).\n \n-        .. warning::\n+        .. versionchanged:: 1.8\n \n-           Consecutive calls to ``add_translation_dirs`` will sort the\n-           directories such that the later calls will add folders with\n-           lower precedence than earlier calls.\n+           The ``override`` parameter was added to allow a later call\n+           to ``add_translation_dirs`` to override an earlier call, inserting\n+           folders at the beginning of the translation directory list.\n \n         \"\"\"\n         introspectables = []\n+        override = kw.pop('override', False)\n+        if kw:\n+            raise TypeError('invalid keyword arguments: %s', sorted(kw.keys()))\n \n         def register():\n             directories = []\n@@ -80,7 +89,7 @@\n \n             # defer spec resolution until register to allow for asset\n             # overrides to take place in an earlier config phase\n-            for spec in specs[::-1]:  # reversed\n+            for spec in specs:\n                 # the trailing slash helps match asset overrides for folders\n                 if not spec.endswith('/'):\n                     spec += '/'\n@@ -100,8 +109,11 @@\n             if tdirs is None:\n                 tdirs = []\n                 self.registry.registerUtility(tdirs, ITranslationDirectories)\n-            for directory in directories:\n-                tdirs.insert(0, directory)\n+            if override:\n+                tdirs.extend(directories)\n+            else:\n+                for directory in reversed(directories):\n+                    tdirs.insert(0, directory)\n \n         self.action(None, register, introspectables=introspectables)\n", "issue": "add_translation_dirs behaves the wrong way around\nThis is a follow-up to #1473. See the reproducer and notes there.\n\nI would propose an API change that changes behaviour of add_translation_dirs to append specs at the end of existing specs instead of prepending it. That way, API users simply need to understand \"last spec wins\". This matches much closer to the mental model of \"add\".\n\nIt matches the current documented behaviour of how the method is to _behave_ in case of multiple calls.\n\n", "before_files": [{"content": "from pyramid.interfaces import (\n    ILocaleNegotiator,\n    ITranslationDirectories,\n    )\n\nfrom pyramid.exceptions import ConfigurationError\nfrom pyramid.path import AssetResolver\nfrom pyramid.util import action_method\n\nclass I18NConfiguratorMixin(object):\n    @action_method\n    def set_locale_negotiator(self, negotiator):\n        \"\"\"\n        Set the :term:`locale negotiator` for this application.  The\n        :term:`locale negotiator` is a callable which accepts a\n        :term:`request` object and which returns a :term:`locale\n        name`.  The ``negotiator`` argument should be the locale\n        negotiator implementation or a :term:`dotted Python name`\n        which refers to such an implementation.\n\n        Later calls to this method override earlier calls; there can\n        be only one locale negotiator active at a time within an\n        application.  See :ref:`activating_translation` for more\n        information.\n\n        .. note::\n\n           Using the ``locale_negotiator`` argument to the\n           :class:`pyramid.config.Configurator` constructor can be used to\n           achieve the same purpose.\n        \"\"\"\n        def register():\n            self._set_locale_negotiator(negotiator)\n        intr = self.introspectable('locale negotiator', None,\n                                   self.object_description(negotiator),\n                                   'locale negotiator')\n        intr['negotiator'] = negotiator\n        self.action(ILocaleNegotiator, register, introspectables=(intr,))\n\n    def _set_locale_negotiator(self, negotiator):\n        locale_negotiator = self.maybe_dotted(negotiator)\n        self.registry.registerUtility(locale_negotiator, ILocaleNegotiator)\n\n    @action_method\n    def add_translation_dirs(self, *specs):\n        \"\"\" Add one or more :term:`translation directory` paths to the\n        current configuration state.  The ``specs`` argument is a\n        sequence that may contain absolute directory paths\n        (e.g. ``/usr/share/locale``) or :term:`asset specification`\n        names naming a directory path (e.g. ``some.package:locale``)\n        or a combination of the two.\n\n        Example:\n\n        .. code-block:: python\n\n           config.add_translation_dirs('/usr/share/locale',\n                                       'some.package:locale')\n\n        The translation directories are defined as a list in which\n        translations defined later have precedence over translations defined\n        earlier.\n\n        If multiple specs are provided in a single call to\n        ``add_translation_dirs``, the directories will be inserted in the\n        order they're provided (earlier items are trumped by later items).\n\n        .. warning::\n\n           Consecutive calls to ``add_translation_dirs`` will sort the\n           directories such that the later calls will add folders with\n           lower precedence than earlier calls.\n\n        \"\"\"\n        introspectables = []\n\n        def register():\n            directories = []\n            resolver = AssetResolver(self.package_name)\n\n            # defer spec resolution until register to allow for asset\n            # overrides to take place in an earlier config phase\n            for spec in specs[::-1]:  # reversed\n                # the trailing slash helps match asset overrides for folders\n                if not spec.endswith('/'):\n                    spec += '/'\n                asset = resolver.resolve(spec)\n                directory = asset.abspath()\n                if not asset.isdir():\n                    raise ConfigurationError('\"%s\" is not a directory' %\n                                            directory)\n                intr = self.introspectable('translation directories', directory,\n                                        spec, 'translation directory')\n                intr['directory'] = directory\n                intr['spec'] = spec\n                introspectables.append(intr)\n                directories.append(directory)\n\n            tdirs = self.registry.queryUtility(ITranslationDirectories)\n            if tdirs is None:\n                tdirs = []\n                self.registry.registerUtility(tdirs, ITranslationDirectories)\n            for directory in directories:\n                tdirs.insert(0, directory)\n\n        self.action(None, register, introspectables=introspectables)\n\n", "path": "pyramid/config/i18n.py"}]}