Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-agate for openSUSE:Factory 
checked in at 2026-03-23 17:14:49
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-agate (Old)
 and      /work/SRC/openSUSE:Factory/.python-agate.new.8177 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-agate"

Mon Mar 23 17:14:49 2026 rev:22 rq:1341750 version:1.14.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-agate/python-agate.changes        
2025-07-14 10:57:12.714335678 +0200
+++ /work/SRC/openSUSE:Factory/.python-agate.new.8177/python-agate.changes      
2026-03-23 17:17:02.634846780 +0100
@@ -1,0 +2,12 @@
+Sat Mar 14 21:42:10 UTC 2026 - Dirk Müller <[email protected]>
+
+- update to 1.14.2:
+  * fix: :meth:`.Table.from_csv` on empty CSV.
+  * fix: :meth:`.Table.join` was joining incorrectly when
+    full_outer=True and left_key and right_key were sequences.
+  * fix: :meth:`.Table.print_table` replaces newlines with ↵ to
+    avoid broken output.
+  * Add Python 3.13 and 3.14 support. Drop support for end-of-
+    life versions 3.8 and 3.9.
+
+-------------------------------------------------------------------

Old:
----
  agate-1.13.0.tar.gz

New:
----
  agate-1.14.2.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-agate.spec ++++++
--- /var/tmp/diff_new_pack.1rbhbB/_old  2026-03-23 17:17:04.654930794 +0100
+++ /var/tmp/diff_new_pack.1rbhbB/_new  2026-03-23 17:17:04.666931293 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package python-agate
 #
-# Copyright (c) 2025 SUSE LLC
+# Copyright (c) 2026 SUSE LLC and contributors
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -17,7 +17,7 @@
 
 
 Name:           python-agate
-Version:        1.13.0
+Version:        1.14.2
 Release:        0
 Summary:        Data analysis library optimized for humans instead of machines
 License:        MIT

++++++ agate-1.13.0.tar.gz -> agate-1.14.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agate-1.13.0/.github/workflows/automerge.yml 
new/agate-1.14.2/.github/workflows/automerge.yml
--- old/agate-1.13.0/.github/workflows/automerge.yml    1970-01-01 
01:00:00.000000000 +0100
+++ new/agate-1.14.2/.github/workflows/automerge.yml    2026-02-27 
17:33:42.000000000 +0100
@@ -0,0 +1,9 @@
+name: Auto-merge
+on: pull_request_target
+jobs:
+  automerge:
+    uses: open-contracting/.github/.github/workflows/automerge.yml@main
+    permissions:
+      actions: write
+      contents: write
+      pull-requests: write
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agate-1.13.0/.github/workflows/ci.yml 
new/agate-1.14.2/.github/workflows/ci.yml
--- old/agate-1.13.0/.github/workflows/ci.yml   2025-01-29 07:21:29.000000000 
+0100
+++ new/agate-1.14.2/.github/workflows/ci.yml   2026-02-27 17:33:42.000000000 
+0100
@@ -7,25 +7,24 @@
     strategy:
       matrix:
         os: [macos-latest, windows-latest, ubuntu-latest]
-        python-version: [3.8, 3.9, '3.10', '3.11', '3.12', pypy-3.9]
+        python-version: ['3.10', '3.11', '3.12', '3.13', '3.14', pypy-3.11]
     steps:
       - if: matrix.os == 'ubuntu-latest'
         name: Install UTF-8 locales and lxml requirements
         run: |
+          sudo apt update
           sudo apt install libxml2-dev libxslt-dev
           sudo locale-gen de_DE.UTF-8
           sudo locale-gen en_US.UTF-8
           sudo locale-gen ko_KR.UTF-8
           sudo update-locale
-      - uses: actions/checkout@v4
-      - uses: actions/setup-python@v5
+      - uses: actions/checkout@v6
+      - uses: actions/setup-python@v6
         with:
           python-version: ${{ matrix.python-version }}
           cache: pip
-          cache-dependency-path: setup.py
-      - run: pip install .[test] coveralls
-      - if: matrix.python-version == '3.8'
-        run: pip install 'lxml<5'
+          cache-dependency-path: pyproject.toml
+      - run: pip install .[test]
       - env:
           LANG: en_US.UTF-8
           PYTHONIOENCODING: utf-8
@@ -37,6 +36,6 @@
       - name: Read from pipe
         run: printf 'a,b,c\n1,2,3' | python -c 'import sys; import agate; 
agate.Table.from_csv(sys.stdin, sniff_limit=1)'
       - run: python charts.py
-      - env:
-          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-        run: coveralls --service=github
+      - uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 
# v5.5.1
+        with:
+          fail_ci_if_error: true
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agate-1.13.0/.github/workflows/lint.yml 
new/agate-1.14.2/.github/workflows/lint.yml
--- old/agate-1.13.0/.github/workflows/lint.yml 2025-01-29 07:21:29.000000000 
+0100
+++ new/agate-1.14.2/.github/workflows/lint.yml 2026-02-27 17:33:42.000000000 
+0100
@@ -5,12 +5,12 @@
     if: github.event_name == 'push' || 
github.event.pull_request.head.repo.full_name != github.repository
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@v4
-      - uses: actions/setup-python@v5
+      - uses: actions/checkout@v6
+      - uses: actions/setup-python@v6
         with:
           python-version: '3.10'
           cache: pip
-          cache-dependency-path: setup.py
+          cache-dependency-path: pyproject.toml
       - run: pip install --upgrade check-manifest flake8 isort setuptools
       - run: check-manifest
       - run: flake8 .
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agate-1.13.0/.github/workflows/pypi.yml 
new/agate-1.14.2/.github/workflows/pypi.yml
--- old/agate-1.13.0/.github/workflows/pypi.yml 2025-01-29 07:21:29.000000000 
+0100
+++ new/agate-1.14.2/.github/workflows/pypi.yml 2026-02-27 17:33:42.000000000 
+0100
@@ -4,13 +4,13 @@
   build:
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@v4
-      - uses: actions/setup-python@v5
+      - uses: actions/checkout@v6
+      - uses: actions/setup-python@v6
         with:
           python-version: '3.10'
       - run: pip install --upgrade build
       - run: python -m build --sdist --wheel
-      - uses: actions/upload-artifact@v4
+      - uses: actions/upload-artifact@v7
         with:
           name: python-package-distributions
           path: dist/
@@ -20,7 +20,7 @@
       id-token: write
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/download-artifact@v4
+      - uses: actions/download-artifact@v8
         with:
           name: python-package-distributions
           path: dist/
@@ -35,7 +35,7 @@
       id-token: write
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/download-artifact@v4
+      - uses: actions/download-artifact@v8
         with:
           name: python-package-distributions
           path: dist/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agate-1.13.0/.pre-commit-config.yaml 
new/agate-1.14.2/.pre-commit-config.yaml
--- old/agate-1.13.0/.pre-commit-config.yaml    2025-01-29 07:21:29.000000000 
+0100
+++ new/agate-1.14.2/.pre-commit-config.yaml    2026-02-27 17:33:42.000000000 
+0100
@@ -1,10 +1,10 @@
 repos:
   - repo: https://github.com/pycqa/flake8
-    rev: 3.9.2
+    rev: 7.1.2
     hooks:
       - id: flake8
   - repo: https://github.com/pycqa/isort
-    rev: 5.8.0
+    rev: 6.0.1
     hooks:
       - id: isort
   - repo: https://github.com/mgedmin/check-manifest
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agate-1.13.0/.readthedocs.yaml 
new/agate-1.14.2/.readthedocs.yaml
--- old/agate-1.13.0/.readthedocs.yaml  2025-01-29 07:21:29.000000000 +0100
+++ new/agate-1.14.2/.readthedocs.yaml  2026-02-27 17:33:42.000000000 +0100
@@ -1,11 +1,12 @@
 version: 2
 build:
-  os: ubuntu-20.04
+  os: ubuntu-lts-latest
   tools:
-    python: "3.9"
+    python: "3"
 python:
   install:
     - path: .
     - requirements: docs/requirements.txt
 sphinx:
+  configuration: docs/conf.py
   fail_on_warning: true
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agate-1.13.0/AUTHORS.rst new/agate-1.14.2/AUTHORS.rst
--- old/agate-1.13.0/AUTHORS.rst        2025-01-29 07:21:29.000000000 +0100
+++ new/agate-1.14.2/AUTHORS.rst        2026-02-27 17:33:42.000000000 +0100
@@ -48,3 +48,6 @@
 * `castorf <https://github.com/castorf>`_
 * `Julien Enselme <https://github.com/Jenselme>`__
 * `Scott Gigante <https://github.com/scottgigante>`__
+* `John Paul Martyn <https://github.com/catowhee>`__
+* `Michał Górny <https://github.com/mgorny>`__
+* `Karthik Ramadugu <https://github.com/karthiksai109>`__
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agate-1.13.0/CHANGELOG.rst 
new/agate-1.14.2/CHANGELOG.rst
--- old/agate-1.13.0/CHANGELOG.rst      2025-01-29 07:21:29.000000000 +0100
+++ new/agate-1.14.2/CHANGELOG.rst      2026-02-27 17:33:42.000000000 +0100
@@ -1,5 +1,21 @@
-1.13.0 - Jan 29, 2025
----------------------
+1.14.2 - February 27, 2026
+--------------------------
+
+- fix: :meth:`.Table.from_csv` on empty CSV.
+
+1.14.1 - January 15, 2026
+-------------------------
+
+- fix: :meth:`.Table.join` was joining incorrectly when ``full_outer=True`` 
and ``left_key`` and ``right_key`` were sequences.
+
+1.14.0 - December 15, 2025
+--------------------------
+
+- fix: :meth:`.Table.print_table` replaces newlines with ``↵`` to avoid broken 
output.
+- Add Python 3.13 and 3.14 support. Drop support for end-of-life versions 3.8 
and 3.9.
+
+1.13.0 - January 29, 2025
+-------------------------
 
 - fix: :meth:`.Table.order_by` sorts None as equal to None.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agate-1.13.0/README.rst new/agate-1.14.2/README.rst
--- old/agate-1.13.0/README.rst 2025-01-29 07:21:29.000000000 +0100
+++ new/agate-1.14.2/README.rst 2026-02-27 17:33:42.000000000 +0100
@@ -2,8 +2,8 @@
     :target: https://github.com/wireservice/agate/actions
     :alt: Build status
 
-.. image:: https://coveralls.io/repos/wireservice/agate/badge.svg?branch=master
-    :target: https://coveralls.io/r/wireservice/agate
+.. image:: https://codecov.io/github/wireservice/agate/graph/badge.svg
+    :target: https://codecov.io/github/wireservice/agate
     :alt: Coverage status
 
 .. image:: https://img.shields.io/pypi/dm/agate.svg
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agate-1.13.0/agate/table/from_csv.py 
new/agate-1.14.2/agate/table/from_csv.py
--- old/agate-1.13.0/agate/table/from_csv.py    2025-01-29 07:21:29.000000000 
+0100
+++ new/agate-1.14.2/agate/table/from_csv.py    2026-02-27 17:33:42.000000000 
+0100
@@ -86,9 +86,15 @@
 
         if header:
             if column_names is None:
-                column_names = next(reader)
+                try:
+                    column_names = next(reader)
+                except StopIteration:
+                    column_names = []
             else:
-                next(reader)
+                try:
+                    next(reader)
+                except StopIteration:
+                    pass
 
         if row_limit is None:
             rows = reader
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agate-1.13.0/agate/table/join.py 
new/agate-1.14.2/agate/table/join.py
--- old/agate-1.13.0/agate/table/join.py        2025-01-29 07:21:29.000000000 
+0100
+++ new/agate-1.14.2/agate/table/join.py        2026-02-27 17:33:42.000000000 
+0100
@@ -94,7 +94,7 @@
     # Left key is a sequence
     elif left_key_is_sequence:
         left_columns = [self._columns[key] for key in left_key]
-        left_data = zip(*[column.values() for column in left_columns])
+        left_data = list(zip(*[column.values() for column in left_columns]))
     # Left key is a column name/index
     else:
         left_data = self._columns[left_key].values()
@@ -111,7 +111,7 @@
     # Right key is a sequence
     elif right_key_is_sequence:
         right_columns = [right_table._columns[key] for key in right_key]
-        right_data = zip(*[column.values() for column in right_columns])
+        right_data = list(zip(*[column.values() for column in right_columns]))
         right_key_indices = [right_table._columns._keys.index(key) for key in 
right_key]
     # Right key is a column name/index
     else:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agate-1.13.0/agate/table/print_html.py 
new/agate-1.14.2/agate/table/print_html.py
--- old/agate-1.13.0/agate/table/print_html.py  2025-01-29 07:21:29.000000000 
+0100
+++ new/agate-1.14.2/agate/table/print_html.py  2026-02-27 17:33:42.000000000 
+0100
@@ -95,7 +95,7 @@
                 v = str(v)
 
             if max_column_width is not None and len(v) > max_column_width:
-                v = '%s%s' % (v[:max_column_width - len_truncation], 
truncation)
+                v = '{}{}'.format(v[:max_column_width - len_truncation], 
truncation)
 
             formatted_row.append(v)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agate-1.13.0/agate/table/print_table.py 
new/agate-1.14.2/agate/table/print_table.py
--- old/agate-1.13.0/agate/table/print_table.py 2025-01-29 07:21:29.000000000 
+0100
+++ new/agate-1.14.2/agate/table/print_table.py 2026-02-27 17:33:42.000000000 
+0100
@@ -56,7 +56,7 @@
     column_names = []
     for column_name in self.column_names[:max_columns]:
         if max_column_width is not None and len(column_name) > 
max_column_width:
-            column_names.append('%s%s' % (column_name[:max_column_width - 
len_truncation], truncation))
+            column_names.append('{}{}'.format(column_name[:max_column_width - 
len_truncation], truncation))
         else:
             column_names.append(column_name)
 
@@ -101,10 +101,10 @@
                     locale=locale
                 )
             else:
-                v = str(v)
+                v = str(v).replace('\n', '↵')
 
             if max_column_width is not None and len(v) > max_column_width:
-                v = '%s%s' % (v[:max_column_width - len_truncation], 
truncation)
+                v = '{}{}'.format(v[:max_column_width - len_truncation], 
truncation)
 
             if len(v) > widths[j]:
                 widths[j] = len(v)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agate-1.13.0/docs/conf.py 
new/agate-1.14.2/docs/conf.py
--- old/agate-1.13.0/docs/conf.py       2025-01-29 07:21:29.000000000 +0100
+++ new/agate-1.14.2/docs/conf.py       2026-02-27 17:33:42.000000000 +0100
@@ -12,7 +12,7 @@
 
 project = 'agate'
 copyright = '2017, Christopher Groskopf'
-version = '1.13.0'
+version = '1.14.2'
 release = version
 
 # -- General configuration ---------------------------------------------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agate-1.13.0/docs/cookbook/datetime.rst 
new/agate-1.14.2/docs/cookbook/datetime.rst
--- old/agate-1.13.0/docs/cookbook/datetime.rst 2025-01-29 07:21:29.000000000 
+0100
+++ new/agate-1.14.2/docs/cookbook/datetime.rst 2026-02-27 17:33:42.000000000 
+0100
@@ -34,11 +34,7 @@
 
 .. code-block:: python
 
-    try:
-        from zoneinfo import ZoneInfo
-    except ImportError:
-        # Fallback for Python < 3.9
-        from backports.zoneinfo import ZoneInfo
+    from zoneinfo import ZoneInfo
 
     eastern = ZoneInfo('US/Eastern')
     datetime_type = agate.DateTime(timezone=eastern)
@@ -64,11 +60,7 @@
 
 .. code-block:: python
 
-    try:
-        from zoneinfo import ZoneInfo
-    except ImportError:
-        # Fallback for Python < 3.9
-        from backports.zoneinfo import ZoneInfo
+    from zoneinfo import ZoneInfo
 
     us_eastern = ZoneInfo('US/Eastern')
     datetime_type = agate.DateTime(timezone=us_eastern)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agate-1.13.0/docs/install.rst 
new/agate-1.14.2/docs/install.rst
--- old/agate-1.13.0/docs/install.rst   2025-01-29 07:21:29.000000000 +0100
+++ new/agate-1.14.2/docs/install.rst   2026-02-27 17:33:42.000000000 +0100
@@ -22,8 +22,6 @@
 
     pip install -e .[test]
 
-    python setup.py develop
-
 .. note::
 
     To run the agate tests with coverage::
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agate-1.13.0/docs/release_process.rst 
new/agate-1.14.2/docs/release_process.rst
--- old/agate-1.13.0/docs/release_process.rst   2025-01-29 07:21:29.000000000 
+0100
+++ new/agate-1.14.2/docs/release_process.rst   2026-02-27 17:33:42.000000000 
+0100
@@ -4,7 +4,6 @@
 
 If substantial changes were made to the code:
 
-#. Ensure any new modules have been added to setup.py's ``packages`` list
 #. Ensure any new public interfaces have been added to the documentation
 #. Ensure TableSet proxy methods have been added for new Table methods
 
@@ -14,7 +13,7 @@
 #. The changelog is up-to-date and dated
 #. The version number is correct in:
 
-   -  setup.py
+   -  pyproject.toml
    -  docs/conf.py
 
 #. Check for new authors:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agate-1.13.0/pyproject.toml 
new/agate-1.14.2/pyproject.toml
--- old/agate-1.13.0/pyproject.toml     1970-01-01 01:00:00.000000000 +0100
+++ new/agate-1.14.2/pyproject.toml     2026-02-27 17:33:42.000000000 +0100
@@ -0,0 +1,55 @@
+[build-system]
+requires = ["setuptools>=61"]
+build-backend = "setuptools.build_meta"
+
+[project]
+name = "agate"
+version = "1.14.2"
+authors = [{name = "Christopher Groskopf", email = "[email protected]"}]
+description = "A data analysis library that is optimized for humans instead of 
machines."
+readme = "README.rst"
+license = {text = "MIT"}
+urls = {Homepage = "https://agate.readthedocs.org/";, Source = 
"https://github.com/wireservice/agate"}
+classifiers = [
+    "Development Status :: 5 - Production/Stable",
+    "Framework :: IPython",
+    "Intended Audience :: Developers",
+    "Intended Audience :: Science/Research",
+    "License :: OSI Approved :: MIT License",
+    "Natural Language :: English",
+    "Operating System :: OS Independent",
+    "Programming Language :: Python",
+    "Programming Language :: Python :: 3.10",
+    "Programming Language :: Python :: 3.11",
+    "Programming Language :: Python :: 3.12",
+    "Programming Language :: Python :: 3.13",
+    "Programming Language :: Python :: 3.14",
+    "Programming Language :: Python :: Implementation :: CPython",
+    "Programming Language :: Python :: Implementation :: PyPy",
+    "Topic :: Scientific/Engineering :: Information Analysis",
+    "Topic :: Software Development :: Libraries :: Python Modules",
+]
+dependencies = [
+    "Babel>=2.0",
+    "isodate>=0.5.4",
+    "leather>=0.3.2",
+    # KeyError: 's' https://github.com/bear/parsedatetime/pull/233 
https://github.com/wireservice/agate/issues/743
+    "parsedatetime>=2.1,!=2.5",
+    "python-slugify>=1.2.1",
+    "pytimeparse>=1.1.5",
+    "tzdata>=2023.3;platform_system=='Windows'",
+]
+
+[project.optional-dependencies]
+test = [
+    "coverage>=3.7.1",
+    "cssselect>=0.9.1",
+    "lxml>=3.6.0",
+    # CI is not configured to install PyICU on macOS and Windows.
+    "PyICU>=2.4.2;sys_platform=='linux'",
+    "pytest",
+    "pytest-cov",
+]
+
+[tool.isort]
+line_length = 119
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agate-1.13.0/setup.cfg new/agate-1.14.2/setup.cfg
--- old/agate-1.13.0/setup.cfg  2025-01-29 07:21:29.000000000 +0100
+++ new/agate-1.14.2/setup.cfg  2026-02-27 17:33:42.000000000 +0100
@@ -9,9 +9,3 @@
     # module level import not at top of file
     agate/tableset/__init__.py: E402
     agate/table/__init__.py: E402
-
-[isort]
-line_length = 119
-
-[bdist_wheel]
-universal = 1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agate-1.13.0/setup.py new/agate-1.14.2/setup.py
--- old/agate-1.13.0/setup.py   2025-01-29 07:21:29.000000000 +0100
+++ new/agate-1.14.2/setup.py   1970-01-01 01:00:00.000000000 +0100
@@ -1,61 +0,0 @@
-from setuptools import find_packages, setup
-
-with open('README.rst') as f:
-    long_description = f.read()
-
-setup(
-    name='agate',
-    version='1.13.0',
-    description='A data analysis library that is optimized for humans instead 
of machines.',
-    long_description=long_description,
-    long_description_content_type='text/x-rst',
-    author='Christopher Groskopf',
-    author_email='[email protected]',
-    url='https://agate.readthedocs.org/',
-    project_urls={
-        'Source': 'https://github.com/wireservice/agate',
-    },
-    license='MIT',
-    classifiers=[
-        'Development Status :: 5 - Production/Stable',
-        'Framework :: IPython',
-        'Intended Audience :: Developers',
-        'Intended Audience :: Science/Research',
-        'License :: OSI Approved :: MIT License',
-        'Natural Language :: English',
-        'Operating System :: OS Independent',
-        'Programming Language :: Python',
-        'Programming Language :: Python :: 3.8',
-        'Programming Language :: Python :: 3.9',
-        'Programming Language :: Python :: 3.10',
-        'Programming Language :: Python :: 3.11',
-        'Programming Language :: Python :: 3.12',
-        'Programming Language :: Python :: Implementation :: CPython',
-        'Programming Language :: Python :: Implementation :: PyPy',
-        'Topic :: Scientific/Engineering :: Information Analysis',
-        'Topic :: Software Development :: Libraries :: Python Modules',
-    ],
-    packages=find_packages(exclude=['benchmarks', 'tests', 'tests.*']),
-    install_requires=[
-        'Babel>=2.0',
-        'isodate>=0.5.4',
-        'leather>=0.3.2',
-        # KeyError: 's' https://github.com/bear/parsedatetime/pull/233 
https://github.com/wireservice/agate/issues/743
-        'parsedatetime>=2.1,!=2.5',
-        'python-slugify>=1.2.1',
-        'pytimeparse>=1.1.5',
-        'tzdata>=2023.3;platform_system=="Windows"',
-    ],
-    extras_require={
-        'test': [
-            'coverage>=3.7.1',
-            'cssselect>=0.9.1',
-            'lxml>=3.6.0',
-            # CI is not configured to install PyICU on macOS and Windows.
-            'PyICU>=2.4.2;sys_platform=="linux"',
-            'pytest',
-            'pytest-cov',
-            'backports.zoneinfo;python_version<"3.9"',
-        ],
-    }
-)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agate-1.13.0/tests/test_data_types.py 
new/agate-1.14.2/tests/test_data_types.py
--- old/agate-1.13.0/tests/test_data_types.py   2025-01-29 07:21:29.000000000 
+0100
+++ new/agate-1.14.2/tests/test_data_types.py   2026-02-27 17:33:42.000000000 
+0100
@@ -2,15 +2,10 @@
 import pickle
 import unittest
 from decimal import Decimal
+from zoneinfo import ZoneInfo
 
 import parsedatetime
 
-try:
-    from zoneinfo import ZoneInfo
-except ImportError:
-    # Fallback for Python < 3.9
-    from backports.zoneinfo import ZoneInfo
-
 from agate.data_types import Boolean, Date, DateTime, Number, Text, TimeDelta
 from agate.exceptions import CastError
 
@@ -410,7 +405,7 @@
         # so we will catch any CastError that may arise from the conversion
         possible_values = (
             ('1994-03-01 12:30 오후', '2011-02-17 06:30 오전', None, '1984-01-05 
06:30 오후', 'n/a'),
-            ('1994-03-01 12:30 PM', '2011-02-17 06:30 AM', None, '1984-01-05 
06:30 PM', 'n/a'),
+            ('1994-03-01 12:30 AM', '2011-02-17 06:30 #오전', None, '1984-01-05 
06:30 AM', 'n/a'),
         )
         valid = False
         exceptions = []
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agate-1.13.0/tests/test_table/test_from_csv.py 
new/agate-1.14.2/tests/test_table/test_from_csv.py
--- old/agate-1.13.0/tests/test_table/test_from_csv.py  2025-01-29 
07:21:29.000000000 +0100
+++ new/agate-1.14.2/tests/test_table/test_from_csv.py  2026-02-27 
17:33:42.000000000 +0100
@@ -195,3 +195,20 @@
         self.assertColumnTypes(table, [])
 
         self.assertRows(table, [])
+
+    def test_from_csv_empty_input(self):
+        import io
+
+        table = Table.from_csv(io.StringIO(''))
+
+        self.assertColumnNames(table, [])
+        self.assertColumnTypes(table, [])
+        self.assertRows(table, [])
+
+    def test_from_csv_empty_input_with_column_names(self):
+        import io
+
+        table = Table.from_csv(io.StringIO(''), column_names=['a', 'b'])
+
+        self.assertColumnNames(table, ['a', 'b'])
+        self.assertRows(table, [])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agate-1.13.0/tests/test_table/test_join.py 
new/agate-1.14.2/tests/test_table/test_join.py
--- old/agate-1.13.0/tests/test_table/test_join.py      2025-01-29 
07:21:29.000000000 +0100
+++ new/agate-1.14.2/tests/test_table/test_join.py      2026-02-27 
17:33:42.000000000 +0100
@@ -277,6 +277,35 @@
             (None, None, None, 4, 2, 'c')
         ])
 
+    def test_full_outer_key_list(self):
+        left_rows = (
+            (1, 4, 'a'),
+            (2, 3, 'b'),
+            (3, 2, 'c')
+        )
+
+        right_rows = (
+            (1, 4, 'a'),
+            (2, 3, 'b'),
+            (4, 2, 'c')
+        )
+
+        left = Table(left_rows, self.left_column_names, self.column_types)
+        right = Table(right_rows, self.right_column_names, self.column_types)
+
+        new_table = left.join(right, ['one'], ['four'], full_outer=True)
+
+        self.assertIsNot(new_table, left)
+        self.assertIsNot(new_table, right)
+        self.assertColumnNames(new_table, ['one', 'two', 'three', 'four', 
'five', 'six'])
+        self.assertColumnTypes(new_table, [Number, Number, Text, Number, 
Number, Text])
+        self.assertRows(new_table, [
+            (1, 4, 'a', 1, 4, 'a'),
+            (2, 3, 'b', 2, 3, 'b'),
+            (3, 2, 'c', None, None, None),
+            (None, None, None, 4, 2, 'c')
+        ])
+
     def test_join_by_row_number(self):
         new_table = self.left.join(self.right, full_outer=True)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agate-1.13.0/tests/test_table/test_print_table.py 
new/agate-1.14.2/tests/test_table/test_print_table.py
--- old/agate-1.13.0/tests/test_table/test_print_table.py       2025-01-29 
07:21:29.000000000 +0100
+++ new/agate-1.14.2/tests/test_table/test_print_table.py       2026-02-27 
17:33:42.000000000 +0100
@@ -131,3 +131,20 @@
         table.print_table(max_columns=2, output=output, locale='de_DE.UTF-8')
         # If it's working, the english '2,000' should appear as '2.000'
         self.assertTrue("2.000" in output.getvalue())
+
+    def test_print_table_replace_newlines(self):
+        """Verify that \n characters are replaced with the '↵' symbol."""
+        rows = (
+            ('1.7', 2000, 2000, 'a\nvalue with one newline'),
+            ('11.18', None, None, None),
+            ('0', 1, 1, 'a\n\nvalue with two newlines')
+        )
+
+        table = Table(rows, self.column_names, self.column_types)
+
+        output = StringIO()
+        table.print_table(output=output, max_column_width=30)
+        lines = output.getvalue().split('\n')
+
+        self.assertIn('a↵value with one newline', lines[2])
+        self.assertIn('a↵↵value with two newlines', lines[4])

Reply via email to