Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-roman for openSUSE:Factory 
checked in at 2026-04-01 19:51:47
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-roman (Old)
 and      /work/SRC/openSUSE:Factory/.python-roman.new.21863 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-roman"

Wed Apr  1 19:51:47 2026 rev:16 rq:1343966 version:5.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-roman/python-roman.changes        
2025-08-28 17:20:21.511465138 +0200
+++ /work/SRC/openSUSE:Factory/.python-roman.new.21863/python-roman.changes     
2026-04-01 19:53:00.431058410 +0200
@@ -1,0 +2,9 @@
+Tue Mar 31 19:06:34 UTC 2026 - Dirk Müller <[email protected]>
+
+- update to 5.2:
+  * Add support for Python 3.14.
+  * Drop support for Python 3.9.
+  * Hide undocumented special behavior for N behind method
+    parameter.
+
+-------------------------------------------------------------------

Old:
----
  roman-5.0.tar.gz

New:
----
  roman-5.2.tar.gz

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

Other differences:
------------------
++++++ python-roman.spec ++++++
--- /var/tmp/diff_new_pack.sJ8zYL/_old  2026-04-01 19:53:01.271093302 +0200
+++ /var/tmp/diff_new_pack.sJ8zYL/_new  2026-04-01 19:53:01.275093468 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package python-roman
 #
-# Copyright (c) 2025 SUSE LLC and contributors
+# 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
@@ -24,15 +24,15 @@
 %endif
 %{?sle15_python_module_pythons}
 Name:           python-roman
-Version:        5.0
+Version:        5.2
 Release:        0
 Summary:        Integer to Roman numerals converter
 License:        ZPL-2.1
 URL:            https://github.com/zopefoundation/roman
 Source:         
https://files.pythonhosted.org/packages/source/r/roman/%{packagename}-%{version}.tar.gz
-BuildRequires:  %{python_module base >= 3.9}
+BuildRequires:  %{python_module base >= 3.10}
 BuildRequires:  %{python_module pip}
-BuildRequires:  %{python_module setuptools}
+BuildRequires:  %{python_module setuptools >= 78.1.1}
 BuildRequires:  %{python_module wheel}
 BuildRequires:  fdupes
 BuildRequires:  python-rpm-macros
@@ -77,12 +77,7 @@
 %files %{python_files}
 %doc README.rst CHANGES.rst
 %license LICENSE.txt
-%pycache_only %{python_sitelib}/__pycache__/%{packagename}*pyc
-%{python_sitelib}/%{packagename}-%{version}.dist-info
-%{python_sitelib}/%{packagename}.py
 %python_alternative %{_bindir}/roman
-
-%if 0%{?sle_version} > 0 && 0%{?sle_version} <= 150200
-%{_prefix}/lib/python2.7/site-packages/%{packagename}.py*
-%endif
+%{python_sitelib}/%{packagename}/
+%{python_sitelib}/%{packagename}-%{version}.dist-info
 

++++++ roman-5.0.tar.gz -> roman-5.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/roman-5.0/.pre-commit-config.yaml 
new/roman-5.2/.pre-commit-config.yaml
--- old/roman-5.0/.pre-commit-config.yaml       2025-01-15 07:43:12.000000000 
+0100
+++ new/roman-5.2/.pre-commit-config.yaml       2025-11-11 09:03:51.000000000 
+0100
@@ -3,25 +3,25 @@
 minimum_pre_commit_version: '3.6'
 repos:
   - repo: https://github.com/pycqa/isort
-    rev: "5.13.2"
+    rev: "7.0.0"
     hooks:
     - id: isort
   - repo: https://github.com/hhatto/autopep8
-    rev: "v2.3.1"
+    rev: "v2.3.2"
     hooks:
     - id: autopep8
       args: [--in-place, --aggressive, --aggressive]
   - repo: https://github.com/asottile/pyupgrade
-    rev: v3.19.0
+    rev: v3.21.0
     hooks:
     - id: pyupgrade
-      args: [--py39-plus]
+      args: [--py310-plus]
   - repo: https://github.com/isidentical/teyit
     rev: 0.4.3
     hooks:
     - id: teyit
   - repo: https://github.com/PyCQA/flake8
