Consequent refactor for format and converters independance
I'm Valentin Lab, the original author of python package 'colour'. I'm pinging @multani @priestc @hellais @mehcode @JDongian because you have contributed in one way or another to 'colour' package. So first of all : thank you all.
I have just rewritten a substantial part of 'colour' without changing the tests. This should somewhat garantee some level of iso-functionality. But I would hate breaking anything in your possible usage of 'color'.
I have committed this on github in this PR.
I guess some of you have moved away from color since a long time, or others simply don't have time to help me now. Please then ignore this PR and emails (and you can unregiser I guess from this thread), and thank you again for your help last time. It was and is still very appreciated.
For those that currently have color used in a project, I would be very happy and relieved if you could run your tests with this PR (the rc1 branch) to check that nothing odd is happening as a consequence of this rewrite.
For the one interested, and for documentation purpose, I'll now develop some aspect of what changed, and why:
Let me first start with the changelog for end-users:
-
Engine rewrite to provide easier writing of new formats. [Valentin Lab]
These are the biggest API changes:
- attribute
hex_lremoved in favor ofhexwhich is now long (6 hexadigit long). Usehexsfor the possibly shortened version to 3 hexadigit when possible. LONG_HEX_COLORandSHORT_HEX_COLORare not available in module's scope anymore, but are moved in each corresponding format's attribute (Hex.regex, andHexS.regex).RGB,HEX,HSLhelper classes output now again basic python types output (tuples and strings). And thus are unaware of any formats.- in a similar way,
xxx2yyyconversion functions are unaware of any format and work with basic python types and returns basic python types.
- attribute
-
Use namedtuple for rgb and hsl tuples. (fixes #22) [Valentin Lab]
Now let me expand a little on the rewrite part, with this refactor, providing a new format will limit itself to:
- provide an
Formatobject, - and at least 2 converters.
Let's illustrate this with the HSL format, here's the defintion of Hsl format object:
@register_format(Formats)
class HSL(Tuple("hue", "saturation", "luminance")):
"""3-uple of Hue, Saturation, Lightness all between 0.0 and 1.0"""
Yes, that's all. We can easily see that providing any CMYK, HSV, YUV Format object should not be so difficult.
What you need then is to provide at least a way to convert to any format already supported in your format registry, back and forth. Here's how it is done:
@register_converter(Converters, HSL, RGB)
def hsl2rgb(hsl):
...
@register_converter(Converters, RGB, HSL)
def rgb2hsl(rgb):
...
The color object will figure itself all the rest... getter/setters on the different format available like Color("red").rgb ... using format names as attribute. Or even Color("red").saturation ... using name of subattributes of a format.
There are still some design choice that could change. And in this new version of Color, now stores the in a variable format (you can fix it if needed) and it will change to the last valuation (usage of setters). Before, colors where stored in HSL format inside the object and so, did need te be converted to this format upon setter calls.
Some advantage:
- You can define new format in your code very simply if you want to hook up a new format
- without tinkering with the Color object or any code. You can define need colors from your own project with a few lines of code.
- Lines of codes needed to define new color is reduced to a strict minimal.
- You can create your own
Colorwith only the format you care about to remove some load - Your new format will get the same first class attention than current supported formats:
- automatic
Converter.xxx2yyy(..)methods for all given supported formats. - getter and setter magics on
Colorobjects.
- automatic
I'll probably add an additional commit with a YUV, HSV, or CMYK additional format to check that everything is okay.
Of course, if you feel like reviewing some code, that will be appreciated also. But what I need first is checking that I don't break anything.
Codecov Report
Merging #31 into master will decrease coverage by
0.12%. The diff coverage is98.79%.
@@ Coverage Diff @@
## master #31 +/- ##
==========================================
- Coverage 99.13% 99.01% -0.13%
==========================================
Files 1 1
Lines 232 405 +173
Branches 0 121 +121
==========================================
+ Hits 230 401 +171
+ Misses 2 0 -2
- Partials 0 4 +4
| Impacted Files | Coverage Δ | |
|---|---|---|
| colour.py | 99.01% <98.79%> (-0.13%) |
:arrow_down: |
Continue to review full report at Codecov.
Legend - Click here to learn more
Δ = absolute <relative> (impact),ø = not affected,? = missing dataPowered by Codecov. Last update c64602b...870dc94. Read the comment docs.
LGTM but AppVeyor configuration does not seems to be working...