def map_add(state, arg):
    if sys.version_info >= (3, 8):
        # PEP 572 The MAP_ADD expects the value as the first element in the stack
        # and the key as the second element.
        new_value_type = Const.unwrap(state.stack.pop())
        new_key_type = Const.unwrap(state.stack.pop())
    else:
        new_key_type = Const.unwrap(state.stack.pop())
        new_value_type = Const.unwrap(state.stack.pop())
    state.stack[-arg] = Dict[Union[state.stack[-arg].key_type, new_key_type],
                             Union[state.stack[-arg].value_type,
                                   new_value_type]]
Ejemplo n.º 2
0
def load_method(state, arg):
    """Like load_attr. Replaces TOS object with method and TOS."""
    o = state.stack.pop()
    name = state.get_name(arg)
    if isinstance(o, Const):
        method = Const(getattr(o.value, name))
    elif isinstance(o, typehints.AnyTypeConstraint):
        method = typehints.Any
    else:
        method = Const(BoundMethod(getattr(o, name), o))

    state.stack.append(method)
Ejemplo n.º 3
0
def _getattr(o, name):
    if isinstance(o, Const) and hasattr(o.value, name):
        return Const(getattr(o.value, name))
    elif (inspect.isclass(o)
          and isinstance(getattr(o, name, None),
                         (types.MethodType, types.FunctionType))):
        # TODO(luke-zhu): Support other callable objects
        func = getattr(o, name)  # Python 3 has no unbound methods
        return Const(BoundMethod(func, o))
    elif isinstance(o, row_type.RowTypeConstraint):
        return o.get_type_for(name)
    else:
        return Any
Ejemplo n.º 4
0
def build_tuple(state, arg):
    if arg == 0:
        state.stack.append(Tuple[()])
    else:
        state.stack[-arg:] = [
            Tuple[[Const.unwrap(t) for t in state.stack[-arg:]]]
        ]
Ejemplo n.º 5
0
def make_function(state, arg):
    """Creates a function with the arguments at the top of the stack.
  """
    # TODO(luke-zhu): Handle default argument types
    globals = state.f.__globals__  # Inherits globals from the current frame
    func_name = state.stack[-1].value
    func_code = state.stack[-2].value
    pop_count = 2
    closure = None
    # arg contains flags, with corresponding stack values if positive.
    # https://docs.python.org/3.6/library/dis.html#opcode-MAKE_FUNCTION
    pop_count += bin(arg).count('1')
    if arg & 0x08:
        # Convert types in Tuple constraint to a tuple of CPython cells.
        # https://stackoverflow.com/a/44670295
        closure = tuple((lambda _: lambda: _)(t).__closure__[0]
                        for t in state.stack[-3].tuple_types)

    func = types.FunctionType(func_code,
                              globals,
                              name=func_name,
                              closure=closure)

    assert pop_count <= len(state.stack)
    state.stack[-pop_count:] = [Const(func)]
Ejemplo n.º 6
0
def load_attr(state, arg):
    """Replaces the top of the stack, TOS, with
  getattr(TOS, co_names[arg])
  """
    o = state.stack.pop()
    name = state.get_name(arg)
    if isinstance(o, Const) and hasattr(o.value, name):
        state.stack.append(Const(getattr(o.value, name)))
    elif (inspect.isclass(o)
          and isinstance(getattr(o, name, None),
                         (types.MethodType, types.FunctionType))):
        # TODO(luke-zhu): Support other callable objects
        if sys.version_info[0] == 2:
            func = getattr(o, name).__func__
        else:
            func = getattr(o, name)  # Python 3 has no unbound methods
        state.stack.append(Const(BoundMethod(func, o)))
    else:
        state.stack.append(Any)
Ejemplo n.º 7
0
def load_method(state, arg):
    """Like load_attr. Replaces TOS object with method and TOS."""
    o = state.stack.pop()
    name = state.get_name(arg)
    if isinstance(o, Const):
        method = Const(getattr(o.value, name))
    elif isinstance(o, typehints.AnyTypeConstraint):
        method = typehints.Any
    elif hasattr(o, name):
        attr = getattr(o, name)
        if isinstance(attr, _MethodDescriptorType):
            # Skip builtins since they don't disassemble.
            method = typehints.Any
        else:
            method = Const(BoundMethod(attr, o))
    else:
        method = typehints.Any

    state.stack.append(method)
