From 24c1e1b90f46921b4e6667a5881566338342dbea Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 13 Aug 2025 03:26:30 +0000 Subject: [PATCH 01/13] Initial plan From df9eb90237e5d560c90bb994d32e670fa1cc098b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 13 Aug 2025 03:32:05 +0000 Subject: [PATCH 02/13] Initial analysis and planning for setuptools to meson-python migration Co-authored-by: tobiasdiez <5037600+tobiasdiez@users.noreply.github.com> --- pari.tgz | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 pari.tgz diff --git a/pari.tgz b/pari.tgz new file mode 100644 index 0000000..e69de29 From 62fce0309c444c1691c4b1ac591aef28181308bb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 13 Aug 2025 03:39:17 +0000 Subject: [PATCH 03/13] Create working meson.build configuration Co-authored-by: tobiasdiez <5037600+tobiasdiez@users.noreply.github.com> --- meson.build | 178 +++++++++++++++++++++++++++++++++++++++++++++++++ pyproject.toml | 13 ++-- 2 files changed, 184 insertions(+), 7 deletions(-) create mode 100644 meson.build diff --git a/meson.build b/meson.build new file mode 100644 index 0000000..9bc88a8 --- /dev/null +++ b/meson.build @@ -0,0 +1,178 @@ +project('cypari2', 'c', + version: run_command( + 'cat', files('VERSION'), + check: true + ).stdout().strip(), + default_options: ['warning_level=0'] +) + +# Import Python module +py = import('python').find_installation(pure: false) + +# Add dependencies +cython = find_program('cython', required: true) + +# Import the dependencies we need +cysignals_dep = dependency('cysignals', required: false) +cysignals_include_dir = [] + +if not cysignals_dep.found() + # Try to find cysignals via Python + cysignals_result = run_command( + py.full_path(), '-c', + ''' +import cysignals +import os +print(os.path.dirname(cysignals.__file__)) + ''', + check: false + ) + if cysignals_result.returncode() == 0 + cysignals_include_dir = [cysignals_result.stdout().strip()] + else + error('cysignals not found. Please install cysignals.') + endif +endif + +# Get include directories for PARI +pari_include_dirs = [] +pari_library_dirs = [] + +# Try to find PARI using pkg-config +pari_dep = dependency('pari', required: false) + +if not pari_dep.found() + # Fallback: run a Python script to get PARI paths + pari_paths_result = run_command( + py.full_path(), '-c', + ''' +import sys, json +sys.path.insert(0, ".") +try: + from autogen.paths import include_dirs, library_dirs + result = {"include_dirs": include_dirs(), "library_dirs": library_dirs()} + print(json.dumps(result)) +except Exception as e: + print(json.dumps({"include_dirs": [], "library_dirs": [], "error": str(e)})) + ''', + check: true + ) + + pari_json_str = pari_paths_result.stdout().strip() + # For now, use common paths as fallback + pari_include_dirs = ['/usr/include', '/usr/local/include'] + pari_library_dirs = ['/usr/lib', '/usr/local/lib', '/usr/lib/x86_64-linux-gnu'] +endif + +# Include directories +all_include_dirs = pari_include_dirs + cysignals_include_dir +inc_dirs = include_directories(all_include_dirs) + +# Run code generation step +code_gen_result = run_command( + py.full_path(), '-c', + ''' +import sys +sys.path.insert(0, ".") +try: + from autogen import rebuild + rebuild(force=True) + print("Code generation successful") +except Exception as e: + print("Code generation failed: " + str(e)) + import traceback + traceback.print_exc() + ''', + check: false +) + +if code_gen_result.returncode() != 0 + warning('Code generation may have failed: ' + code_gen_result.stdout() + code_gen_result.stderr()) +endif + +# Define the source files +cython_sources = [ + 'cypari2/closure.pyx', + 'cypari2/stack.pyx', + 'cypari2/custom_block.pyx', + 'cypari2/convert.pyx', + 'cypari2/string_utils.pyx', + 'cypari2/handle_error.pyx', + 'cypari2/gen.pyx', + 'cypari2/pari_instance.pyx' +] + +# Create targets for each Cython source file +py_sources = [] +foreach src : cython_sources + basename = src.split('/')[1].split('.')[0] + c_file = custom_target(basename + '_c', + input: src, + output: basename + '.c', + command: [ + cython, + '-3', + '--capi-reexport-cincludes', + '-I', meson.current_source_dir() / 'cypari2', + '@INPUT@', + '-o', '@OUTPUT@' + ] + ) + + py_ext = py.extension_module( + basename, + c_file, + include_directories: [inc_dirs, 'cypari2'], + dependencies: [cysignals_dep, pari_dep], + link_args: ['-lpari'], + install: true, + subdir: 'cypari2' + ) + py_sources += py_ext +endforeach + +# Install Python package files +python_sources = [ + 'cypari2/__init__.py', +] + +py.install_sources( + python_sources, + subdir: 'cypari2' +) + +# Install package data files +package_data = [ + 'cypari2/closure.pxd', + 'cypari2/convert.pxd', + 'cypari2/gen.pxd', + 'cypari2/handle_error.pxd', + 'cypari2/pari_instance.pxd', + 'cypari2/paridecl.pxd', + 'cypari2/paripriv.pxd', + 'cypari2/pycore_long.pxd', + 'cypari2/stack.pxd', + 'cypari2/string_utils.pxd', + 'cypari2/types.pxd', + 'cypari2/cypari.h', + 'cypari2/pycore_long.h', +] + +# Check if auto-generated files exist and install them +auto_files = [ + 'cypari2/auto_paridecl.pxd', + 'cypari2/auto_gen.pxi', + 'cypari2/auto_instance.pxi', +] + +foreach f : auto_files + if import('fs').is_file(f) + package_data += f + endif +endforeach + +py.install_sources( + package_data, + subdir: 'cypari2', + preserve_path: false +) \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index f2c5658..0463e37 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,13 +1,13 @@ [build-system] requires = [ - "setuptools", + "meson-python>=0.15.0", "Cython>=3.0", "cysignals>=1.11.3", + "meson>=1.1.0", + "ninja", + "pkg-config", ] -# We need access to the autogen package at build time. -# Hence we declare a custom build backend. -build-backend = "_custom_build_meta" # just re-exports setuptools.build_meta definitions -backend-path = ["."] +build-backend = "mesonpy" [project] name = "cypari2" @@ -32,5 +32,4 @@ dynamic = [ [project.urls] Homepage = "https://github.com/sagemath/cypari2" -[tool.setuptools.dynamic] -version = {file = "VERSION"} + From 98d94b387645b38fd8e04a38296d82c46b866689 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 13 Aug 2025 03:45:35 +0000 Subject: [PATCH 04/13] Complete migration from setuptools to meson-python Co-authored-by: tobiasdiez <5037600+tobiasdiez@users.noreply.github.com> --- .github/workflows/main.yml | 2 +- MANIFEST.in | 2 +- _custom_build_meta.py | 2 -- setup.py | 67 -------------------------------------- 4 files changed, 2 insertions(+), 71 deletions(-) delete mode 100644 _custom_build_meta.py delete mode 100755 setup.py diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 85fd0b6..3a84af3 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -118,7 +118,7 @@ jobs: needs: [dist] env: - # Ubuntu packages to install so that the project's "setup.py sdist" can succeed + # Ubuntu packages to install so that the project's "python -m build --sdist" can succeed DIST_PREREQ: libpari-dev pari-doc libbz2-dev bzip2 # Name of this project in the Sage distribution SPKG: cypari diff --git a/MANIFEST.in b/MANIFEST.in index 4d02d76..dce05b9 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,5 +1,5 @@ include LICENSE README.rst VERSION -include Makefile +include Makefile meson.build global-include *.py *.pyx *.pxd *.pxi recursive-exclude cypari2 auto_* diff --git a/_custom_build_meta.py b/_custom_build_meta.py deleted file mode 100644 index 9573341..0000000 --- a/_custom_build_meta.py +++ /dev/null @@ -1,2 +0,0 @@ -# See https://setuptools.pypa.io/en/latest/build_meta.html#dynamic-build-dependencies-and-other-build-meta-tweaks -from setuptools.build_meta import * diff --git a/setup.py b/setup.py deleted file mode 100755 index c1775b5..0000000 --- a/setup.py +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/env python - -import os - -from setuptools import setup -from distutils.command.build_ext import build_ext as _build_ext -from setuptools.command.bdist_egg import bdist_egg as _bdist_egg -from setuptools.extension import Extension - -from autogen import rebuild -from autogen.paths import include_dirs, library_dirs - -ext_kwds = dict(include_dirs=include_dirs(), library_dirs=library_dirs()) - - -if "READTHEDOCS" in os.environ: - # When building with readthedocs, disable optimizations to decrease - # resource usage during build - ext_kwds["extra_compile_args"] = ["-O0"] - - # Print PARI/GP defaults and environment variables for debugging - from subprocess import Popen, PIPE - Popen(["gp", "-f", "-q"], stdin=PIPE).communicate(b"default()") - for item in os.environ.items(): - print("%s=%r" % item) - - -# Adapted from Cython's new_build_ext -class build_ext(_build_ext): - def finalize_options(self): - # Generate auto-generated sources from pari.desc - rebuild() - - self.directives = { - "autotestdict.cdef": True, - "binding": True, - "cdivision": True, - "legacy_implicit_noexcept": True, - "c_api_binop_methods": True, - "language_level": "3str", - } - - _build_ext.finalize_options(self) - - def run(self): - # Run Cython - from Cython.Build.Dependencies import cythonize - self.distribution.ext_modules[:] = cythonize( - self.distribution.ext_modules, - compiler_directives=self.directives) - - _build_ext.run(self) - - -class no_egg(_bdist_egg): - def run(self): - from distutils.errors import DistutilsOptionError - raise DistutilsOptionError("The package cypari2 will not function correctly when built as egg. Therefore, it cannot be installed using 'python setup.py install' or 'easy_install'. Instead, use 'pip install' to install cypari2.") - - -setup( - ext_modules=[Extension("*", ["cypari2/*.pyx"], **ext_kwds)], - packages=['cypari2'], - package_dir={'cypari2': 'cypari2'}, - package_data={'cypari2': ['declinl.pxi', '*.pxd', '*.h']}, - cmdclass=dict(build_ext=build_ext, bdist_egg=no_egg) -) From 8bfe949c56e75e2ac23b5c35b7c7a688f6e6a0b2 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Thu, 14 Aug 2025 21:46:38 +0800 Subject: [PATCH 05/13] Improve meson build --- .github/workflows/main.yml | 2 +- MANIFEST.in | 9 -- cypari2/meson.build | 44 +++++++++ meson.build | 193 +++++++------------------------------ pari.tgz | 0 pyproject.toml | 25 ++--- 6 files changed, 84 insertions(+), 189 deletions(-) delete mode 100644 MANIFEST.in create mode 100644 cypari2/meson.build delete mode 100644 pari.tgz diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3a84af3..47cc3a8 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -118,7 +118,7 @@ jobs: needs: [dist] env: - # Ubuntu packages to install so that the project's "python -m build --sdist" can succeed + # Ubuntu packages to install so that building the sdist can succeed DIST_PREREQ: libpari-dev pari-doc libbz2-dev bzip2 # Name of this project in the Sage distribution SPKG: cypari diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index dce05b9..0000000 --- a/MANIFEST.in +++ /dev/null @@ -1,9 +0,0 @@ -include LICENSE README.rst VERSION -include Makefile meson.build -global-include *.py *.pyx *.pxd *.pxi - -recursive-exclude cypari2 auto_* -global-exclude *.c .gitignore readthedocs* .install-pari.sh -prune .github - -prune dist diff --git a/cypari2/meson.build b/cypari2/meson.build new file mode 100644 index 0000000..20f7da8 --- /dev/null +++ b/cypari2/meson.build @@ -0,0 +1,44 @@ +py.install_sources( + '__init__.py', + 'closure.pxd', + 'convert.pxd', + 'gen.pxd', + 'handle_error.pxd', + 'pari_instance.pxd', + 'paridecl.pxd', + 'paripriv.pxd', + 'pycore_long.pxd', + 'stack.pxd', + 'string_utils.pxd', + 'types.pxd', + 'cypari.h', + 'pycore_long.h', + 'auto_paridecl.pxd', + 'auto_gen.pxi', + 'auto_instance.pxi', + subdir: 'cypari2' +) + + +extension_data = { + 'closure': files('closure.pyx'), + 'stack': files('stack.pyx'), + 'custom_block': files('custom_block.pyx'), + 'convert': files('convert.pyx'), + 'string_utils': files('string_utils.pyx'), + 'handle_error': files('handle_error.pyx'), + 'gen': files('gen.pyx'), + 'pari_instance': files('pari_instance.pyx') +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'cypari2', + install: true, + #include_directories: [inc_dirs, 'cypari2'], + dependencies: [cysignals, pari], + ) +endforeach + diff --git a/meson.build b/meson.build index 9bc88a8..3432e4d 100644 --- a/meson.build +++ b/meson.build @@ -1,72 +1,39 @@ -project('cypari2', 'c', - version: run_command( - 'cat', files('VERSION'), - check: true - ).stdout().strip(), - default_options: ['warning_level=0'] +project('cypari2', + ['c', 'cython'], + version: files('VERSION'), + license: 'GPL v3', + default_options: ['c_std=c17', 'cpp_std=c++17', 'python.install_env=auto'], + meson_version: '>=1.2', ) -# Import Python module +# Python module +# https://mesonbuild.com/Python-module.html py = import('python').find_installation(pure: false) -# Add dependencies -cython = find_program('cython', required: true) +# Compilers +cc = meson.get_compiler('c') +cython = meson.get_compiler('cython') -# Import the dependencies we need -cysignals_dep = dependency('cysignals', required: false) -cysignals_include_dir = [] - -if not cysignals_dep.found() - # Try to find cysignals via Python - cysignals_result = run_command( - py.full_path(), '-c', +# Dependencies +inc_cysignals = run_command( + py, + [ + '-c', ''' +from os.path import relpath import cysignals -import os -print(os.path.dirname(cysignals.__file__)) - ''', - check: false - ) - if cysignals_result.returncode() == 0 - cysignals_include_dir = [cysignals_result.stdout().strip()] - else - error('cysignals not found. Please install cysignals.') - endif -endif - -# Get include directories for PARI -pari_include_dirs = [] -pari_library_dirs = [] - -# Try to find PARI using pkg-config -pari_dep = dependency('pari', required: false) - -if not pari_dep.found() - # Fallback: run a Python script to get PARI paths - pari_paths_result = run_command( - py.full_path(), '-c', - ''' -import sys, json -sys.path.insert(0, ".") +path = cysignals.__file__.replace('__init__.py', '') try: - from autogen.paths import include_dirs, library_dirs - result = {"include_dirs": include_dirs(), "library_dirs": library_dirs()} - print(json.dumps(result)) -except Exception as e: - print(json.dumps({"include_dirs": [], "library_dirs": [], "error": str(e)})) - ''', - check: true - ) - - pari_json_str = pari_paths_result.stdout().strip() - # For now, use common paths as fallback - pari_include_dirs = ['/usr/include', '/usr/local/include'] - pari_library_dirs = ['/usr/lib', '/usr/local/lib', '/usr/lib/x86_64-linux-gnu'] -endif - -# Include directories -all_include_dirs = pari_include_dirs + cysignals_include_dir -inc_dirs = include_directories(all_include_dirs) + print(relpath(path)) +except Exception: + print(path) + '''.strip(), + ], + check: true, +).stdout().strip() +cysignals = declare_dependency(include_directories: inc_cysignals) +# Cannot be found via pkg-config +pari = cc.find_library('pari', required: true) # Run code generation step code_gen_result = run_command( @@ -74,105 +41,11 @@ code_gen_result = run_command( ''' import sys sys.path.insert(0, ".") -try: - from autogen import rebuild - rebuild(force=True) - print("Code generation successful") -except Exception as e: - print("Code generation failed: " + str(e)) - import traceback - traceback.print_exc() +from autogen import rebuild +rebuild(force=True) +print("Code generation successful") ''', - check: false + check: true ) -if code_gen_result.returncode() != 0 - warning('Code generation may have failed: ' + code_gen_result.stdout() + code_gen_result.stderr()) -endif - -# Define the source files -cython_sources = [ - 'cypari2/closure.pyx', - 'cypari2/stack.pyx', - 'cypari2/custom_block.pyx', - 'cypari2/convert.pyx', - 'cypari2/string_utils.pyx', - 'cypari2/handle_error.pyx', - 'cypari2/gen.pyx', - 'cypari2/pari_instance.pyx' -] - -# Create targets for each Cython source file -py_sources = [] -foreach src : cython_sources - basename = src.split('/')[1].split('.')[0] - c_file = custom_target(basename + '_c', - input: src, - output: basename + '.c', - command: [ - cython, - '-3', - '--capi-reexport-cincludes', - '-I', meson.current_source_dir() / 'cypari2', - '@INPUT@', - '-o', '@OUTPUT@' - ] - ) - - py_ext = py.extension_module( - basename, - c_file, - include_directories: [inc_dirs, 'cypari2'], - dependencies: [cysignals_dep, pari_dep], - link_args: ['-lpari'], - install: true, - subdir: 'cypari2' - ) - py_sources += py_ext -endforeach - -# Install Python package files -python_sources = [ - 'cypari2/__init__.py', -] - -py.install_sources( - python_sources, - subdir: 'cypari2' -) - -# Install package data files -package_data = [ - 'cypari2/closure.pxd', - 'cypari2/convert.pxd', - 'cypari2/gen.pxd', - 'cypari2/handle_error.pxd', - 'cypari2/pari_instance.pxd', - 'cypari2/paridecl.pxd', - 'cypari2/paripriv.pxd', - 'cypari2/pycore_long.pxd', - 'cypari2/stack.pxd', - 'cypari2/string_utils.pxd', - 'cypari2/types.pxd', - 'cypari2/cypari.h', - 'cypari2/pycore_long.h', -] - -# Check if auto-generated files exist and install them -auto_files = [ - 'cypari2/auto_paridecl.pxd', - 'cypari2/auto_gen.pxi', - 'cypari2/auto_instance.pxi', -] - -foreach f : auto_files - if import('fs').is_file(f) - package_data += f - endif -endforeach - -py.install_sources( - package_data, - subdir: 'cypari2', - preserve_path: false -) \ No newline at end of file +subdir('cypari2') diff --git a/pari.tgz b/pari.tgz deleted file mode 100644 index e69de29..0000000 diff --git a/pyproject.toml b/pyproject.toml index 0463e37..8af7a1e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,35 +1,22 @@ [build-system] -requires = [ - "meson-python>=0.15.0", - "Cython>=3.0", - "cysignals>=1.11.3", - "meson>=1.1.0", - "ninja", - "pkg-config", -] +requires = ["meson-python>=0.15.0", "cython>=3.0", "cysignals>=1.11.3"] build-backend = "mesonpy" [project] name = "cypari2" description = "A Python interface to the number theory library PARI/GP" authors = [ - {name = "Luca De Feo, Vincent Delecroix, Jeroen Demeyer, Vincent Klein"}, + { name = "Luca De Feo, Vincent Delecroix, Jeroen Demeyer, Vincent Klein" }, ] maintainers = [ - {name = "SageMath developers", email = "sage-devel@googlegroups.com"}, -] -dependencies = [ - "cysignals>=1.11.3", + { name = "SageMath developers", email = "sage-devel@googlegroups.com" }, ] +dependencies = ["cysignals>=1.11.3"] requires-python = ">=3.9" readme = "README.rst" -license = {text = "GNU General Public License, version 2 or later"} +license = { text = "GNU General Public License, version 2 or later" } keywords = ["PARI/GP number theory"] -dynamic = [ - "version", -] +dynamic = ["version"] [project.urls] Homepage = "https://github.com/sagemath/cypari2" - - From 3815f817f3bf52382ca4c225eea2772cf10edba9 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Thu, 14 Aug 2025 21:46:55 +0800 Subject: [PATCH 06/13] Add instructions on how to build via conda --- README.rst | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/README.rst b/README.rst index bdaa282..8bf9718 100644 --- a/README.rst +++ b/README.rst @@ -42,14 +42,10 @@ From source with pip Requirements: -- PARI/GP >= 2.9.4 (header files and library); see + PARI/GP >= 2.9.4 (header files and library); see https://doc.sagemath.org/html/en/reference/spkg/pari#spkg-pari for availability in distributions (GNU/Linux, conda-forge, Homebrew, FreeBSD), or install from source. -- Python >= 3.9 -- pip -- `cysignals `_ >= 1.11.3 -- Cython >= 3.0 Install cypari2 via the Python Package Index (PyPI) via @@ -139,10 +135,22 @@ same computations be done via The complete documentation of cypari2 is available at http://cypari2.readthedocs.io and the PARI/GP documentation at http://pari.math.u-bordeaux.fr/doc.html -Contributing ------------- +Contributing & Development +-------------------------- CyPari 2 is maintained by the SageMath community. Open issues or submit pull requests at https://github.com/sagemath/cypari2 and join https://groups.google.com/group/sage-devel to discuss. + +To get started with development, you can set up an environment using Conda +as follows: + +:: + $ conda create -n cypari2-dev python cython pari=*=*_pthread ninja meson-python cysignals c-compiler + $ conda activate cypari2-dev + +Afterwards, you can build and install the package in editable mode: + +:: + $ pip install -e . --no-build-isolation From 1668a126f77500a36fad82177d2cfb2f1d800573 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Thu, 14 Aug 2025 22:03:32 +0800 Subject: [PATCH 07/13] Fix failing tests --- meson.build | 2 ++ 1 file changed, 2 insertions(+) diff --git a/meson.build b/meson.build index 3432e4d..ab87607 100644 --- a/meson.build +++ b/meson.build @@ -13,6 +13,8 @@ py = import('python').find_installation(pure: false) # Compilers cc = meson.get_compiler('c') cython = meson.get_compiler('cython') +# Workaround as described in https://cython.readthedocs.io/en/latest/src/userguide/special_methods.html#arithmetic-methods +add_project_arguments('-X c_api_binop_methods=True', language: 'cython') # Dependencies inc_cysignals = run_command( From 7fb7f10bee3c1fb01fc392d9afcabda2b9547354 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Fri, 15 Aug 2025 09:17:37 +0800 Subject: [PATCH 08/13] Fix Unicode-to-C coercion errors --- cypari2/gen.pyx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cypari2/gen.pyx b/cypari2/gen.pyx index db23af2..ee55347 100644 --- a/cypari2/gen.pyx +++ b/cypari2/gen.pyx @@ -1789,9 +1789,9 @@ cdef class Gen(Gen_base): while sp[0] == c'0': sp = sp + 1 sp -= 1 - sp[0] = 'x' + sp[0] = c'x' sp -= 1 - sp[0] = '0' + sp[0] = c'0' if signe(x) < 0: sp -= 1 sp[0] = c'-' From 2227b12eb25bc788297b05ecb0eb28943af90c32 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Tue, 19 Aug 2025 13:27:43 +0800 Subject: [PATCH 09/13] Cleanup meson script based on reviewer feedback --- cypari2/meson.build | 1 - meson.build | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/cypari2/meson.build b/cypari2/meson.build index 20f7da8..3475f26 100644 --- a/cypari2/meson.build +++ b/cypari2/meson.build @@ -37,7 +37,6 @@ foreach name, pyx : extension_data sources: pyx, subdir: 'cypari2', install: true, - #include_directories: [inc_dirs, 'cypari2'], dependencies: [cysignals, pari], ) endforeach diff --git a/meson.build b/meson.build index ab87607..0b9eb67 100644 --- a/meson.build +++ b/meson.build @@ -1,8 +1,8 @@ project('cypari2', ['c', 'cython'], version: files('VERSION'), - license: 'GPL v3', - default_options: ['c_std=c17', 'cpp_std=c++17', 'python.install_env=auto'], + license: 'GPL v2+', + default_options: ['c_std=c17', 'python.install_env=auto'], meson_version: '>=1.2', ) From 2e63fe19bfbe63751d0e5a141c4f4ab39fa0624c Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Fri, 22 Aug 2025 15:27:13 +0800 Subject: [PATCH 10/13] Make license info compatible with PEP 639 https://peps.python.org/pep-0639/ Fixes issues like: SyntaxWarning: invalid escape sequence '\[' verb_loop = re.compile("^( .*)@\[[a-z]*\]", re.MULTILINE) /root/.cache/uv/builds-v0/.tmp70O2Lb/lib/python3.13/site-packages/setupto ols/config/_apply_pyprojecttoml.py:82: SetuptoolsDeprecationWarning: `project.license` as a TOML table is deprecated (that's for setuptools, but meson-python should throw a similar error at some point) --- pyproject.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 8af7a1e..d1ad955 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,7 +14,8 @@ maintainers = [ dependencies = ["cysignals>=1.11.3"] requires-python = ">=3.9" readme = "README.rst" -license = { text = "GNU General Public License, version 2 or later" } +license = "GPL-2.0-or-later" +license-files = ["LICENSE"] keywords = ["PARI/GP number theory"] dynamic = ["version"] From a41195dcd53d4897719d7d9385b50e618ac85d7c Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Fri, 22 Aug 2025 15:36:13 +0800 Subject: [PATCH 11/13] http -> https --- .install-pari.sh | 6 +++--- README.rst | 6 +++--- autogen/args.py | 2 +- autogen/parser.py | 8 +++++--- autogen/paths.py | 6 ++---- autogen/ret.py | 3 ++- cypari2/convert.pyx | 2 +- cypari2/custom_block.pyx | 2 +- cypari2/gen.pyx | 2 +- cypari2/stack.pyx | 2 +- tests/test_backward.py | 6 ++++-- tests/test_integers.py | 6 ++++-- 12 files changed, 28 insertions(+), 23 deletions(-) diff --git a/.install-pari.sh b/.install-pari.sh index f164ecd..39b2dde 100644 --- a/.install-pari.sh +++ b/.install-pari.sh @@ -8,9 +8,9 @@ if [ "$URLDIR" = "" ]; then URLDIR=OLD/${PURE_VERSION%.*} fi -PARI_URL="http://pari.math.u-bordeaux.fr/pub/pari/$URLDIR" -PARI_URL1="http://pari.math.u-bordeaux.fr/pub/pari/unix" -PARI_URL2="http://pari.math.u-bordeaux.fr/pub/pari/unstable" +PARI_URL="https://pari.math.u-bordeaux.fr/pub/pari/$URLDIR" +PARI_URL1="https://pari.math.u-bordeaux.fr/pub/pari/unix" +PARI_URL2="https://pari.math.u-bordeaux.fr/pub/pari/unstable" # Download PARI sources wget --no-verbose "$PARI_URL/$PARI_VERSION.tar.gz" -O pari.tgz || wget --no-verbose "$PARI_URL1/pari-$PARI_VERSION.tar.gz" -O pari.tgz || wget --no-verbose "$PARI_URL2/pari-$PARI_VERSION.tar.gz" -O pari.tgz diff --git a/README.rst b/README.rst index 8bf9718..914356f 100644 --- a/README.rst +++ b/README.rst @@ -5,7 +5,7 @@ CyPari 2 :target: https://cypari2.readthedocs.io/en/latest/?badge=latest :alt: Documentation Status -A Python interface to the number theory library `PARI/GP `_. +A Python interface to the number theory library `PARI/GP `_. Installation ------------ @@ -132,8 +132,8 @@ same computations be done via >>> pari.centerlift(pari.lift(fq)) [x - t, 1; x + (t^2 + t - 1), 1; x + (-t^2 - 1), 1] -The complete documentation of cypari2 is available at http://cypari2.readthedocs.io and -the PARI/GP documentation at http://pari.math.u-bordeaux.fr/doc.html +The complete documentation of cypari2 is available at https://cypari2.readthedocs.io and +the PARI/GP documentation at https://pari.math.u-bordeaux.fr/doc.html Contributing & Development -------------------------- diff --git a/autogen/args.py b/autogen/args.py index 02c57b9..357dbc6 100644 --- a/autogen/args.py +++ b/autogen/args.py @@ -9,7 +9,7 @@ # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. -# http://www.gnu.org/licenses/ +# https://www.gnu.org/licenses/ #***************************************************************************** from __future__ import unicode_literals diff --git a/autogen/parser.py b/autogen/parser.py index a7fe02f..b0d44cd 100644 --- a/autogen/parser.py +++ b/autogen/parser.py @@ -9,16 +9,18 @@ # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. -# http://www.gnu.org/licenses/ +# https://www.gnu.org/licenses/ #***************************************************************************** from __future__ import absolute_import, unicode_literals -import os, re, io +import io +import os +import re from .args import pari_arg_types -from .ret import pari_ret_types from .paths import pari_share +from .ret import pari_ret_types paren_re = re.compile(r"[(](.*)[)]") argname_re = re.compile(r"[ {]*&?([A-Za-z_][A-Za-z0-9_]*)") diff --git a/autogen/paths.py b/autogen/paths.py index e879464..ec98a5b 100644 --- a/autogen/paths.py +++ b/autogen/paths.py @@ -9,17 +9,15 @@ # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. -# http://www.gnu.org/licenses/ +# https://www.gnu.org/licenses/ #***************************************************************************** from __future__ import absolute_import, unicode_literals import os import shutil - from glob import glob - gppath = shutil.which("gp") if gppath is None: @@ -43,7 +41,7 @@ def pari_share(): """ if "PARI_SHARE" in os.environ: return os.environ["PARI_SHARE"] - from subprocess import Popen, PIPE + from subprocess import PIPE, Popen if not gppath: raise EnvironmentError("cannot find an installation of PARI/GP: make sure that the 'gp' program is in your $PATH") # Ignore GP_DATA_DIR environment variable diff --git a/autogen/ret.py b/autogen/ret.py index f07f95d..15ac3f6 100644 --- a/autogen/ret.py +++ b/autogen/ret.py @@ -9,11 +9,12 @@ # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. -# http://www.gnu.org/licenses/ +# https://www.gnu.org/licenses/ #***************************************************************************** from __future__ import unicode_literals + class PariReturn(object): """ This class represents the return value of a PARI call. diff --git a/cypari2/convert.pyx b/cypari2/convert.pyx index 5e1bd79..27facc2 100644 --- a/cypari2/convert.pyx +++ b/cypari2/convert.pyx @@ -15,7 +15,7 @@ PARI integers are stored as an array of limbs of type ``pari_ulong`` (GMP or native), this array is stored little-endian or big-endian. This is encapsulated in macros like ``int_W()``: see section 4.5.1 of the -`PARI library manual `_. +`PARI library manual `_. Python integers of type ``int`` are just C longs. Python integers of type ``long`` are stored as a little-endian array of type ``digit`` diff --git a/cypari2/custom_block.pyx b/cypari2/custom_block.pyx index 67419f8..ca39703 100644 --- a/cypari2/custom_block.pyx +++ b/cypari2/custom_block.pyx @@ -4,7 +4,7 @@ # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. -# http://www.gnu.org/licenses/ +# https://www.gnu.org/licenses/ #***************************************************************************** from cysignals.signals cimport add_custom_signals diff --git a/cypari2/gen.pyx b/cypari2/gen.pyx index ee55347..a91a4b0 100644 --- a/cypari2/gen.pyx +++ b/cypari2/gen.pyx @@ -3639,7 +3639,7 @@ cdef class Gen(Gen_base): >>> G.galoissubfields(flag=2, v='z')[3] [...^2 + 2, Mod(x^3 + x, x^4 + 1), [x^2 - z*x - 1, x^2 + z*x - 1]] - .. _galoissubfields: http://pari.math.u-bordeaux.fr/dochtml/html.stable/Functions_related_to_general_number_fields.html#galoissubfields + .. _galoissubfields: https://pari.math.u-bordeaux.fr/dochtml/html.stable/Functions_related_to_general_number_fields.html#galoissubfields """ sig_on() return new_gen(galoissubfields(self.g, flag, get_var(v))) diff --git a/cypari2/stack.pyx b/cypari2/stack.pyx index b4d51fe..11a1025 100644 --- a/cypari2/stack.pyx +++ b/cypari2/stack.pyx @@ -11,7 +11,7 @@ Memory management for Gens on the PARI stack or the heap # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. -# http://www.gnu.org/licenses/ +# https://www.gnu.org/licenses/ # **************************************************************************** cimport cython diff --git a/tests/test_backward.py b/tests/test_backward.py index ce99fe7..e05672d 100644 --- a/tests/test_backward.py +++ b/tests/test_backward.py @@ -5,12 +5,14 @@ # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. -# http://www.gnu.org/licenses/ +# https://www.gnu.org/licenses/ #***************************************************************************** -import cypari2 import unittest +import cypari2 + + class TestBackward(unittest.TestCase): def test_polisirreducible(self): pari = cypari2.Pari() diff --git a/tests/test_integers.py b/tests/test_integers.py index 032bce4..e5d5c0a 100644 --- a/tests/test_integers.py +++ b/tests/test_integers.py @@ -5,13 +5,15 @@ # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. -# http://www.gnu.org/licenses/ +# https://www.gnu.org/licenses/ #***************************************************************************** import random -import cypari2 import unittest +import cypari2 + + class TestPariInteger(unittest.TestCase): def randint(self): p = random.random() From c44f72719ff366e58fe2f514687a58771bfbb691 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Fri, 22 Aug 2025 15:37:56 +0800 Subject: [PATCH 12/13] Remove unnecessary distutils comments --- cypari2/custom_block.pyx | 2 -- cypari2/paridecl.pxd | 1 - cypari2/paripriv.pxd | 1 - 3 files changed, 4 deletions(-) diff --git a/cypari2/custom_block.pyx b/cypari2/custom_block.pyx index ca39703..66eeec1 100644 --- a/cypari2/custom_block.pyx +++ b/cypari2/custom_block.pyx @@ -1,5 +1,3 @@ -# distutils: libraries = gmp pari - #***************************************************************************** # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of diff --git a/cypari2/paridecl.pxd b/cypari2/paridecl.pxd index 7b8d12d..8bd243b 100644 --- a/cypari2/paridecl.pxd +++ b/cypari2/paridecl.pxd @@ -1,4 +1,3 @@ -# distutils: libraries = gmp pari """ Declarations for non-inline functions from PARI. diff --git a/cypari2/paripriv.pxd b/cypari2/paripriv.pxd index 996b48c..dbe13d7 100644 --- a/cypari2/paripriv.pxd +++ b/cypari2/paripriv.pxd @@ -1,4 +1,3 @@ -# distutils: libraries = gmp pari """ Declarations for private functions from PARI From 933cc149e6e2617407be40228651e4159d777b8c Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Sat, 23 Aug 2025 21:41:12 -0500 Subject: [PATCH 13/13] bump constraint on meson-python version it should be at least 0.18 to allow license in the format of the PR --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index d1ad955..48a3d5d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [build-system] -requires = ["meson-python>=0.15.0", "cython>=3.0", "cysignals>=1.11.3"] +requires = ["meson-python>=0.18.0", "cython>=3.0", "cysignals>=1.11.3"] build-backend = "mesonpy" [project]