Skip to content

Conversation

@vaab
Copy link
Owner

@vaab vaab commented Apr 19, 2017

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_l removed in favor of hex which is now long (6
      hexadigit long). Use hexs for the possibly shortened version to
      3 hexadigit when possible.
    • LONG_HEX_COLOR and SHORT_HEX_COLOR are not available in
      module's scope anymore, but are moved in each corresponding format's
      attribute (Hex.regex, and HexS.regex).
    • RGB, HEX, HSL helper classes output now again basic
      python types output (tuples and strings). And thus are unaware of
      any formats.
    • in a similar way, xxx2yyy conversion functions are unaware of
      any format and work with basic python types and returns basic
      python types.
  • Use namedtuple for rgb and hsl tuples. (fixes Using named tuples #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 Format object,
  • 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 Color with 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 Color objects.

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.

vaab added 5 commits May 4, 2017 22:23
This is to ensure minimal dependency towards nosetests and means
that even if only the ``colour.py`` is copied in a project, it will
be testable with ``python -m doctest colour.py``.
The aim here is to be able to plug formats at will. The Color object
will then give easy access to given formats. Thus, it should have
no previous knowledge of names of formats nor inner attributes.

The remaining attributes will be removed in upcoming commits.
@codecov
Copy link

codecov bot commented May 5, 2017

Codecov Report

Merging #31 into master will decrease coverage by 0.12%.
The diff coverage is 98.79%.

Impacted file tree graph

@@            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%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update c64602b...870dc94. Read the comment docs.

vaab added 10 commits May 5, 2017 17:00
API changes:

- attribute ``hex_l`` removed in favor of ``hex`` which is now long (6
  hexadigit long). Use ``hexs`` for the possibly shortened version to 3
  hex digit.
- ``LONG_HEX_COLOR`` and ``SHORT_HEX_COLOR`` are not available in
  module's scope anymore, but are moved in each corresponding format's
  attribute (``Hex.regex``, and ``HexS.regex``).
- ``HEX`` helper class is renamed ``Hex``.
- ``xxx2yyy`` conversion functions are unaware of any format and work
  with basic python types and returns basic python types.
…g with their format name.

Color instances would have to infer the target format based with the
name of the attribute. For instance ``Color(..).red`` would refer to
RGB format only because it is the only format being a ``namedtuple`` AND
having a component named 'red'.

This behavior is kept if it is not ambiguous, and it is now allowed to
be more specific (to avoid ambiguous cases) by prefixing by the format
name.

For instance, ``.red`` is equivalent to ``.rgb_red``.
API breaks is introduced for all code using ``hue``,``saturation`` to
access ``HSL`` components of a ``Color`` object, either as attributes or
keyword values when instantiating.

Please change these to ``hsl_hue``, and ``hsl_saturation``.
…``.xxx2yyy(..)``.

In particular, ``colour.Convertors`` provides all possible conversion
methods implemented and integrated in current ``colour`` version.
@pradyunsg
Copy link

LGTM but AppVeyor configuration does not seems to be working...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Using named tuples

3 participants