mirror of
https://github.com/google/re2.git
synced 2025-10-14 10:48:20 +08:00

2025-08-12 will be the same as 2025-08-05 except for having some Bazel-related fixes and possibly the right files to automatically push an update to the Bazel Central Registry. Change-Id: I178dd5ab31eeb29c97d9f687cbe7553d02dca8cb Reviewed-on: https://code-review.googlesource.com/c/re2/+/63910 Reviewed-by: Russ Cox <rsc@swtch.com> Reviewed-by: Jeremy Kun <jkun@google.com>
159 lines
5.5 KiB
Python
159 lines
5.5 KiB
Python
# Copyright 2019 The RE2 Authors. All Rights Reserved.
|
|
# Use of this source code is governed by a BSD-style
|
|
# license that can be found in the LICENSE file.
|
|
|
|
import os
|
|
import re
|
|
import setuptools
|
|
import setuptools.command.build_ext
|
|
import shutil
|
|
|
|
long_description = r"""A drop-in replacement for the re module.
|
|
|
|
It uses RE2 under the hood, of course, so various PCRE features
|
|
(e.g. backreferences, look-around assertions) are not supported.
|
|
See https://github.com/google/re2/wiki/Syntax for the canonical
|
|
reference, but known syntactic "gotchas" relative to Python are:
|
|
|
|
* PCRE supports \Z and \z; RE2 supports \z; Python supports \z,
|
|
but calls it \Z. You must rewrite \Z to \z in pattern strings.
|
|
|
|
Known differences between this module's API and the re module's API:
|
|
|
|
* The error class does not provide any error information as attributes.
|
|
* The Options class replaces the re module's flags with RE2's options as
|
|
gettable/settable properties. Please see re2.h for their documentation.
|
|
* The pattern string and the input string do not have to be the same type.
|
|
Any str will be encoded to UTF-8.
|
|
* The pattern string cannot be str if the options specify Latin-1 encoding.
|
|
|
|
Known issues with regard to building the C++ extension:
|
|
|
|
* Building requires RE2 to be installed on your system.
|
|
On Debian, for example, install the libre2-dev package.
|
|
* Building requires pybind11 to be installed on your system OR venv.
|
|
On Debian, for example, install the pybind11-dev package.
|
|
For a venv, install the pybind11 package from PyPI.
|
|
* Building on macOS is known to work, but has been known to fail.
|
|
For example, the system Python may not know which compiler flags
|
|
to set when building bindings for software installed by Homebrew;
|
|
see https://docs.brew.sh/Homebrew-and-Python#brewed-python-modules.
|
|
* Building on Windows has not been tested yet and will probably fail.
|
|
"""
|
|
|
|
|
|
class BuildExt(setuptools.command.build_ext.build_ext):
|
|
|
|
def build_extension(self, ext):
|
|
if 'GITHUB_ACTIONS' not in os.environ:
|
|
return super().build_extension(ext)
|
|
|
|
cmd = ['bazel', 'build']
|
|
try:
|
|
cpu = os.environ['BAZEL_CPU']
|
|
cmd.append(f'--cpu={cpu}')
|
|
cmd.append(f'--platforms=//python:{cpu}')
|
|
if cpu == 'x64_x86_windows':
|
|
# Register the local 32-bit C++ toolchain with highest priority.
|
|
# (This is likely to break in some release of Bazel after 7.0.0,
|
|
# but this special case can hopefully be entirely removed then.)
|
|
cmd.append(f'--extra_toolchains=@local_config_cc//:cc-toolchain-{cpu}')
|
|
except KeyError:
|
|
pass
|
|
try:
|
|
ver = os.environ['MACOSX_DEPLOYMENT_TARGET']
|
|
cmd.append(f'--macos_minimum_os={ver}')
|
|
except KeyError:
|
|
pass
|
|
# Register the local Python toolchains with highest priority.
|
|
cmd.append('--extra_toolchains=//python/toolchains:all')
|
|
cmd += ['--compilation_mode=opt', '--', ':all']
|
|
self.spawn(cmd)
|
|
|
|
# This ensures that f'_re2.{importlib.machinery.EXTENSION_SUFFIXES[0]}'
|
|
# is the filename in the destination directory, which is what's needed.
|
|
shutil.copyfile('../bazel-bin/python/_re2.so',
|
|
self.get_ext_fullpath(ext.name))
|
|
|
|
cmd = ['bazel', 'clean', '--expunge']
|
|
self.spawn(cmd)
|
|
|
|
|
|
def options():
|
|
bdist_wheel = {}
|
|
try:
|
|
bdist_wheel['plat_name'] = os.environ['PLAT_NAME']
|
|
except KeyError:
|
|
pass
|
|
return {'bdist_wheel': bdist_wheel}
|
|
|
|
|
|
def include_dirs():
|
|
try:
|
|
import pybind11
|
|
yield pybind11.get_include()
|
|
except ModuleNotFoundError:
|
|
pass
|
|
|
|
|
|
ext_module = setuptools.Extension(
|
|
name='_re2',
|
|
sources=['_re2.cc'],
|
|
include_dirs=list(include_dirs()),
|
|
libraries=['re2'],
|
|
extra_compile_args=['-fvisibility=hidden'],
|
|
)
|
|
|
|
# We need `re2` to be a package, not a module, because it appears that
|
|
# modules can't have `.pyi` files, so munge the module into a package.
|
|
PACKAGE = 're2'
|
|
try:
|
|
# If we are building from the sdist, we are already in package form.
|
|
if not os.path.exists('PKG-INFO'):
|
|
os.makedirs(PACKAGE)
|
|
for filename in (
|
|
're2.py',
|
|
# TODO(junyer): Populate as per https://github.com/google/re2/issues/496.
|
|
# 're2.pyi',
|
|
# '_re2.pyi',
|
|
):
|
|
with open(filename, 'r') as file:
|
|
contents = file.read()
|
|
filename = re.sub(r'^re2(?=\.py)', '__init__', filename)
|
|
contents = re.sub(r'^(?=import _)', 'from . ', contents, flags=re.MULTILINE)
|
|
with open(f'{PACKAGE}/{filename}', 'x') as file:
|
|
file.write(contents)
|
|
# TODO(junyer): Populate as per https://github.com/google/re2/issues/496.
|
|
# with open(f'{PACKAGE}/py.typed', 'x') as file:
|
|
# pass
|
|
|
|
setuptools.setup(
|
|
name='google-re2',
|
|
version='1.1.20250812',
|
|
description='RE2 Python bindings',
|
|
long_description=long_description,
|
|
long_description_content_type='text/plain',
|
|
author='The RE2 Authors',
|
|
author_email='re2-dev@googlegroups.com',
|
|
url='https://github.com/google/re2',
|
|
packages=[PACKAGE],
|
|
ext_package=PACKAGE,
|
|
ext_modules=[ext_module],
|
|
classifiers=[
|
|
'Development Status :: 5 - Production/Stable',
|
|
'Intended Audience :: Developers',
|
|
'License :: OSI Approved :: BSD License',
|
|
'Programming Language :: C++',
|
|
'Programming Language :: Python :: 3.9',
|
|
],
|
|
options=options(),
|
|
cmdclass={'build_ext': BuildExt},
|
|
python_requires='~=3.9',
|
|
)
|
|
except:
|
|
raise
|
|
else:
|
|
# If we are building from the sdist, we are already in package form.
|
|
if not os.path.exists('PKG-INFO'):
|
|
shutil.rmtree(PACKAGE)
|