-    rev: "7.1.1"
+    rev: "7.3.0"
     hooks:
     - id: flake8
       additional_dependencies:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/roman-5.0/CHANGES.rst new/roman-5.2/CHANGES.rst
--- old/roman-5.0/CHANGES.rst   2025-01-15 07:43:12.000000000 +0100
+++ new/roman-5.2/CHANGES.rst   2025-11-11 09:03:51.000000000 +0100
@@ -1,6 +1,20 @@
 Change log
 ==========
 
+5.2 (2025-11-11)
+----------------
+
+- Add support for Python 3.14.
+
+- Drop support for Python 3.9.
+
+5.1 (2025-07-18)
+----------------
+
+- Hide undocumented special behavior for ``N`` behind method parameter.
+  (`#30 <https://github.com/zopefoundation/roman/issues/30>`_)
+
+
 5.0 (2025-01-15)
 ----------------
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/roman-5.0/CONTRIBUTING.md 
new/roman-5.2/CONTRIBUTING.md
--- old/roman-5.0/CONTRIBUTING.md       2025-01-15 07:43:12.000000000 +0100
+++ new/roman-5.2/CONTRIBUTING.md       2025-11-11 09:03:51.000000000 +0100
@@ -1,7 +1,7 @@
 <!--
 Generated from:
 https://github.com/zopefoundation/meta/tree/master/config/pure-python
---> 
+-->
 # Contributing to zopefoundation projects
 
 The projects under the zopefoundation GitHub organization are open source and
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/roman-5.0/PKG-INFO new/roman-5.2/PKG-INFO
--- old/roman-5.0/PKG-INFO      2025-01-15 07:43:13.169437400 +0100
+++ new/roman-5.2/PKG-INFO      2025-11-11 09:03:52.426931600 +0100
@@ -1,31 +1,43 @@
-Metadata-Version: 2.1
+Metadata-Version: 2.4
 Name: roman
-Version: 5.0
+Version: 5.2
 Summary: Integer to Roman numerals converter
 Home-page: https://github.com/zopefoundation/roman
 Author: Mark Pilgrim
 Maintainer: Zope Foundation and Contributors
 Maintainer-email: [email protected]
-License: ZPL 2.1
+License: ZPL-2.1
 Keywords: roman
 Classifier: Development Status :: 5 - Production/Stable
 Classifier: Intended Audience :: Developers
 Classifier: Programming Language :: Python
 Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.9
 Classifier: Programming Language :: Python :: 3.10
 Classifier: Programming Language :: Python :: 3.11
 Classifier: Programming Language :: Python :: 3.12
 Classifier: Programming Language :: Python :: 3.13
+Classifier: Programming Language :: Python :: 3.14
 Classifier: Programming Language :: Python :: Implementation :: CPython
 Classifier: Programming Language :: Python :: Implementation :: PyPy
 Classifier: License :: OSI Approved :: Zope Public License
 Classifier: Programming Language :: Python
 Classifier: Natural Language :: English
 Classifier: Operating System :: OS Independent
-Requires-Python: >=3.9
+Requires-Python: >=3.10
 Description-Content-Type: text/x-rst
 License-File: LICENSE.txt
+Dynamic: author
+Dynamic: classifier
+Dynamic: description
+Dynamic: description-content-type
+Dynamic: home-page
+Dynamic: keywords
+Dynamic: license
+Dynamic: license-file
+Dynamic: maintainer
+Dynamic: maintainer-email
+Dynamic: requires-python
+Dynamic: summary
 
 .. image:: 
https://github.com/zopefoundation/roman/actions/workflows/tests.yml/badge.svg
     :target: 
https://github.com/zopefoundation/roman/actions/workflows/tests.yml
@@ -81,6 +93,20 @@
 Change log
 ==========
 
+5.2 (2025-11-11)
+----------------
+
+- Add support for Python 3.14.
+
+- Drop support for Python 3.9.
+
+5.1 (2025-07-18)
+----------------
+
+- Hide undocumented special behavior for ``N`` behind method parameter.
+  (`#30 <https://github.com/zopefoundation/roman/issues/30>`_)
+
+
 5.0 (2025-01-15)
 ----------------
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/roman-5.0/pyproject.toml new/roman-5.2/pyproject.toml
--- old/roman-5.0/pyproject.toml        2025-01-15 07:43:12.000000000 +0100
+++ new/roman-5.2/pyproject.toml        2025-11-11 09:03:51.000000000 +0100
@@ -3,7 +3,10 @@
 # https://github.com/zopefoundation/meta/tree/master/config/pure-python
 
 [build-system]
