Skip to content

Commit

Permalink
bpo-41521: Replace whitelist/blacklist with allowlist/denylist (pytho…
Browse files Browse the repository at this point in the history
…nGH-21822)

Automerge-Triggered-By: @tiran
  • Loading branch information
vstinner authored Aug 11, 2020
1 parent 1d541c2 commit fabd7bb
Show file tree
Hide file tree
Showing 12 changed files with 36 additions and 36 deletions.
12 changes: 6 additions & 6 deletions Doc/library/http.cookiejar.rst
Original file line number Diff line number Diff line change
Expand Up @@ -462,16 +462,16 @@ receiving cookies. There are also some strictness switches that allow you to
tighten up the rather loose Netscape protocol rules a little bit (at the cost of
blocking some benign cookies).

A domain blacklist and whitelist is provided (both off by default). Only domains
not in the blacklist and present in the whitelist (if the whitelist is active)
A domain denylist and allowlist is provided (both off by default). Only domains
not in the denylist and present in the allowlist (if the allowlist is active)
participate in cookie setting and returning. Use the *blocked_domains*
constructor argument, and :meth:`blocked_domains` and
:meth:`set_blocked_domains` methods (and the corresponding argument and methods
for *allowed_domains*). If you set a whitelist, you can turn it off again by
for *allowed_domains*). If you set an allowlist, you can turn it off again by
setting it to :const:`None`.

Domains in block or allow lists that do not start with a dot must equal the
cookie domain to be matched. For example, ``"example.com"`` matches a blacklist
cookie domain to be matched. For example, ``"example.com"`` matches a denylist
entry of ``"example.com"``, but ``"www.example.com"`` does not. Domains that do
start with a dot are matched by more specific domains too. For example, both
``"www.example.com"`` and ``"www.coyote.example.com"`` match ``".example.com"``
Expand All @@ -494,7 +494,7 @@ and ``".168.1.2"``, 192.168.1.2 is blocked, but 193.168.1.2 is not.

.. method:: DefaultCookiePolicy.is_blocked(domain)

Return whether *domain* is on the blacklist for setting or receiving cookies.
Return whether *domain* is on the denylist for setting or receiving cookies.


.. method:: DefaultCookiePolicy.allowed_domains()
Expand All @@ -509,7 +509,7 @@ and ``".168.1.2"``, 192.168.1.2 is blocked, but 193.168.1.2 is not.

.. method:: DefaultCookiePolicy.is_not_allowed(domain)

Return whether *domain* is not on the whitelist for setting or receiving
Return whether *domain* is not on the allowlist for setting or receiving
cookies.

:class:`DefaultCookiePolicy` instances have the following attributes, which are
Expand Down
2 changes: 1 addition & 1 deletion Doc/library/urllib.parse.rst
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ or on combining URL components into a URL string.

.. versionchanged:: 3.3
The fragment is now parsed for all URL schemes (unless *allow_fragment* is
false), in accordance with :rfc:`3986`. Previously, a whitelist of
false), in accordance with :rfc:`3986`. Previously, an allowlist of
schemes that support fragments existed.

.. versionchanged:: 3.6
Expand Down
2 changes: 1 addition & 1 deletion Lib/codecs.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@
class CodecInfo(tuple):
"""Codec details when looking up the codec registry"""

# Private API to allow Python 3.4 to blacklist the known non-Unicode
# Private API to allow Python 3.4 to denylist the known non-Unicode
# codecs in the standard library. A more general mechanism to
# reliably distinguish test encodings from other codecs will hopefully
# be defined for Python 3.5
Expand Down
4 changes: 2 additions & 2 deletions Lib/ipaddress.py
Original file line number Diff line number Diff line change
Expand Up @@ -1214,7 +1214,7 @@ def _parse_octet(cls, octet_str):
"""
if not octet_str:
raise ValueError("Empty octet not permitted")
# Whitelist the characters, since int() allows a lot of bizarre stuff.
# Reject non-ASCII digits.
if not (octet_str.isascii() and octet_str.isdigit()):
msg = "Only decimal digits permitted in %r"
raise ValueError(msg % octet_str)
Expand Down Expand Up @@ -1719,7 +1719,7 @@ def _parse_hextet(cls, hextet_str):
[0..FFFF].
"""
# Whitelist the characters, since int() allows a lot of bizarre stuff.
# Reject non-ASCII digits.
if not cls._HEX_DIGITS.issuperset(hextet_str):
raise ValueError("Only hex digits permitted in %r" % hextet_str)
# We do the length check second, since the invalid character error
Expand Down
12 changes: 6 additions & 6 deletions Lib/test/test___all__.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ def walk_modules(self, basedir, modpath):
yield path, modpath + fn[:-3]

