Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion py4j-python/.pydevproject
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
<path>/py4j-python/src</path>
</pydev_pathproperty>
<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.6</pydev_property>
<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 3.9</pydev_property>
<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
</pydev_project>
2 changes: 0 additions & 2 deletions py4j-python/nose.cfg

This file was deleted.

5 changes: 0 additions & 5 deletions py4j-python/setup.cfg

This file was deleted.

12 changes: 5 additions & 7 deletions py4j-python/setup.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
try:
from setuptools import setup
except ImportError:
from distutils.core import setup
from setuptools import setup
import os

DOC_DIR = "doc"
DIST_DIR = "dist"
VERSION_PATH = os.path.join("src", "py4j", "version.py")
# For Python 3 compatibility, we can't use execfile; this is 2to3's conversion:
exec(compile(open(VERSION_PATH).read(),
VERSION_PATH, "exec"))
VERSION = __version__ # noqa
Expand Down Expand Up @@ -37,18 +33,20 @@
author="Barthelemy Dagenais",
author_email="barthelemy@infobart.com",
license="BSD License",
python_requires=">=3.9",
classifiers=[
"Development Status :: 4 - Beta",
"Intended Audience :: Developers",
"License :: OSI Approved :: BSD License",
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 2",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Java",
"Topic :: Software Development :: Libraries",
"Topic :: Software Development :: Object Brokering",
Expand Down
1 change: 0 additions & 1 deletion py4j-python/src/py4j/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# Py4J Package
from __future__ import absolute_import
from . import version

__version__ = version.__version__
4 changes: 0 additions & 4 deletions py4j-python/src/py4j/clientserver.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
# -*- coding: UTF-8 -*-
"""Module that implements a different threading model between
a Java Virtual Machine a Python interpreter.

In this model, Java and Python can exchange resquests and responses in the same
thread. For example, if a request is started in a Java UI thread and the Python
code calls some Java code, the Java code will be executed in the UI thread.
"""

from __future__ import unicode_literals, absolute_import

from collections import deque
import logging
import socket
Expand Down
159 changes: 65 additions & 94 deletions py4j-python/src/py4j/compat.py
Original file line number Diff line number Diff line change
@@ -1,112 +1,95 @@
# coding: utf-8
"""
Compatibility functions for unified behavior between Python 2.x and 3.x.
Compatibility shims left over from py4j's Python 2 / 3 dual-support era.

Python 2 support has been removed (py4j requires Python 3.9+). The
names below are kept solely so that downstream code that still imports
from this module (``from py4j.compat import unicode``, etc.) continues
to work.

New code inside py4j should use the Python 3 built-ins directly:

- ``unicode`` -> ``str``
- ``basestring`` -> ``str``
- ``long`` -> ``int``
- ``range`` -> built-in ``range``
- ``unichr`` -> ``chr``
- ``bytestr`` -> ``bytes``
- ``bytearray2`` -> ``bytes`` (or ``bytearray``; alias kept as ``bytes``)
- ``iteritems(d)`` -> ``d.items()``
- ``items(d)`` -> ``list(d.items())``
- ``next(x)`` -> built-in ``next(x)``
- ``Queue`` -> ``from queue import Queue``
- ``Empty`` -> ``from queue import Empty``
- ``CompatThread`` -> ``threading.Thread`` (already supports ``daemon``)

Only ``hasattr2`` has no Python-3-builtin replacement: it uses
``inspect.getattr_static`` to test for an attribute without triggering
descriptor / ``__getattr__`` side effects, which is genuinely
different behavior from the built-in ``hasattr``.

This module may be removed in a future major release; downstream code
should migrate off the imports above.

:author: Alex Grönholm
"""
from __future__ import unicode_literals, absolute_import

import inspect
import sys
from threading import Thread
from queue import Queue as _StdQueue, Empty as _StdEmpty

version_info = sys.version_info

if version_info.major < 3:
def items(d):
return d.items()

def iteritems(d):
return d.iteritems()

def next(x):
return x.next()

range = xrange # noqa

long = long # noqa

basestring = basestring # noqa

unicode = unicode # noqa

bytearray2 = bytearray

unichr = unichr # noqa

bytestr = str

tobytestr = str

def isbytestr(s):
return isinstance(s, str)

def ispython3bytestr(s):
return False

def isbytearray(s):
return isinstance(s, bytearray)
version_info = sys.version_info

def bytetoint(b):
return ord(b)

def bytetostr(b):
return b
def items(d):
return list(d.items())

def strtobyte(b):
return b

import Queue
Empty = Queue.Empty
Queue = Queue.Queue
def iteritems(d):
return d.items()

else:
def items(d):
return list(d.items())

def iteritems(d):
return d.items()
# Built-in passthroughs — kept as module attributes so existing
# ``from py4j.compat import range, unicode, ...`` imports still work.
range = range
long = int
basestring = str
unicode = str
bytearray2 = bytes
unichr = chr
bytestr = bytes

next = next

range = range
def tobytestr(s):
return bytes(s, "ascii")

long = int

basestring = str
def isbytestr(s):
return isinstance(s, bytes)

unicode = str

bytearray2 = bytes
def ispython3bytestr(s):
return isinstance(s, bytes)

unichr = chr

bytestr = bytes
def isbytearray(s):
return isinstance(s, bytearray)

def tobytestr(s):
return bytes(s, "ascii")

def isbytestr(s):
return isinstance(s, bytes)
def bytetoint(b):
return b

def ispython3bytestr(s):
return isinstance(s, bytes)

def isbytearray(s):
return isinstance(s, bytearray)
def bytetostr(b):
return str(b, encoding="ascii")

def bytetoint(b):
return b

def bytetostr(b):
return str(b, encoding="ascii")
def strtobyte(s):
return bytes(s, encoding="ascii")

def strtobyte(s):
return bytes(s, encoding="ascii")

import queue
Queue = queue.Queue
Empty = queue.Empty
Queue = _StdQueue
Empty = _StdEmpty


if hasattr(inspect, "getattr_static"):
Expand All @@ -116,19 +99,7 @@ def hasattr2(obj, attr):
hasattr2 = hasattr


class CompatThread(Thread):
"""Compatibility Thread class.

Allows Python 2 Thread class to accept daemon kwarg in init.
"""

def __init__(self, *args, **kwargs):
daemon = None
try:
daemon = kwargs.pop("daemon")
except KeyError:
pass
super(CompatThread, self).__init__(*args, **kwargs)

if daemon:
self.daemon = daemon
# Python 3's ``threading.Thread`` accepts the ``daemon`` kwarg natively,
# so this is just a passthrough. Kept as a name for external callers
# that imported ``CompatThread`` from this module.
CompatThread = Thread
9 changes: 2 additions & 7 deletions py4j-python/src/py4j/finalizer.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# -*- coding: UTF-8 -*-
"""
Module that defines a Finalizer class responsible for registering and cleaning
finalizer
Expand All @@ -7,12 +6,8 @@

:author: Barthelemy Dagenais
"""
from __future__ import unicode_literals, absolute_import

from threading import RLock

from py4j.compat import items


class ThreadSafeFinalizer(object):
"""A `ThreadSafeFinalizer` is a global class used to register weak
Expand Down Expand Up @@ -64,7 +59,7 @@ def clear_finalizers(cls, clear_all=False):
if clear_all:
cls.finalizers.clear()
else:
for id, ref in items(cls.finalizers):
for id, ref in list(cls.finalizers.items()):
if ref() is None:
cls.finalizers.pop(id, None)

Expand Down Expand Up @@ -116,7 +111,7 @@ def clear_finalizers(cls, clear_all=False):
if clear_all:
cls.finalizers.clear()
else:
for id, ref in items(cls.finalizers):
for id, ref in list(cls.finalizers.items()):
if ref() is None:
cls.finalizers.pop(id, None)

Expand Down
37 changes: 11 additions & 26 deletions py4j-python/src/py4j/java_collections.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# -*- coding: UTF-8 -*-
"""
Module responsible for converting Java collection classes to Python collection
classes. This module is optional but loaded by default.
Expand All @@ -8,26 +7,11 @@

:author: Barthelemy Dagenais
"""
from __future__ import unicode_literals, absolute_import

# As of Python 3.3, the abstract base classes in the collections module have
# been moved to collections.abc.
# (see https://docs.python.org/3.3/library/collections.abc.html)
try:
# Python >=3.3
from collections.abc import (
MutableMapping, Sequence, MutableSequence,
MutableSet, Set)
except ImportError:
# Python <=3.2
from collections import (
MutableMapping, Sequence, MutableSequence,
MutableSet, Set)
import sys

from py4j.compat import (
iteritems, next, hasattr2, isbytearray,
ispython3bytestr, basestring)
from collections.abc import (
MutableMapping, Sequence, MutableSequence,
MutableSet, Set)

from py4j.compat import hasattr2
from py4j.java_gateway import JavaObject, JavaMember, get_method, JavaClass
from py4j import protocol as proto
from py4j.protocol import (
Expand Down Expand Up @@ -105,7 +89,7 @@ def __str__(self):
def __repr__(self):
items = (
"{0}: {1}".format(repr(k), repr(v))
for k, v in iteritems(self))
for k, v in self.items())
return "{{{0}}}".format(", ".join(items))


Expand All @@ -114,8 +98,8 @@ class JavaSet(JavaObject, MutableSet):

All operations possible on a Python set are implemented."""

__EMPTY_SET = "set([])" if sys.version_info.major < 3 else "set()"
__SET_TEMPLATE = "set([{0}])" if sys.version_info.major < 3 else "{{{0}}}"
__EMPTY_SET = "set()"
__SET_TEMPLATE = "{{{0}}}"

def __init__(self, target_id, gateway_client):
JavaObject.__init__(self, target_id, gateway_client)
Expand Down Expand Up @@ -507,8 +491,9 @@ class ListConverter(object):
def can_convert(self, object):
# Check for iterator protocol and should not be an instance of byte
# array (taken care of by protocol)
return hasattr2(object, "__iter__") and not isbytearray(object) and\
not ispython3bytestr(object) and not isinstance(object, basestring)
return hasattr2(object, "__iter__") and \
not isinstance(object, bytearray) and \
not isinstance(object, bytes) and not isinstance(object, str)

def convert(self, object, gateway_client):
ArrayList = JavaClass("java.util.ArrayList", gateway_client)
Expand Down
Loading
Loading