Ejemplo n.º 8
0
def build_const_key_map(state, arg):
    key_tuple = state.stack.pop()
    if isinstance(key_tuple, typehints.TupleHint.TupleConstraint):
        key_types = key_tuple.tuple_types
    elif isinstance(key_tuple, Const):
        key_types = [Const(v) for v in key_tuple.value]
    else:
        key_types = [Any]
    state.stack[-arg:] = [
        Dict[reduce(union, key_types, Union[()]),
             reduce(union, state.stack[-arg:], Union[()])]
    ]
Ejemplo n.º 9
0
def unpack_sequence(state, arg):
    t = state.stack.pop()
    if isinstance(t, Const):
        try:
            unpacked = [Const(ti) for ti in t.value]
            if len(unpacked) != arg:
                unpacked = [Any] * arg
        except TypeError:
            unpacked = [Any] * arg
    elif (isinstance(t, typehints.TupleHint.TupleConstraint)
          and len(t.tuple_types) == arg):
        unpacked = list(t.tuple_types)
    else:
        unpacked = [element_type(t)] * arg
    state.stack += reversed(unpacked)
Ejemplo n.º 10
0
def binary_subscr(state, unused_arg):
  index = state.stack.pop()
  base = Const.unwrap(state.stack.pop())
  if base in (str, unicode):
    out = base
  elif (isinstance(index, Const) and isinstance(index.value, int) and
        isinstance(base, typehints.IndexableTypeConstraint)):
    try:
      out = base._constraint_for_index(index.value)
    except IndexError:
      out = element_type(base)
  elif index == slice and isinstance(base, typehints.IndexableTypeConstraint):
    out = base
  else:
    out = element_type(base)
  state.stack.append(out)
Ejemplo n.º 11
0
def make_function(state, arg):
    """Creates a function with the arguments at the top of the stack.
  """
    # TODO(luke-zhu): Handle default argument types
    globals = state.f.__globals__  # Inherits globals from the current frame
    if sys.version_info[0] == 2:
        func_code = state.stack[-1].value
        func = types.FunctionType(func_code, globals)
        # argc is the number of default parameters. Ignored here.
        pop_count = 1 + arg
    else:  # Python 3.x
        func_name = state.stack[-1].value
        func_code = state.stack[-2].value
        pop_count = 2
        closure = None
        if sys.version_info[:2] == (3, 5):
            # https://docs.python.org/3.5/library/dis.html#opcode-MAKE_FUNCTION
            num_default_pos_args = (arg & 0xff)
            num_default_kwonly_args = ((arg >> 8) & 0xff)
            num_annotations = ((arg >> 16) & 0x7fff)
            pop_count += (num_default_pos_args + 2 * num_default_kwonly_args +
                          num_annotations + num_annotations > 0)
        elif sys.version_info >= (3, 6):
            # arg contains flags, with corresponding stack values if positive.
            # https://docs.python.org/3.6/library/dis.html#opcode-MAKE_FUNCTION
            pop_count += bin(arg).count('1')
            if arg & 0x08:
                # Convert types in Tuple constraint to a tuple of CPython cells.
                # https://stackoverflow.com/a/44670295
                closure = tuple((lambda _: lambda: _)(t).__closure__[0]
                                for t in state.stack[-3].tuple_types)

        func = types.FunctionType(func_code,
                                  globals,
                                  name=func_name,
                                  closure=closure)

    assert pop_count <= len(state.stack)
    state.stack[-pop_count:] = [Const(func)]
Ejemplo n.º 12
0
def map_add(state, arg):
    new_key_type = Const.unwrap(state.stack.pop())
    new_value_type = Const.unwrap(state.stack.pop())
    state.stack[-arg] = Dict[Union[state.stack[-arg].key_type, new_key_type],
                             Union[state.stack[-arg].value_type,
                                   new_value_type]]
Ejemplo n.º 13
0
def list_append(state, arg):
    new_element_type = Const.unwrap(state.stack.pop())
    state.stack[-arg] = List[Union[element_type(state.stack[-arg]),
                                   new_element_type]]
Ejemplo n.º 14
0
def unary(state, unused_arg):
    state.stack[-1] = Const.unwrap(state.stack[-1])
Ejemplo n.º 15
0
def set_add(state, arg):
    new_element_type = Const.unwrap(state.stack.pop())
    state.stack[-arg] = Set[union(element_type(state.stack[-arg]),
                                  new_element_type)]