1.1 --- a/common.py Thu Jul 05 23:41:16 2018 +0200
1.2 +++ b/common.py Mon Jul 09 17:32:35 2018 +0200
1.3 @@ -462,7 +462,9 @@
1.4 for i, node in enumerate(n.nodes):
1.5 statements.append(
1.6 compiler.ast.Assign([node], compiler.ast.CallFunc(
1.7 - compiler.ast.Getattr(compiler.ast.Name(temp), "__get_single_item_unchecked__"),
1.8 + compiler.ast.Getattr(compiler.ast.Name(temp),
1.9 + "__get_single_item_unchecked__",
1.10 + privileged=True),
1.11 [compiler.ast.Const(i, str(i))]))
1.12 )
1.13
1.14 @@ -1591,6 +1593,10 @@
1.15
1.16 predefined_constants = "False", "None", "NotImplemented", "True"
1.17
1.18 +privileged_attributes = [
1.19 + "__get_single_item_unchecked__",
1.20 + ]
1.21 +
1.22 unary_operator_functions = {
1.23
1.24 # Unary operations.
2.1 --- a/compiler/ast.py Thu Jul 05 23:41:16 2018 +0200
2.2 +++ b/compiler/ast.py Mon Jul 09 17:32:35 2018 +0200
2.3 @@ -868,11 +868,15 @@
2.4 return "%s %s" % (self.expr, " ".join(map(str, self.quals)))
2.5
2.6 class Getattr(Node):
2.7 - def __init__(self, expr, attrname, lineno=None):
2.8 + def __init__(self, expr, attrname, lineno=None, privileged=False):
2.9 self.expr = expr
2.10 self.attrname = attrname
2.11 self.lineno = lineno
2.12
2.13 + # Support privileged internal accesses.
2.14 +
2.15 + self.privileged = privileged
2.16 +
2.17 def getChildren(self):
2.18 return self.expr, self.attrname
2.19
3.1 --- a/inspector.py Thu Jul 05 23:41:16 2018 +0200
3.2 +++ b/inspector.py Mon Jul 09 17:32:35 2018 +0200
3.3 @@ -21,7 +21,8 @@
3.4 """
3.5
3.6 from branching import BranchTracker
3.7 -from common import CommonModule, get_argnames, init_item, predefined_constants
3.8 +from common import CommonModule, get_argnames, init_item, \
3.9 + predefined_constants, privileged_attributes
3.10 from modules import BasicModule, CacheWritingModule, InspectionNaming
3.11 from errors import InspectError
3.12 from referencing import Reference
3.13 @@ -358,6 +359,16 @@
3.14
3.15 "Process the given attribute access node 'n'."
3.16
3.17 + path = self.get_namespace_path()
3.18 +
3.19 + # Test for access to special privileged attributes.
3.20 +
3.21 + if isinstance(n, compiler.ast.Getattr) and \
3.22 + n.attrname in privileged_attributes and not n.privileged:
3.23 +
3.24 + raise InspectError("Attribute %s is accessed by an unprivileged operation." %
3.25 + n.attrname, path, n)
3.26 +
3.27 # Obtain any completed chain and return the reference to it.
3.28
3.29 name_ref = self.process_attribute_chain(n)
3.30 @@ -372,8 +383,6 @@
3.31 # either being name-based and thus an access rooted on a name, or being
3.32 # based on some other node and thus an anonymous access of some kind.
3.33
3.34 - path = self.get_namespace_path()
3.35 -
3.36 # Start with the the full attribute chain.
3.37
3.38 remaining = self.attrs
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/tests/tuple_unpack_bad.py Mon Jul 09 17:32:35 2018 +0200
4.3 @@ -0,0 +1,9 @@
4.4 +def good(t):
4.5 + a, b, c = t
4.6 +
4.7 +def bad(t):
4.8 + a = t.__get_single_item_unchecked__(0)
4.9 +
4.10 +t = 1, 2, 3
4.11 +good(t)
4.12 +bad(t)