Skip to content

Commit 88d6a3e

Browse files
committed
[GR-72503][GR-72420] Add Pattern.__class_getitem__
PullRequest: graalpython/4188
2 parents a7e6f14 + c2cefd4 commit 88d6a3e

6 files changed

Lines changed: 104 additions & 93 deletions

File tree

graalpython/com.oracle.graal.python.test/src/tests/test_interop.py

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1524,35 +1524,32 @@ def __init__(self, source, want, *args, **kwargs):
15241524
def test_keep_gil_around_interop(self):
15251525
import java.lang.Thread as Thread
15261526
import threading, time
1527-
lst = []
1528-
enter_sleep = threading.Event()
1527+
resumed = 0
15291528
done = threading.Event()
15301529

15311530
def worker():
1532-
enter_sleep.wait(timeout=5)
1533-
lst.append(time.time())
1534-
done.set()
1531+
nonlocal resumed
1532+
resumed = 0
1533+
while not done.is_set():
1534+
resumed += 1
1535+
time.sleep(0.0001)
15351536

1536-
def gil_test(before_or_after):
1537-
enter_sleep.clear()
1537+
def gil_test(gil_locked):
15381538
done.clear()
1539-
lst.clear()
15401539
t = threading.Thread(target=worker)
15411540
t.start()
1542-
start = time.time()
1543-
enter_sleep.set()
15441541
Thread.sleep(1000)
1545-
end = time.time()
1546-
done.wait(timeout=5)
1542+
done.set()
15471543
t.join(timeout=5)
1548-
assert lst, "worker thread did not run"
1549-
t_run = lst[0]
1550-
result = t_run <= end if before_or_after == "after" else t_run >= end
1551-
assert result, f"worker ran {before_or_after} sleep finished: t_run={t_run}, end={end}"
1544+
if gil_locked:
1545+
self.assertLess(resumed, 200, "Worker ran too many times when GIL was supposed to be locked")
1546+
else:
1547+
self.assertGreater(resumed, 200, "Worker ran too few times when GIL was supposed to be released")
15521548

1553-
gil_test("after")
1549+
gil_test(gil_locked=False)
15541550
with polyglot.gil_locked_during_interop(True):
1555-
gil_test("before")
1551+
gil_test(gil_locked=True)
15561552
with polyglot.gil_locked_during_interop(False):
1557-
gil_test("after")
1558-
gil_test("before")
1553+
gil_test(gil_locked=False)
1554+
gil_test(gil_locked=True)
1555+
gil_test(gil_locked=False)

graalpython/com.oracle.graal.python.test/src/tests/test_re.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
# Copyright (c) 2019, 2025, Oracle and/or its affiliates.
1+
# Copyright (c) 2019, 2026, Oracle and/or its affiliates.
22
# Copyright (C) 1996-2017 Python Software Foundation
33
#
44
# Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
55
import re
66
import string
7+
import types
78
import unittest
89
import sys
910

@@ -1540,6 +1541,9 @@ def test_scanner(self):
15401541
with self.assertRaisesRegex(TypeError, "cannot use a bytes pattern on a string-like object"):
15411542
pattern.scanner("abc")
15421543

1544+
def test_class_getitem(self):
1545+
self.assertIsInstance(re.Pattern[bytes], types.GenericAlias)
1546+
15431547

15441548
class MatchTest(unittest.TestCase):
15451549
def test_expand(self):
@@ -2081,6 +2085,9 @@ def test_subclassing(self):
20812085
class A(re.Match):
20822086
pass
20832087

2088+
def test_class_getitem(self):
2089+
self.assertIsInstance(re.Match[bytes], types.GenericAlias)
2090+
20842091

20852092
class SREScannerTest(unittest.TestCase):
20862093
# _sre.SRE_Scanner is not publicly visible so test it through Pattern#scanner()

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextArrayBuiltins.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -93,7 +93,11 @@ abstract static class GraalPyArray_Data extends CApiUnaryBuiltinNode {
9393
static Object get(PArray array,
9494
@Bind Node inliningTarget,
9595
@Cached ArrayNodes.EnsureNativeStorageNode ensureNativeStorageNode) {
96-
return ensureNativeStorageNode.execute(inliningTarget, array).getPtr();
96+
if (array.getBytesLength() > 0) {
97+
return ensureNativeStorageNode.execute(inliningTarget, array).getPtr();
98+
} else {
99+
return getNativeNull(inliningTarget);
100+
}
97101
}
98102
}
99103

@@ -104,7 +108,6 @@ static int getbuffer(PArray array, Object pyBufferPtr, int flags,
104108
@Bind Node inliningTarget,
105109
@Cached ArrayNodes.EnsureNativeStorageNode ensureNativeStorageNode,
106110
@Cached TruffleString.SwitchEncodingNode switchEncodingNode,
107-
@Cached TruffleString.CopyToByteArrayNode copyToByteArrayNode,
108111
@Cached CApiTransitions.PythonToNativeNewRefNode toNativeNewRefNode,
109112
@Cached CStructAccess.WritePointerNode writePointerNode,
110113
@Cached CStructAccess.WriteLongNode writeLongNode,

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/re/MatchBuiltins.java

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -40,6 +40,17 @@
4040
*/
4141
package com.oracle.graal.python.builtins.modules.re;
4242

43+
import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CLASS_GETITEM__;
44+
import static com.oracle.graal.python.nodes.SpecialMethodNames.J___COPY__;
45+
import static com.oracle.graal.python.nodes.SpecialMethodNames.J___DEEPCOPY__;
46+
import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING;
47+
import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING_BINARY;
48+
import static com.oracle.graal.python.util.PythonUtils.tsLiteral;
49+
50+
import java.util.LinkedHashMap;
51+
import java.util.List;
52+
import java.util.Map;
53+
4354
import com.oracle.graal.python.PythonLanguage;
4455
import com.oracle.graal.python.annotations.Builtin;
4556
import com.oracle.graal.python.annotations.Slot;
@@ -58,6 +69,7 @@
5869
import com.oracle.graal.python.lib.PyUnicodeCheckNode;
5970
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
6071
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
72+
import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
6173
import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
6274
import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode;
6375
import com.oracle.graal.python.nodes.statement.AbstractImportNode;
@@ -76,14 +88,6 @@
7688
import com.oracle.truffle.api.strings.TruffleString;
7789
import com.oracle.truffle.api.strings.TruffleStringBuilder;
7890

79-
import java.util.LinkedHashMap;
80-
import java.util.List;
81-
import java.util.Map;
82-
83-
import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING;
84-
import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING_BINARY;
85-
import static com.oracle.graal.python.util.PythonUtils.tsLiteral;
86-
8791
@CoreFunctions(extendClasses = {PythonBuiltinClassType.PMatch})
8892
public final class MatchBuiltins extends PythonBuiltins {
8993

@@ -612,7 +616,7 @@ static Object lastGroup(PMatch self,
612616
}
613617
}
614618

615-
@Builtin(name = "__copy__", minNumOfPositionalArgs = 1, parameterNames = {"$self"}, doc = "__copy__($self, /)\n--\n\n")
619+
@Builtin(name = J___COPY__, minNumOfPositionalArgs = 1, parameterNames = {"$self"}, doc = "__copy__($self, /)\n--\n\n")
616620
@GenerateNodeFactory
617621
public abstract static class CopyNode extends PythonBuiltinNode {
618622

@@ -622,7 +626,7 @@ static PMatch copy(PMatch self) {
622626
}
623627
}
624628

625-
@Builtin(name = "__deepcopy__", minNumOfPositionalArgs = 2, parameterNames = {"$self", "memo"}, doc = "__deepcopy__($self, memo, /)\n--\n\n")
629+
@Builtin(name = J___DEEPCOPY__, minNumOfPositionalArgs = 2, parameterNames = {"$self", "memo"}, doc = "__deepcopy__($self, memo, /)\n--\n\n")
626630
@GenerateNodeFactory
627631
public abstract static class DeepCopyNode extends PythonBuiltinNode {
628632

@@ -631,4 +635,14 @@ static PMatch deepCopy(PMatch self, Object memo) {
631635
return self;
632636
}
633637
}
638+
639+
@Builtin(name = J___CLASS_GETITEM__, minNumOfPositionalArgs = 2, isClassmethod = true)
640+
@GenerateNodeFactory
641+
public abstract static class ClassGetItemNode extends PythonBinaryBuiltinNode {
642+
@Specialization
643+
static Object classGetItem(Object cls, Object key,
644+
@Bind PythonLanguage language) {
645+
return PFactory.createGenericAlias(language, cls, key);
646+
}
647+
}
634648
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/re/PatternBuiltins.java

Lines changed: 42 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -40,6 +40,34 @@
4040
*/
4141
package com.oracle.graal.python.builtins.modules.re;
4242

43+
import static com.oracle.graal.python.builtins.modules.re.TRegexCache.FLAG_ASCII;
44+
import static com.oracle.graal.python.builtins.modules.re.TRegexCache.FLAG_DOTALL;
45+
import static com.oracle.graal.python.builtins.modules.re.TRegexCache.FLAG_IGNORECASE;
46+
import static com.oracle.graal.python.builtins.modules.re.TRegexCache.FLAG_LOCALE;
47+
import static com.oracle.graal.python.builtins.modules.re.TRegexCache.FLAG_MULTILINE;
48+
import static com.oracle.graal.python.builtins.modules.re.TRegexCache.FLAG_UNICODE;
49+
import static com.oracle.graal.python.builtins.modules.re.TRegexCache.FLAG_VERBOSE;
50+
import static com.oracle.graal.python.nodes.BuiltinNames.T__SRE;
51+
import static com.oracle.graal.python.nodes.ErrorMessages.BAD_CHAR_IN_GROUP_NAME;
52+
import static com.oracle.graal.python.nodes.ErrorMessages.BAD_ESCAPE_END_OF_STRING;
53+
import static com.oracle.graal.python.nodes.ErrorMessages.BAD_ESCAPE_S;
54+
import static com.oracle.graal.python.nodes.ErrorMessages.INVALID_GROUP_REFERENCE;
55+
import static com.oracle.graal.python.nodes.ErrorMessages.MISSING_GROUP_NAME;
56+
import static com.oracle.graal.python.nodes.ErrorMessages.MISSING_LEFT_ANGLE_BRACKET;
57+
import static com.oracle.graal.python.nodes.ErrorMessages.MISSING_RIGHT_ANGLE_BRACKET;
58+
import static com.oracle.graal.python.nodes.ErrorMessages.OCTAL_ESCAPE_OUT_OF_RANGE;
59+
import static com.oracle.graal.python.nodes.ErrorMessages.UNKNOWN_GROUP_NAME;
60+
import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CLASS_GETITEM__;
61+
import static com.oracle.graal.python.nodes.SpecialMethodNames.J___COPY__;
62+
import static com.oracle.graal.python.nodes.SpecialMethodNames.J___DEEPCOPY__;
63+
import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING;
64+
import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING_BINARY;
65+
import static com.oracle.graal.python.util.PythonUtils.tsLiteral;
66+
67+
import java.util.ArrayList;
68+
import java.util.LinkedHashMap;
69+
import java.util.List;
70+
4371
import com.oracle.graal.python.PythonLanguage;
4472
import com.oracle.graal.python.annotations.ArgumentClinic;
4573
import com.oracle.graal.python.annotations.Builtin;
@@ -72,6 +100,7 @@
72100
import com.oracle.graal.python.nodes.call.CallNode;
73101
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
74102
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
103+
import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
75104
import com.oracle.graal.python.nodes.function.builtins.PythonClinicBuiltinNode;
76105
import com.oracle.graal.python.nodes.function.builtins.PythonQuaternaryClinicBuiltinNode;
77106
import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
@@ -113,31 +142,6 @@
113142
import com.oracle.truffle.api.strings.TruffleStringBuilder;
114143
import com.oracle.truffle.api.strings.TruffleStringBuilderUTF32;
115144

116-
import java.util.ArrayList;
117-
import java.util.LinkedHashMap;
118-
import java.util.List;
119-
120-
import static com.oracle.graal.python.builtins.modules.re.TRegexCache.FLAG_ASCII;
121-
import static com.oracle.graal.python.builtins.modules.re.TRegexCache.FLAG_DOTALL;
122-
import static com.oracle.graal.python.builtins.modules.re.TRegexCache.FLAG_IGNORECASE;
123-
import static com.oracle.graal.python.builtins.modules.re.TRegexCache.FLAG_LOCALE;
124-
import static com.oracle.graal.python.builtins.modules.re.TRegexCache.FLAG_MULTILINE;
125-
import static com.oracle.graal.python.builtins.modules.re.TRegexCache.FLAG_UNICODE;
126-
import static com.oracle.graal.python.builtins.modules.re.TRegexCache.FLAG_VERBOSE;
127-
import static com.oracle.graal.python.nodes.BuiltinNames.T__SRE;
128-
import static com.oracle.graal.python.nodes.ErrorMessages.BAD_CHAR_IN_GROUP_NAME;
129-
import static com.oracle.graal.python.nodes.ErrorMessages.BAD_ESCAPE_END_OF_STRING;
130-
import static com.oracle.graal.python.nodes.ErrorMessages.BAD_ESCAPE_S;
131-
import static com.oracle.graal.python.nodes.ErrorMessages.INVALID_GROUP_REFERENCE;
132-
import static com.oracle.graal.python.nodes.ErrorMessages.MISSING_GROUP_NAME;
133-
import static com.oracle.graal.python.nodes.ErrorMessages.MISSING_LEFT_ANGLE_BRACKET;
134-
import static com.oracle.graal.python.nodes.ErrorMessages.MISSING_RIGHT_ANGLE_BRACKET;
135-
import static com.oracle.graal.python.nodes.ErrorMessages.OCTAL_ESCAPE_OUT_OF_RANGE;
136-
import static com.oracle.graal.python.nodes.ErrorMessages.UNKNOWN_GROUP_NAME;
137-
import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING;
138-
import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING_BINARY;
139-
import static com.oracle.graal.python.util.PythonUtils.tsLiteral;
140-
141145
@CoreFunctions(extendClasses = {PythonBuiltinClassType.PPattern})
142146
public final class PatternBuiltins extends PythonBuiltins {
143147

@@ -665,7 +669,7 @@ static Object getScanner(VirtualFrame frame, PPattern self, Object string, int p
665669
}
666670
}
667671

668-
@Builtin(name = "__copy__", minNumOfPositionalArgs = 1, parameterNames = {"$self"}, doc = "__copy__($self, /)\n--\n\n")
672+
@Builtin(name = J___COPY__, minNumOfPositionalArgs = 1, parameterNames = {"$self"}, doc = "__copy__($self, /)\n--\n\n")
669673
@GenerateNodeFactory
670674
public abstract static class CopyNode extends PythonBuiltinNode {
671675

@@ -675,7 +679,7 @@ static PPattern copy(PPattern self) {
675679
}
676680
}
677681

678-
@Builtin(name = "__deepcopy__", minNumOfPositionalArgs = 2, parameterNames = {"$self", "memo"}, doc = "__deepcopy__($self, memo, /)\n--\n\n")
682+
@Builtin(name = J___DEEPCOPY__, minNumOfPositionalArgs = 2, parameterNames = {"$self", "memo"}, doc = "__deepcopy__($self, memo, /)\n--\n\n")
679683
@GenerateNodeFactory
680684
public abstract static class DeepCopyNode extends PythonBuiltinNode {
681685

@@ -685,6 +689,16 @@ static PPattern deepCopy(PPattern self, Object memo) {
685689
}
686690
}
687691

692+
@Builtin(name = J___CLASS_GETITEM__, minNumOfPositionalArgs = 2, isClassmethod = true)
693+
@GenerateNodeFactory
694+
public abstract static class ClassGetItemNode extends PythonBinaryBuiltinNode {
695+
@Specialization
696+
static Object classGetItem(Object cls, Object key,
697+
@Bind PythonLanguage language) {
698+
return PFactory.createGenericAlias(language, cls, key);
699+
}
700+
}
701+
688702
/**
689703
* There are multiple nested inner nodes used in {@link SplitNode}. The number at the end of
690704
* each inner node indicates the nesting level.

graalpython/lib-graalpython/patches/pyarrow-20.0.0.patch

Lines changed: 6 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
iff --git a/pyarrow/error.pxi b/pyarrow/error.pxi
1+
diff --git a/pyarrow/error.pxi b/pyarrow/error.pxi
22
index cbe2552..8d0d9d9 100644
33
--- a/pyarrow/error.pxi
44
+++ b/pyarrow/error.pxi
@@ -17,8 +17,8 @@ index fdd5b99..ea611cd 100644
1717
+++ b/pyarrow/memory.pxi
1818
@@ -20,6 +20,10 @@
1919
# cython: embedsignature = True
20-
21-
20+
21+
2222
+cdef extern from "Python.h":
2323
+ void Py_INCREF(object)
2424
+
@@ -27,7 +27,7 @@ index fdd5b99..ea611cd 100644
2727
"""
2828
Base class for memory allocation.
2929
@@ -35,6 +39,13 @@ cdef class MemoryPool(_Weakrefable):
30-
30+
3131
cdef void init(self, CMemoryPool* pool):
3232
self.pool = pool
3333
+ # GraalPy change: pyarrow doesn't maintain python references from
@@ -37,7 +37,7 @@ index fdd5b99..ea611cd 100644
3737
+ # a buffer outlive its pool. Since we can't guarantee destruction
3838
+ # order, we just leak the pool.
3939
+ Py_INCREF(self)
40-
40+
4141
def release_unused(self):
4242
"""
4343
diff --git a/pyarrow_build_backend.py b/pyarrow_build_backend.py
@@ -150,30 +150,6 @@ index e7c95e0..abab83e 100644
150150
-build-backend = "setuptools.build_meta"
151151
+build-backend = "pyarrow_build_backend"
152152
+backend-path = ["."]
153-
153+
154154
[project]
155155
name = "pyarrow"
156-
diff --git a/MANIFEST.in b/MANIFEST.in
157-
index ef2043f..cb08a86 100644
158-
--- a/MANIFEST.in
159-
+++ b/MANIFEST.in
160-
@@ -1,6 +1,4 @@
161-
include README.md
162-
-include ../LICENSE.txt
163-
-include ../NOTICE.txt
164-
165-
global-include CMakeLists.txt
166-
graft pyarrow
167-
diff --git a/setup.cfg b/setup.cfg
168-
index ef2043f..cb08a86 100644
169-
--- a/setup.cfg
170-
+++ b/setup.cfg
171-
@@ -1,7 +1,6 @@
172-
[metadata]
173-
license_files =
174-
- ../LICENSE.txt
175-
- ../NOTICE.txt
176-
+ README.md
177-
178-
[build_sphinx]
179-
source-dir = doc/

0 commit comments

Comments
 (0)