From 8f3a5b4b201f091713cb4e2b1b5883a4b12d10b2 Mon Sep 17 00:00:00 2001 From: Frost Ming Date: Thu, 18 Jul 2024 05:32:08 +0800 Subject: [PATCH] fix: release sdist to PyPI (#797) * fix: release sdist to PyPI * fix: add newline at file end * fix: ignore more files Signed-off-by: Frost Ming * fix: change the install root of cmake Signed-off-by: Frost Ming * fix: make it work for editable build as well Signed-off-by: Frost Ming * fix release script Signed-off-by: Frost Ming * fix: include files in sdist Signed-off-by: Frost Ming --------- Signed-off-by: Frost Ming Co-authored-by: Carbo Kuo --- .github/workflows/python.yml | 10 ++++---- .gitignore | 1 + MANIFEST.in | 9 +++++++ Makefile | 6 ++--- pyproject.toml | 3 +++ python/opencc/.gitignore | 1 + python/opencc/clib/__init__.py | 1 - release-pypi-linux.sh | 8 +++---- release-pypi-macos.sh | 6 ++--- release-pypi-windows.cmd | 6 ++--- setup.py | 43 +++++++++------------------------- 11 files changed, 43 insertions(+), 51 deletions(-) create mode 100644 MANIFEST.in create mode 100644 pyproject.toml diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index ccf6e78e6..2fde2983c 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -15,9 +15,9 @@ jobs: python-version: [3.8, 3.9, '3.10', '3.11', '3.12'] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - name: Install dependencies @@ -32,9 +32,9 @@ jobs: # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide flake8 . --exclude deps --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics - name: Build and install - run: python setup.py build_ext install + run: python -m pip install . - name: Test with pytest - run: cd python && pytest + run: pytest python/ test-pypi: strategy: @@ -43,7 +43,7 @@ jobs: runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v4 - name: Build package and upload from docker (Linux) if: runner.os == 'Linux' diff --git a/.gitignore b/.gitignore index 36ecd86f5..f5164873a 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,4 @@ /xcode /node_modules /*.egg-info +/.venv/ diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 000000000..38ab0ada5 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,9 @@ +graft src +graft deps +graft test +graft data +graft doc +include CMakeLists.txt OpenCCConfig.cmake.in opencc.pc.in README* LICENSE* +global-exclude *~ *.py[cod] *.so +include python/**/__init__.py +graft python/tests diff --git a/Makefile b/Makefile index ff8bc89b9..c10fe4e12 100644 --- a/Makefile +++ b/Makefile @@ -78,13 +78,13 @@ xcode-build: xcodebuild build) python-build: - python setup.py build_ext + echo "No need to build" python-install: python-build - python setup.py install + python -m pip install . python-dist: python-build - python setup.py bdist_wheel + python -m build python-test: python-build cd python; pytest . diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 000000000..9ec751f5b --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["setuptools>=61", "wheel", "cmake"] +build-backend = "setuptools.build_meta" diff --git a/python/opencc/.gitignore b/python/opencc/.gitignore index 8840e7698..a1374b4e1 100644 --- a/python/opencc/.gitignore +++ b/python/opencc/.gitignore @@ -1,2 +1,3 @@ version.py clib/ +!clib/__init__.py diff --git a/python/opencc/clib/__init__.py b/python/opencc/clib/__init__.py index 8b1378917..e69de29bb 100644 --- a/python/opencc/clib/__init__.py +++ b/python/opencc/clib/__init__.py @@ -1 +0,0 @@ - diff --git a/release-pypi-linux.sh b/release-pypi-linux.sh index 7f02f7ca5..d5391dbf3 100644 --- a/release-pypi-linux.sh +++ b/release-pypi-linux.sh @@ -33,13 +33,13 @@ for VERSION in 3.8 3.9 3.10 3.11 3.12; do conda activate py$VERSION # Build and package - pip install --no-cache-dir setuptools wheel cmake - python setup.py build_ext bdist_wheel \ - --plat-name "manylinux2014_$(uname --machine)" + pip install --no-cache-dir build + python -m build \ + -C--plat-name="manylinux2014_$(uname --machine)" # Cleanup conda deactivate - rm -rf build python/opencc/clib OpenCC.egg-info + rm -rf build OpenCC.egg-info done if [ "$1" != "testonly" ]; then diff --git a/release-pypi-macos.sh b/release-pypi-macos.sh index 7b3c632a2..909bea7ce 100644 --- a/release-pypi-macos.sh +++ b/release-pypi-macos.sh @@ -20,12 +20,12 @@ for VERSION in 3.8 3.9 3.10 3.11 3.12; do conda activate py$VERSION # Build and package - pip install --no-cache-dir setuptools wheel - python setup.py build_ext bdist_wheel + pip install --no-cache-dir build + python -m build --wheel # Cleanup conda deactivate - rm -rf build python/opencc/clib OpenCC.egg-info + rm -rf build OpenCC.egg-info done if [ "$1" != "testonly" ]; then diff --git a/release-pypi-windows.cmd b/release-pypi-windows.cmd index 21b9e96ee..7056d9d5d 100644 --- a/release-pypi-windows.cmd +++ b/release-pypi-windows.cmd @@ -17,16 +17,16 @@ for %%v in (%VERSIONS%) do ( if !ERRORLEVEL! NEQ 0 (EXIT !ERRORLEVEL!) CALL C:\Miniconda/condabin/conda.bat activate py%%v if !ERRORLEVEL! NEQ 0 (EXIT !ERRORLEVEL!) - pip install --no-cache-dir setuptools wheel pytest + pip install --no-cache-dir build if !ERRORLEVEL! NEQ 0 (EXIT !ERRORLEVEL!) REM Build and package - python setup.py build_ext bdist_wheel + python -m build --wheel if !ERRORLEVEL! NEQ 0 (EXIT !ERRORLEVEL!) REM Cleanup CALL C:\Miniconda/condabin/conda.bat deactivate - rmdir /S /Q build python\opencc\clib OpenCC.egg-info + rmdir /S /Q build OpenCC.egg-info ) if NOT "%~1"=="testonly" ( diff --git a/setup.py b/setup.py index a7ce160dd..a4bc500f2 100644 --- a/setup.py +++ b/setup.py @@ -9,21 +9,12 @@ import wheel.bdist_wheel _this_dir = os.path.dirname(os.path.abspath(__file__)) -_clib_dir = os.path.join(_this_dir, 'python', 'opencc', 'clib') _build_dir = os.path.join(_this_dir, 'build', 'python') _cmake_file = os.path.join(_this_dir, 'CMakeLists.txt') _author_file = os.path.join(_this_dir, 'AUTHORS') _readme_file = os.path.join(_this_dir, 'README.md') -try: - sys.path.insert(0, os.path.join(_this_dir, 'python')) - - import opencc # noqa - _libopencc_built = True -except ImportError: - _libopencc_built = False - def get_version_info(): version_info = ['1', '0', '0'] @@ -70,20 +61,13 @@ def get_long_description(): return f.read().decode('utf-8') -def build_libopencc(): - if _libopencc_built: - return # Skip building binary file +def build_libopencc(output_path): print('building libopencc into %s' % _build_dir) is_windows = sys.platform == 'win32' # Make build directories - if is_windows: - subprocess.call('md {}'.format(_build_dir), shell=True) - subprocess.call('md {}'.format(_clib_dir), shell=True) - else: - subprocess.call('mkdir -p {}'.format(_build_dir), shell=True) - subprocess.call('mkdir -p {}'.format(_clib_dir), shell=True) + os.makedirs(_build_dir, exist_ok=True) # Configure cmake_args = [ @@ -93,14 +77,14 @@ def build_libopencc(): '-DENABLE_BENCHMARK:BOOL=OFF', '-DBUILD_PYTHON:BOOL=ON', '-DCMAKE_BUILD_TYPE=Release', - '-DCMAKE_INSTALL_PREFIX={}'.format(_clib_dir), - '-DCMAKE_LIBRARY_OUTPUT_DIRECTORY={}'.format(_clib_dir), + '-DCMAKE_INSTALL_PREFIX={}'.format(output_path), + '-DCMAKE_LIBRARY_OUTPUT_DIRECTORY={}'.format(output_path), '-DPYTHON_EXECUTABLE={}'.format(sys.executable), ] if is_windows: cmake_args += \ - ['-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE={}'.format(_clib_dir)] + ['-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE={}'.format(output_path)] if sys.maxsize > 2**32: cmake_args += ['-A', 'x64'] @@ -117,11 +101,6 @@ def build_libopencc(): errno = subprocess.call(cmd) assert errno == 0, 'Build failed' - # Empty __init__.py file has to be created - # to make opencc.clib a module - with open('{}/__init__.py'.format(_clib_dir), 'w'): - pass - class OpenCCExtension(setuptools.Extension, object): def __init__(self, name, sourcedir=''): @@ -131,8 +110,12 @@ def __init__(self, name, sourcedir=''): class BuildExtCommand(setuptools.command.build_ext.build_ext, object): def build_extension(self, ext): + if self.inplace: + output_path = os.path.join(_this_dir, 'python', 'opencc', 'clib') + else: + output_path = os.path.abspath(os.path.join(self.build_lib, 'opencc', 'clib')) if isinstance(ext, OpenCCExtension): - build_libopencc() + build_libopencc(output_path) else: super(BuildExtCommand, self).build_extension(ext) @@ -157,7 +140,7 @@ def _determine_platform_tag(): return 'macosx-11.0-{}'.format(machine) else: raise NotImplementedError - + if os.name == 'posix': _, _, _, _, machine = os.uname() return 'manylinux2014-{}'.format(machine) @@ -190,10 +173,6 @@ def initialize_options(self): packages=packages, package_dir={'opencc': 'python/opencc'}, - package_data={str('opencc'): [ - 'clib/opencc_clib*', - 'clib/share/opencc/*', - ]}, ext_modules=[OpenCCExtension('opencc.clib.opencc_clib', 'python')], cmdclass={ 'build_ext': BuildExtCommand,