Skip to content

Commit

Permalink
Merge pull request #3233 from regro/noarch-py-upper
Browse files Browse the repository at this point in the history
fix: handle upper bounds for `noarch: python` min migration
  • Loading branch information
beckermr authored Nov 28, 2024
2 parents 396be94 + 19ec004 commit 8b0b79d
Show file tree
Hide file tree
Showing 5 changed files with 299 additions and 10 deletions.
2 changes: 1 addition & 1 deletion conda_forge_tick/make_migrators.py
Original file line number Diff line number Diff line change
Expand Up @@ -773,7 +773,7 @@ def initialize_migrators(
"To maintain the old behavior you should migrate to astropy-base.",
)

#add_noarch_python_min_migrator(migrators, gx)
add_noarch_python_min_migrator(migrators, gx)

pinning_migrators: List[Migrator] = []
migration_factory(pinning_migrators, gx)
Expand Down
73 changes: 67 additions & 6 deletions conda_forge_tick/migrators/noarch_python_min.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,61 @@ def _has_req_section(lines, section_name):
return False


def _extract_bounds(req):
comma_parts = req.split(",")
parts = []
for part in comma_parts:
parts += part.split("|")
num_upper = sum("<" in part for part in parts)
if num_upper == 1:
for part in parts:
if "<" in part:
upper = part
break
upper_ver = upper.replace("<=", "").replace("<", "").strip()
if "<=" in upper:
upper_ver = upper_ver.split(".")
if len(upper_ver) < 2:
upper_ver.append("0")
upper_ver[-1] = str(int(upper_ver[-1]) + 1)
upper_ver[-1] = upper_ver[-1] + "a0"
upper_ver = ".".join(upper_ver)
elif num_upper == 0:
upper_ver = None
else:
raise RuntimeError(
"Encountered a python requirement `{req}` that cannot easily be "
"handled by the bot for setting the runtime python "
"version range. The bot will not be able to issue the "
"`noarch: python` min migration PR!"
)

num_lower = sum(">" in part for part in parts)
if num_lower == 1:
for part in parts:
if ">" in part:
lower = part
break
lower_ver = lower.replace(">=", "").replace(">", "").strip()
if ">" in lower and ">=" not in lower:
lower_ver = lower_ver.split(".")
if len(lower_ver) < 2:
lower_ver.append("0")
lower_ver[-1] = str(int(lower_ver[-1]) + 1)
lower_ver = ".".join(lower_ver)
elif num_lower == 0:
lower_ver = None
else:
raise RuntimeError(
"Encountered a python requirement `{req}` that cannot easily be "
"handled by the bot for setting the runtime python "
"version range. The bot will not be able to issue the "
"`noarch: python` min migration PR!"
)

return lower_ver, upper_ver


def _process_req_list(section, req_list_name, new_python_req, force_apply=False):
found_it = False
new_lines = []
Expand Down Expand Up @@ -175,16 +230,22 @@ def _process_req_list(section, req_list_name, new_python_req, force_apply=False)

if name == "python" and (force_apply or req == ""):
adjusted_python = True

_new_py_req = new_python_req
if req_list_name == "run":
py_lower_bound, py_upper_bound = _extract_bounds(req)
if py_upper_bound is not None:
_new_py_req = new_python_req + f",<{py_upper_bound}"
if py_lower_bound is not None:
python_min_override = py_lower_bound

new_line = (
indent_to_keep
+ "- python "
+ new_python_req
+ _new_py_req
+ (" # " + comment if comment != "" else "")
+ "\n"
)
if req.startswith(">="):
python_min_override = req[2:].strip()

