diff options
author | Thomas Touhey <thomas@touhey.fr> | 2021-12-31 21:43:10 +0100 |
---|---|---|
committer | Thomas Touhey <thomas@touhey.fr> | 2021-12-31 21:43:58 +0100 |
commit | f7ebc55d149a600ab0d5bdbdb0d3693f394c8d89 (patch) | |
tree | cef2f6f81c5c64d0729e0611f97078a2139e8a76 | |
parent | 542a4bcb3ca5fc0c867c07c399dd16e8642f68d9 (diff) |
Compatibility with Python < 3.10
-rwxr-xr-x | Makefile | 2 | ||||
-rw-r--r-- | setup.cfg | 3 | ||||
-rw-r--r-- | thcolor/colors.py | 6 | ||||
-rw-r--r-- | thcolor/decoders/base.py | 51 |
4 files changed, 54 insertions, 8 deletions
@@ -2,7 +2,7 @@ DNAME := dist/$(shell ./setup.py --name)-$(shell ./setup.py --version).tar.gz test tests: - @pytest -s -q + @pytest -s docs: @./setup.py build_sphinx @@ -23,8 +23,7 @@ classifiers = zip_safe = False include_package_data = True packages = thcolor, thcolor.builtin -install_requires = - regex +python_requires = >= 3.6 [options.package_data] * = *.txt, *.rst diff --git a/thcolor/colors.py b/thcolor/colors.py index afbfd58..d459886 100644 --- a/thcolor/colors.py +++ b/thcolor/colors.py @@ -5,11 +5,13 @@ # ***************************************************************************** """ Color representations and conversions. """ -from collections.abc import Mapping as _Mapping, Sequence as _Sequence from math import ( atan2 as _atan2, ceil as _ceil, cos as _cos, sin as _sin, sqrt as _sqrt, ) -from typing import Optional as _Optional, Tuple as _Tuple +from typing import ( + Optional as _Optional, Tuple as _Tuple, Mapping as _Mapping, + Sequence as _Sequence, +) from .angles import ( Angle as _Angle, DegreesAngle as _DegreesAngle, diff --git a/thcolor/decoders/base.py b/thcolor/decoders/base.py index 227b0a6..0f4d7cf 100644 --- a/thcolor/decoders/base.py +++ b/thcolor/decoders/base.py @@ -48,6 +48,51 @@ def _factor(x, max_=100): return x / max_ +def _issubclass(cls, types): + """ Check if ``cls`` is a subclass of ``types``. + + Until Python 3.10, this function is not aware of the special + types available in the standard ``typing`` module; this function + aims at fixing this for Python <= 3.9. + """ + + # Check if is a special case from typing that we know of. + + try: + origin = types.__origin__ + except AttributeError: + if types is _Any: + return True + else: + if origin is _Union or origin is _Optional: + return any(_issubclass(cls, type_) for type_ in types.__args__) + + # If ``types`` is any iterable type (tuple, list, you name it), + # then we check if the class is a subclass of at least one element + # in the iterable. + + try: + types_iter = iter(types) + except TypeError: + pass + else: + return any(_issubclass(cls, type_) for type_ in types) + + # We default on the base ``issubclass`` from here. + + return issubclass(cls, types) + + +def _isinstance(value, types): + """ Check if ``cls`` is a subclass of ``types``. + + Until Python 3.10, this function is not aware of the special + types available in the standard ``typing`` module; this function + aims at fixing this for Python <= 3.9. + """ + + return _issubclass(type(value), types) + def _get_args(func) -> _Sequence[_Tuple[str, _Any, _Any]]: """ Get the arguments from a function in order to call it using optional or make an alias. @@ -861,15 +906,15 @@ class ColorDecoder(_Mapping): func=func_name, ) - if argtype is None or isinstance(arg, argtype): + if argtype is None or _isinstance(arg, argtype): pass elif ( - issubclass(_Color, argtype) and defaults_to_netscape + _issubclass(_Color, argtype) and defaults_to_netscape and fallback_string is not None ): arg = _SRGBColor.fromnetscapecolorname(fallback_string) elif ( - issubclass(_Angle, argtype) + _issubclass(_Angle, argtype) and isinstance(arg, (int, float)) ): arg = _DegreesAngle(arg) |