• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

CityOfZion / neo3-boa / 0aff654d-b027-49a1-9d97-558d9a2a52ff

05 Mar 2024 04:57PM UTC coverage: 91.985% (-0.1%) from 92.106%
0aff654d-b027-49a1-9d97-558d9a2a52ff

push

circleci

web-flow
Merge pull request #1215 from CityOfZion/CU-86drpndkk

CU-86drpndkk - Refactor test_interop/test_blockchain.py to use BoaTestConstructor

1 of 1 new or added line in 1 file covered. (100.0%)

658 existing lines in 143 files now uncovered.

20635 of 22433 relevant lines covered (91.99%)

1.84 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.85
/boa3/internal/model/builtin/classmethod/joinmethod.py
1
from collections.abc import Iterable
2✔
2
from typing import Any
2✔
3

4
from boa3.internal.model.builtin.method.builtinmethod import IBuiltinMethod
2✔
5
from boa3.internal.model.type.collection.mapping.mutable.dicttype import DictType
2✔
6
from boa3.internal.model.type.collection.sequence.sequencetype import SequenceType
2✔
7
from boa3.internal.model.type.primitive.ibytestringtype import IByteStringType
2✔
8
from boa3.internal.model.variable import Variable
2✔
9
from boa3.internal.neo.vm.opcode.Opcode import Opcode
2✔
10

11

12
class JoinMethod(IBuiltinMethod):
2✔
13
    def __init__(self, self_type: IByteStringType = None, iterable_type: SequenceType | DictType = None):
2✔
14
        from boa3.internal.model.type.type import Type
2✔
15

16
        if not isinstance(self_type, IByteStringType):
2✔
17
            self_type = Type.bytes
2✔
18

19
        if not isinstance(iterable_type, (SequenceType, DictType)):
2✔
20
            iterable_type = Type.sequence.build_collection([self_type])
2✔
21

22
        identifier = 'join'
2✔
23
        args: dict[str, Variable] = {
2✔
24
            'self': Variable(self_type),
25
            'iterable': Variable(iterable_type),
26
        }
27

28
        super().__init__(identifier, args, return_type=self_type)
2✔
29

30
    @property
2✔
31
    def identifier(self) -> str:
2✔
32
        from boa3.internal.model.type.type import Type
2✔
33

34
        if Type.dict.is_type_of(self._arg_iterable.type):
2✔
35
            return '-{0}_{1}'.format(self._identifier, Type.dict.identifier)
2✔
36

37
        return self._identifier  # JoinMethod default value for self
2✔
38

39
    @property
2✔
40
    def _arg_self(self) -> Variable:
2✔
41
        return self.args['self']
2✔
42

43
    @property
2✔
44
    def _arg_iterable(self) -> Variable:
2✔
45
        return self.args['iterable']
2✔
46

47
    def push_self_first(self) -> bool:
2✔
48
        return self.has_self_argument
2✔
49

50
    def generate_internal_opcodes(self, code_generator):
2✔
51
        from boa3.internal.model.builtin.builtin import Builtin
2✔
52
        from boa3.internal.model.operation.binaryop import BinaryOp
2✔
53

54
        code_generator.duplicate_stack_top_item()
2✔
55
        # iterable_size = len(iterable)
56
        code_generator.convert_builtin_method_call(Builtin.Len, is_internal=True)
2✔
57
        # index = 0
58
        code_generator.convert_literal(0)
2✔
59
        code_generator.duplicate_stack_item(2)
2✔
60
        code_generator.duplicate_stack_item(2)
2✔
61

62
        # if iterable_size >= 0:
63
        if_iterable_not_empty = code_generator.convert_begin_if()
2✔
64
        code_generator.change_jump(if_iterable_not_empty, Opcode.JMPLE)
2✔
65

66
        from boa3.internal.model.type.type import Type
2✔
67
        if Type.dict.is_type_of(self._arg_iterable.type):
2✔
68
            code_generator.swap_reverse_stack_items(3)
2✔
69
            code_generator.convert_builtin_method_call(Builtin.DictKeys)
2✔
70
            code_generator.swap_reverse_stack_items(3)
2✔
71

72
        #   joined = iterable[0]
73
        code_generator.duplicate_stack_item(3)
2✔
74
        code_generator.duplicate_stack_item(2)
2✔
75
        code_generator.convert_get_item(index_inserted_internally=True)
2✔
76
        code_generator.swap_reverse_stack_items(2)
2✔
77
        #   index += 1
78
        code_generator.insert_opcode(Opcode.INC)
2✔
79
        code_generator.swap_reverse_stack_items(2)
2✔
80

81
        #   while index < iterable_size:
82
        while_start = code_generator.convert_begin_while()
2✔
83

84
        code_generator.duplicate_stack_item(5)
2✔
85
        #       joined = joined + string
86
        code_generator.convert_operation(BinaryOp.Concat, is_internal=True)
2✔
87
        code_generator.duplicate_stack_item(4)
2✔
88
        code_generator.duplicate_stack_item(3)
2✔
89
        code_generator.convert_get_item(index_inserted_internally=True)
2✔
90
        #       joined = joined + iterable[index]
91
        code_generator.convert_operation(BinaryOp.Concat, is_internal=True)
2✔
92
        code_generator.swap_reverse_stack_items(2)
2✔
93
        #       index += 1
94
        code_generator.insert_opcode(Opcode.INC)
2✔
95
        code_generator.swap_reverse_stack_items(2)
2✔
96

97
        # # while condition and end
98
        while_condition = code_generator.bytecode_size
2✔
99
        code_generator.duplicate_stack_item(2)
2✔
100
        code_generator.duplicate_stack_item(4)
2✔
101
        code_generator.convert_operation(BinaryOp.Lt)
2✔
102
        code_generator.convert_end_while(while_start, while_condition, is_internal=True)
2✔
103

104
        #   return joined
105
        code_generator.convert_cast(Type.str, is_internal=True)
2✔
106

107
        # elif iterable_size < 0:
108
        else_iterable_is_empty = code_generator.convert_begin_else(if_iterable_not_empty, is_internal=True)
2✔
109
        #   return ""
110
        code_generator.convert_literal("")
2✔
111
        code_generator.convert_end_if(else_iterable_is_empty)
2✔
112

113
        code_generator.remove_stack_item(2)
2✔
114
        code_generator.remove_stack_item(2)
2✔
115
        code_generator.remove_stack_item(2)
2✔
116
        code_generator.remove_stack_item(2)
2✔
117

118
    @property
2✔
119
    def _args_on_stack(self) -> int:
2✔
120
        return len(self.args)
2✔
121

122
    @property
2✔
123
    def _body(self) -> str | None:
2✔
UNCOV
124
        return None
×
125

126
    def build(self, value: Any) -> IBuiltinMethod:
2✔
127
        if not isinstance(value, Iterable):
2✔
128
            value = [value]
2✔
129
        if isinstance(value, list) and len(value) <= 2:
2✔
130
            self_type = self._arg_self.type
2✔
131
            if len(value) < 2:
2✔
132
                value.append(None)
2✔
133
            if isinstance(value[0], type(self_type)) and isinstance(value[1], SequenceType):
2✔
134
                return self
2✔
135
            else:
136
                return JoinMethod(value[0], value[1])
2✔
137

UNCOV
138
        return super().build(value)
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc