Jinja: 2.9 Regression beim Zuweisen einer Variablen innerhalb einer Schleife

Erstellt am 7. Jan. 2017  ·  65Kommentare  ·  Quelle: pallets/jinja

2.9:

>>> jinja2.Template('{% set a = -1 %}{% for x in range(5) %}[{{ a }}:{% set a = x %}{{ a }}] {% endfor %}{{ a }}').render()
u'[:0] [:1] [:2] [:3] [:4] -1'

2.8:

>>> jinja2.Template('{% set a = -1 %}{% for x in range(5) %}[{{ a }}:{% set a = x %}{{ a }}] {% endfor %}{{ a }}').render()
u'[-1:0] [0:1] [1:2] [2:3] [3:4] -1'

Ursprünglich im IRC berichtet:

Eine Änderung des jinja2-Bereichs scheint mich zu betreffen, und ich bin mir bei der richtigen Lösung nicht sicher. Konkret ist das Problem die Jahreszuordnung hier: https://github.com/kennethlove/alex-gaynor-blog-design/blob/551172/templates/archive.html#L13 -L24

Hilfreichster Kommentar

changed_from_last hört sich gut an - zumindest in Bezug auf die Funktionalität ist der Name selbst IMO etwas umständlich. Vielleicht wäre nur changed klar genug?

Ich denke, das erste Element würde immer als "geändert" angesehen werden, egal was es ist? Wenn dieses Verhalten für jemanden nicht in Ordnung ist, könnte er sowieso immer einen not loop.first Scheck hinzufügen.

Alle 65 Kommentare

Während das aktuelle Verhalten falsch ist, ist das alte Verhalten definitiv auch falsch. Das Tag {% set %} war nie dazu gedacht, äußere Gültigkeitsbereiche zu überschreiben. Ich bin überrascht, dass es in einigen Fällen so war. Nicht sicher, was Sie hier tun sollen.

Das Verhalten, von dem ich annehmen würde, dass es korrekt ist, ist eine Ausgabe wie [-1:0] [-1:1] [-1:2] [-1:3] [-1:4] -1 .

In diesem speziellen Fall habe ich es gelöst, indem ich es umgeschrieben habe, um groupby .

Ich habe das Gefühl, dass dies ein ziemlich häufiger Anwendungsfall ist - auch Sachen wie {% set found = true %} in einer Schleife und dann danach überprüfen. Es ist sicherlich wahrscheinlich, dass die Dinge für die Leute kaputt gehen, wenn dies nicht mehr funktioniert ...

Ich bin schockiert, dass das früher funktioniert hat. Hat das immer funktioniert?

anscheinend ja:

>>> import jinja2
>>> jinja2.__version__
'2.0'
>>> jinja2.Template('{% for x in range(5) %}[{{ a }}:{% set a = x %}{{ a }}] {% endfor %}{{ a }}').render()
u'[:0] [0:1] [1:2] [2:3] [3:4] '

Groß. Denn das Problem hier ist, dass dies absolut nicht stichhaltig ist. Welche Variable soll überschrieben werden? Was ist, wenn ein Funktionsumfang dazwischen liegt. zB: ein Makro oder so ähnlich. Ich habe keine Ahnung, wie ich das jetzt unterstützen soll.

hmm vielleicht ähnlich wie beim Scoping von Python, vorausgesetzt, dass kein nonlocal verwendet wurde)? dh erlauben Sie nicht, etwas zu überschreiben, das in einem äußeren Bereich definiert ist (dh, wenn es ein Makro dazwischen gibt), aber erlauben Sie, es anders zu überschreiben?

Anscheinend wurde dies zuvor mit einem Vorlagenzusicherungsfehler abgefangen:

>>> Template('{% set x = 0 %}{% for y in [1, 2, 3] recursive %}{{ x }}{% set x = y %}{% endfor %}').render()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
jinja2.exceptions.TemplateAssertionError: It's not possible to set and access variables derived from an outer scope! (affects: x (line 1)