-requires = ["setuptools <= 75.6.0"]
+requires = [
+    "setuptools >= 78.1.1,< 81",
+    "wheel",
+]
 build-backend = "setuptools.build_meta"
 
 [tool.coverage.run]
@@ -15,7 +18,16 @@
 precision = 2
 ignore_errors = true
 show_missing = true
-exclude_lines = ["pragma: no cover", "pragma: nocover", "except ImportError:", 
"raise NotImplementedError", "if __name__ == '__main__':", "self.fail", "raise 
AssertionError", "raise unittest.Skip"]
+exclude_lines = [
+    "pragma: no cover",
+    "pragma: nocover",
+    "except ImportError:",
+    "raise NotImplementedError",
+    "if __name__ == '__main__':",
+    "self.fail",
+    "raise AssertionError",
+    "raise unittest.Skip",
+]
 
 [tool.coverage.html]
 directory = "parts/htmlcov"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/roman-5.0/setup.py new/roman-5.2/setup.py
--- old/roman-5.0/setup.py      2025-01-15 07:43:12.000000000 +0100
+++ new/roman-5.2/setup.py      2025-11-11 09:03:51.000000000 +0100
@@ -20,25 +20,25 @@
 
 setup(
     name='roman',
-    version='5.0',
+    version='5.2',
     author="Mark Pilgrim",
     maintainer="Zope Foundation and Contributors",
     maintainer_email="[email protected]",
     description="Integer to Roman numerals converter",
     long_description=desc,
     long_description_content_type='text/x-rst',
-    license="ZPL 2.1",
+    license="ZPL-2.1",
     keywords="roman",
     classifiers=[
         'Development Status :: 5 - Production/Stable',
         'Intended Audience :: Developers',
         'Programming Language :: Python',
         'Programming Language :: Python :: 3',
-        'Programming Language :: Python :: 3.9',
         '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',
         'License :: OSI Approved :: Zope Public License',
@@ -48,8 +48,9 @@
     ],
     url='https://github.com/zopefoundation/roman',
     package_dir={"": "src"},
-    python_requires='>=3.9',
-    py_modules=["roman"],
+    python_requires='>=3.10',
+    packages=["roman"],
+    package_data={"roman": ["py.typed"]},
     include_package_data=True,
     zip_safe=True,
     entry_points={
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/roman-5.0/src/roman/__init__.py 
new/roman-5.2/src/roman/__init__.py
--- old/roman-5.0/src/roman/__init__.py 1970-01-01 01:00:00.000000000 +0100
+++ new/roman-5.2/src/roman/__init__.py 2025-11-11 09:03:51.000000000 +0100
@@ -0,0 +1,163 @@
+##############################################################################
+#
+# Copyright (c) 2001 Mark Pilgrim and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Convert to and from Roman numerals"""
+
+__author__ = "Mark Pilgrim ([email protected])"
+__copyright__ = """Copyright (c) 2001 Mark Pilgrim
+
+This program is part of "Dive Into Python", a free Python tutorial for
+experienced programmers.  Visit http://diveintopython.org/ for the
+latest version.
+"""
+
+import argparse
+import re
+import sys
+
+
+# Define exceptions
+class RomanError(Exception):
+    pass
+
+
+class OutOfRangeError(RomanError):
+    pass
+
+
+class NotIntegerError(RomanError):
+    pass
+
+
+class InvalidRomanNumeralError(RomanError):
+    pass
+
+
+# Define digit mapping
+romanNumeralMap = (('M', 1000),
+                   ('CM', 900),
+                   ('D', 500),
+                   ('CD', 400),
+                   ('C', 100),
+                   ('XC', 90),
+                   ('L', 50),
+                   ('XL', 40),
+                   ('X', 10),
+                   ('IX', 9),
+                   ('V', 5),
+                   ('IV', 4),
+                   ('I', 1))
+
+
+def toRoman(n: int) -> str:
+    """convert integer to Roman numeral"""
+    if not isinstance(n, int):
+        raise NotIntegerError("decimals cannot be converted")
+    if not (-1 < n < 5000):
+        raise OutOfRangeError("number out of range (must be 0..4999)")
+
+    # special case
+    if n == 0:
+        return 'N'
+
+    result = ""
+    for numeral, integer in romanNumeralMap:
+        while n >= integer:
+            result += numeral
+            n -= integer
+    return result
+
+
+# Define pattern to detect valid Roman numerals
+romanNumeralPattern = re.compile("""
+    ^                   # beginning of string
+    M{0,4}              # thousands - 0 to 4 M's
+    (CM|CD|D?C{0,3})    # hundreds - 900 (CM), 400 (CD), 0-300 (0 to 3 C's),
+                        #            or 500-800 (D, followed by 0 to 3 C's)
+    (XC|XL|L?X{0,3})    # tens - 90 (XC), 40 (XL), 0-30 (0 to 3 X's),
+                        #        or 50-80 (L, followed by 0 to 3 X's)
+    (IX|IV|V?I{0,3})    # ones - 9 (IX), 4 (IV), 0-3 (0 to 3 I's),
+                        #        or 5-8 (V, followed by 0 to 3 I's)
+    $                   # end of string
+    """, re.VERBOSE)
+
+
+def fromRoman(s: str, special_case: bool = True) -> int:
+    """
+    Convert Roman numeral to integer.
+
+    Parameters:
+        s (str): The Roman numeral string to convert.
+        special_case (bool, optional): If True (default),
+            interprets 'N' as 0 for the special case of zero.
+
+    Returns:
+        int: The integer value of the Roman numeral.
+
+    Raises:
+        InvalidRomanNumeralError: If the input is not a valid Roman numeral.
+    """
+
+    if not s:
+        raise InvalidRomanNumeralError('Input cannot be blank')
+
+    s = s.upper()  # Handle lowercase inputs
+
+    # special case
+    if s == 'N' and special_case:
+        return 0
+
+    if not romanNumeralPattern.search(s):
+        raise InvalidRomanNumeralError('Invalid Roman numeral: %s' % s)
+
+    result = 0
+    index = 0
+    for numeral, integer in romanNumeralMap:
+        while s[index:index + len(numeral)] == numeral:
+            result += integer
+            index += len(numeral)
+    return result
+
+
+def parse_args() -> argparse.Namespace:
+    parser = argparse.ArgumentParser(
+        prog='roman',
+        description='convert between roman and arabic numerals'
+    )
+    parser.add_argument('number', help='the value to convert')
+    parser.add_argument(
+        '-r', '--reverse',
+        action='store_true',
+        default=False,
+        help='convert roman to numeral (case insensitive) [default: False]')
+
+    args = parser.parse_args()
+    args.number = args.number
+    return args
+
+
+def main() -> int:
+    args = parse_args()
+    if args.reverse:
+        r = fromRoman(args.number)
+        print(r)
+    else:
+        i = int(args.number)
+        n = toRoman(i)
+        print(n)
+
+    return 0
+
+
+if __name__ == "__main__":  # pragma: no cover
+    sys.exit(main())  # pragma: no cover
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/roman-5.0/src/roman.egg-info/PKG-INFO 
new/roman-5.2/src/roman.egg-info/PKG-INFO
--- old/roman-5.0/src/roman.egg-info/PKG-INFO   2025-01-15 07:43:13.000000000 
+0100
+++ new/roman-5.2/src/roman.egg-info/PKG-INFO   2025-11-11 09:03:52.000000000 
+0100
@@ -1,31 +1,43 @@
-Metadata-Version: 2.1
+Metadata-Version: 2.4
 Name: roman
-Version: 5.0
+Version: 5.2
 Summary: Integer to Roman numerals converter
 Home-page: https://github.com/zopefoundation/roman
 Author: Mark Pilgrim
 Maintainer: Zope Foundation and Contributors
 Maintainer-email: [email protected]
-License: ZPL 2.1
+License: ZPL-2.1
 Keywords: roman
 Classifier: Development Status :: 5 - Production/Stable
 Classifier: Intended Audience :: Developers
 Classifier: Programming Language :: Python
 Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.9
 Classifier: Programming Language :: Python :: 3.10
 Classifier: Programming Language :: Python :: 3.11
 Classifier: Programming Language :: Python :: 3.12
 Classifier: Programming Language :: Python :: 3.13
+Classifier: Programming Language :: Python :: 3.14
 Classifier: Programming Language :: Python :: Implementation :: CPython
 Classifier: Programming Language :: Python :: Implementation :: PyPy
 Classifier: License :: OSI Approved :: Zope Public License
 Classifier: Programming Language :: Python
 Classifier: Natural Language :: English
 Classifier: Operating System :: OS Independent
-Requires-Python: >=3.9
+Requires-Python: >=3.10
 Description-Content-Type: text/x-rst
 License-File: LICENSE.txt
+Dynamic: author
+Dynamic: classifier
+Dynamic: description
+Dynamic: description-content-type
+Dynamic: home-page
+Dynamic: keywords
+Dynamic: license
+Dynamic: license-file
+Dynamic: maintainer
+Dynamic: maintainer-email
+Dynamic: requires-python
+Dynamic: summary
 
 .. image:: 
https://github.com/zopefoundation/roman/actions/workflows/tests.yml/badge.svg
     :target: 
https://github.com/zopefoundation/roman/actions/workflows/tests.yml
@@ -81,6 +93,20 @@
 Change log
 ==========
 
+5.2 (2025-11-11)
+----------------
+
+- Add support for Python 3.14.
+
+- Drop support for Python 3.9.
+
+5.1 (2025-07-18)
+----------------
+
+- Hide undocumented special behavior for ``N`` behind method parameter.
+  (`#30 <https://github.com/zopefoundation/roman/issues/30>`_)
+
+
 5.0 (2025-01-15)
 ----------------
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/roman-5.0/src/roman.egg-info/SOURCES.txt 
new/roman-5.2/src/roman.egg-info/SOURCES.txt
--- old/roman-5.0/src/roman.egg-info/SOURCES.txt        2025-01-15 
07:43:13.000000000 +0100
+++ new/roman-5.2/src/roman.egg-info/SOURCES.txt        2025-11-11 
09:03:52.000000000 +0100
@@ -9,8 +9,9 @@
 setup.cfg
 setup.py
 tox.ini
-src/roman.py
 src/tests.py
+src/roman/__init__.py
+src/roman/py.typed
 src/roman.egg-info/PKG-INFO
 src/roman.egg-info/SOURCES.txt
 src/roman.egg-info/dependency_links.txt
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/roman-5.0/src/roman.py new/roman-5.2/src/roman.py
--- old/roman-5.0/src/roman.py  2025-01-15 07:43:12.000000000 +0100
+++ new/roman-5.2/src/roman.py  1970-01-01 01:00:00.000000000 +0100
@@ -1,150 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2001 Mark Pilgrim and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Convert to and from Roman numerals"""
-
-__author__ = "Mark Pilgrim ([email protected])"
-__copyright__ = """Copyright (c) 2001 Mark Pilgrim
-
-This program is part of "Dive Into Python", a free Python tutorial for
-experienced programmers.  Visit http://diveintopython.org/ for the
-latest version.
-"""
-
-import argparse
-import re
-import sys
-
-
-# Define exceptions
-class RomanError(Exception):
-    pass
-
-
-class OutOfRangeError(RomanError):
-    pass
-
-
-class NotIntegerError(RomanError):
-    pass
-
-
-class InvalidRomanNumeralError(RomanError):
-    pass
-
-
-# Define digit mapping
-romanNumeralMap = (('M', 1000),
-                   ('CM', 900),
-                   ('D', 500),
-                   ('CD', 400),
-                   ('C', 100),
-                   ('XC', 90),
-                   ('L', 50),
-                   ('XL', 40),
-                   ('X', 10),
-                   ('IX', 9),
-                   ('V', 5),
-                   ('IV', 4),
-                   ('I', 1))
-
-
-def toRoman(n):
-    """convert integer to Roman numeral"""
-    if not isinstance(n, int):
-        raise NotIntegerError("decimals cannot be converted")
-    if not (-1 < n < 5000):
-        raise OutOfRangeError("number out of range (must be 0..4999)")
-
-    # special case
-    if n == 0:
-        return 'N'
-
-    result = ""
-    for numeral, integer in romanNumeralMap:
-        while n >= integer:
-            result += numeral
-            n -= integer
-    return result
-
-
-# Define pattern to detect valid Roman numerals
-romanNumeralPattern = re.compile("""
-    ^                   # beginning of string
-    M{0,4}              # thousands - 0 to 4 M's
-    (CM|CD|D?C{0,3})    # hundreds - 900 (CM), 400 (CD), 0-300 (0 to 3 C's),
-                        #            or 500-800 (D, followed by 0 to 3 C's)
-    (XC|XL|L?X{0,3})    # tens - 90 (XC), 40 (XL), 0-30 (0 to 3 X's),
-                        #        or 50-80 (L, followed by 0 to 3 X's)
-    (IX|IV|V?I{0,3})    # ones - 9 (IX), 4 (IV), 0-3 (0 to 3 I's),
-                        #        or 5-8 (V, followed by 0 to 3 I's)
-    $                   # end of string
-    """, re.VERBOSE)
-
-
-def fromRoman(s):
-    """convert Roman numeral to integer"""
-
-    if not s:
-        raise InvalidRomanNumeralError('Input cannot be blank')
-
-    s = s.upper()  # Handle lowercase inputs
-
-    # special case
-    if s == 'N':
-        return 0
-
-    if not romanNumeralPattern.search(s):
-        raise InvalidRomanNumeralError('Invalid Roman numeral: %s' % s)
-
-    result = 0
-    index = 0
-    for numeral, integer in romanNumeralMap:
-        while s[index:index + len(numeral)] == numeral:
-            result += integer
-            index += len(numeral)
-    return result
-
-
-def parse_args():
-    parser = argparse.ArgumentParser(
-        prog='roman',
-        description='convert between roman and arabic numerals'
-    )
-    parser.add_argument('number', help='the value to convert')
-    parser.add_argument(
-        '-r', '--reverse',
-        action='store_true',
-        default=False,
-        help='convert roman to numeral (case insensitive) [default: False]')
-
-    args = parser.parse_args()
-    args.number = args.number
-    return args
-
-
-def main():
-    args = parse_args()
-    if args.reverse:
-        r = fromRoman(args.number)
-        print(r)
-    else:
-        i = int(args.number)
-        n = toRoman(i)
-        print(n)
-
-    return 0
-
-
-if __name__ == "__main__":  # pragma: no cover
-    sys.exit(main())  # pragma: no cover
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/roman-5.0/src/tests.py new/roman-5.2/src/tests.py
--- old/roman-5.0/src/tests.py  2025-01-15 07:43:12.000000000 +0100
+++ new/roman-5.2/src/tests.py  2025-11-11 09:03:51.000000000 +0100
@@ -47,6 +47,11 @@
             roman.InvalidRomanNumeralError, roman.fromRoman, '')
         self.assertRaises(
             roman.InvalidRomanNumeralError, roman.fromRoman, 'Q12')
+        self.assertRaises(
+            roman.InvalidRomanNumeralError,
+            roman.fromRoman,
+            'n',
+            special_case=False)
 
     def test_parse_args(self):
         sys.argv = ['roman', '10']
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/roman-5.0/tox.ini new/roman-5.2/tox.ini
--- old/roman-5.0/tox.ini       2025-01-15 07:43:12.000000000 +0100
+++ new/roman-5.2/tox.ini       2025-11-11 09:03:51.000000000 +0100
@@ -5,12 +5,12 @@
 envlist =
     release-check
     lint
-    py39
     py310
     py311
     py312
     py313
     py314
+    py315
     pypy3
     coverage
 
@@ -18,9 +18,9 @@
 usedevelop = true
 package = wheel
 wheel_build_env = .pkg
-pip_pre = py314: true
+pip_pre = py315: true
 deps =
-    setuptools <= 75.6.0
+    setuptools >= 78.1.1,< 81
     zope.testrunner
 commands =
     zope-testrunner --test-path=src {posargs:-vc}
@@ -38,7 +38,8 @@
 basepython = python3
 skip_install = true
 deps =
-    setuptools <= 75.6.0
+    setuptools >= 78.1.1,< 81
+    wheel
     twine
     build
     check-manifest
@@ -47,7 +48,7 @@
 commands_pre =
 commands =
     check-manifest
-    check-python-versions --only setup.py,tox.ini,.github/workflows/tests.yml
+    check-python-versions --only 
pyproject.toml,setup.py,tox.ini,.github/workflows/tests.yml
     python -m build --sdist --no-isolation
     twine check dist/*
 

Reply via email to