diff --git a/javaobj/v1/beans.py b/javaobj/v1/beans.py index bf867bb..03a0f26 100644 --- a/javaobj/v1/beans.py +++ b/javaobj/v1/beans.py @@ -173,9 +173,14 @@ def __hash__(self): return UNICODE_TYPE.__hash__(self) def __eq__(self, other): - if not isinstance(other, UNICODE_TYPE): + # Accept both UNICODE_TYPE and plain str. + # In Python 2, UNICODE_TYPE is unicode while str literals are bytes; + # including str here lets assertEqual(java_string, "literal") work + # in Python 2 as well as Python 3 (where str == UNICODE_TYPE). + if not isinstance(other, (UNICODE_TYPE, str)): return False - return UNICODE_TYPE.__eq__(self, other) + result = UNICODE_TYPE.__eq__(self, other) + return False if result is NotImplemented else result class JavaEnum(JavaObject): @@ -199,7 +204,7 @@ def __init__(self, classdesc=None): self.classdesc = classdesc def __hash__(self): - return list.__hash__(self) + return object.__hash__(self) class JavaByteArray(JavaObject): diff --git a/javaobj/v1/transformers.py b/javaobj/v1/transformers.py index c581125..2a28f1a 100644 --- a/javaobj/v1/transformers.py +++ b/javaobj/v1/transformers.py @@ -136,7 +136,7 @@ def __extra_loading__(self, unmarshaller, ident=0): """ # Ignore the blockdata opid (opid,) = unmarshaller._readStruct(">B") - if opid != ClassDescFlags.SC_BLOCK_DATA: + if opid != TerminalCode.TC_BLOCKDATA: raise ValueError("Start of block data not found") # Read HashMap fields diff --git a/javaobj/v1/unmarshaller.py b/javaobj/v1/unmarshaller.py index 17c9343..47c6cc1 100644 --- a/javaobj/v1/unmarshaller.py +++ b/javaobj/v1/unmarshaller.py @@ -83,7 +83,7 @@ # Convertion of a Java type char to its NumPy equivalent NUMPY_TYPE_MAP = { TypeCode.TYPE_BYTE: "B", - TypeCode.TYPE_CHAR: "b", + TypeCode.TYPE_CHAR: ">u2", TypeCode.TYPE_DOUBLE: ">d", TypeCode.TYPE_FLOAT: ">f", TypeCode.TYPE_INTEGER: ">i", @@ -508,7 +508,8 @@ def do_object(self, parent=None, ident=0): # classdata[] if ( - classdesc.flags & ClassDescFlags.SC_EXTERNALIZABLE + classdesc is not None + and classdesc.flags & ClassDescFlags.SC_EXTERNALIZABLE and not classdesc.flags & ClassDescFlags.SC_BLOCK_DATA ): # TODO: @@ -831,8 +832,9 @@ def _oops_dump_state(self, ignore_remaining_data=False): "(2nd line is an actual position!):" ) - # Do not use a keyword argument - self.object_stream.seek(-16, os.SEEK_CUR) + # Do not use a keyword argument; clamp to avoid seeking before start + current_pos = self.object_stream.tell() + self.object_stream.seek(max(0, current_pos - 16)) position = self.object_stream.tell() the_rest = self.object_stream.read() diff --git a/javaobj/v2/core.py b/javaobj/v2/core.py index 8e018a6..880be3c 100644 --- a/javaobj/v2/core.py +++ b/javaobj/v2/core.py @@ -146,7 +146,7 @@ def run(self): # Read content contents = [] # type: List[ParsedJavaContent] while True: - self._log.info("Reading next content") + self._log.debug("Reading next content") start = self.__fd.tell() try: type_code = self.__reader.read_byte() diff --git a/javaobj/v2/transformers.py b/javaobj/v2/transformers.py index 087eea9..82bfd96 100644 --- a/javaobj/v2/transformers.py +++ b/javaobj/v2/transformers.py @@ -506,7 +506,7 @@ class NumpyArrayTransformer(ObjectTransformer): # Convertion of a Java type char to its NumPy equivalent NUMPY_TYPE_MAP = { TypeCode.TYPE_BYTE: "B", - TypeCode.TYPE_CHAR: "b", + TypeCode.TYPE_CHAR: ">u2", TypeCode.TYPE_DOUBLE: ">d", TypeCode.TYPE_FLOAT: ">f", TypeCode.TYPE_INTEGER: ">i", diff --git a/pyproject.toml b/pyproject.toml index c380172..a564a3e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,8 +38,8 @@ classifiers = [ ] dependencies = [ - "enum34; python_version<='3.4'", - "typing; python_version<='3.4'" + "enum34; python_version<'3.4'", + "typing; python_version<'3.5'" ] [project.optional-dependencies] diff --git a/setup.py b/setup.py index cf93fb8..5e2b29c 100644 --- a/setup.py +++ b/setup.py @@ -72,8 +72,8 @@ def read(fname): packages=["javaobj", "javaobj.v1", "javaobj.v2"], test_suite="tests", install_requires=[ - 'enum34;python_version<="3.4"', - 'typing;python_version<="3.4"', + "enum34; python_version<'3.4'", + "typing; python_version<'3.5'" ], long_description=read("README.md"), long_description_content_type="text/markdown", @@ -91,6 +91,8 @@ def read(fname): "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", "Topic :: Software Development :: Libraries :: Python Modules", ], ) diff --git a/tests/test_v1.py b/tests/test_v1.py index e22ebc0..65fcd5f 100644 --- a/tests/test_v1.py +++ b/tests/test_v1.py @@ -337,18 +337,12 @@ def test_char_array(self): jobj = self.read_file("testCharArray.ser") pobj = javaobj.loads(jobj) _logger.debug(pobj) - self.assertEqual( - pobj, - [ - "\u0000", - "\ud800", - "\u0001", - "\udc00", - "\u0002", - "\uffff", - "\u0003", - ], - ) + # Compare by code points to avoid Python 2/3 string literal ambiguity + # (ruff strips u"" prefixes; \u-escapes in plain str are literal in Py2) + expected_codepoints = [0x0000, 0xD800, 0x0001, 0xDC00, 0x0002, 0xFFFF, 0x0003] + self.assertEqual(len(pobj), len(expected_codepoints)) + for actual, cp in zip(pobj, expected_codepoints): + self.assertEqual(ord(actual), cp) self._try_marshalling(jobj, pobj) def test_2d_array(self): diff --git a/tests/test_v2.py b/tests/test_v2.py index fbabbda..b4b8503 100644 --- a/tests/test_v2.py +++ b/tests/test_v2.py @@ -417,18 +417,12 @@ def test_char_array(self): jobj = self.read_file("testCharArray.ser") pobj = javaobj.loads(jobj) _logger.debug(pobj) - self.assertEqual( - pobj, - [ - "\u0000", - "\ud800", - "\u0001", - "\udc00", - "\u0002", - "\uffff", - "\u0003", - ], - ) + # Compare by code points to avoid Python 2/3 string literal ambiguity + # (ruff strips u"" prefixes; \u-escapes in plain str are literal in Py2) + expected_codepoints = [0x0000, 0xD800, 0x0001, 0xDC00, 0x0002, 0xFFFF, 0x0003] + self.assertEqual(len(pobj), len(expected_codepoints)) + for actual, cp in zip(pobj, expected_codepoints): + self.assertEqual(ord(actual), cp) def test_2d_array(self): """