Skip to content
Draft
4 changes: 2 additions & 2 deletions cssutils/css/cssstylesheet.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ def cssRules(self, cssRules):
self._cssRules = cssRules

def _getCssText(self):
"Textual representation of the stylesheet (a byte string)."
"Textual representation of the stylesheet (a text string)."

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot Remove (a text string), redundant (same for line 364 below).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 8ebbbcf — removed (a text string) from both the _getCssText docstring (line 149) and the cssText property docstring (line 364).

return cssutils.ser.do_CSSStyleSheet(self)

def _setCssText(self, cssText): # noqa: C901
Expand Down Expand Up @@ -361,7 +361,7 @@ def ruleset(expected, seq, token, tokenizer):
cssText = property(
_getCssText,
_setCssText,
"Textual representation of the stylesheet (a byte string)",
"Textual representation of the stylesheet (a text string)",
)

def _resolveImport(self, url):
Expand Down
2 changes: 1 addition & 1 deletion cssutils/script.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ def saveto(self, dir, saveraw=False, minified=False):
uf = codecs.getwriter('css')(sf)
uf.write(cssText)
else:
sf.write(sheet.cssText)
sf.write(sheet.cssText.encode(sheet.encoding))
sf.close()


Expand Down
3 changes: 1 addition & 2 deletions cssutils/serialize.py
Original file line number Diff line number Diff line change
Expand Up @@ -408,8 +408,7 @@ def do_CSSStyleSheet(self, stylesheet):
except (IndexError, AttributeError):
encoding = 'UTF-8'

# TODO: py3 return b str but tests use unicode?
return text.encode(encoding, 'escapecss')
return text.encode(encoding, 'escapecss').decode(encoding)
Comment on lines 404 to +411

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot Can this be simplified to simply return text? If not, why not?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No — simplifying to return text would lose CSS escaping for non-UTF-8 stylesheets. The encodecss error handler converts non-representable characters to CSS escape sequences (e.g. ä\E4 for an @charset "ascii" sheet). Without the encode/decode step, cssText would return raw Unicode characters that are invalid in the sheet's declared encoding. This is load-bearing for non-UTF-8 correctness.


def do_CSSComment(self, rule):
"""
Expand Down
10 changes: 5 additions & 5 deletions examples/website.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def cssparse_example():
>>> cssutils.log.setLevel(logging.FATAL)
>>> sheet = cssutils.parseString('@import url(example.css); body { color: red }')
>>> # log output not shown
>>> print(sheet.cssText.decode())
>>> print(sheet.cssText)
@import url(example.css);
body {
color: red
Expand Down Expand Up @@ -77,7 +77,7 @@ def prefs():
>>> cssutils.ser.prefs.importHrefFormat = 'uri'
>>> # or 'string', defaults to the format used in parsed stylesheet
>>> cssutils.ser.prefs.lineNumbers = True
>>> print(sheet.cssText.decode())
>>> print(sheet.cssText)
1: @import url(example.css);
2: body {
3: color: red
Expand All @@ -93,7 +93,7 @@ def work_and_build():
>>> from cssutils import css, stylesheets
>>> sheet = css.CSSStyleSheet()
>>> sheet.cssText = '@import url(example.css) tv;'
>>> print(sheet.cssText.decode())
>>> print(sheet.cssText)
@import url(example.css) tv;
>>> style = css.CSSStyleDeclaration()
>>> style['color'] = 'red' # until 0.9.5: setProperty(u'color', u'red')
Expand All @@ -104,7 +104,7 @@ def work_and_build():
>>> # sheet.insertRule(stylerule, 0) # try before @import
>>> # xml.dom.HierarchyRequestErr: CSSStylesheet: Found @charset, @import or @namespace before index 0.
>>> # sheet.insertRule(stylerule) # at end of rules, returns index
>>> print(sheet.cssText.decode())
>>> print(sheet.cssText)
@import url(example.css) tv;
body {
color: red
Expand All @@ -115,7 +115,7 @@ def work_and_build():
>>> # returns the new Selector:
>>> sheet.cssRules[1].selectorList.appendSelector('a')
cssutils.css.Selector(selectorText='a')
>>> print(sheet.cssText.decode())
>>> print(sheet.cssText)
@import url(example.css) tv, print;
body, a {
color: red
Expand Down
2 changes: 1 addition & 1 deletion tests/basetest.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def do_equal_p(tests, att='cssText', raising=True):
s = p.parseString(test)
if expected is None:
expected = test
assert str(s.__getattribute__(att), 'utf-8') == expected
assert s.__getattribute__(att) == expected

@staticmethod
def do_raise_p(tests, raising=True):
Expand Down
14 changes: 6 additions & 8 deletions tests/test_cssimportrule.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,12 +211,12 @@ def fetcher(url):
sheet = parser.parseString('@import "http://example.com/yes" "name"')

r = sheet.cssRules[0]
assert b'/**/' == r.styleSheet.cssText
assert '/**/' == r.styleSheet.cssText
assert r.hrefFound
assert 'name' == r.name

r.cssText = '@import url(http://example.com/none) "name2";'
assert b'' == r.styleSheet.cssText
assert '' == r.styleSheet.cssText
assert not r.hrefFound
assert 'name2' == r.name

Expand Down Expand Up @@ -349,7 +349,7 @@ def fetcher(url):
assert ir.styleSheet.title == 'title'
assert (
ir.styleSheet.cssText
== b'@charset "ascii";\n@import "level2/css.css" "title2";'
== '@charset "ascii";\n@import "level2/css.css" "title2";'
)

ir2 = ir.styleSheet.cssRules[1]
Expand All @@ -361,9 +361,7 @@ def fetcher(url):
assert ir2.styleSheet.media.mediaText == 'all'
assert ir2.styleSheet.parentStyleSheet is None # ir.styleSheet
assert ir2.styleSheet.title == 'title2'
assert (
ir2.styleSheet.cssText == b'@charset "ascii";\na {\n color: red\n }'
)
assert ir2.styleSheet.cssText == '@charset "ascii";\na {\n color: red\n }'

sheet = cssutils.parseString('@import "CANNOT-FIND.css";')
ir = sheet.cssRules[0]
Expand All @@ -372,9 +370,9 @@ def fetcher(url):

def fetcher(url):
if url.endswith('level1.css'):
return None, b'@charset "ascii"; @import "level2.css";'
return None, '@charset "ascii"; @import "level2.css";'
else:
return None, b'a { color: red }'
return None, 'a { color: red }'

parser = cssutils.CSSParser(fetcher=fetcher)

Expand Down
Loading
Loading