Pyjnius: методы суперкласса, недоступные в 1.2.1

Созданный на 13 дек. 2019  ·  20Комментарии  ·  Источник: kivy/pyjnius

arraylist = autoclass("java.util.ArrayList")()
arraylist.iterator()
arraylist.stream()

Это работает для 1.2.0, но не для 1.2.1.

AttributeError                            Traceback (most recent call last)
<ipython-input-7-5e67e1c90388> in <module>()
----> 1 arraylist.stream()

AttributeError: 'java.util.ArrayList' object has no attribute 'stream'

Воспроизводимый блокнот по адресу https://colab.research.google.com/drive/1F9u2jVQR5JFw_mk5Bq--VH1Ki91Xe5x3

stream () определен в супер-интерфейсе по умолчанию.

У нас также были проблемы с доступом к методам в интерфейсах, расширяющих java.util.List.

Самый полезный комментарий

Я наблюдаю ту же проблему, методы суперкласса недоступны в 1.2.1, но все работает в 1.2.0. Это довольно неприятная ошибка, вам не кажется, что имеет смысл удалить релиз 1.2.1 или как-то пометить его как непригодный для использования?

Все 20 Комментарий

Я могу воспроизвести это локально, посмотрим, произойдет ли это также в CI, я поищу исправление, когда у меня будет время.

CI не удалось, но я не вижу, как мы его сломали в 1.2.1. Я вижу, что getDeclaredMethods () не включает методы, которые являются реализациями по умолчанию. (Они не объявлены в классе или его супертипах).

В https://blog.jooq.org/2018/03/28/correct-reflective-access-to-interface-default-methods-in-java-8-9-10/ есть обсуждение - я не думаю, что это актуально.

Может ли решение также обходить все интерфейсы и их родительские интерфейсы с добавлением методов по умолчанию? (Мы могли бы добавить абстрактные методы, но это кажется излишним, поскольку они должны быть реализованы конкретным объектом).

Это наиболее актуальный поток stackoverflow, который я нашел: https://stackoverflow.com/questions/28400408/what-is-the-new-way-of-getting-all-methods-of-a-class-including-inherited- defau

кажется, что в разных реализациях JVM могут быть некоторые различия ...

Это сработает, если я сначала перейду к java.util.Collection, но в этом нет необходимости…: /

Я также думаю, что из-за использования getDeclaredMethods вместо getMethods я попытался обойти все интерфейсы, но почему-то не нашел интерфейс Collection в getInterfaces () ...

хм, похоже, это работает ... не совсем понимаю, почему.
https://github.com/kivy/pyjnius/pull/466/files#diff -06f2b31838f083623d82353f734d644a

изменить: эээ, за исключением segfault… https://github.com/kivy/pyjnius/runs/348651345
попробовал запустить снова, если это был сбой, снова вылетел на ubuntu, python3.8, java 10…
edit2: очень запутано, вся текущая комбинация сработала, когда я исключил 3.8 / java10 / ubuntu вместе, затем я включил java 9 и 11, и получил тот же сбой с 3.7 / 11 / ubuntu ... ну, по крайней мере, я могу установить openjdk-11-jdk на моем ubuntu и легко протестирую с python3.7…… и он работает. grmbl.

https://dev.azure.com/conda-forge/feedstock-builds/_build/results?buildId=100815&view=logs&j=696704cc-6fef-57a3-ea36-f27779b8cd5e&t=06421391-4b55-523d-a804fe190a8
Похоже, что сборка conda-forge на Linux также имеет некоторые ошибки в 1.2.1, так что проблема могла существовать до моего изменения.

патч у меня работает на коллаборации

вежливая шишка. Было бы хорошо, если бы это было объединено. Я добавил комментарий к разнице, предлагающий комментарий к коду.

Извините за то, что позволил этому задержаться, я просто понятия не имею, что мешает прохождению CI, и мне не очень нравится отключать часть целей только для того, чтобы замолчать непонятную ошибку, я согласен, что этот битрот не лучше, но я ' Я не знаю, как дальше двигаться дальше.

Я задавался вопросом, была ли это проблема параллелизма согласно # 480, но я не думаю, что pytest по умолчанию работает одновременно.

Пытался воспроизвести локально, но # 480 воспроизвести не удалось. Вот моя команда - образ на основе Debian:

docker run -i continuumio/anaconda3 /bin/bash <<EOF

cat /etc/os-release
apt-get update
mkdir /usr/share/man/man1
apt-get -y install openjdk-11-jdk-headless gcc ant

conda create -y -n pyjnius python=3.7.5
conda activate pyjnius

git clone https://github.com/kivy/pyjnius.git
cd pyjnius/
python -m pip install -U setuptools cython
python setup.py bdist_wheel
pip install --timeout=120 .[dev,ci]
ant all
cd tests/
CLASSPATH="../build/test-classes:../build/classes" PYTHONPATH=/opt/conda/envs/pyjnius/lib/python3.7/site-packages/ pytest -v
cd ../
git checkout -b issue_465 origin/issue_465

python setup.py bdist_wheel
pip install --timeout=120 .[dev,ci]
ant all
cd tests/
CLASSPATH="../build/test-classes:../build/classes" PYTHONPATH=/opt/conda/envs/pyjnius/lib/python3.7/site-packages/ pytest -v

EOF

Все тесты прошли на мастере и на ветке.

Я наблюдаю ту же проблему, методы суперкласса недоступны в 1.2.1, но все работает в 1.2.0. Это довольно неприятная ошибка, вам не кажется, что имеет смысл удалить релиз 1.2.1 или как-то пометить его как непригодный для использования?

Извините за то, что позволил этому задержаться, я просто понятия не имею, что мешает прохождению CI, и мне не очень нравится отключать часть целей только для того, чтобы замолчать непонятную ошибку, я согласен, что этот битрот не лучше, но я ' Я не знаю, как дальше двигаться дальше.

Могу я предложить повторно запустить тесты CI? Можем ли мы попытаться сузить круг вопросов - проблема в этом патче или проблема в предыдущей версии?

Чтобы вернуться к этому:

Я не думаю, что смешивание getDeclaredMethods() и getMethods() - это ответ. getMethods() достаточно.

Мои тестовые примеры для этого:

 def test_super_interface(self):
        LinkedList = autoclass('java.util.LinkedList')
        words = LinkedList()
        words.add('hello')
        words.add('world')
        q = cast('java.util.Queue', words)
        self.assertEqual(2, q.size())
        self.assertIsNotNone(q.iterator())

    def test_super_object(self):
        LinkedList = autoclass('java.util.LinkedList')
        words = LinkedList()
        words.hashCode()

    def test_super_interface_object(self):
        LinkedList = autoclass('java.util.LinkedList')
        words = LinkedList()
        q = cast('java.util.Queue', words)
        q.hashCode()

Различные варианты терпят неудачу, когда мы используем только getDeclaredMethods ().

Моя единственная проблема с getMethods() заключается в том, что test_inheritance.py не работает. Это лишь незначительно проблематично - статический newInstance() org.jnius.Child переопределяет метод org.jnius.Parent newInstance() . Что происходит, так это то, что getMethods() видит оба метода newInstance() , поэтому создает JavaMultipleMethod. Это неправильно: Child.newInstance() должно скрывать Parent.newInstance() - см. Https://www.java67.com/2012/08/can-we-override-static-method-in-java.html. Я также проверил это с помощью Jshell:

jshell> org.jnius.Child.newInstance()
$3 ==> org.jnius.Child<strong i="24">@506c589e</strong>

Привет, @tshirtman, я вижу, вы совершили getMethods (). Я бы также порекомендовал дополнительные тестовые примеры, указанные выше.
Я не был уверен, как решить статический метод, скрывающий, что Child.newInstance () должен скрывать Parent.newInstance (). Я думаю, вам придется изменить порядок итерации классов и интерфейсов в autoclass () - пройти по дереву, чтобы получить классы, а затем применить их в обратном порядке, то есть начиная с java.lang.Object.

хм, действительно добавление этого теста показывает, что в настоящее время объект, представленный как автокласс java.util.Queue , не имеет атрибута size , что неверно.
Я согласен с вашим анализом, обратным поиском, заменой родительских методов идентичной подписью вместо создания JavaMultipleMethod, что кажется хорошей стратегией.

501 прошел все испытания. Закрытие этого вопроса. (Хвала).

Защищенные поля все еще отсутствуют!

Изменение этой строки с public на protected не проходит тест.

На # 500 обсуждается вопрос о том, следует ли вообще открывать частные / защищенные методы / поля.

Я думаю, что это другое, в настоящее время у нас должно быть все, и с вашим исправлением это кажется верным для методов, но, видимо, это не так (и, возможно, никогда не было?) верно для полей, поэтому я думаю, что это ошибка, которую нужно решить в первую очередь , решим ли мы затем разрешить фильтрацию методов / полей, которые мы хотим видеть, в зависимости от их уровня конфиденциальности. Поскольку эта ошибка закрыта, для меня имеет смысл открыть новую для этого случая.

кажется, это верно для методов, но очевидно, что это не так (и, возможно, никогда не было?) верно для полей

Он работал для <1.2.1, поэтому я ожидал, что он будет работать и в> 1.2.1, <2.0, даже если он не должен работать ни для одной версии.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги