Skip to content

Commit

Permalink
Test on more versions of Python (#563)
Browse files Browse the repository at this point in the history
* Add Python versions from 3.8 to the GHA test matrix

* Improve error message for missing conda-recipe-manager

* Remove conda-recipe-manager from environment.yml

* Enable new-style type annotations for py<3.10

* Apply ruff fixes

* Split double context manager call

This enables Python 3.8 compatibility

* Switch to setup-micromamba

* Install conda-recipe-manager in CI if possible
  • Loading branch information
maresb authored Sep 29, 2024
1 parent 7de08dc commit 3402aa0
Show file tree
Hide file tree
Showing 9 changed files with 117 additions and 90 deletions.
36 changes: 25 additions & 11 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,35 +8,51 @@ on:
branches:
- "*"

defaults:
run:
shell: bash -l {0}

jobs:
run:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
py_ver: ["3.11", "3.12"]
py_ver: ["3.8", "3.9", "3.10", "3.11", "3.12"]
env:
OS: ${{ matrix.os }}
PYTHON: ${{ matrix.py_ver }}
steps:
- uses: actions/checkout@master
- uses: conda-incubator/setup-[email protected]
- uses: mamba-org/setup-micromamba@v1
with:
auto-update-conda: true
channels: conda-forge,defaults
channel-priority: true
python-version: ${{ matrix.py_ver }}
####
# https://github.com/mamba-org/setup-micromamba/issues/225
micromamba-version: 1.5.10-0
micromamba-binary-path: /home/runner/micromamba-bin-versioned/micromamba
####
environment-file: environment.yaml
activate-environment: gs
# Added an extra python to the create-args in order to bust the cache:
create-args: >-
python=${{ matrix.py_ver }}
python
cache-environment: true
- name: Install conda-recipe-manager if possible
# Possible when the Python version is >=3.11
run: |
if [ $(python -c "import sys; print(sys.version_info[:2] >= (3,11))") = "True" ]; then
echo "Installing conda-recipe-manager"
micromamba install -y -c conda-forge conda-recipe-manager
else
echo "Skipping conda-recipe-manager installation"
fi
- name: Conda info
shell: bash -l {0}
run: |
conda info --all
conda list
- name: Running doctests
shell: bash -l {0}
run: |
pytest grayskull \
-vv \
Expand All @@ -51,7 +67,6 @@ jobs:
--junit-prefix=Linux-py${{ matrix.py_ver }}-serial
- name: Running serial tests
shell: bash -l {0}
run: |
pytest tests \
-vv \
Expand All @@ -67,7 +82,6 @@ jobs:
--junit-prefix=Linux-py${{ matrix.py_ver }}-serial
- name: Running parallel tests
shell: bash -l {0}
run: |
pytest tests \
-vv \
Expand Down
1 change: 0 additions & 1 deletion environment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,3 @@ dependencies:
- libcblas
- beautifulsoup4
- semver >=3.0.0,<4.0.0
- conda-recipe-manager >=0.2.0
2 changes: 2 additions & 0 deletions grayskull/base/factory.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from __future__ import annotations

import re
from abc import ABC
from pathlib import Path
Expand Down
53 changes: 27 additions & 26 deletions grayskull/license/discovery.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from __future__ import annotations

import base64
import json
import logging
Expand All @@ -10,7 +12,6 @@
from pathlib import Path
from subprocess import check_output
from tempfile import mkdtemp
from typing import List, Optional, Tuple, Union

import requests
from colorama import Fore
Expand All @@ -27,12 +28,12 @@
@dataclass
class ShortLicense:
name: str
path: Union[str, Path, None]
path: str | Path | None
is_packaged: bool


@lru_cache(maxsize=10)
def get_all_licenses_from_spdx() -> List:
def get_all_licenses_from_spdx() -> list:
"""Get all licenses available on spdx.org
:return: List with all licenses information on spdx.org
Expand Down Expand Up @@ -163,7 +164,7 @@ def get_short_license_id(name: str) -> str:
return recipe_license["licenseId"]


def _get_license(license_id: str, all_licenses: List) -> dict:
def _get_license(license_id: str, all_licenses: list) -> dict:
"""Search for the license identification in all licenses received
:param license_id: license identification
Expand All @@ -175,7 +176,7 @@ def _get_license(license_id: str, all_licenses: List) -> dict:
return one_license


def _get_all_names_from_api(one_license: dict) -> List:
def _get_all_names_from_api(one_license: dict) -> list:
"""Get the names and other names which each license has.
:param one_license: License name
Expand All @@ -191,7 +192,7 @@ def _get_all_names_from_api(one_license: dict) -> List:
return list(result)


def get_other_names_from_opensource(license_spdx: str) -> List:
def get_other_names_from_opensource(license_spdx: str) -> list:
lic = get_opensource_license(license_spdx)
return [_license["name"] for _license in lic.get("other_names", [])]

Expand All @@ -213,7 +214,7 @@ def read_licence_cache():


@lru_cache(maxsize=10)
def get_opensource_license_data() -> List:
def get_opensource_license_data() -> list:
try:
response = requests.get(url="https://api.opensource.org/licenses/", timeout=5)
except requests.exceptions.RequestException:
Expand All @@ -223,7 +224,7 @@ def get_opensource_license_data() -> List:
return response.json()


def _get_all_license_choice(all_licenses: List) -> List:
def _get_all_license_choice(all_licenses: list) -> list:
"""Function responsible to get the whole licenses name
:param all_licenses: list with all licenses
Expand All @@ -237,11 +238,11 @@ def _get_all_license_choice(all_licenses: List) -> List:

def search_license_file(
folder_path: str,
git_url: Optional[str] = None,
version: Optional[str] = None,
license_name_metadata: Optional[str] = None,
folders_exclude_search: Tuple[str] = tuple(),
) -> List[ShortLicense]:
git_url: str | None = None,
version: str | None = None,
license_name_metadata: str | None = None,
folders_exclude_search: tuple[str] = tuple(),
) -> list[ShortLicense]:
"""Search for the license file. First it will try to find it in the given
folder, after that it will search on the github api and for the last it will
clone the repository and it will search for the license there.
Expand Down Expand Up @@ -286,8 +287,8 @@ def search_license_file(

@lru_cache(maxsize=13)
def search_license_api_github(
github_url: str, version: Optional[str] = None, default: Optional[str] = "Other"
) -> Optional[ShortLicense]:
github_url: str, version: str | None = None, default: str | None = "Other"
) -> ShortLicense | None:
"""Search for the license asking in the github api
:param github_url: GitHub URL
Expand Down Expand Up @@ -315,7 +316,7 @@ def search_license_api_github(
)


def _get_api_github_url(github_url: str, version: Optional[str] = None) -> str:
def _get_api_github_url(github_url: str, version: str | None = None) -> str:
"""Try to presume the github url
:param github_url: GitHub URL
Expand All @@ -331,10 +332,10 @@ def _get_api_github_url(github_url: str, version: Optional[str] = None) -> str:


def search_license_folder(
path: Union[str, Path],
default: Optional[str] = None,
folders_exclude_search: Tuple[str] = tuple(),
) -> List[ShortLicense]:
path: str | Path,
default: str | None = None,
folders_exclude_search: tuple[str] = tuple(),
) -> list[ShortLicense]:
"""Search for the license in the given folder
:param path: Sdist folder
Expand Down Expand Up @@ -366,10 +367,10 @@ def search_license_folder(

def search_license_repo(
git_url: str,
version: Optional[str],
default: Optional[str] = None,
folders_exclude_search: Tuple[str] = tuple(),
) -> Optional[List[ShortLicense]]:
version: str | None,
default: str | None = None,
folders_exclude_search: tuple[str] = tuple(),
) -> list[ShortLicense] | None:
"""Search for the license file in the given github repository
:param git_url: GitHub URL
Expand Down Expand Up @@ -399,7 +400,7 @@ def search_license_repo(
)


def _get_git_cmd(git_url: str, version: str, dest) -> List[str]:
def _get_git_cmd(git_url: str, version: str, dest) -> list[str]:
"""Return the full git command to clone the repository
:param git_url: GitHub URL
Expand All @@ -413,7 +414,7 @@ def _get_git_cmd(git_url: str, version: str, dest) -> List[str]:
return git_cmd + [git_url, str(dest)]


def get_license_type(path_license: str, default: Optional[str] = None) -> Optional[str]:
def get_license_type(path_license: str, default: str | None = None) -> str | None:
"""Function tries to match the license with one of the models present in
grayskull/license/data
Expand Down
5 changes: 3 additions & 2 deletions grayskull/main.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
from __future__ import annotations

import argparse
import logging
import os
import sys
from pathlib import Path
from typing import List, Optional

import requests
from colorama import Fore, Style, init
Expand Down Expand Up @@ -445,7 +446,7 @@ def create_r_recipe(pkg_name, sections_populate=None, **kwargs):
)


def add_extra_section(recipe, maintainers: Optional[List] = None):
def add_extra_section(recipe, maintainers: list | None = None):
maintainers = maintainers or [get_git_current_user()]
if "extra" in recipe:
recipe["extra"]["recipe-maintainers"] = maintainers
Expand Down
5 changes: 3 additions & 2 deletions grayskull/strategy/cran.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from __future__ import annotations

import logging
import os
import re
Expand All @@ -7,7 +9,6 @@
from copy import deepcopy
from os.path import basename
from tempfile import mkdtemp
from typing import Optional
from urllib.request import Request, urlopen

import requests
Expand Down Expand Up @@ -235,7 +236,7 @@ def get_webpage(cran_url):
return BeautifulSoup(html_page, features="html.parser")


def get_cran_index(cran_url: str, pkg_name: str, pkg_version: Optional[str] = None):
def get_cran_index(cran_url: str, pkg_name: str, pkg_version: str | None = None):
"""Fetch the entire CRAN index and store it."""
print_msg(f"Fetching main index from {cran_url}")

Expand Down
Loading

0 comments on commit 3402aa0

Please sign in to comment.