Skip to content

Commit 3c839ee

Browse files
mavwolverineSteve Canny
authored andcommitted
shr: transplant RGBColor
1 parent 397cef4 commit 3c839ee

File tree

2 files changed

+57
-1
lines changed

2 files changed

+57
-1
lines changed

docx/shared.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,37 @@ def __new__(cls, twips):
124124
return Length.__new__(cls, emu)
125125

126126

127+
class RGBColor(tuple):
128+
"""
129+
Immutable value object defining a particular RGB color.
130+
"""
131+
def __new__(cls, r, g, b):
132+
msg = 'RGBColor() takes three integer values 0-255'
133+
for val in (r, g, b):
134+
if not isinstance(val, int) or val < 0 or val > 255:
135+
raise ValueError(msg)
136+
return super(RGBColor, cls).__new__(cls, (r, g, b))
137+
138+
def __repr__(self):
139+
return 'RGBColor(0x%02x, 0x%02x, 0x%02x)' % self
140+
141+
def __str__(self):
142+
"""
143+
Return a hex string rgb value, like '3C2F80'
144+
"""
145+
return '%02X%02X%02X' % self
146+
147+
@classmethod
148+
def from_string(cls, rgb_hex_str):
149+
"""
150+
Return a new instance from an RGB color hex string like ``'3C2F80'``.
151+
"""
152+
r = int(rgb_hex_str[:2], 16)
153+
g = int(rgb_hex_str[2:4], 16)
154+
b = int(rgb_hex_str[4:], 16)
155+
return cls(r, g, b)
156+
157+
127158
def lazyproperty(f):
128159
"""
129160
@lazyprop decorator. Decorated method will be called only on first access

tests/test_shared.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111
import pytest
1212

1313
from docx.opc.part import XmlPart
14-
from docx.shared import ElementProxy, Length, Cm, Emu, Inches, Mm, Pt, Twips
14+
from docx.shared import (
15+
ElementProxy, Length, Cm, Emu, Inches, Mm, Pt, RGBColor, Twips
16+
)
1517

1618
from .unitutil.cxml import element
1719
from .unitutil.mock import instance_mock
@@ -113,3 +115,26 @@ def construct_fixture(self, request):
113115
def units_fixture(self, request):
114116
emu, units_prop_name, expected_length_in_units, type_ = request.param
115117
return emu, units_prop_name, expected_length_in_units, type_
118+
119+
120+
class DescribeRGBColor(object):
121+
122+
def it_is_natively_constructed_using_three_ints_0_to_255(self):
123+
RGBColor(0x12, 0x34, 0x56)
124+
with pytest.raises(ValueError):
125+
RGBColor('12', '34', '56')
126+
with pytest.raises(ValueError):
127+
RGBColor(-1, 34, 56)
128+
with pytest.raises(ValueError):
129+
RGBColor(12, 256, 56)
130+
131+
def it_can_construct_from_a_hex_string_rgb_value(self):
132+
rgb = RGBColor.from_string('123456')
133+
assert rgb == RGBColor(0x12, 0x34, 0x56)
134+
135+
def it_can_provide_a_hex_string_rgb_value(self):
136+
assert str(RGBColor(0x12, 0x34, 0x56)) == '123456'
137+
138+
def it_has_a_custom_repr(self):
139+
rgb_color = RGBColor(0x42, 0xF0, 0xBA)
140+
assert repr(rgb_color) == 'RGBColor(0x42, 0xf0, 0xba)'

0 commit comments

Comments
 (0)