das Verhalten scheint mit/ohne rekursiv unterschiedlich zu sein (2.8.1 gibt mir einen UnboundLocalError-Fehler mit rekursiv und '012' ohne)

Der ungebundene lokale Fehler sollte auf dem Master behoben werden.

Ich bin mir nicht sicher, wie ich hier vorankommen soll. Ich mag es wirklich nicht, dass es anscheinend möglich war, so etwas zu tun.

Mit den letzten Änderungen werde ich dies als "funktioniert wie beabsichtigt" schließen. Sollten sich daraus weitere Konsequenzen ergeben, können wir erneut nach Alternativen suchen.

Ich wurde zu diesem Problem (siehe #656) geschickt, nachdem diese Änderung mein Blog-Template beim Upgrade von v.2.8.1 auf v2.9.4 in die Luft gesprengt hat.

Ich habe es verwendet, um den Überblick zu behalten, wenn sich verschiedene Daten zwischen den Schleifeniterationen ändern. Ich konnte das Problem beheben, weil ich den ursprünglichen Vorlagencode geschrieben habe (siehe https://github.com/MinchinWeb/seafoam/commit/8eb760816a06e4f0382816f82586204d1e7734fd und https://github.com/MinchinWeb/seafoam/commit/89d555dbd6a2f256471d43e41845 bezweifle, dass ich sonst in der Lage gewesen wäre. Der neue Code ist schwieriger zu befolgen, da die Vergleiche jetzt inline durchgeführt werden. Zum Beispiel mein alter Code (v.2.8.1):

{%- set last_day = None -%}

{% for article in dates %}
    {# ... #}
    <div class="archives-date">
        {%- if last_day != article.date.day %}
            {{ article.date | strftime('%a %-d') }}
        {% else -%}
            &mdash;
        {%- endif -%}
    </div>
    {%- set last_day = article.date.day %}
{% endfor %}

und der neue Code mit Inline-Vergleichen (v2.9.4):

{% for article in dates %}
    {# ... #}
    <div class="archives-date">
        {%- if ((article.date.day == dates[loop.index0 - 1].date.day) and
                (article.date.month == dates[loop.index0 - 1].date.month) and 
                (article.date.year == dates[loop.index0 - 1].date.year)) %}
                    &mdash;
        {% else -%}
                    {{ article.date | strftime('%a %-d') }}
        {%- endif -%}
    </div>
{% endfor %}

Also ich wollte nur sagen , dass das „Feature“ (oder „Hack“, wenn Sie es vorziehen) verwendet und ist bereits verpasst.

Wenn die Scoping-Probleme im Moment zu komplex sind, um sie vernünftig herauszufinden, könnte dann (zumindest) etwas zum Changelog hinzugefügt werden, damit es weniger Leute unwissend beißt?

Mir war nicht bewusst, dass dies so häufig missbraucht wird :-/ Ärgerlicherweise gibt es wirklich keine Möglichkeit, dies zuverlässig zum Laufen zu bringen. Ich frage mich jedoch, ob wir hier die üblichen Anwendungsfälle isolieren und eine schönere API einführen können.

Insbesondere möchten wir vielleicht so etwas hinzufügen ( loop.changed_from_last ):

{% for article in dates %}
    <div class="archives-date">
        {%- if loop.changed_from_last(article.date.day) %}
            {{ article.date | strftime('%a %-d') }}
        {% else -%}
            &mdash;
        {%- endif -%}
    </div>
{% endfor %}

changed_from_last hört sich gut an - zumindest in Bezug auf die Funktionalität ist der Name selbst IMO etwas umständlich. Vielleicht wäre nur changed klar genug?

Ich denke, das erste Element würde immer als "geändert" angesehen werden, egal was es ist? Wenn dieses Verhalten für jemanden nicht in Ordnung ist, könnte er sowieso immer einen not loop.first Scheck hinzufügen.

Vielleicht hält previous_context einfach den gesamten vorherigen Kontext, anstatt zu versuchen zu entscheiden, was die Benutzer damit machen.

nur previous oder prev ? "Kontext" klingt in diesem Zusammenhang eher verwirrend (kein Wortspiel beabsichtigt)

.....und jetzt kann ich mir schon vorstellen, dass jemand nach einem next fragt :/

Oder vielleicht eine explizite Anweisung zum Schreiben außerhalb des Geltungsbereichs: set_outer oder so.

ich dachte das:

class LoopContextBase(object):

    def __init__(self, recurse=None, depth0=0):
        ...
        self._last_iteration = missing

    def changed(self, *value):
        if self._last_iteration != value:
            self._last_iteration = value
            return True
        return False

@davidism können wir nicht set_outer ohne das gesamte Scoping-System zu durchbrechen. Das würde das Ganze massiv vermasseln.

Ja, dachte, das wäre so. Ich gehe davon aus, "was ist, wenn ich wissen möchte, ob der aktuelle Wert größer als der vorherige ist" oder etwas Ähnliches. Aber ich mag auch die Methode changed .

Als zusätzlicher Datenpunkt fiel es mir auf die Beine, wenn ich eine spezielle Klasse in generiertes HTML einfügen muss, aber nur für das erste Element der iterierten Liste, das nicht auch einen bestimmten Eigenschaftssatz hat. Ich kann die iterierten Daten nicht ändern. Ich kann nicht loop.first (so sehr ich es gerne würde) oder mit irgendetwas vom letzten Element vergleichen, um zuverlässig zu tun, was ich hier tun muss, was dazu führte, dass ich mit dem bösen Konstrukt experimentierte, das perfekt funktionierte (und mir war nicht klar, dass ich tatsächlich einen Fehler missbraucht habe).

Darüber hinaus biete ich Erweiterungsmöglichkeiten durch Plugins von Drittanbietern und habe keine Möglichkeit zu überwachen, wie die Autoren ihre Vorlagen strukturieren, was zu einem plötzlichen Bruch für Endbenutzer nach dem Update auf Jinja 2.9+ führt. Aus diesem Grund habe ich die neueste Version 2.8 jetzt in mein Programm gepinnt, um abwärtskompatibel zu bleiben (wie mein Versionierungsschema verspricht), bis ich einen Weg finde, Autoren dazu zu bringen, ihre Vorlagen zu aktualisieren.

Könnte jemand bitte klären, warum jinja2-Bereiche nicht genau so funktionieren, wie Python funktioniert? dh jinja2-Templates entsprechen Python-Modulen, Makros entsprechen Funktionen (und haben ihren eigenen Geltungsbereich), for-Schleifen haben keinen eigenen Geltungsbereich und so weiter. Während @mitsuhiko sagt, dass jinja 2.8 und

Für Python-Programmierer ist das Verhalten aus dem ersten Post (Jinja 2.8) offensichtlich. Gleiches gilt für https://github.com/pallets/jinja/issues/660 . Ich verstehe nicht, warum die Python-Bibliothek Javascript-Verhalten implementieren sollte (ich verstehe, dass Pythons Umgang mit Standardargumenten nicht ideal ist, aber jeder Python-Entwickler ist sich dessen bewusst.) davon).

Alternativ sollte es ein Dokument geben, das beschreibt, wie das Scoping in jinja funktioniert, damit wir nicht raten müssen.

Bitte nehmt meinen Kommentar auch nicht negativ auf, ich bin sehr dankbar für Jinja.

@roganov ein paar Anmerkungen dazu:

Könnte mir bitte jemand erklären, warum jinja2-Scopes nicht genau so funktionieren, wie Python funktioniert?

Denn Pythons Scoping ist meiner Meinung nach wirklich schlecht, insbesondere in Templates, weil man leicht wichtige Informationen aus Versehen überschreiben kann.

Während @mitsuhiko sagt, dass jinja 2.8 und

Beachten Sie, dass dies aufgrund eines Fehlers eine Ausnahme war und nur in einigen begrenzten Situationen und rein zufällig funktionierte. Jinja hatte immer die gleichen dokumentierten Scoping-Regeln und dieses Verhalten wurde nie dokumentiert. Zu allen Zeiten wurde gesagt, dass sich Variablen nicht in äußere Bereiche ausbreiten. Sie können dies leicht daran erkennen, dass die Variable nach dem Ende der Schleife nie gesetzt wurde.

Alternativ sollte es ein Dokument geben, das beschreibt, wie das Scoping in jinja funktioniert, damit wir nicht raten müssen.

Ich habe die Dokumentation dafür schon vor ein paar Tagen verbessert

Was wäre, wenn es eine Möglichkeit gäbe, eine Variable explizit an eine Schleife zu übergeben? Vielleicht Syntax wie diese (Ausleihe von Textfiltern):

{%- set last_day = None -%}

{% for article in dates | pass_variable ( last_day ) %}
    {# ... #}
    <div class="archives-date">
        {%- if last_day != article.date.day -%}
            {{ article.date | strftime('%a %-d') }}
        {%- else %}
            &mdash;
        {% endif -%}
    </div>
    {%- set last_day = article.date.day %}
{% endfor %}

Oder gibt es eine Möglichkeit, etwas Ähnliches wie scoped zu tun, wie es derzeit für Makros gilt?


Ein anderer Anwendungsfall wäre, eine Art Zähler zwischen Schleifen zu pflegen. Zum Beispiel, wie viele Zeilen insgesamt? Wie viele Zeilen erfüllen bestimmte Kriterien? Die Summe einiger Eigenschaften für ausgewählte Zeilen (um eine Gesamtzeile zu drucken)?

Filtersyntax wäre hier nicht möglich, da Filter bereits auf dem Iterable möglich sind.

Eine mögliche Syntax dafür, die nicht schlecht aussehen würde, könnte dies sein:

{% for article in dates with last_day %}

Zumal with in Jinja bereits Scoping-Sachen macht, wenn es zB als {% with %} . OTOH, hier wäre das Gegenteil der Fall, da mit Blöcken ein neuer Bereich geöffnet und keine Variablen für den äußeren Bereich zugänglich gemacht werden.

Ich bin mir jedoch nicht sicher, ob das eine Funktion ist, die Jinja braucht oder nicht.

Keine Syntax wird dies ändern, da sie die Bereichsregeln immer noch unterlaufen würde. Dies ist weder mit dem aktuellen Zusammenstellungs- noch mit dem ID-Tracking-System möglich. Selbst wenn es für diesen einfachen Fall funktioniert, was passiert, wenn man eine for-Schleife hat, die recursive . Was ist, wenn jemand ein Makro in einer for-Schleife definiert. Was passiert, wenn ein Aufrufblock in einer for-Schleife erscheint.

Ich denke, es wäre sinnvoller, ein globales Objekt einzuführen, das als Speichernamensraum fungiert und dann mit geändert werden kann. Z.B:

{% set foo = namespace() %}
{% set foo.iterated = false %}
{% for item in seq %}
  {% set foo.iterated = true %}
{% endfor %}

Dies würde jedoch eine grundlegende Änderung des Tags set erfordern.

@mitsuhiko und diese Art von Muster wird bereits mit dem Tag do : http://stackoverflow.com/a/4880398/400617

FWIW, die Lösung mit do ist extrem schrecklich. Genau wie die Problemumgehung, die Leute in Python 2 verwenden, wenn sie nonlocal benötigen würden ...

Ich stimme voll und ganz zu und weise nur darauf hin, dass es da draußen ist. Und wie Alex betonte, können viele dieser Probleme neu geschrieben werden, entweder mit Filtern oder indem man einen Teil der Logik in Python steckt.

Ein weiterer (hässlicher) Hack besteht darin, eine Liste zu verwenden, anzuhängen und zu öffnen: http://stackoverflow.com/a/32700975/4276230

Hallo, ich benutze diesen Code seit ungefähr 2 Jahren, jetzt bricht er und aufgrund neuer Dokumentation und dieser Diskussion gibt es keine andere Möglichkeit, das zu tun, was ich hier versuche. Wenn nicht, korrigiere mich bitte.

{% set list = "" %}
{% for name in names %}
{% if name.last is defined %}
{% set list = list + name.last + " " %}
{% if loop.last %}
{{ list.split(' ')|unique }}
{% endfor %}

@pujan14

{{ names|map(attribute="last")|select|unique }}

Obwohl unique kein eingebauter Filter ist, können Sie jederzeit einen weiteren Filter hinzufügen, der das Ganze erledigt, da Sie bereits den Filter unique hinzufügen.

Hi,
Ich verstehe, dass es aus diesem Grund viele "hässliche" Beispiele gibt, aber könnten Sie bitte sagen, wie Sie eine Variable in einer for-Schleife in einer Jinja-Vorlage auf elegante / richtige Weise inkrementieren können? Weil mein Code auch kaputt ist.

Warum musst du es überhaupt tun? Bitte geben Sie auch Ihren Code an.

{% for state in states.sensor -%}
{% if loop.first %}
{% set devnum = 0 %}
{% endif -%}
{%- if state.state == "online" %}
{% set devnum = devnum + 1 %}
{%- endif -%}
{% if loop.last %}
{{ devnum }}
{% endif -%}
{%- endfor -%}

Könnten Sie bitte raten, wie man eine Variable in einer for-Schleife in der Jinja-Vorlage auf elegante / richtige Weise inkrementiert?

Das hättest du nie tun dürfen (oder können). Die Antwort lautet also: Tu das nicht. Uns interessiert jedoch, warum Vorlagenautoren dies zu tun scheinen.

Jinja zählt die Schleife bereits auf. {{ loop.index0 }}

@davidism Ich brauche nur die, die eine Bedingung erfüllen

Schreiben Sie einen Filter, der devnum, sensor Tupel genau so liefert, wie Sie sie brauchen. Oder berechnen Sie es in Python und übergeben Sie es an die Vorlage. Oder verwenden Sie das folgende Beispiel. Dies gilt für jedes andere Beispiel, das ich gesehen habe.

@Molodax können Sie dies tun:

{{ states.sensor|selectattr('state', 'equalto', 'online')|sum }}

meintest du nicht |count ?

Entschuldigung, ja, zählen.

@mitsuhiko , danke für deine Unterstützung, leider funktioniert es nicht.
Vielleicht wurde jinja2 (Filter) mit einigen Einschränkungen in einem Projekt implementiert, das ( Home Assistant ) verwendet. Aber mit dem von mir bereitgestellten Code hat es funktioniert. Das Mitleid.

Hallo Leute. Sie fragen nach Beispielcode, der unter 2.8 funktioniert, also hier ist meiner:

{% set count = 0 %}
{% if 'anchors' in group_names %}
nameserver 127.0.0.1
{% set count = count+1 %}
{% endif %}
{% for resolver in resolvers %}
{% if count < 3 %}
{% if resolver|ipv6 and ansible_default_ipv6.address is defined %}
nameserver {{ resolver }}
{% set count = count+1 %}
{% elif resolver|ipv4 and ansible_default_ipv4.address is defined %}
nameserver {{ resolver }}
{% set count = count+1 %}
{% endif %}
{% endif %}
{% endfor %}

Ich weiß nicht, wie ich dies ohne eine globale "count" -Variable tun würde, auf die ich in 2 separaten Schleifen verweisen kann. Haben Sie Vorschläge, die es ermöglichen, dass dies sowohl unter 2.8 als auch unter 2.9 funktioniert?

@davidism Ihre Lösung ist großartig, aber ich versuche, dies zu erreichen.
Erstellen Sie 2 Listen wie folgt

{% set list1 = name|default()|map(attribute="last")|select|list %}
{% set list2 = name|default()|map(attribute="age")|select|list %}

und fügen Sie sie dann in list3 zusammen, die wie folgt aussehen sollte, und wenden Sie schließlich einen einzigartigen (ansible-Filter) auf list3 an
last1-alter1
last2-alter2
letztes 3-Alter3
letztes4-alter4
letztes5-Alter5
letztes6-Alter6

Von dem, was ich gesammelt habe, funktioniert die Karte nicht mit mehreren Attributen #554
Ich verwende jinja2 über ansible und daher ist es für mich keine gute Idee, vorher etwas in Python zu tun.

@pujan14 @aabdnn @Molodax stammt dieses Muster aus der offiziellen Ansible-Dokumentation oder ist es etwas, das Sie sich

@davidism Die oben vorgestellte Vorlage stammt aus keiner Ansible-Dokumentation. Ansible dokumentiert Jinja2 nicht speziell. Ich habe diese Vorlage gerade selbst erstellt, indem ich die Jinja2-Dokumentation gelesen habe, und sie hat funktioniert, also habe ich sie in Produktion genommen. Ich nahm an, dass Jinja2 Variablen global gemacht hat.

Wenn es nicht offiziell dokumentiert ist, neige ich eher dazu, dies so zu schließen, wie es ursprünglich war. Ich möchte wiederholen, dass Ansible Ihnen in dieser Hinsicht möglicherweise mehr helfen kann.

@davidism Ich habe in New Jinja 2.9 mit Loops .
Hier ist ein Beispiel.

{% for name in names %}
{% if loop.first %}
{% set list = "" %}
{% endif %}
{% if name.first is defined and name.last is defined and not name.disabled %}
{% set list = list + name.first|string + "-" + name.last|string %}
{% if loop.last %}
{% for item in list.split(' ')|unique %}
{{ item }}
{% endfor %}
{% else %}
{% set list = list + " " %}{% endif %}
{% endif %}
{% endfor %}

Dies ist vielleicht nicht der beste Weg, dies zu tun, aber hier verstoße ich meines Wissens gegen keine Scoping-Regeln.

Hatte dieses Problem in 2.8 und höher

Hier geht es zu einem Testfall:

import unittest
from jinja2 import Template

TEMPLATE1 = """{% set a = 1 %}{% for i in items %}{{a}},{% set a = a + 1 %}{% endfor %}"""

class TestTemplate(unittest.TestCase):

  def test_increment(self):
    items = xrange(1,10)
    expected='%s,' % ','.join([str(i) for i in items])
    t = Template(TEMPLATE1)
    result = t.render(items=items)
    self.assertEqual(expected,result)

unittest.main()

Verwenden Sie stattdessen loop.index .

Ich denke, der Zugriff auf den vorherigen Schleifenwert über ein Attribut des loop Objekts ist die einzige gute Lösung dafür. Ich habe gerade diesen Ausschnitt in unserem Projekt entdeckt, der nicht gelöst werden konnte, indem man einfach prüfte, ob sich das letzte Objekt vom aktuellen unterscheidet und groupby dort auch nicht funktioniert, da es mehr als nur ein trivialer Item- / Attributzugriff ist, um den Schlüssel zu erhalten :

{% set previous_date = none %}
{% for item in entries -%}
    {% set date = item.start_dt.astimezone(tz_object).date() %}
    {% if previous_date and previous_date != date -%}
        ...
    {% endif %}
    {% set previous_date = date %}
{%- endfor %}

Ja, das klingt nach einer Idee.

Wie wäre es mit dem Hinzufügen von set(key, value) und get(key) Methoden zum Schleifenobjekt? Dann können die Leute in der Schleife speichern, was sie wollen.

Hatte die gleiche Idee, konnte dann aber keine nicht hässlichen Fälle finden, in denen dies erforderlich wäre. Und ich konnte schon sehen, wie jemand nach setdefault , pop und anderen dict-ähnlichen Methoden fragte.

@davidism @ThiefMaster Ich dachte daran, nur ein Speicherobjekt zur Verfügung zu haben. So was:

{% set ns = namespace() %}
{% set ns.value = 42 %}
...{% set ns.value = 23 %}

Offensichtlich kann set im Moment keine Attribute setzen, aber dies könnte leicht erweitert werden. Da keine Neuzuweisung an den Namespace selbst erfolgt, ist dies ziemlich sicher zu implementieren.

Scheint mir in Ordnung zu sein, es ist die gleiche Lösung wie nonlocal für Py 2. Alternativ können Sie automatisch loop.ns einrichten, obwohl dies außerhalb der Schleife nicht verfügbar wäre.

Was ich am Namensraum nicht mag, ist, dass es sehr verlockend ist, {% set obj.attr = 42 %} mit obj zu tun, das kein namespace() - etwas, das meiner Meinung nach nicht funktionieren sollte .

Ansonsten sieht es nach einer interessanten Idee aus, obwohl ich denke, dass previtem / nextitem / changed() "einfache" Fälle gut abdecken, ohne den "Lärm", ein neues Objekt definieren zu müssen in der Vorlage.

@ThiefMaster es würde nicht funktionieren. Ich würde dies so sehen, dass Attributzuweisungen einen Rückruf in der Umgebung durchlaufen, der nur Änderungen an Namespace-Objekten zulassen würde.

ok, also zumindest kein Risiko, dass Vorlagen unerwartete Nebenwirkungen auf an sie übergebene Objekte verursachen.

immer noch ein bisschen misstrauisch gegenüber den Dingen, die die Leute tun könnten...

{% macro do_stuff(ns) %}
    {% set ns.foo %}bar{% endset %}
    {% set ns.bar %}foobar{% endset %}
{% endmacro %}

{% set ns = namespace() %}
{{ do_stuff(ns) }}

Eigentlich denke ich, dass es besser wäre, einen neuen Block wie {% namespace ns %} zu definieren als einen aufrufbaren - eine Variable namens namespace klingt nicht nach etwas, das sehr unwahrscheinlich an eine Vorlage übergeben wird, und während es würde Sie wahrscheinlich einfach daran hindern, die Namespace-Funktion in dieser Vorlage zu verwenden (genau wie das Shadowing eines eingebauten in Python). Es fühlt sich ein bisschen schmutzig an ...

Haben Sie einen Workaround für dieses Problem oder müssen wir in 2.9.6 auf previtem/nextitem warten?
Einige meiner Saltstack-Vorlagen sind jetzt kaputt.

Wie oben in unterschiedlichem Maße gezeigt wurde, müssen Sie möglicherweise nicht einmal tun, was Sie tun. Andernfalls müssen Sie warten, wenn Sie 2.9 verwenden möchten. Es wurde noch nie zuvor unterstützt, es hat einfach funktioniert.

Wir werden nicht zum alten Verhalten zurückkehren. Obwohl es in einfachen Fällen funktionierte, war es nicht korrekt und wurde nie als unterstützt dokumentiert. Obwohl ich verstehe, dass es sich um eine bahnbrechende Änderung handelt, trat sie in einem Feature-Release (zweite Nummernänderung) auf, so dass wir diese Änderungen immer gehandhabt haben. Fixieren Sie die Version, bis ein Fix veröffentlicht wird, wenn Sie sich weiterhin auf das alte Verhalten verlassen müssen.

Sperren, weil alles gesagt wurde, was gesagt werden muss. Siehe #676 und #684 für die Fixes, die derzeit in Betracht gezogen werden.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen