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])
