From 972cf5c06a5ba16ad243a442dbb9c15307fbed95 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 11 Sep 2019 14:04:04 +0300 Subject: [PATCH] bpo-35168: Make shlex.punctuation_chars read-only (#11631) * bpo-35168: Documentation about shlex.punctuation_chars now states that it should be set in __init__.py * bpo-35168: Convert shlex.punctuation_chars to read-only property * Add NEWS.d entry --- Doc/library/shlex.rst | 8 +++++--- Lib/shlex.py | 6 +++++- Lib/test/test_shlex.py | 7 +++++++ .../next/Library/2019-01-22-09-23-20.bpo-35168.UGv2yW.rst | 1 + 4 files changed, 18 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-01-22-09-23-20.bpo-35168.UGv2yW.rst diff --git a/Doc/library/shlex.rst b/Doc/library/shlex.rst index a8421fdb700..adc23da6d49 100644 --- a/Doc/library/shlex.rst +++ b/Doc/library/shlex.rst @@ -113,7 +113,9 @@ The :mod:`shlex` module defines the following class: characters, those characters will be used as the punctuation characters. Any characters in the :attr:`wordchars` attribute that appear in *punctuation_chars* will be removed from :attr:`wordchars`. See - :ref:`improved-shell-compatibility` for more information. + :ref:`improved-shell-compatibility` for more information. *punctuation_chars* + can be set only upon :class:`~shlex.shlex` instance creation and can't be + modified later. .. versionchanged:: 3.6 The *punctuation_chars* parameter was added. @@ -317,8 +319,8 @@ variables which either control lexical analysis or can be used for debugging: .. attribute:: shlex.punctuation_chars - Characters that will be considered punctuation. Runs of punctuation - characters will be returned as a single token. However, note that no + A read-only property. Characters that will be considered punctuation. Runs of + punctuation characters will be returned as a single token. However, note that no semantic validity checking will be performed: for example, '>>>' could be returned as a token, even though it may not be recognised as such by shells. diff --git a/Lib/shlex.py b/Lib/shlex.py index edea0779486..ae0f5ddec18 100644 --- a/Lib/shlex.py +++ b/Lib/shlex.py @@ -55,7 +55,7 @@ class shlex: punctuation_chars = '' elif punctuation_chars is True: punctuation_chars = '();<>|&' - self.punctuation_chars = punctuation_chars + self._punctuation_chars = punctuation_chars if punctuation_chars: # _pushback_chars is a push back queue used by lookahead logic self._pushback_chars = deque() @@ -65,6 +65,10 @@ class shlex: t = self.wordchars.maketrans(dict.fromkeys(punctuation_chars)) self.wordchars = self.wordchars.translate(t) + @property + def punctuation_chars(self): + return self._punctuation_chars + def push_token(self, tok): "Push a token onto the stack popped by the get_token method" if self.debug >= 1: diff --git a/Lib/test/test_shlex.py b/Lib/test/test_shlex.py index 376c5e88d38..a21ccd2fdf4 100644 --- a/Lib/test/test_shlex.py +++ b/Lib/test/test_shlex.py @@ -353,6 +353,13 @@ class ShlexTest(unittest.TestCase): resplit = shlex.split(joined) self.assertEqual(split_command, resplit) + def testPunctuationCharsReadOnly(self): + punctuation_chars = "/|$%^" + shlex_instance = shlex.shlex(punctuation_chars=punctuation_chars) + self.assertEqual(shlex_instance.punctuation_chars, punctuation_chars) + with self.assertRaises(AttributeError): + shlex_instance.punctuation_chars = False + # Allow this test to be used with old shlex.py if not getattr(shlex, "split", None): diff --git a/Misc/NEWS.d/next/Library/2019-01-22-09-23-20.bpo-35168.UGv2yW.rst b/Misc/NEWS.d/next/Library/2019-01-22-09-23-20.bpo-35168.UGv2yW.rst new file mode 100644 index 00000000000..10684fdbde2 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-01-22-09-23-20.bpo-35168.UGv2yW.rst @@ -0,0 +1 @@ +:attr:`shlex.shlex.punctuation_chars` is now a read-only property.