mirror of https://github.com/python/cpython
bpo-41521: Replace whitelist/blacklist with allowlist/denylist (GH-21822)
Automerge-Triggered-By: @tiran
This commit is contained in:
parent
1d541c25c8
commit
fabd7bb8e0
|
@ -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
|
tighten up the rather loose Netscape protocol rules a little bit (at the cost of
|
||||||
blocking some benign cookies).
|
blocking some benign cookies).
|
||||||
|
|
||||||
A domain blacklist and whitelist is provided (both off by default). Only domains
|
A domain denylist and allowlist is provided (both off by default). Only domains
|
||||||
not in the blacklist and present in the whitelist (if the whitelist is active)
|
not in the denylist and present in the allowlist (if the allowlist is active)
|
||||||
participate in cookie setting and returning. Use the *blocked_domains*
|
participate in cookie setting and returning. Use the *blocked_domains*
|
||||||
constructor argument, and :meth:`blocked_domains` and
|
constructor argument, and :meth:`blocked_domains` and
|
||||||
:meth:`set_blocked_domains` methods (and the corresponding argument and methods
|
: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`.
|
setting it to :const:`None`.
|
||||||
|
|
||||||
Domains in block or allow lists that do not start with a dot must equal the
|
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
|
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
|
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"``
|
``"www.example.com"`` and ``"www.coyote.example.com"`` match ``".example.com"``
|
||||||
|
@ -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)
|
.. 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()
|
.. method:: DefaultCookiePolicy.allowed_domains()
|
||||||
|
@ -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)
|
.. 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.
|
cookies.
|
||||||
|
|
||||||
:class:`DefaultCookiePolicy` instances have the following attributes, which are
|
:class:`DefaultCookiePolicy` instances have the following attributes, which are
|
||||||
|
|
|
@ -153,7 +153,7 @@ or on combining URL components into a URL string.
|
||||||
|
|
||||||
.. versionchanged:: 3.3
|
.. versionchanged:: 3.3
|
||||||
The fragment is now parsed for all URL schemes (unless *allow_fragment* is
|
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.
|
schemes that support fragments existed.
|
||||||
|
|
||||||
.. versionchanged:: 3.6
|
.. versionchanged:: 3.6
|
||||||
|
|
|
@ -83,7 +83,7 @@ BOM64_BE = BOM_UTF32_BE
|
||||||
class CodecInfo(tuple):
|
class CodecInfo(tuple):
|
||||||
"""Codec details when looking up the codec registry"""
|
"""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
|
# codecs in the standard library. A more general mechanism to
|
||||||
# reliably distinguish test encodings from other codecs will hopefully
|
# reliably distinguish test encodings from other codecs will hopefully
|
||||||
# be defined for Python 3.5
|
# be defined for Python 3.5
|
||||||
|
|
|
@ -1214,7 +1214,7 @@ class _BaseV4:
|
||||||
"""
|
"""
|
||||||
if not octet_str:
|
if not octet_str:
|
||||||
raise ValueError("Empty octet not permitted")
|
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()):
|
if not (octet_str.isascii() and octet_str.isdigit()):
|
||||||
msg = "Only decimal digits permitted in %r"
|
msg = "Only decimal digits permitted in %r"
|
||||||
raise ValueError(msg % octet_str)
|
raise ValueError(msg % octet_str)
|
||||||
|
@ -1719,7 +1719,7 @@ class _BaseV6:
|
||||||
[0..FFFF].
|
[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):
|
if not cls._HEX_DIGITS.issuperset(hextet_str):
|
||||||
raise ValueError("Only hex digits permitted in %r" % hextet_str)
|
raise ValueError("Only hex digits permitted in %r" % hextet_str)
|
||||||
# We do the length check second, since the invalid character error
|
# We do the length check second, since the invalid character error
|
||||||
|
|
|
@ -69,8 +69,8 @@ class AllTest(unittest.TestCase):
|
||||||
yield path, modpath + fn[:-3]
|
yield path, modpath + fn[:-3]
|
||||||
|
|
||||||
def test_all(self):
|
def test_all(self):
|
||||||
# Blacklisted modules and packages
|
# List of denied modules and packages
|
||||||
blacklist = set([
|
denylist = set([
|
||||||
# Will raise a SyntaxError when compiling the exec statement
|
# Will raise a SyntaxError when compiling the exec statement
|
||||||
'__future__',
|
'__future__',
|
||||||
])
|
])
|
||||||
|
@ -85,13 +85,13 @@ class AllTest(unittest.TestCase):
|
||||||
lib_dir = os.path.dirname(os.path.dirname(__file__))
|
lib_dir = os.path.dirname(os.path.dirname(__file__))
|
||||||
for path, modname in self.walk_modules(lib_dir, ""):
|
for path, modname in self.walk_modules(lib_dir, ""):
|
||||||
m = modname
|
m = modname
|
||||||
blacklisted = False
|
denylisted = False
|
||||||
while m:
|
while m:
|
||||||
if m in blacklist:
|
if m in denylist:
|
||||||
blacklisted = True
|
denylisted = True
|
||||||
break
|
break
|
||||||
m = m.rpartition('.')[0]
|
m = m.rpartition('.')[0]
|
||||||
if blacklisted:
|
if denylisted:
|
||||||
continue
|
continue
|
||||||
if support.verbose:
|
if support.verbose:
|
||||||
print(modname)
|
print(modname)
|
||||||
|
|
|
@ -1434,9 +1434,9 @@ class OfflineTest(TestCase):
|
||||||
expected = {"responses"} # White-list documented dict() object
|
expected = {"responses"} # White-list documented dict() object
|
||||||
# HTTPMessage, parse_headers(), and the HTTP status code constants are
|
# HTTPMessage, parse_headers(), and the HTTP status code constants are
|
||||||
# intentionally omitted for simplicity
|
# intentionally omitted for simplicity
|
||||||
blacklist = {"HTTPMessage", "parse_headers"}
|
denylist = {"HTTPMessage", "parse_headers"}
|
||||||
for name in dir(client):
|
for name in dir(client):
|
||||||
if name.startswith("_") or name in blacklist:
|
if name.startswith("_") or name in denylist:
|
||||||
continue
|
continue
|
||||||
module_object = getattr(client, name)
|
module_object = getattr(client, name)
|
||||||
if getattr(module_object, "__module__", None) == "http.client":
|
if getattr(module_object, "__module__", None) == "http.client":
|
||||||
|
|
|
@ -1189,9 +1189,9 @@ class SimpleHTTPRequestHandlerTestCase(unittest.TestCase):
|
||||||
class MiscTestCase(unittest.TestCase):
|
class MiscTestCase(unittest.TestCase):
|
||||||
def test_all(self):
|
def test_all(self):
|
||||||
expected = []
|
expected = []
|
||||||
blacklist = {'executable', 'nobody_uid', 'test'}
|
denylist = {'executable', 'nobody_uid', 'test'}
|
||||||
for name in dir(server):
|
for name in dir(server):
|
||||||
if name.startswith('_') or name in blacklist:
|
if name.startswith('_') or name in denylist:
|
||||||
continue
|
continue
|
||||||
module_object = getattr(server, name)
|
module_object = getattr(server, name)
|
||||||
if getattr(module_object, '__module__', None) == 'http.server':
|
if getattr(module_object, '__module__', None) == 'http.server':
|
||||||
|
|
|
@ -197,11 +197,11 @@ class NetworkedNNTPTestsMixin:
|
||||||
self.assertTrue(resp.startswith("220 "), resp)
|
self.assertTrue(resp.startswith("220 "), resp)
|
||||||
self.check_article_resp(resp, article, art_num)
|
self.check_article_resp(resp, article, art_num)
|
||||||
# Tolerate running the tests from behind a NNTP virus checker
|
# 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
|
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
|
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)
|
self.assertEqual(filtered_lines, filtered_head_lines + [b''] + body.lines)
|
||||||
|
|
||||||
def test_capabilities(self):
|
def test_capabilities(self):
|
||||||
|
|
|
@ -16,18 +16,18 @@ skip_if_missing()
|
||||||
|
|
||||||
class TestSundryScripts(unittest.TestCase):
|
class TestSundryScripts(unittest.TestCase):
|
||||||
# At least make sure the rest don't have syntax errors. When tests are
|
# 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.
|
# scripts that have independent tests.
|
||||||
whitelist = ['reindent', 'pdeps', 'gprof2html', 'md5sum']
|
allowlist = ['reindent', 'pdeps', 'gprof2html', 'md5sum']
|
||||||
# scripts that can't be imported without running
|
# scripts that can't be imported without running
|
||||||
blacklist = ['make_ctype']
|
denylist = ['make_ctype']
|
||||||
# scripts that use windows-only modules
|
# scripts that use windows-only modules
|
||||||
windows_only = ['win_add2path']
|
windows_only = ['win_add2path']
|
||||||
# blacklisted for other reasons
|
# denylisted for other reasons
|
||||||
other = ['analyze_dxp', '2to3']
|
other = ['analyze_dxp', '2to3']
|
||||||
|
|
||||||
skiplist = blacklist + whitelist + windows_only + other
|
skiplist = denylist + allowlist + windows_only + other
|
||||||
|
|
||||||
def test_sundry(self):
|
def test_sundry(self):
|
||||||
old_modules = import_helper.modules_setup()
|
old_modules = import_helper.modules_setup()
|
||||||
|
|
|
@ -1191,9 +1191,9 @@ class MiscTest(unittest.TestCase):
|
||||||
|
|
||||||
def test_all(self):
|
def test_all(self):
|
||||||
expected = set()
|
expected = set()
|
||||||
blacklist = {'print_list'}
|
denylist = {'print_list'}
|
||||||
for name in dir(traceback):
|
for name in dir(traceback):
|
||||||
if name.startswith('_') or name in blacklist:
|
if name.startswith('_') or name in denylist:
|
||||||
continue
|
continue
|
||||||
module_object = getattr(traceback, name)
|
module_object = getattr(traceback, name)
|
||||||
if getattr(module_object, '__module__', None) == 'traceback':
|
if getattr(module_object, '__module__', None) == 'traceback':
|
||||||
|
|
|
@ -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
|
In theory the proper fix would be to identify which classes rely on
|
||||||
this invariant and somehow disallow __class__ assignment only for them,
|
this invariant and somehow disallow __class__ assignment only for them,
|
||||||
perhaps via some mechanism like a new Py_TPFLAGS_IMMUTABLE flag (a
|
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
|
noticed late in the 3.5 RC cycle, we're taking the conservative
|
||||||
approach and reinstating the same HEAPTYPE->HEAPTYPE check that we used
|
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
|
ModuleType subtypes, since those are the cases that motivated the patch
|
||||||
in the first place -- see https://bugs.python.org/issue22986 -- and
|
in the first place -- see https://bugs.python.org/issue22986 -- and
|
||||||
since module objects are mutable we can be sure that they are
|
since module objects are mutable we can be sure that they are
|
||||||
|
|
|
@ -4433,7 +4433,7 @@ class DSLParser:
|
||||||
|
|
||||||
if 'c_default' not in kwargs:
|
if 'c_default' not in kwargs:
|
||||||
# we can only represent very simple data values in C.
|
# 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.
|
# of disallowed ast nodes.
|
||||||
class DetectBadNodes(ast.NodeVisitor):
|
class DetectBadNodes(ast.NodeVisitor):
|
||||||
bad = False
|
bad = False
|
||||||
|
@ -4456,9 +4456,9 @@ class DSLParser:
|
||||||
# "starred": "a = [1, 2, 3]; *a"
|
# "starred": "a = [1, 2, 3]; *a"
|
||||||
visit_Starred = bad_node
|
visit_Starred = bad_node
|
||||||
|
|
||||||
blacklist = DetectBadNodes()
|
denylist = DetectBadNodes()
|
||||||
blacklist.visit(module)
|
denylist.visit(module)
|
||||||
bad = blacklist.bad
|
bad = denylist.bad
|
||||||
else:
|
else:
|
||||||
# if they specify a c_default, we can be more lenient about the default value.
|
# 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.
|
# but at least make an attempt at ensuring it's a valid expression.
|
||||||
|
|
Loading…
Reference in New Issue