def test_all(self):
# Blacklisted modules and packages
blacklist = set([
# List of denied modules and packages
denylist = set([
# Will raise a SyntaxError when compiling the exec statement
'__future__',
])
Expand All @@ -85,13 +85,13 @@ def test_all(self):
lib_dir = os.path.dirname(os.path.dirname(__file__))
for path, modname in self.walk_modules(lib_dir, ""):
m = modname
blacklisted = False
denylisted = False
while m:
if m in blacklist:
blacklisted = True
if m in denylist:
denylisted = True
break
m = m.rpartition('.')[0]
if blacklisted:
if denylisted:
continue
if support.verbose:
print(modname)
Expand Down
4 changes: 2 additions & 2 deletions Lib/test/test_httplib.py
Original file line number Diff line number Diff line change
Expand Up @@ -1434,9 +1434,9 @@ def test_all(self):
expected = {"responses"} # White-list documented dict() object
# HTTPMessage, parse_headers(), and the HTTP status code constants are
# intentionally omitted for simplicity
blacklist = {"HTTPMessage", "parse_headers"}
denylist = {"HTTPMessage", "parse_headers"}
for name in dir(client):
if name.startswith("_") or name in blacklist:
if name.startswith("_") or name in denylist:
continue
module_object = getattr(client, name)
if getattr(module_object, "__module__", None) == "http.client":
Expand Down
4 changes: 2 additions & 2 deletions Lib/test/test_httpservers.py
Original file line number Diff line number Diff line change
Expand Up @@ -1189,9 +1189,9 @@ def test_windows_colon(self):
class MiscTestCase(unittest.TestCase):
def test_all(self):
expected = []
blacklist = {'executable', 'nobody_uid', 'test'}
denylist = {'executable', 'nobody_uid', 'test'}
for name in dir(server):
if name.startswith('_') or name in blacklist:
if name.startswith('_') or name in denylist:
continue
module_object = getattr(server, name)
if getattr(module_object, '__module__', None) == 'http.server':
Expand Down
6 changes: 3 additions & 3 deletions Lib/test/test_nntplib.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,11 +197,11 @@ def test_article_head_body(self):
self.assertTrue(resp.startswith("220 "), resp)
self.check_article_resp(resp, article, art_num)
# Tolerate running the tests from behind a NNTP virus checker
blacklist = lambda line: line.startswith(b'X-Antivirus')
denylist = lambda line: line.startswith(b'X-Antivirus')
filtered_head_lines = [line for line in head.lines
if not blacklist(line)]
if not denylist(line)]
filtered_lines = [line for line in article.lines
if not blacklist(line)]
if not denylist(line)]
self.assertEqual(filtered_lines, filtered_head_lines + [b''] + body.lines)

def test_capabilities(self):
Expand Down
10 changes: 5 additions & 5 deletions Lib/test/test_tools/test_sundry.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,18 @@

class TestSundryScripts(unittest.TestCase):
# At least make sure the rest don't have syntax errors. When tests are
# added for a script it should be added to the whitelist below.
# added for a script it should be added to the allowlist below.

# scripts that have independent tests.
whitelist = ['reindent', 'pdeps', 'gprof2html', 'md5sum']
allowlist = ['reindent', 'pdeps', 'gprof2html', 'md5sum']
# scripts that can't be imported without running
blacklist = ['make_ctype']
denylist = ['make_ctype']
# scripts that use windows-only modules
windows_only = ['win_add2path']
# blacklisted for other reasons
# denylisted for other reasons
other = ['analyze_dxp', '2to3']

skiplist = blacklist + whitelist + windows_only + other
skiplist = denylist + allowlist + windows_only + other

def test_sundry(self):
old_modules = import_helper.modules_setup()
Expand Down
4 changes: 2 additions & 2 deletions Lib/test/test_traceback.py
Original file line number Diff line number Diff line change
Expand Up @@ -1191,9 +1191,9 @@ class MiscTest(unittest.TestCase):

def test_all(self):
expected = set()
blacklist = {'print_list'}
denylist = {'print_list'}
for name in dir(traceback):
if name.startswith('_') or name in blacklist:
if name.startswith('_') or name in denylist:
continue
module_object = getattr(traceback, name)
if getattr(module_object, '__module__', None) == 'traceback':
Expand Down
4 changes: 2 additions & 2 deletions Objects/typeobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -4171,10 +4171,10 @@ object_set_class(PyObject *self, PyObject *value, void *closure)
In theory the proper fix would be to identify which classes rely on
this invariant and somehow disallow __class__ assignment only for them,
perhaps via some mechanism like a new Py_TPFLAGS_IMMUTABLE flag (a
"blacklisting" approach). But in practice, since this problem wasn't
"denylisting" approach). But in practice, since this problem wasn't
noticed late in the 3.5 RC cycle, we're taking the conservative
approach and reinstating the same HEAPTYPE->HEAPTYPE check that we used
to have, plus a "whitelist". For now, the whitelist consists only of
to have, plus an "allowlist". For now, the allowlist consists only of
ModuleType subtypes, since those are the cases that motivated the patch
in the first place -- see https://bugs.python.org/issue22986 -- and
since module objects are mutable we can be sure that they are
Expand Down
8 changes: 4 additions & 4 deletions Tools/clinic/clinic.py
Original file line number Diff line number Diff line change
Expand Up @@ -4433,7 +4433,7 @@ def state_parameter(self, line):

if 'c_default' not in kwargs:
# we can only represent very simple data values in C.
# detect whether default is okay, via a blacklist
# detect whether default is okay, via a denylist
# of disallowed ast nodes.
class DetectBadNodes(ast.NodeVisitor):
bad = False
Expand All @@ -4456,9 +4456,9 @@ def bad_node(self, node):
# "starred": "a = [1, 2, 3]; *a"
visit_Starred = bad_node

blacklist = DetectBadNodes()
blacklist.visit(module)
bad = blacklist.bad
denylist = DetectBadNodes()
denylist.visit(module)
bad = denylist.bad
else:
# if they specify a c_default, we can be more lenient about the default value.
# but at least make an attempt at ensuring it's a valid expression.
Expand Down

0 comments on commit fabd7bb

Please sign in to comment.