Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-flit-core for
openSUSE:Factory checked in at 2025-05-07 19:14:34
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-flit-core (Old)
and /work/SRC/openSUSE:Factory/.python-flit-core.new.30101 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-flit-core"
Wed May 7 19:14:34 2025 rev:21 rq:1274041 version:3.12.0
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-flit-core/python-flit-core.changes
2025-03-17 22:20:31.493827000 +0100
+++
/work/SRC/openSUSE:Factory/.python-flit-core.new.30101/python-flit-core.changes
2025-05-07 19:14:36.110539634 +0200
@@ -1,0 +2,10 @@
+Fri May 2 14:17:24 UTC 2025 - Nico Krapp <[email protected]>
+
+- Update to 3.12.0
+ * Support for license expressions using the AND and OR operators.
+ * Recognise __version__: str = "0.1" annotated assignments when
+ finding the version number.
+ * Clear error message when referring to a license file in a parent
+ directory, which is not supported.
+
+-------------------------------------------------------------------
Old:
----
flit_core-3.11.0.tar.gz
New:
----
flit_core-3.12.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-flit-core.spec ++++++
--- /var/tmp/diff_new_pack.yvORZP/_old 2025-05-07 19:14:36.694563996 +0200
+++ /var/tmp/diff_new_pack.yvORZP/_new 2025-05-07 19:14:36.698564163 +0200
@@ -52,7 +52,7 @@
%endif
%{?sle15_python_module_pythons}
Name: %{pprefix}-flit-core%{?psuffix}
-Version: 3.11.0
+Version: 3.12.0
Release: 0
Summary: Distribution-building parts of Flit
License: BSD-3-Clause AND MIT
++++++ flit_core-3.11.0.tar.gz -> flit_core-3.12.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/flit_core-3.11.0/PKG-INFO
new/flit_core-3.12.0/PKG-INFO
--- old/flit_core-3.11.0/PKG-INFO 1970-01-01 01:00:00.000000000 +0100
+++ new/flit_core-3.12.0/PKG-INFO 1970-01-01 01:00:00.000000000 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 2.4
Name: flit_core
-Version: 3.11.0
+Version: 3.12.0
Summary: Distribution-building parts of Flit. See flit package for more
information
Author-email: Thomas Kluyver & contributors <[email protected]>
Requires-Python: >=3.6
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/flit_core-3.11.0/flit_core/__init__.py
new/flit_core-3.12.0/flit_core/__init__.py
--- old/flit_core-3.11.0/flit_core/__init__.py 2025-02-19 09:21:57.541935200
+0100
+++ new/flit_core-3.12.0/flit_core/__init__.py 2025-03-25 09:03:05.503557200
+0100
@@ -4,4 +4,4 @@
All the convenient development features live in the main 'flit' package.
"""
-__version__ = '3.11.0'
+__version__ = '3.12.0'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/flit_core-3.11.0/flit_core/common.py
new/flit_core-3.12.0/flit_core/common.py
--- old/flit_core-3.11.0/flit_core/common.py 2025-02-19 09:21:57.542935100
+0100
+++ new/flit_core-3.12.0/flit_core/common.py 2025-03-25 09:03:05.503557200
+0100
@@ -148,22 +148,7 @@
with target_path.open('rb') as f:
node = ast.parse(f.read())
for child in node.body:
- if sys.version_info >= (3, 8):
- target_type = ast.Constant
- else:
- target_type = ast.Str
- # Only use the version from the given module if it's a simple
- # string assignment to __version__
- is_version_str = (
- isinstance(child, ast.Assign)
- and any(
- isinstance(target, ast.Name)
- and target.id == "__version__"
- for target in child.targets
- )
- and isinstance(child.value, target_type)
- )
- if is_version_str:
+ if is_version_str_assignment(child):
if sys.version_info >= (3, 8):
version = child.value.value
else:
@@ -172,6 +157,20 @@
return ast.get_docstring(node), version
+def is_version_str_assignment(node):
+ """Check if *node* is a simple string assignment to __version__"""
+ if not isinstance(node, (ast.Assign, ast.AnnAssign)):
+ return False
+ constant_type = ast.Constant if sys.version_info >= (3, 8) else ast.Str
+ if not isinstance(node.value, constant_type):
+ return False
+ targets = (node.target,) if isinstance(node, ast.AnnAssign) else
node.targets
+ for target in targets:
+ if isinstance(target, ast.Name) and target.id == "__version__":
+ return True
+ return False
+
+
# To ensure we're actually loading the specified file, give it a unique name to
# avoid any cached import. In normal use we'll only load one module per
process,
# so it should only matter for the tests, but we'll do it anyway.
@@ -379,7 +378,7 @@
return [item.strip() for item in list_str.split(',')]
else:
return None
-
+
def _normalise_requires_dist(self, req):
extras = self._extract_extras(req)
if extras:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/flit_core-3.11.0/flit_core/config.py
new/flit_core-3.12.0/flit_core/config.py
--- old/flit_core-3.11.0/flit_core/config.py 2025-02-19 09:21:57.542935100
+0100
+++ new/flit_core-3.12.0/flit_core/config.py 2025-03-25 09:03:05.504557400
+0100
@@ -4,7 +4,6 @@
import logging
import os
import os.path as osp
-from os.path import isabs
from pathlib import Path
import re
@@ -18,6 +17,7 @@
except ImportError:
import tomli as tomllib
+from ._spdx_data import licenses
from .common import normalise_core_metadata_name
from .versionno import normalise_version
@@ -92,7 +92,7 @@
def prep_toml_config(d, path):
"""Validate config loaded from pyproject.toml and prepare common metadata
-
+
Returns a LoadedConfig object.
"""
dtool = d.get('tool', {}).get('flit', {})
@@ -310,11 +310,11 @@
def _prep_metadata(md_sect, path):
"""Process & verify the metadata from a config file
-
+
- Pull out the module name we're packaging.
- Read description-file and check that it's valid rst
- Convert dashes in key names to underscores
- (e.g. home-page in config -> home_page in metadata)
+ (e.g. home-page in config -> home_page in metadata)
"""
if not set(md_sect).issuperset(metadata_required_fields):
missing = metadata_required_fields - set(md_sect)
@@ -473,7 +473,7 @@
)
try:
files = [
- str(file.relative_to(project_dir)).replace(osp.sep, "/")
+ file.relative_to(project_dir).as_posix()
for file in project_dir.glob(pattern)
if file.is_file()
]
@@ -587,7 +587,8 @@
if 'license' in proj:
_check_types(proj, 'license', (str, dict))
if isinstance(proj['license'], str):
- md_dict['license_expression'] =
normalize_license_expr(proj['license'])
+ licence_expr = proj['license']
+ md_dict['license_expression'] =
normalise_compound_license_expr(licence_expr)
else:
license_tbl = proj['license']
unrec_keys = set(license_tbl.keys()) - {'text', 'file'}
@@ -603,14 +604,20 @@
raise ConfigError(
"[project.license] should specify file or text, not
both"
)
- license_f = license_tbl['file']
+ license_f = osp.normpath(license_tbl['file'])
if isabs_ish(license_f):
raise ConfigError(
- f"License file path ({license_f}) cannot be an
absolute path"
+ f"License file path ({license_tbl['file']}) cannot be
an absolute path"
)
- if not (path.parent / license_f).is_file():
- raise ConfigError(f"License file {license_f} does not
exist")
- license_files.add(license_tbl['file'])
+ if license_f.startswith('..' + os.sep):
+ raise ConfigError(
+ f"License file path ({license_tbl['file']}) cannot
contain '..'"
+ )
+ license_p = path.parent / license_f
+ if not license_p.is_file():
+ raise ConfigError(f"License file {license_tbl['file']}
does not exist")
+ license_f = license_p.relative_to(path.parent).as_posix()
+ license_files.add(license_f)
elif 'text' in license_tbl:
pass
else:
@@ -816,34 +823,97 @@
return os.path.isabs(path) or path.startswith(('/', '\\'))
-def normalize_license_expr(s: str):
- """Validate & normalise an SPDX license expression
+def normalise_compound_license_expr(s: str) -> str:
+ """Validate and normalise a compund SPDX license expression.
+
+ Per the specification, licence expression operators (AND, OR and WITH)
+ are matched case-sensitively. The WITH operator is not currently supported.
- For now this only handles simple expressions (referring to 1 license)
+ Spec: https://spdx.github.io/spdx-spec/v2.2.2/SPDX-license-expressions/
+ """
+ invalid_msg = "'{s}' is not a valid SPDX license expression: {reason}"
+ if not s or s.isspace():
+ raise ConfigError(f"The SPDX license expression must not be empty")
+
+ stack = 0
+ parts = []
+ try:
+ for part in filter(None, re.split(r' +|([()])', s)):
+ if part.upper() == 'WITH':
+ # provide a sensible error message for the WITH operator
+ raise ConfigError(f"The SPDX 'WITH' operator is not yet
supported!")
+ elif part in {'AND', 'OR'}:
+ if not parts or parts[-1] in {' AND ', ' OR ', ' WITH ', '('}:
+ reason = f"a license ID is missing before '{part}'"
+ raise ConfigError(invalid_msg.format(s=s, reason=reason))
+ parts.append(f' {part} ')
+ elif part.lower() in {'and', 'or', 'with'}:
+ # provide a sensible error message for non-uppercase operators
+ reason = f"operators must be uppercase, not '{part}'"
+ raise ConfigError(invalid_msg.format(s=s, reason=reason))
+ elif part == '(':
+ if parts and parts[-1] not in {' AND ', ' OR ', '('}:
+ reason = f"'(' must follow either AND, OR, or '('"
+ raise ConfigError(invalid_msg.format(s=s, reason=reason))
+ stack += 1
+ parts.append(part)
+ elif part == ')':
+ if not parts or parts[-1] in {' AND ', ' OR ', ' WITH ', '('}:
+ reason = f"a license ID is missing before '{part}'"
+ raise ConfigError(invalid_msg.format(s=s, reason=reason))
+ stack -= 1
+ if stack < 0:
+ reason = 'unbalanced brackets'
+ raise ConfigError(invalid_msg.format(s=s, reason=reason))
+ parts.append(part)
+ else:
+ if parts and parts[-1] not in {' AND ', ' OR ', '('}:
+ reason = f"a license ID must follow either AND, OR, or '('"
+ raise ConfigError(invalid_msg.format(s=s, reason=reason))
+ simple_expr = normalise_simple_license_expr(part)
+ parts.append(simple_expr)
+
+ if stack != 0:
+ reason = 'unbalanced brackets'
+ raise ConfigError(invalid_msg.format(s=s, reason=reason))
+ if parts[-1] in {' AND ', ' OR ', ' WITH '}:
+ last_part = parts[-1].strip()
+ reason = f"a license ID or expression should follow '{last_part}'"
+ raise ConfigError(invalid_msg.format(s=s, reason=reason))
+ except ConfigError:
+ if os.environ.get('FLIT_ALLOW_INVALID'):
+ log.warning(f"Invalid license ID {s!r} allowed by
FLIT_ALLOW_INVALID")
+ return s
+ raise
+
+ return ''.join(parts)
+
+
+def normalise_simple_license_expr(s: str) -> str:
+ """Normalise a simple SPDX license expression.
+
+
https://spdx.github.io/spdx-spec/v2.2.2/SPDX-license-expressions/#d3-simple-license-expressions
"""
- from ._spdx_data import licenses
ls = s.lower()
if ls.startswith('licenseref-'):
- ref = s.partition('-')[2]
- if re.match(r'([a-zA-Z0-9\-.])+$', ref):
+ ref = s[11:]
+ if re.fullmatch(r'[a-zA-Z0-9\-.]+', ref):
# Normalise case of LicenseRef, leave the rest alone
- return "LicenseRef-" + ref
+ return f"LicenseRef-{ref}"
raise ConfigError(
"LicenseRef- license expression can only contain ASCII letters "
"& digits, - and ."
)
- or_later = s.endswith('+')
+ or_later = ls.endswith('+')
if or_later:
ls = ls[:-1]
try:
- info = licenses[ls]
+ normalised_id = licenses[ls]['id']
except KeyError:
- if os.environ.get('FLIT_ALLOW_INVALID'):
- log.warning("Invalid license ID {!r} allowed by FLIT_ALLOW_INVALID"
- .format(s))
- return s
raise ConfigError(f"{s!r} is not a recognised SPDX license ID")
- return info['id'] + ('+' if or_later else '')
+ if or_later:
+ return f'{normalised_id}+'
+ return normalised_id
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/flit_core-3.11.0/flit_core/vendor/tomli-1.2.3.dist-info/METADATA
new/flit_core-3.12.0/flit_core/vendor/tomli-1.2.3.dist-info/METADATA
--- old/flit_core-3.11.0/flit_core/vendor/tomli-1.2.3.dist-info/METADATA
2025-02-19 09:21:57.542935100 +0100
+++ new/flit_core-3.12.0/flit_core/vendor/tomli-1.2.3.dist-info/METADATA
2025-03-25 09:03:05.504557400 +0100
@@ -205,4 +205,3 @@
The parsers are ordered from fastest to slowest, using the fastest parser as
baseline.
Tomli performed the best out of all pure Python TOML parsers,
losing only to pytomlpp (wraps C++) and rtoml (wraps Rust).
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/flit_core-3.11.0/flit_core/versionno.py
new/flit_core-3.12.0/flit_core/versionno.py
--- old/flit_core-3.11.0/flit_core/versionno.py 2025-02-19 09:21:57.542935100
+0100
+++ new/flit_core-3.12.0/flit_core/versionno.py 2025-03-25 09:03:05.504557400
+0100
@@ -124,4 +124,3 @@
log.warning("Version number normalised: {!r} -> {!r} (see PEP 440)"
.format(orig_version, version))
return version
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/flit_core-3.11.0/tests_core/samples/annotated_version/module1.py
new/flit_core-3.12.0/tests_core/samples/annotated_version/module1.py
--- old/flit_core-3.11.0/tests_core/samples/annotated_version/module1.py
1970-01-01 01:00:00.000000000 +0100
+++ new/flit_core-3.12.0/tests_core/samples/annotated_version/module1.py
2025-03-25 09:03:05.505557300 +0100
@@ -0,0 +1,4 @@
+
+"""This module has a __version__ that has a type annotation"""
+
+__version__: str = '0.1'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/flit_core-3.11.0/tests_core/samples/annotated_version/pyproject.toml
new/flit_core-3.12.0/tests_core/samples/annotated_version/pyproject.toml
--- old/flit_core-3.11.0/tests_core/samples/annotated_version/pyproject.toml
1970-01-01 01:00:00.000000000 +0100
+++ new/flit_core-3.12.0/tests_core/samples/annotated_version/pyproject.toml
2025-03-25 09:03:05.505557300 +0100
@@ -0,0 +1,12 @@
+[build-system]
+requires = ["flit_core >=2,<4"]
+build-backend = "flit_core.buildapi"
+
+[tool.flit.metadata]
+module = "module1"
+author = "Sir Robin"
+author-email = "[email protected]"
+home-page = "http://github.com/sirrobin/module1"
+requires = [
+ "numpy >=1.16.0",
+]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/flit_core-3.11.0/tests_core/samples/imported_version/package1/__init__.py
new/flit_core-3.12.0/tests_core/samples/imported_version/package1/__init__.py
---
old/flit_core-3.11.0/tests_core/samples/imported_version/package1/__init__.py
2025-02-19 09:21:57.543935000 +0100
+++
new/flit_core-3.12.0/tests_core/samples/imported_version/package1/__init__.py
2025-03-25 09:03:05.505557300 +0100
@@ -2,4 +2,4 @@
from ._version import __version__
-import a_package_that_doesnt_exist
\ No newline at end of file
+import a_package_that_doesnt_exist
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/flit_core-3.11.0/tests_core/samples/invalid_version1.py
new/flit_core-3.12.0/tests_core/samples/invalid_version1.py
--- old/flit_core-3.11.0/tests_core/samples/invalid_version1.py 2025-02-19
09:21:57.543935000 +0100
+++ new/flit_core-3.12.0/tests_core/samples/invalid_version1.py 2025-03-25
09:03:05.505557300 +0100
@@ -1,3 +1,3 @@
"""Sample module with invalid __version__ string"""
-__version__ = "not starting with a number"
\ No newline at end of file
+__version__ = "not starting with a number"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/flit_core-3.11.0/tests_core/samples/ns1-pkg/ns1/pkg/__init__.py
new/flit_core-3.12.0/tests_core/samples/ns1-pkg/ns1/pkg/__init__.py
--- old/flit_core-3.11.0/tests_core/samples/ns1-pkg/ns1/pkg/__init__.py
2025-02-19 09:21:57.544935200 +0100
+++ new/flit_core-3.12.0/tests_core/samples/ns1-pkg/ns1/pkg/__init__.py
2025-03-25 09:03:05.506557200 +0100
@@ -5,4 +5,3 @@
"""
__version__ = '0.1'
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/flit_core-3.11.0/tests_core/test_common.py
new/flit_core-3.12.0/tests_core/test_common.py
--- old/flit_core-3.11.0/tests_core/test_common.py 2025-02-19
09:21:57.545935200 +0100
+++ new/flit_core-3.12.0/tests_core/test_common.py 2025-03-25
09:03:05.508557300 +0100
@@ -75,6 +75,11 @@
'version': '0.1'}
)
+ info = get_info_from_module(Module('module1', samples_dir /
'annotated_version'))
+ self.assertEqual(info, {'summary': 'This module has a __version__ that
has a type annotation',
+ 'version': '0.1'}
+ )
+
info = get_info_from_module(Module('module1', samples_dir /
'constructed_version'))
self.assertEqual(info, {'summary': 'This module has a __version__ that
requires runtime interpretation',
'version': '1.2.3'}
@@ -210,8 +215,12 @@
('value', 'expected_license', 'expected_license_expression'),
[
({'license': 'MIT'}, 'MIT', None),
+ ({'license': 'MIT OR Apache-2.0'}, 'MIT OR Apache-2.0', None),
+ ({'license': 'MIT AND Apache-2.0'}, 'MIT AND Apache-2.0', None),
({'license_expression': 'MIT'}, None, 'MIT'),
({'license_expression': 'Apache-2.0'}, None, 'Apache-2.0'),
+ ({'license_expression': 'MIT OR Apache-2.0'}, None, 'MIT OR
Apache-2.0'),
+ ({'license_expression': 'MIT AND Apache-2.0'}, None, 'MIT AND
Apache-2.0'),
],
)
def test_metadata_license(value, expected_license,
expected_license_expression):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/flit_core-3.11.0/tests_core/test_config.py
new/flit_core-3.12.0/tests_core/test_config.py
--- old/flit_core-3.11.0/tests_core/test_config.py 2025-02-19
09:21:57.545935200 +0100
+++ new/flit_core-3.12.0/tests_core/test_config.py 2025-03-25
09:03:05.508557300 +0100
@@ -1,4 +1,5 @@
import logging
+import re
import sys
from pathlib import Path
import pytest
@@ -139,6 +140,14 @@
({'version': 1}, r'\bstr\b'),
({'license': {'fromage': 2}}, '[Uu]nrecognised'),
({'license': {'file': 'LICENSE', 'text': 'xyz'}}, 'both'),
+ (
+ {'license': {'file': '/LICENSE'}},
+ re.escape("License file path (/LICENSE) cannot be an absolute path"),
+ ),
+ (
+ {'license': {'file': '../LICENSE'}},
+ re.escape("License file path (../LICENSE) cannot contain '..'"),
+ ),
({'license': {}}, 'required'),
({'license': 1}, "license field should be <class 'str'> or <class 'dict'>,
not <class 'int'>"),
# ({'license': "MIT License"}, "Invalid license expression: 'MIT
License'"), # TODO
@@ -213,8 +222,17 @@
("mit", "MIT"),
("apache-2.0", "Apache-2.0"),
("APACHE-2.0+", "Apache-2.0+"),
- # TODO: compound expressions
- #("mit and (apache-2.0 or bsd-2-clause)", "MIT AND (Apache-2.0 OR
BSD-2-Clause)"),
+ ("mit AND (apache-2.0 OR bsd-2-clause)", "MIT AND (Apache-2.0 OR
BSD-2-Clause)"),
+ ("(mit)", "(MIT)"),
+ ("MIT OR Apache-2.0", "MIT OR Apache-2.0"),
+ ("MIT AND Apache-2.0", "MIT AND Apache-2.0"),
+ ("MIT AND Apache-2.0+ OR 0BSD", "MIT AND Apache-2.0+ OR 0BSD"),
+ ("MIT AND (Apache-2.0+ OR (0BSD))", "MIT AND (Apache-2.0+ OR (0BSD))"),
+ ("MIT OR(mit)", "MIT OR (MIT)"),
+ ("(mit)AND mit", "(MIT) AND MIT"),
+ ("MIT OR (MIT OR ( MIT )) AND ((MIT) AND MIT) OR MIT", "MIT OR (MIT OR
(MIT)) AND ((MIT) AND MIT) OR MIT"),
+ ("LICENSEREF-Public-Domain OR cc0-1.0 OR unlicense",
"LicenseRef-Public-Domain OR CC0-1.0 OR Unlicense"),
+ ("mit AND ( apache-2.0+ OR mpl-2.0+ )", "MIT AND (Apache-2.0+ OR
MPL-2.0+)"),
# LicenseRef expressions: only the LicenseRef is normalised
("LiceNseref-Public-DoMain", "LicenseRef-Public-DoMain"),
])
@@ -226,19 +244,143 @@
assert 'license' not in info.metadata
assert info.metadata['license_expression'] == license_expression
-def test_license_expr_error():
[email protected]('invalid_expr', [
+ "LicenseRef-foo_bar",
+ "LicenseRef-foo~bar",
+ "LicenseRef-foo:bar",
+ "LicenseRef-foo[bar]",
+ "LicenseRef-foo-bar+",
+])
+def test_license_expr_error_licenseref(invalid_expr: str):
proj = {
'name': 'module1', 'version': '1.0', 'description': 'x',
- 'license': 'LicenseRef-foo_bar', # Underscore not allowed
+ 'license': invalid_expr,
}
with pytest.raises(config.ConfigError, match="can only contain"):
config.read_pep621_metadata(proj, samples_dir / 'pep621' /
'pyproject.toml')
- proj['license'] = "BSD-33-Clause" # Not a real license
+
[email protected]('invalid_expr', [
+ # Not a real licence
+ "BSD-33-Clause",
+ "MIT OR BSD-33-Clause",
+ "MIT OR (MIT AND BSD-33-Clause)",
+])
+def test_license_expr_error_not_recognised(invalid_expr: str):
+ proj = {
+ 'name': 'module1', 'version': '1.0', 'description': 'x',
+ 'license': invalid_expr,
+ }
with pytest.raises(config.ConfigError, match="recognised"):
config.read_pep621_metadata(proj, samples_dir / 'pep621' /
'pyproject.toml')
[email protected]('invalid_expr', [
+ # No operator
+ "MIT MIT",
+ "MIT OR (MIT MIT)",
+ # Only operator
+ "AND",
+ "OR",
+ "AND AND AND",
+ "OR OR OR",
+ "OR AND OR",
+ "AND OR OR AND OR OR AND",
+ # Too many operators
+ "MIT AND AND MIT",
+ "MIT OR OR OR MIT",
+ "MIT AND OR MIT",
+ # Mixed case operator
+ "MIT aND MIT",
+ "MIT oR MIT",
+ "MIT AND MIT oR MIT",
+ # Missing operand
+ "MIT AND",
+ "AND MIT",
+ "MIT OR",
+ "OR MIT",
+ "MIT (AND MIT)",
+ "(MIT OR) MIT",
+ # Unbalanced brackets
+ ")(",
+ "(",
+ ")",
+ "MIT OR ()",
+ ") AND MIT",
+ "MIT OR (",
+ "MIT OR (MIT))",
+ # Only brackets
+ "()",
+ "()()",
+ "()(())",
+ "( )",
+ " ( )",
+ "( ) ",
+ " ( ) ",
+])
+def test_license_expr_error(invalid_expr: str):
+ proj = {
+ 'name': 'module1', 'version': '1.0', 'description': 'x',
+ 'license': invalid_expr,
+ }
+ with pytest.raises(config.ConfigError, match="is not a valid"):
+ config.read_pep621_metadata(proj, samples_dir / 'pep621' /
'pyproject.toml')
+
+
[email protected]('invalid_expr', [
+ "",
+ " ",
+ "\t",
+ "\r",
+ "\n",
+ "\f",
+ " \t \n \r \f ",
+])
+def test_license_expr_error_empty(invalid_expr: str):
+ proj = {
+ 'name': 'module1', 'version': '1.0', 'description': 'x',
+ 'license': invalid_expr,
+ }
+ with pytest.raises(config.ConfigError, match="must not be empty"):
+ config.read_pep621_metadata(proj, samples_dir / 'pep621' /
'pyproject.toml')
+
+
[email protected]('invalid_expr', [
+ "mit or mit",
+ "or",
+ "and",
+ "MIT and MIT",
+ "MIT AND MIT or MIT",
+ "MIT AND (MIT or MIT)",
+])
+def test_license_expr_error_lowercase(invalid_expr: str):
+ proj = {
+ 'name': 'module1', 'version': '1.0', 'description': 'x',
+ 'license': invalid_expr,
+ }
+ with pytest.raises(config.ConfigError, match="must be uppercase"):
+ config.read_pep621_metadata(proj, samples_dir / 'pep621' /
'pyproject.toml')
+
+
[email protected]('invalid_expr', [
+ "WITH",
+ "with",
+ "WiTh",
+ "wiTH",
+ "MIT WITH MIT-Exception",
+ "(MIT WITH MIT-Exception)",
+ "MIT OR MIT WITH MIT-Exception",
+ "MIT WITH MIT-Exception OR (MIT AND MIT)",
+])
+def test_license_expr_error_unsupported_with(invalid_expr: str):
+ proj = {
+ 'name': 'module1', 'version': '1.0', 'description': 'x',
+ 'license': invalid_expr,
+ }
+ with pytest.raises(config.ConfigError, match="not yet supported"):
+ config.read_pep621_metadata(proj, samples_dir / 'pep621' /
'pyproject.toml')
+
+
def test_license_file_defaults_with_old_metadata():
metadata = {'module': 'mymod', 'author': ''}
info = config._prep_metadata(metadata, samples_dir /
'pep621_license_files' / 'pyproject.toml')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/flit_core-3.11.0/tests_core/test_wheel.py
new/flit_core-3.12.0/tests_core/test_wheel.py
--- old/flit_core-3.11.0/tests_core/test_wheel.py 2025-02-19
09:21:57.546935000 +0100
+++ new/flit_core-3.12.0/tests_core/test_wheel.py 2025-03-25
09:03:05.508557300 +0100
@@ -39,7 +39,7 @@
with ZipFile(wheels[0], 'r') as zf:
assert 'module1a.py' in zf.namelist()
-
+
def test_data_dir(tmp_path):
info = make_wheel_in(samples_dir / 'with_data_dir' / 'pyproject.toml',
tmp_path)
assert_isfile(info.file)