else:
new_line = line
else:
Expand Down Expand Up @@ -254,11 +315,11 @@ def _process_section(
if (not _has_noarch_python(section)) and (not force_noarch_python):
return section, None

found_it, section, python_min_override = _process_req_list(
found_it, section, _ = _process_req_list(
section, build_or_host, "{{ python_min }}", force_apply=force_apply
)
logger.debug("applied `noarch: python` host? %s", found_it)
found_it, section, _ = _process_req_list(
found_it, section, python_min_override = _process_req_list(
section, "run", ">={{ python_min }}", force_apply=force_apply
)
logger.debug("applied `noarch: python` to run? %s", found_it)
Expand Down
127 changes: 124 additions & 3 deletions tests/test_noarch_python_min_migrator.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,46 @@
"""
),
),
(
textwrap.dedent(
"""\
build:
noarch: python
requirements:
host:
- python 3.6.* # this is cool
- numpy
run:
- python <=3.12
- numpy
test:
requires:
- python =3.6
- numpy
"""
),
textwrap.dedent(
"""\
build:
noarch: python
requirements:
host:
- python {{ python_min }} # this is cool
- numpy
run:
- python >={{ python_min }},<3.13a0
- numpy
test:
requires:
- python {{ python_min }}
- numpy
"""
),
),
(
textwrap.dedent(
f"""\
Expand All @@ -157,7 +197,7 @@
- python >={NEXT_GLOBAL_PYTHON_MIN} # this is cool
- numpy
run:
- python
- python >={NEXT_GLOBAL_PYTHON_MIN}
- numpy
test:
Expand Down Expand Up @@ -198,7 +238,7 @@
- python >={GLOBAL_PYTHON_MIN} # this is cool
- numpy
run:
- python
- python >={GLOBAL_PYTHON_MIN}
- numpy
test:
Expand Down Expand Up @@ -227,6 +267,87 @@
"""
),
),
(
textwrap.dedent(
f"""\
build:
noarch: python
requirements:
host:
- python >={NEXT_GLOBAL_PYTHON_MIN} # this is cool
- numpy
run:
- python >={NEXT_GLOBAL_PYTHON_MIN},<3.13
- numpy
test:
requires:
- python =3.6
- numpy
"""
),
textwrap.dedent(
f"""\
{{% set python_min = '{NEXT_GLOBAL_PYTHON_MIN}' %}}
build:
noarch: python
requirements:
host:
- python {{{{ python_min }}}} # this is cool
- numpy
run:
- python >={{{{ python_min }}}},<3.13
- numpy
test:
requires:
- python {{{{ python_min }}}}
- numpy
"""
),
),
(
textwrap.dedent(
f"""\
build:
noarch: python
requirements:
host:
- python >={GLOBAL_PYTHON_MIN} # this is cool
- numpy
run:
- python >={GLOBAL_PYTHON_MIN},<3.12
- numpy
test:
requires:
- python =3.6
- numpy
"""
),
textwrap.dedent(
"""\
build:
noarch: python
requirements:
host:
- python {{ python_min }} # this is cool
- numpy
run:
- python >={{ python_min }},<3.12
- numpy
test:
requires:
- python {{ python_min }}
- numpy
"""
),
),
(
textwrap.dedent(
"""\
Expand Down Expand Up @@ -430,7 +551,7 @@ def test_apply_noarch_python_min(
assert f.read() == expected_meta_yaml


@pytest.mark.parametrize("name", ["seaborn", "extra_new_line"])
@pytest.mark.parametrize("name", ["seaborn", "extra_new_line", "zospy"])
def test_noarch_python_min_migrator(tmpdir, name):
with open(
os.path.join(TEST_YAML_PATH, f"noarch_python_min_{name}_before_meta.yaml")
Expand Down
54 changes: 54 additions & 0 deletions tests/test_yaml/noarch_python_min_zospy_after_meta.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
{% set name = "zospy" %}
{% set version = "1.3.0" %}

package:
name: {{ name|lower }}
version: {{ version }}

source:
url: https://pypi.io/packages/source/{{ name[0] }}/{{ name }}/zospy-{{ version }}.tar.gz
sha256: 202d05fda8f8a81db6ddadd62712424763e1abd51d56d6c30fbaaf07463083b2

build:
noarch: python
script: {{ PYTHON }} -m pip install . -vv --no-deps --no-build-isolation
number: 1

requirements:
host:
- python {{ python_min }}
- flit-core >=3.2,<4
- pip
run:
- eval_type_backport
- lark ~=1.2.0
- pydantic >=2.4.0
- python >={{ python_min }},<3.13
- pythonnet >=3.0.1,<3.1.dev0
- pandas
- numpy
- semver >=3.0.0,<3.1.dev0
- __win

test:
imports:
- zospy
commands:
- pip check
requires:
- pip
- python {{ python_min }}

about:
home: https://zospy.readthedocs.io/
summary: A Python package used to communicate with Zemax OpticStudio through the API
doc_url: https://zospy.readthedocs.io/
dev_url: https://github.com/MREYE-LUMC/ZOSPy/
license: MIT
license_file: LICENSE.txt

extra:
recipe-maintainers:
- LucVV
- crnh
- jwmbeenakker
53 changes: 53 additions & 0 deletions tests/test_yaml/noarch_python_min_zospy_before_meta.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
{% set name = "zospy" %}
{% set version = "1.3.0" %}

package:
name: {{ name|lower }}
version: {{ version }}

source:
url: https://pypi.io/packages/source/{{ name[0] }}/{{ name }}/zospy-{{ version }}.tar.gz
sha256: 202d05fda8f8a81db6ddadd62712424763e1abd51d56d6c30fbaaf07463083b2

build:
noarch: python
script: {{ PYTHON }} -m pip install . -vv --no-deps --no-build-isolation
number: 0

requirements:
host:
- python >=3.9,<3.13
- flit-core >=3.2,<4
- pip
run:
- eval_type_backport
- lark ~=1.2.0
- pydantic >=2.4.0
- python >=3.9,<3.13
- pythonnet >=3.0.1,<3.1.dev0
- pandas
- numpy
- semver >=3.0.0,<3.1.dev0
- __win

test:
imports:
- zospy
commands:
- pip check
requires:
- pip

about:
home: https://zospy.readthedocs.io/
summary: A Python package used to communicate with Zemax OpticStudio through the API
doc_url: https://zospy.readthedocs.io/
dev_url: https://github.com/MREYE-LUMC/ZOSPy/
license: MIT
license_file: LICENSE.txt

extra:
recipe-maintainers:
- LucVV
- crnh
- jwmbeenakker

0 comments on commit 8b0b79d

Please sign in to comment.