PrimeIntellect/SWE-rebench-V2-Filtered-Easy-Verified huggingface dataset:
Repository: Kozea/WeasyPrint (python)
Issue: Bug with columns
I've noticed that sometimes splitting into columns are incorrect. Here is a way that may reproduce it. You may need it few times to notice a bug.

```python
import random
import string
from weasyprint import HTML

h = f"""
<html><body>"""

text = ''

# prefill
for _ in range(60):
    text += ' ' + random.choice(string.ascii_letters) * random.randint(10,20)

# growing text with different words. Maybe it will create the `bad` one.
for p in range(20):
    word_length = random.randint(10, 15)
    text += ' ' + random.choice(string.ascii_letters) * word_length
    h += "<div style='columns: 2; page-break-before: always; '><p>"
    s = str(p) + ' --- ' + text
    h += s
    h += "</p></div>"
h += "</body></html>"
print(h)
doc = HTML(string=h).render()
doc.write_pdf('two.pdf')

```
Here is an example output with problem.
![image](https://user-images.githubusercontent.com/4893428/229906578-7091d42d-9f7c-451a-82fc-20b13bc9607b.png)
In this case the problem is on pages 9 and 10. There is only one narrow column.

It happen only when text fully fit in one column and reaches page bottom. If there is less or more text, then everything ok.

Also it never happens on first page. Looks like `page-break-before` somehow involved.


Pull request description: Ignore last child’s bottom margin in columns
Fix #1856.

Patch:
diff --git a/weasyprint/layout/column.py b/weasyprint/layout/column.py
index 691ba8cb..375141f8 100644
--- a/weasyprint/layout/column.py
+++ b/weasyprint/layout/column.py
@@ -190,6 +190,7 @@ def columns_layout(context, box, bottom_space, skip_stack, containing_block,
                         in_flow_children[-1].margin_height() +
                         in_flow_children[-1].position_y - current_position_y)
                     empty_space = height - consumed_height
+                    consumed_height -= in_flow_children[-1].margin_bottom
 
                     # Get the minimum size needed to render the next box
                     if column_skip_stack:


Test patch:
diff --git a/tests/layout/test_column.py b/tests/layout/test_column.py
index 4bee7b57..c61192ea 100644
--- a/tests/layout/test_column.py
+++ b/tests/layout/test_column.py
@@ -834,6 +834,30 @@ def test_columns_padding():
     assert [column.position_y for column in columns] == [1, 1, 1]
 
 
+@assert_no_logs
+def test_columns_bottom_margin():
+    page, = render_pages('''
+      <style>
+        div { columns: 2; column-gap: 1px }
+        body { margin: 0; font: 2px / 1 weasyprint }
+        p { margin-bottom: 1em }
+        @page { margin: 0; size: 5px 7px; font-size: 1px }
+      </style>
+      <div><p>a b c</p></div>
+    ''')
+    html, = page.children
+    body, = html.children
+    div, = body.children
+    column1, column2 = div.children
+    p, = column1.children
+    line1, line2 = p.children
+    assert line1.children[0].text == 'a'
+    assert line2.children[0].text == 'b'
+    p, = column2.children
+    line1, = p.children
+    assert line1.children[0].text == 'c'
+
+
 @assert_no_logs
 def test_columns_relative():
     page, = render_pages('''