Skip to content

Add support for Python 3.13 #51

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 14, 2025
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 .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-22.04]
python-version: [3.9, '3.10', '3.11', '3.12']
python-version: [3.9, '3.10', '3.11', '3.12', '3.13']

steps:
- uses: actions/checkout@v4
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/conda-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
fail-fast: false
matrix:
os: ['ubuntu-22.04', 'macos-13']
python-version: ['3.9', '3.10', '3.11', '3.12']
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']
env:
OS: ${{ matrix.os }}
PYTHON: ${{ matrix.python-version }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ jobs:
CIBW_TEST_SKIP: "*_arm64 *universal2:arm64 *linux_i686"
CIBW_MANYLINUX_X86_64_IMAGE: manylinux2014
CIBW_MANYLINUX_I686_IMAGE: manylinux2010
CIBW_BUILD: cp38-* cp39-* cp310-* cp311-* cp312-*
CIBW_BUILD: cp38-* cp39-* cp310-* cp311-* cp312-* cp313-*
CIBW_SKIP: "*musllinux* *i686"
CIBW_BEFORE_ALL_LINUX: >
yum -y update && yum -y install epel-release && yum install -y re2-devel ninja-build
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ jobs:
CIBW_TEST_SKIP: "*_arm64 *universal2:arm64 *linux_i686"
CIBW_MANYLINUX_X86_64_IMAGE: manylinux2014
CIBW_MANYLINUX_I686_IMAGE: manylinux2010
CIBW_BUILD: cp38-* cp39-* cp310-* cp311-* cp312-*
CIBW_BUILD: cp38-* cp39-* cp310-* cp311-* cp312-* cp313-*
CIBW_SKIP: "*musllinux* *i686"
CIBW_BEFORE_ALL_LINUX: >
yum -y update && yum -y install epel-release && yum install -y re2-devel ninja-build
Expand Down Expand Up @@ -128,7 +128,7 @@ jobs:

- name: Create draft release
id: create_release
uses: softprops/action-gh-release@main
uses: softprops/action-gh-release@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
Expand All @@ -145,4 +145,4 @@ jobs:
with:
user: __token__
password: ${{ secrets.pypi_password }}
packages_dir: artifact/
packages_dir: artifacts/
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ requires = [
"Cython>=0.20",
"pybind11>=2.12",
"ninja; sys_platform != 'Windows'",
"cmake>=3.18",
"cmake (>=3.18,<4.0.0)",
]

build-backend = "setuptools.build_meta"
Expand Down
15 changes: 7 additions & 8 deletions src/compile.pxi
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,13 @@ def _compile(object pattern, int flags=0, int max_mem=8388608):
return fallback(original_pattern, flags, "re.LOCALE not supported")
pattern = unicode_to_bytes(pattern, &encoded, -1)
newflags = flags
if not PY2:
if not encoded and flags & _U: # re.UNICODE
pass # can use UNICODE with bytes pattern, but assumes valid UTF-8
# raise ValueError("can't use UNICODE flag with a bytes pattern")
elif encoded and not (flags & ASCII): # re.ASCII (not in Python 2)
newflags = flags | _U # re.UNICODE
elif encoded and flags & ASCII:
newflags = flags & ~_U # re.UNICODE
if not encoded and flags & _U: # re.UNICODE
pass # can use UNICODE with bytes pattern, but assumes valid UTF-8
# raise ValueError("can't use UNICODE flag with a bytes pattern")
elif encoded and not (flags & ASCII): # re.ASCII (not in Python 2)
newflags = flags | _U # re.UNICODE
elif encoded and flags & ASCII:
newflags = flags & ~_U # re.UNICODE
try:
pattern = _prepare_pattern(pattern, newflags)
except BackreferencesException:
Expand Down
5 changes: 0 additions & 5 deletions src/includes.pxi
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,6 @@ cdef extern from *:
cdef void emit_endif "#endif //" ()


cdef extern from "Python.h":
int PyObject_CheckReadBuffer(object)
int PyObject_AsReadBuffer(object, const void **, Py_ssize_t *)


cdef extern from "re2/stringpiece.h" namespace "re2":
cdef cppclass StringPiece:
StringPiece()
Expand Down
4 changes: 2 additions & 2 deletions src/match.pxi
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,12 @@ cdef class Match:
"""Expand a template with groups."""
cdef bytearray result = bytearray()
if isinstance(template, unicode):
if not PY2 and not self.encoded:
if not self.encoded:
raise ValueError(
'cannot expand unicode template on bytes pattern')
templ = template.encode('utf8')
else:
if not PY2 and self.encoded:
if self.encoded:
raise ValueError(
'cannot expand bytes template on unicode pattern')
templ = bytes(template)
Expand Down
2 changes: 1 addition & 1 deletion src/pattern.pxi
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ cdef class Pattern:
if not repl_encoded and not isinstance(repl, bytes):
repl_b = bytes(repl) # coerce buffer to bytes object

if count > 1 or (b'\\' if PY2 else <char>b'\\') in repl_b:
if count > 1 or <char>b'\\' in repl_b:
# Limit on number of substitutions or replacement string contains
# escape sequences; handle with Match.expand() implementation.
# RE2 does support simple numeric group references \1, \2,
Expand Down
19 changes: 5 additions & 14 deletions src/re2.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,6 @@ VERSION_HEX = 0x000217

cdef int _I = I, _M = M, _S = S, _U = U, _X = X, _L = L
cdef int current_notification = FALLBACK_QUIETLY
cdef bint PY2 = PY_MAJOR_VERSION == 2

# Type of compiled re object from Python stdlib
SREPattern = type(re.compile(''))
Expand Down Expand Up @@ -252,7 +251,7 @@ def escape(pattern):
"""Escape all non-alphanumeric characters in pattern."""
cdef bint uni = isinstance(pattern, unicode)
cdef list s
if PY2 or uni:
if uni:
s = list(pattern)
else:
s = [bytes([c]) for c in pattern]
Expand Down Expand Up @@ -350,9 +349,9 @@ cdef inline unicode_to_bytes(object pystring, int * encoded,
encoded[0] = 1 if origlen == len(pystring) else 2
else:
encoded[0] = 0
if not PY2 and checkotherencoding > 0 and not encoded[0]:
if checkotherencoding > 0 and not encoded[0]:
raise TypeError("can't use a string pattern on a bytes-like object")
elif not PY2 and checkotherencoding == 0 and encoded[0]:
elif checkotherencoding == 0 and encoded[0]:
raise TypeError("can't use a bytes pattern on a string-like object")
return pystring

Expand All @@ -366,14 +365,7 @@ cdef inline int pystring_to_cstring(
cdef int result = -1
cstring[0] = NULL
size[0] = 0
if PY2:
# Although the new-style buffer interface was backported to Python 2.6,
# some modules, notably mmap, only support the old buffer interface.
# Cf. http://bugs.python.org/issue9229
if PyObject_CheckReadBuffer(pystring) == 1:
result = PyObject_AsReadBuffer(
pystring, <const void **>cstring, size)
elif PyObject_CheckBuffer(pystring) == 1: # new-style Buffer interface
if PyObject_CheckBuffer(pystring) == 1: # new-style Buffer interface
result = PyObject_GetBuffer(pystring, buf, PyBUF_SIMPLE)
if result == 0:
cstring[0] = <char *>buf.buf
Expand All @@ -383,8 +375,7 @@ cdef inline int pystring_to_cstring(

cdef inline void release_cstring(Py_buffer *buf):
"""Release buffer if necessary."""
if not PY2:
PyBuffer_Release(buf)
PyBuffer_Release(buf)


cdef utf8indices(char * cstring, int size, int *pos, int *endpos):
Expand Down
40 changes: 40 additions & 0 deletions tests/test_charliterals.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import re2 as re
import warnings

warnings.filterwarnings('ignore', category=DeprecationWarning)

import unittest

class TestCharLiterals(unittest.TestCase):
def test_character_literals(self):
i = 126

assert re.compile(r"\%03o" % i) == re.compile('\\176')
assert re.compile(r"\%03o" % i)._dump_pattern() == '\\176'
assert (re.match(r"\%03o" % i, chr(i)) is None) == False
assert (re.match(r"\%03o0" % i, chr(i) + "0") is None) == False
assert (re.match(r"\%03o8" % i, chr(i) + "8") is None) == False
assert (re.match(r"\x%02x" % i, chr(i)) is None) == False
assert (re.match(r"\x%02x0" % i, chr(i) + "0") is None) == False
assert (re.match(r"\x%02xz" % i, chr(i) + "z") is None) == False

try:
re.match("\911", "")
except Exception as exp:
assert exp.msg == "invalid group reference 91 at position 1"


def test_character_class_literals(self):
i = 126

assert (re.match(r"[\%03o]" % i, chr(i)) is None) == False
assert (re.match(r"[\%03o0]" % i, chr(i) + "0") is None) == False
assert (re.match(r"[\%03o8]" % i, chr(i) + "8") is None) == False
assert (re.match(r"[\x%02x]" % i, chr(i)) is None) == False
assert (re.match(r"[\x%02x0]" % i, chr(i) + "0") is None) == False
assert (re.match(r"[\x%02xz]" % i, chr(i) + "z") is None) == False

try:
re.match("[\911]", "")
except Exception as exp:
assert exp.msg == "invalid escape sequence: \9"
47 changes: 0 additions & 47 deletions tests/test_charliterals.txt

This file was deleted.

5 changes: 3 additions & 2 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[tox]
envlist = py3{7,8,9,10,11,12}
envlist = py3{7,8,9,10,11,12,13}
skip_missing_interpreters = true
isolated_build = true
skipsdist=True
Expand All @@ -12,6 +12,7 @@ python =
3.10: py310
3.11: py311
3.12: py312
3.13: py313

[gh-actions:env]
PLATFORM =
Expand Down Expand Up @@ -166,7 +167,7 @@ deps =
pip>=20.0.1

commands =
pip install pyre2 --force-reinstall --prefer-binary -f dist/
pip install pyre2 --force-reinstall --prefer-binary --no-index -f dist/
python -m unittest discover -f -s .

[testenv:style]
Expand Down
Loading