Shofel2_T124_python/venv/lib/python3.10/site-packages/jpype/beans.py

100 lines
3.6 KiB
Python

# *****************************************************************************
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# See NOTICE file for details.
#
# *****************************************************************************
"""
JPype Beans Module
------------------
This customizer finds all occurences of methods with get or set and converts
them into Python properties. This behavior is sometimes useful in programming
with JPype with interactive shells, but also leads to a lot of confusion.
Is this class exposing a variable or is this a property added JPype.
As an unnecessary behavior that violates both the Python principle
*"There should be one-- and preferably only one --obvious way to do it."* and
the C++ principle *"You only pay for what you use"*. This misfeature
was removed from the distribution as a default. However, given that it is
useful to have methods appear as properties, it was moved to a
an optional module.
To use beans as properties:
.. code-block:: python
import jpype.beans
The beans property modification is a global behavior and applies retroactively
to all classes currently loaded. Once started it can not be undone.
"""
import _jpype
from . import _jcustomizer
from ._pykeywords import pysafe as _pysafe
def _extract_accessor_pairs(members):
"""Extract pairs of corresponding property access methods
(getter and setter) from a Java class's members (attributes).
If a public method with a property's name exists no pair for
that property will be extracted.
Returns a dictionary with the property name as key and a tuple
of (getter method, setter method) as value. A tuple element
value might be `None` if only a getter or only a setter
exists.
"""
accessor_pairs = {}
for name, member in members.items():
if not isinstance(member, _jpype._JMethod) or len(name) <= 3:
continue
if name == "getClass":
continue
if member._isBeanAccessor():
property_name = name[3].lower() + name[4:]
try:
pair = accessor_pairs[property_name]
pair[0] = member
except KeyError:
accessor_pairs[property_name] = [member, None]
elif member._isBeanMutator():
property_name = name[3].lower() + name[4:]
try:
pair = accessor_pairs[property_name]
pair[1] = member
except KeyError:
accessor_pairs[property_name] = [None, member]
return accessor_pairs
@_jcustomizer.JImplementationFor("java.lang.Object")
class _BeansCustomizer(object):
""" Add properties for get/set Bean patterns found in classes. """
def __jclass_init__(self):
accessor_pairs = _extract_accessor_pairs(self.__dict__)
for attr_name, (getter, setter) in accessor_pairs.items():
attr_name = _pysafe(attr_name)
# Don't mess with an existing member
if attr_name is None or attr_name in self.__dict__:
continue
# Add the property
self._customize(attr_name, property(getter, setter))