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
3 changes: 3 additions & 0 deletions demo/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,9 @@ for (path in listOf(
}

dependencies {
// See TestAndroidReflect.
compileOnly(project(":compileOnly"))

// Keep these versions the same as the pkgtest app.
implementation("androidx.appcompat:appcompat:1.7.1")
implementation("androidx.constraintlayout:constraintlayout:1.1.3")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
package com.chaquo.python.demo;

import android.view.textclassifier.*;

// Some of the members of this class refer to classes which don't exist at runtime
// (see test_reflect.py). This is done by putting them in a compileOnly dependency in
// build.gradle.kts.
@SuppressWarnings("unused")
public class TestAndroidReflect {
public TextClassifier tcFieldPublic;
protected TextClassifier tcFieldProtected;
public CompileOnly coFieldPublic;
protected CompileOnly coFieldProtected;

public TextClassifier tcMethodPublic() { return null; }
protected TextClassifier tcMethodProtected() { return null; }
public CompileOnly coMethodPublic() { return null; }
protected CompileOnly coMethodProtected() { return null; }

public int iFieldPublic;
protected int iFieldProtected;
Expand Down
1 change: 1 addition & 0 deletions demo/compileOnly/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
9 changes: 9 additions & 0 deletions demo/compileOnly/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// See TestAndroidReflect.

plugins {
id("java-library")
}
java {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.chaquo.python.demo;

// See TestAndroidReflect.
public class CompileOnly {
}
1 change: 1 addition & 0 deletions demo/settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@ dependencyResolutionManagement {
}
}
include(":app")
include(":compileOnly")
11 changes: 5 additions & 6 deletions product/runtime/src/main/python/java/android/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,11 @@ def get_exec_path_override(*args, **kwargs):
# these result in an OSError, so the calling code will still work, but it generates
# a log message like `avc: denied { ioctl } for path="pipe:[10138300]"`, which can
# be a problem if the app is doing it repeatedly.
#
# TODO: remove once fixed upstream (https://github.com/python/cpython/pull/154885).
def get_terminal_size_override(*args, **kwargs):
error = errno.ENOTTY
raise OSError(error, os.strerror(error))
os.get_terminal_size = get_terminal_size_override
if sys.version_info < (3, 15): # https://github.com/python/cpython/pull/154885
def get_terminal_size_override(*args, **kwargs):
error = errno.ENOTTY
raise OSError(error, os.strerror(error))
os.get_terminal_size = get_terminal_size_override


def initialize_tempfile():
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"java.android.stream" if sys.version_info < (3, 13) else "_android_support")
TextLogStream = import_module(stream_mod_name).TextLogStream

from ..test_utils import FilterWarningsCase
from ..test_utils import API_LEVEL as api_level, FilterWarningsCase


# (name, level, fileno)
Expand All @@ -30,6 +30,10 @@

redirected_native = False

# Some API levels filter out consecutive identical lines and replace them with a
# "chatty" marker.
chatty_issue = (26 <= api_level <= 30)


class TestAndroidOutput(FilterWarningsCase):
maxDiff = None
Expand Down Expand Up @@ -172,15 +176,13 @@ def write(s, lines=None, *, write_len=None):
write("\u0000b", [r"\xc0\x80b"])
write("a\u0000b", [r"a\xc0\x80b"])

# Multi-line messages. Avoid identical consecutive lines, as
# they may activate "chatty" filtering and break the tests.
#
# Additional spaces will appear in the output where necessary to
# protect leading newlines.
# Multi-line messages. Additional spaces will appear in the output where
# necessary to protect leading newlines.
write("\nx", [" "])
write("\na\n", ["x", "a"])
write("\n", [" "])
write("\n\n", [" ", " "])
if not chatty_issue:
write("\n\n", [" ", " "])
write("b\n", ["b"])
write("c\n\n", ["c", " "])
write("d\ne", ["d"])
Expand All @@ -199,7 +201,8 @@ def write(s, lines=None, *, write_len=None):
write("\nx", [" ", "x"])
write("\na\n", [" ", "a"])
write("\n", [" "])
write("\n\n", [" ", " "])
if not chatty_issue:
write("\n\n", [" ", " "])
write("b\n", ["b"])
write("c\n\n", ["c", " "])
write("d\ne", ["d", "e"])
Expand Down
19 changes: 5 additions & 14 deletions product/runtime/src/test/python/chaquopy/test/test_reflect.py
Original file line number Diff line number Diff line change
Expand Up @@ -561,20 +561,16 @@ def multi_fi(self, *interfaces):
@skipIf(not API_LEVEL, "Android only")
class TestAndroidReflect(FilterWarningsCase):

MEMBERS = ["tcFieldPublic", "tcFieldProtected", "tcMethodPublic", "tcMethodProtected",
MEMBERS = ["coFieldPublic", "coFieldProtected", "coMethodPublic", "coMethodProtected",
"iFieldPublic", "iFieldProtected", "iMethodPublic", "iMethodProtected",
"finalize"]

def test_android_reflect(self):
from com.chaquo.python.demo import TestAndroidReflect as TAR
from com.chaquo.python.demo import TestAndroidReflect

if API_LEVEL >= 26:
# TextClassifier is in the platform, so all members should be visible.
self.assertMembers(TAR, self.MEMBERS)
else:
# Overridden methods should be visible, plus public methods that don't involve
# TextClassifier.
self.assertMembers(TAR, ["iMethodPublic", "finalize"])
# Overridden methods should be visible, plus public methods that don't involve
# TextClassifier.
self.assertMembers(TestAndroidReflect, ["iMethodPublic", "finalize"])

def assertMembers(self, cls, names):
for name in names:
Expand All @@ -583,11 +579,6 @@ def assertMembers(self, cls, names):

for name in self.MEMBERS:
if name not in names:
# With AGP 9.0, ProGuard causes this method to become visible for some
# reason. See also TestReflect.test_access.
if name == "iMethodProtected":
continue

with self.subTest(name=name):
self.assertFalse(self.declares_member(cls, name))

Expand Down
Loading