Jinja: lstrip_blocks tidak menyimpan ruang sebelum blok akhir pada baris yang sama

Dibuat pada 29 Jan 2020  ·  13Komentar  ·  Sumber: pallets/jinja

Lihat kode template berikut:

set_property verilog_define {
  {%- for k, v in vlogdefine.items() %}{{ k }}={{ v|param_value_str }} {% endfor -%}
  } [get_filesets sources_1]

https://github.com/olofk/edalize/blob/bdb6c9ccc666e9f60333279ad53ed09cda88b3dc/edalize/templates/vivado/vivado-project.tcl.j2#L27 -L29

Hingga Jinja2 2.10.3 ini akan menghasilkan sesuatu seperti

set_property verilog_define {vlogdefine_bool=1 vlogdefine_int=42 vlogdefine_str=hello } [get_filesets sources_1]

https://github.com/olofk/edalize/blob/bdb6c9ccc666e9f60333279ad53ed09cda88b3dc/tests/test_vivado/test_vivado_0.tcl#L10

Kode memiliki lstrip_blocks = True .

Sekarang dengan 2.11.0 kode tersebut dirender seperti ini:

set_property verilog_define {vlogdefine_bool=1vlogdefine_int=42vlogdefine_str=hello} [get_filesets sources_1]

@towoe membagi dua perubahan perilaku ke https://github.com/pallets/jinja/commit/7d00a40465c89bee141ab5a3db545a20e7d30509 (oleh @ petee-d di https://github.com/pallets/jinja/issues/857)

Menurut dokumentasi

lstrip_blocks
Jika ini disetel ke True, spasi dan tab akan dilucuti dari awal baris ke blok. Default-nya adalah False.

Saya tidak berpikir spasi harus dihapus sebelum endfor , karena itu bukan spasi "dari awal baris". Apakah saya salah paham, atau apakah versi baru memperkenalkan perubahan perilaku yang tidak terduga?

Python 3.7.3 (tetapi juga terjadi pada 3.5 di CI)

bug

Komentar yang paling membantu

Baru saja merilis 2.11.2 dengan ini.

Semua 13 komentar

Saya akan memeriksanya, maaf atas penyebab sesi debug membingungkan yang Anda tautkan! Pada pandangan pertama, sepertinya perilakunya lebih konsisten sekarang, dan kami tidak melakukan pengujian untuk tingkah laku sebelumnya, tapi saya harus memeriksanya. Mungkinkah Anda menggunakan {%+ endfor -%} untuk secara eksplisit mendeklarasikan pelestarian spasi?

@vidisme terima kasih telah melihatnya.

Ya, kita dapat membuat perubahan pada edalize (perpustakaan tempat Jinja digunakan) dengan berbagai cara (tambahkan + , alihkan ke lstrip_blocks = False , dll.), Tetapi saya ingin memastikan terlebih dahulu bahwa kita memiliki pemahaman bersama tentang perilaku yang diharapkan.

Ini juga memengaruhi saya dengan cara yang sama seperti poster asli. Dokumentasi tampak cukup jelas bagi saya bahwa perilaku 2.11 salah. Dari https://github.com/pallets/jinja/blob/2.11.x/docs/templates.rst#whitespace -control:

(Tidak ada yang akan dihapus jika ada karakter lain sebelum blok dimulai.)

Ini karena # 858, yang memperbaiki masalah kecepatan yang cukup besar dengan ruang parsing. Saya baik-baik saja dengan memperbaiki masalah yang disebabkannya, tetapi saya tidak ingin mengembalikan perubahan itu begitu saja. Jika ada yang ingin bermain-main dengan regex di lexer dan memperbaikinya, saya akan dengan senang hati memeriksanya.

Maaf tentang perbaikan yang melanggar perilaku yang dimaksudkan dari lstrip_blocks, saya ingat saya agak bingung tentang apa sebenarnya yang harus dilakukan dan tidak dapat menemukan dokumentasi yang tepat untuk itu. Saya tidak yakin mengapa Google tidak membawa saya ke bagian dokumen yang ditautkan oleh @kenyon , sangat aneh. Jadi saya akhirnya mencari tahu perilaku yang diinginkan dari tes dan implementasi dan tampaknya melewatkan ini.

Seperti yang dikatakan @davidism , mengembalikan perbaikan akan menyebabkan masalah lain sehingga perbaikan baru perlu dirancang. Saya akan mencoba menyediakan waktu untuk itu minggu ini.

from jinja2 import Template

t = Template(
    "{% if x %}{{ x }} {% endif %}y",
    lstrip_blocks=True,
)
out = t.render(x="x")
assert out == "x y"

https://github.com/pallets/jinja/blob/547e6e39ec3994c9dd0c806ee7bb29353843060e/src/jinja2/lexer.py#L721 -L735

Inilah masalahnya. Saat template ini sedang diberi token, find("\n") diberikan teks yang hanya berisi spasi antara {{ x }} dan {% endif %} , tidak melihat baris baru, lalu strip dari awal teks.

Menambahkan "\n" in text ke elif membuat banyak pengujian gagal karena baris pertama template tidak berisi baris baru tetapi harus dihilangkan jika hanya memiliki spasi. Jika kita menjadi sedikit lebih pintar dan melacak apakah kita berada di baris pertama, masih gagal jika trim_blocks juga diaktifkan karena menghapus baris baru sebagai bagian dari regex.

Tampaknya juga perilaku {%- raw %} {% endraw -%} terpengaruh. Sebelum 2.11.0 ini akan memaksa spasi di tempat ini. Sekarang ruang ini dihapus.

from jinja2 import Template

t = Template(
    "{{x}}\n{%- raw %} {% endraw -%}\n{{ y }}",
    lstrip_blocks=True,
)
out = t.render(x="x", y="y")
assert out == "x y"

@ petee-d ada kemungkinan Anda punya waktu untuk melihat ini lagi? Saya akan mengembalikannya ke 2.11.2 jika tidak.

Aduh, benar-benar lupakan tentang ini. Akan mencoba untuk benar-benar meluangkan waktu minggu ini, jika tidak mengembalikannya jika efek sampingnya seburuk kelihatannya.

Rencana tentatif saya adalah rilis pada hari Sabtu. Beri tahu saya jika Anda sedang mengerjakannya, saya dapat mendorongnya kembali jika demikian.

Saya pikir saya punya perbaikan. Saya mencoba untuk tidak terpengaruh dalam perbaikan saya oleh komentar Anda sebelumnya @davidisme , namun masih sampai pada solusi yang sama dengan yang Anda coba, hanya melangkah lebih jauh.

Pertama-tama, saya pikir saya awalnya bermaksud agar perbaikan saya berperilaku berbeda jika l_pos = text.rfind("\n") + 1 tidak menemukan karakter baris baru tetapi kemudian melupakannya. Jadi saya tidak lagi melakukan stripping jika tidak ada baris baru di text . Kemudian saya juga mencoba memecahkan masalah dengan baris pertama source perlu dihilangkan, tetapi alih-alih menggunakan or pos == 0 , saya menggunakan bendera line_starting boolean yang diinisialisasi di True. Kemudian saya hanya mengatur bendera ini setelah memproses setiap token berdasarkan apakah string yang cocok diakhiri dengan baris baru dan itu juga menyelesaikan masalah trim_blocks. Lihat perbaikan di # 1183.

Rangkaian pengujian saat ini berlalu, besok saya juga akan menambahkan pengujian baru untuk kasus dalam masalah ini dan lainnya yang dapat saya pikirkan. Saya juga akan menjalankan versi asli, perbaikan pertama dan perbaikan kedua tentang kumpulan template buatan pengguna 5GB yang baru saya kumpulkan yang saya kumpulkan dari proyek saya, bandingkan pohon parse dan kinerja.

Tes menambahkan, tes kinerja tidak menunjukkan degradasi, jadi itu dilakukan dari sisi saya. :)

Baru saja merilis 2.11.2 dengan ini.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat