Skip to content

Commit

Permalink
Fix GitHub Action Workflows and Add Support for Newer Python Versions (
Browse files Browse the repository at this point in the history
…#29)

* Use ubuntu 20 instead of latest

* Add python 3.10, 3.11, and 3.12

* Update action versions and use poetry cache

* Install poetry before using cache

* Use matrix for different os versions

* Fix mypy install failure

* Fix pathlib subclassing and strtobool distutils deprecation

* Pin poetry in CI to 1.7.0

* Remove 3.11 and 3.12 temporarily

* Add 3.11

* Add coverage.xml to gitignore

* Only run 3.11 temporarily

* Temp test command change

* Use cov report

* Show files

* Use newer pytest versions for newer python versions

* Try using 3.12

* Tweak command

* Test using coverage directly

* Use poetry run

* Fix typo

* Add back other python versions

* Remove test_ci task

* Add changelog entry
  • Loading branch information
eugenetriguba authored Nov 5, 2023
1 parent 0c70929 commit fa90fba
Show file tree
Hide file tree
Showing 8 changed files with 1,007 additions and 629 deletions.
30 changes: 20 additions & 10 deletions .github/workflows/python-package-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,40 @@ on: [push, pull_request]

jobs:
build:
runs-on: ubuntu-latest
runs-on: ubuntu-20.04
strategy:
matrix:
python-version: [3.6, 3.7, 3.8, 3.9]
python-version:
- 3.6
- 3.7
- 3.8
- 3.9
- '3.10'
- '3.11'
- '3.12'

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3

- name: Install poetry
run: pipx install poetry==1.7.0

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
cache: 'poetry'

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install poetry
poetry install -E toml -E yaml
run: poetry install -E toml -E yaml

- name: Run tests
run: poetry run task test_ci
run: |
poetry run pytest --cov=config_file/ --cov-report=term-missing
poetry run coverage xml -o coverage.xml
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v1
uses: codecov/codecov-action@v3
with:
token: ${{ secrets.CODECOV_TOKEN }}
file: ./coverage.xml
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ __pycache__/
.coverage
.benchmarks/
.mypy_cache/
coverage.xml

# Package Publishing
dist/
Expand Down
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## Unreleased

### Added

- Support for Python 3.9, 3.10, 3.11, and 3.12. The way `pathlib.Path` was being subclassed
was causing issues in newer Python versions and `distutils.util.strtobool` has been removed
in newer Python versions so a backported version is now being used.

## 0.12.0 - 2020-10-03

### Added
Expand Down
10 changes: 2 additions & 8 deletions config_file/config_file_path.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import os
from pathlib import Path as _Path_
from pathlib import _posix_flavour, _windows_flavour
from pathlib import Path
from typing import Type

from config_file.parsers.abstract_parser import AbstractParser
Expand All @@ -12,19 +11,14 @@
from .utils import split_on_dot


class ConfigFilePath(_Path_):
class ConfigFilePath(type(Path())):
"""A ConfigFilePath object, which subclasses Path.
It provides us easy ways to grab the original config file
path, file extension, validate the path, or determine the parser
that should be use for the given file type.
See https://codereview.stackexchange.com/questions/162426/subclassing-pathlib-path
for more details on subclassing the pathlib.Path object.
"""

_flavour = _windows_flavour if os.name == "nt" else _posix_flavour

@property
def original_path(self) -> "ConfigFilePath":
"""Computes the original configuration file path.
Expand Down
17 changes: 16 additions & 1 deletion config_file/parsers/parse_value.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
"""This module allows you to parse a string into its native type."""
import ast
import re
from distutils.util import strtobool
from typing import Any


Expand Down Expand Up @@ -149,6 +148,22 @@ def can_be_parsed_as_bool(value: Any) -> bool:
return value == "true" or value == "false"


# distutils strtobool backport: https://github.com/yukinarit/strtobool
def strtobool(val):
"""Convert a string representation of truth to true (1) or false (0).
True values are 'y', 'yes', 't', 'true', 'on', and '1'; false values
are 'n', 'no', 'f', 'false', 'off', and '0'. Raises ValueError if
'val' is anything else.
"""
val = val.lower()
if val in ('y', 'yes', 't', 'true', 'on', '1'):
return 1
elif val in ('n', 'no', 'f', 'false', 'off', '0'):
return 0
else:
raise ValueError("invalid truth value %r" % (val,))


def can_be_parsed_as_dict(value: Any) -> bool:
"""Checks whether a value can be parsed as a dictionary.
Expand Down
1,532 changes: 942 additions & 590 deletions poetry.lock

Large diffs are not rendered by default.

22 changes: 17 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ packages = [
[tool.taskipy.tasks]
test = "task test_cov -- --cov-report term-missing"
test_cov = "task pytest -- --cov=config_file/"
test_ci = "task test_cov -- --cov-report=xml"
lint = "task lint_types && task lint_precommit"
lint_types = "poetry run mypy config_file/ tests/"
lint_precommit = "poetry run pre-commit run --all"
Expand All @@ -49,14 +48,27 @@ pre-commit = { version = "^2.1", python = "^3.6.1" }
autoflake = "^1.3.1"
isort = "^5.6.4"
seed-isort-config = { version = "^2.1.1", python = "^3.6.1" }
pytest = "^6.0.0"
pytest-cov = "^2.8.1"
pytest-sugar = "^0.9.3"
pytest = [
{ version = "^6.0.0", python = ">=3.6,<3.7" },
{ version = "^7", python = ">=3.7,<4.0" }
]
pytest-cov = [
{ version = "^2.8.1", python = ">=3.6,<3.7" },
{ version = "^4", python = ">=3.7,<4.0" }
]
pytest-sugar = [
{ version = "^0.9.3", python = ">=3.6,<3.7" },
{ version = "^0.9.7", python = ">=3.7,<4.0" }
]
taskipy = "^1.2.1"
bump2version = "^1.0.0"
flake8 = "^3.7.9"
black = "^20.8b1"
mypy = "^0.782"
mypy = [
{ version = "^0.971", python = ">=3.6,<3.8" },
{ version = "^1.6", python = "^3.8"}
]

[tool.black]
target_version = ['py36']
include = '\.pyi?$'
Expand Down
16 changes: 1 addition & 15 deletions tests/test_config_file_path.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import os
from pathlib import Path, _posix_flavour, _windows_flavour
from pathlib import Path

import pytest

Expand All @@ -20,20 +20,6 @@ def test_config_file_path_is_a_path():
assert isinstance(ConfigFilePath("."), Path)


def test_config_file_path_has_the_correct_flavour():
"""
config_file.config_file_path.ConfigFilePath
Ensure that the ConfigFilePath object has the
correct Path flavor (since Path is actually
swapped out, depending on the operating system,
to a Posix flavour or Windows flavour)
"""
path = ConfigFilePath(".")

assert path._flavour == _windows_flavour if os.name == "nt" else _posix_flavour


def test_config_file_path_is_able_to_read_the_contents(template_file):
"""
config_file.config_file_path.ConfigFilePath
Expand Down

0 comments on commit fa90fba

Please sign in to comment.