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

tcalmant / python-javaobj / 26727702718

31 May 2026 11:33PM UTC coverage: 78.944% (-0.02%) from 78.962%
26727702718

push

github

web-flow
Merge pull request #65 from tcalmant/bug-fix

Bug fix

4 of 8 new or added lines in 4 files covered. (50.0%)

2587 of 3277 relevant lines covered (78.94%)

4.3 hits per line

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

83.95
/javaobj/v1/beans.py
1
#!/usr/bin/python
2
# -- Content-Encoding: utf-8 --
3
"""
4
Definition of the beans of the v1 parser
5

6
:authors: Volodymyr Buell, Thomas Calmant
7
:license: Apache License 2.0
8
:version: 0.4.4
9
:status: Alpha
10

11
..
12

13
    Copyright 2024 Thomas Calmant
14

15
    Licensed under the Apache License, Version 2.0 (the "License");
16
    you may not use this file except in compliance with the License.
17
    You may obtain a copy of the License at
18

19
        http://www.apache.org/licenses/LICENSE-2.0
20

21
    Unless required by applicable law or agreed to in writing, software
22
    distributed under the License is distributed on an "AS IS" BASIS,
23
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24
    See the License for the specific language governing permissions and
25
    limitations under the License.
26
"""
27

28
from __future__ import absolute_import
7✔
29

30
from typing import List
7✔
31
import struct
7✔
32

33
from ..utils import UNICODE_TYPE
7✔
34

35
# ------------------------------------------------------------------------------
36

37
__all__ = (
7✔
38
    "JavaArray",
39
    "JavaByteArray",
40
    "JavaClass",
41
    "JavaEnum",
42
    "JavaObject",
43
    "JavaString",
44
)
45

46
# Module version
47
__version_info__ = (0, 4, 4)
7✔
48
__version__ = ".".join(str(x) for x in __version_info__)
7✔
49

50
# Documentation strings format
51
__docformat__ = "restructuredtext en"
7✔
52

53
# ------------------------------------------------------------------------------
54

55

56
class JavaClass(object):  # pylint:disable=R0205
7✔
57
    """
58
    Represents a class in the Java world
59
    """
60

61
    def __init__(self):
7✔
62
        """
63
        Sets up members
64
        """
65
        self.name = None  # type: str
7✔
66
        self.serialVersionUID = None  # type: int  # pylint:disable=C0103
7✔
67
        self.flags = None  # type: int
7✔
68
        self.fields_names = []  # type: List[str]
7✔
69
        self.fields_types = []  # type: List[JavaString]
7✔
70
        self.superclass = None  # type: JavaClass
7✔
71

72
    def __str__(self):
7✔
73
        """
74
        String representation of the Java class
75
        """
76
        return self.__repr__()
7✔
77

78
    def __repr__(self):
7✔
79
        """
80
        String representation of the Java class
81
        """
82
        return "[{0:s}:0x{1:X}]".format(self.name, self.serialVersionUID)
7✔
83

84
    def __eq__(self, other):
7✔
85
        """
86
        Equality test between two Java classes
87

88
        :param other: Other JavaClass to test
89
        :return: True if both classes share the same fields and name
90
        """
91
        if not isinstance(other, type(self)):
7✔
92
            return False
7✔
93

94
        return (
7✔
95
            self.name == other.name
96
            and self.serialVersionUID == other.serialVersionUID
97
            and self.flags == other.flags
98
            and self.fields_names == other.fields_names
99
            and self.fields_types == other.fields_types
100
            and self.superclass == other.superclass
101
        )
102

103

104
class JavaObject(object):  # pylint:disable=R0205
7✔
105
    """
106
    Represents a deserialized non-primitive Java object
107
    """
108

109
    def __init__(self):
7✔
110
        """
111
        Sets up members
112
        """
113
        self.classdesc = None  # type: JavaClass
7✔
114
        self.annotations = []
7✔
115

116
    def get_class(self):
7✔
117
        """
118
        Returns the JavaClass that defines the type of this object
119
        """
120
        return self.classdesc
7✔
121

122
    def __str__(self):
7✔
123
        """
124
        String representation
125
        """
126
        return self.__repr__()
7✔
127

128
    def __repr__(self):
7✔
129
        """
130
        String representation
131
        """
132
        name = "UNKNOWN"
7✔
133
        if self.classdesc:
7✔
134
            name = self.classdesc.name
7✔
135
        return "<javaobj:{0}>".format(name)
7✔
136

137
    def __hash__(self):
7✔
138
        """
139
        Each JavaObject we load must have a hash method to be accepted in sets
140
        and alike. The default hash is the memory address of the object.
141
        """
142
        return id(self)
×
143

144
    def __eq__(self, other):
7✔
145
        """
146
        Equality test between two Java classes
147

148
        :param other: Other JavaClass to test
149
        :return: True if both classes share the same fields and name
150
        """
151
        if not isinstance(other, type(self)):
×
152
            return False
×
153

154
        res = (
×
155
            self.classdesc == other.classdesc
156
            and self.annotations == other.annotations
157
        )
158
        if not res:
×
159
            return False
×
160

161
        for name in self.classdesc.fields_names:
×
162
            if not getattr(self, name) == getattr(other, name):
×
163
                return False
×
164
        return True
×
165

166

167
class JavaString(UNICODE_TYPE):
7✔
168
    """
169
    Represents a Java String
170
    """
171

172
    def __hash__(self):
7✔
173
        return UNICODE_TYPE.__hash__(self)
7✔
174

175
    def __eq__(self, other):
7✔
176
        # Accept both UNICODE_TYPE and plain str.
177
        # In Python 2, UNICODE_TYPE is unicode while str literals are bytes;
178
        # including str here lets assertEqual(java_string, "literal") work
179
        # in Python 2 as well as Python 3 (where str == UNICODE_TYPE).
180
        if not isinstance(other, (UNICODE_TYPE, str)):
7✔
181
            return False
7✔
182
        result = UNICODE_TYPE.__eq__(self, other)
7✔
183
        return False if result is NotImplemented else result
7✔
184

185

186
class JavaEnum(JavaObject):
7✔
187
    """
188
    Represents a Java enumeration
189
    """
190

191
    def __init__(self, constant=None):
7✔
192
        super(JavaEnum, self).__init__()
7✔
193
        self.constant = constant
7✔
194

195

196
class JavaArray(list, JavaObject):
7✔
197
    """
198
    Represents a Java Array
199
    """
200

201
    def __init__(self, classdesc=None):
7✔
202
        list.__init__(self)
7✔
203
        JavaObject.__init__(self)
7✔
204
        self.classdesc = classdesc
7✔
205

206
    def __hash__(self):
7✔
NEW
207
        return object.__hash__(self)
×
208

209

210
class JavaByteArray(JavaObject):
7✔
211
    """
212
    Represents the special case of Java Array which contains bytes
213
    """
214

215
    def __init__(self, data, classdesc=None):
7✔
216
        JavaObject.__init__(self)
7✔
217
        self._data = struct.unpack("b" * len(data), data)
7✔
218
        self.classdesc = classdesc
7✔
219

220
    def __str__(self):
7✔
221
        return "JavaByteArray({0})".format(self._data)
×
222

223
    def __getitem__(self, item):
7✔
224
        return self._data[item]
×
225

226
    def __iter__(self):
7✔
227
        return iter(self._data)
7✔
228

229
    def __len__(self):
7✔
230
        return len(self._data)
7✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc