diff --git a/.github/workflows/autoblack.yml b/.github/workflows/autoblack.yml new file mode 100644 index 0000000..50e6209 --- /dev/null +++ b/.github/workflows/autoblack.yml @@ -0,0 +1,32 @@ +# GitHub Action that uses Black to reformat the Python code in an incoming pull request. +# If all Python code in the pull request is compliant with Black then this Action does nothing. +# Othewrwise, Black is run and its changes are committed back to the incoming pull request. +# https://github.com/cclauss/autoblack + +name: autoblack +on: [pull_request] +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: 3.13 + - name: Install click + run: pip install 'click==8.0.4' + - name: Install Black + run: pip install 'black==25.1.0' + - name: Run black --check . + run: black --check . + - name: If needed, commit black changes to the pull request + if: failure() + run: | + black . + git config --global user.name 'autoblack' + git config --global user.email 'rocky@users.noreply.github.com' + git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY + git checkout $GITHUB_HEAD_REF + git commit -am "fixup: Format Python code with Black" + git push diff --git a/.github/workflows/isort-and-black-checks.yml b/.github/workflows/isort-and-black-checks.yml new file mode 100644 index 0000000..9366048 --- /dev/null +++ b/.github/workflows/isort-and-black-checks.yml @@ -0,0 +1,32 @@ +# GitHub Action that uses Black to reformat the Python code in an incoming pull request. +# If all Python code in the pull request is compliant with Black then this Action does nothing. +# Othewrwise, Black is run and its changes are committed back to the incoming pull request. +# https://github.com/cclauss/autoblack + +name: isort and black check +on: [pull_request] +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: 3.13 + - name: Install click, black and isort + run: pip install 'click==8.0.4' 'black==25.1.0' 'isort==5.13.2' + - name: Run isort --check . + run: isort --check . + - name: Run black --check . + run: black --check . + # - name: If needed, commit black changes to the pull request + # if: failure() + # run: | + # black . + # git config --global user.name 'autoblack' + # git config --global user.email 'rocky@users.noreply.github.com' + # git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY + # git checkout $GITHUB_HEAD_REF + # git commit -am "fixup: Format Python code with Black" + # git push diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml new file mode 100644 index 0000000..ae7b8af --- /dev/null +++ b/.github/workflows/ubuntu.yml @@ -0,0 +1,38 @@ +name: Mathics3-Module-pyICU (ubuntu) + +on: + push: + branches: [ master ] + pull_request: + branches: '**' + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ['3.12', '3.13'] + steps: + - uses: actions/checkout@v4 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + sudo apt install libicu-dev + python -m pip install --upgrade pip + python -m pip install pytest + # # Go over and comment out stuff when next Mathics core and Mathics-scanner are released + # python -m pip install -e git+https://github.com/Mathics3/mathics-scanner#egg=Mathics-Scanner[full] + # git clone https://github.com/Mathics3/mathics-core + # (cd mathics-core && pip3 install -e .[full]) + # (cd mathics-core && bash ./admin-tools/make-JSON-tables.sh) + # python -m pip install -e git+https://github.com/Mathics3/Mathics3-Module-Base#egg=Mathics3-Module-Base + - name: install Mathic3 PyICU Module + run: | + python -m pip install Mathics3 PyICU + python -m pip install --no-build-isolation -e . + - name: Test Mathics3 PyICU Module + run: | + make check diff --git a/.gitignore b/.gitignore index 53413ad..a5a9ab3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ *~ .python-version /ChangeLog +/Mathics3_Module_PyICU.egg-info /build /dist /pymathics_language.egg-info diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b4165f5 --- /dev/null +++ b/Makefile @@ -0,0 +1,66 @@ +# A GNU Makefile to run various tasks - compatibility for us old-timers. + +# Note: This makefile include remake-style target comments. +# These comments before the targets start with #: +# remake --tasks to shows the targets and the comments + +GIT2CL ?= admin-tools/git2cl +PYTHON ?= python3 +PIP ?= pip3 +RM ?= rm +LANG = en + +.PHONY: all build \ + check clean \ + develop dist doc doc-data \ + pypi-setup \ + pytest \ + rmChangeLog \ + test + +#: Default target - same as "develop" +all: develop + +#: build everything needed to install +build: + $(PYTHON) ./setup.py build + +#: Make PyPI distribution +dist: + ./admin-tools/make-dist.sh + +#: Check Python version, and install PyPI dependencies +pypi-setup: + $(PIP) install -e . + +#: Set up to run from the source tree +develop: pypi-setup + $(PIP) install -e . + +# Run tests +check: pytest + +#: Remove derived files +clean: clean-pyc + +#: Remove old PYC files +clean-pyc: + @find . -name "*.pyc" -type f -delete + +#: Run py.test tests. Use environment variable "o" for pytest options +pytest: + pytest test $o + + +# #: Make Mathics PDF manual +# doc mathics.pdf: mathics/doc/tex/data +# (cd mathics/doc/tex && $(MAKE) mathics.pdf) + +#: Remove ChangeLog +rmChangeLog: + $(RM) ChangeLog || true + +#: Create a ChangeLog from git via git log and git2cl +ChangeLog: rmChangeLog + git log --pretty --numstat --summary | $(GIT2CL) >$@ + patch ChangeLog < ChangeLog-spell-corrected.diff diff --git a/pymathics/language/__init__.py b/pymathics/language/__init__.py index 2bf6646..46cb8a4 100644 --- a/pymathics/language/__init__.py +++ b/pymathics/language/__init__.py @@ -1,10 +1,9 @@ -"""Pymathics Language +"""Mathics3 Module PyICU This module provides Mathics functions and varialbles to work with -Lanugages and Translations +Languages and Translations. """ - from pymathics.language.__main__ import Alphabet from pymathics.language.version import __version__ diff --git a/pymathics/language/__main__.py b/pymathics/language/__main__.py index 810200b..a25a238 100644 --- a/pymathics/language/__main__.py +++ b/pymathics/language/__main__.py @@ -9,11 +9,11 @@ # PyICU: human-language alphabets and locales -from icu import Locale, LocaleData from typing import List, Optional -from mathics.builtin.base import Builtin +from icu import Locale, LocaleData from mathics.core.atoms import String +from mathics.core.builtin import Builtin from mathics.core.convert.expression import to_mathics_list availableLocales = Locale.getAvailableLocales() @@ -27,6 +27,7 @@ def eval_alphabet(language_name: String) -> Optional[List[String]]: py_language_name = language_name.value locale = language2locale.get(py_language_name, py_language_name) + print(locale) if locale not in availableLocales: return alphabet_set = LocaleData(locale).getExemplarSet(0, 0) @@ -70,7 +71,7 @@ class Alphabet(Builtin): summary_text = "lowercase letters in an alphabet" - def apply(self, alpha: String, evaluation): + def eval(self, alpha: String, evaluation): """Alphabet[alpha_String]""" alphabet_list = eval_alphabet(alpha) if alphabet_list is None: diff --git a/pymathics/language/version.py b/pymathics/language/version.py index bf28bad..9d003f0 100644 --- a/pymathics/language/version.py +++ b/pymathics/language/version.py @@ -5,4 +5,4 @@ # well as importing into Python. That's why there is no # space around "=" below. # fmt: off -__version__="5.0.0" # noqa +__version__="9.0.0" # noqa diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..2b4fb10 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,56 @@ +[build-system] +requires = [ + "setuptools", + "Mathics3-Module-Base >= 9.0.0", + "Mathics3>=9.0.0", + "PyICU>=2.9", +] +build-backend = "setuptools.build_meta" + +[project] +name = "Mathics3-Module-PyICU" +description = 'Mathics3 Hello, World! module' +dependencies = [ + "Mathics3-Module-Base >= 9.0.0", + "Mathics3 >= 9.0.0", + "PyICU>=2.9", +] +requires-python = ">=3.10" +readme = "README.rst" +license = "GPL-3.0-or-later" +keywords = ["Mathematica", "Wolfram", "Interpreter", "Shell", "Math", "CAS"] +maintainers = [ + {name = "Mathics Group", email = "mathics-devel@googlegroups.com"}, +] +classifiers = [ + "Intended Audience :: Developers", + "Intended Audience :: Science/Research", + "Programming Language :: Python", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy", + "Topic :: Scientific/Engineering", + "Topic :: Scientific/Engineering :: Mathematics", + "Topic :: Software Development :: Interpreters", +] +dynamic = ["version"] + +[project.urls] +Homepage = "https://github.com/Mathics3/Mathics3-Module-PyICU" +Downloads = "https://github.com/Mathics3/Mathics-Module-PyICU/releases" + +[project.optional-dependencies] +dev = [ + "pytest", +] + +[tool.setuptools] +packages = [ + "pymathics.language", +] + +[tool.setuptools.dynamic] +version = {attr = "pymathics.language.__version__"} diff --git a/setup.py b/setup.py deleted file mode 100644 index f6e01b7..0000000 --- a/setup.py +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -import sys -import platform -import os -import os.path as osp -from setuptools import setup, find_namespace_packages - -# Ensure user has the correct Python version -if sys.version_info < (3, 6): - print("Mathics support Python 3.6 and above; you have %d.%d" % sys.version_info[:2]) - sys.exit(-1) - - -def get_srcdir(): - filename = osp.normcase(osp.dirname(osp.abspath(__file__))) - return osp.realpath(filename) - - -def read(*rnames): - return open(osp.join(get_srcdir(), *rnames)).read() - - -# Get/set VERSION and long_description from files -long_description = read("README.rst") + "\n" - -__version__ = "0.0.0" # overwritten by exec below - -# stores __version__ in the current namespace -exec(compile(open("pymathics/language/version.py").read(), "version.py", "exec")) - -setup( - name="pymathics-language", - version=__version__, - packages=find_namespace_packages(include=["pymathics.*"]), - install_requires=[ - "Mathics3 >= 5.0.0.dev0,<5.1.0", - "PyICU>=2.9", - ], - zip_safe=False, - maintainer="Mathics Group", - long_description=long_description, - long_description_content_type="text/x-rst", - # metadata for upload to PyPI - classifiers=[ - "Intended Audience :: Developers", - "Intended Audience :: Science/Research", - "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", - "Programming Language :: Python", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy", - "Topic :: Scientific/Engineering", - "Topic :: Scientific/Engineering :: Mathematics", - "Topic :: Scientific/Engineering :: Physics", - "Topic :: Software Development :: Interpreters", - "Topic :: Scientific/Engineering :: Human Machine Interfaces", - "Topic :: Text Processing", - "Topic :: Text Processing :: Linguistic", - ], - # TODO: could also include long_description, download_url, -) diff --git a/test/test_basic.py b/test/test_basic.py new file mode 100644 index 0000000..5d17257 --- /dev/null +++ b/test/test_basic.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- + +from mathics.core.load_builtin import import_and_load_builtins +from mathics.session import MathicsSession + +import_and_load_builtins() + +session = MathicsSession(character_encoding="UTF-8") + + +def check_evaluation(str_expr: str, expected: str, assert_message=""): + """Helper function to test that a Mathics expression against + its results""" + result = session.evaluate(str_expr).value + + if assert_message: + assert result == expected, f"{assert_message}: got: {result}" + else: + assert result == expected + + +def test_language(): + session.evaluate('LoadModule["pymathics.language"]') == "pymathics.language" + check_evaluation( + 'Alphabet["es"]', + ( + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "á", + "é", + "í", + "ñ", + "ó", + "ú", + "ü", + ), + )