From cd630856ef84fcdd0f22c94d73c7aa3ed4bc1a9d Mon Sep 17 00:00:00 2001 From: Majid Hajiloo Date: Thu, 29 Jan 2026 22:47:26 +0330 Subject: [PATCH 1/5] add python 3.14 support --- .github/workflows/ci.yml | 2 +- pyproject.toml | 2 +- setup.py | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1c7aeb8..36686ab 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,7 +20,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, macos-latest, windows-latest] - python-version: ['3.9', '3.10', '3.11', '3.12', '3.13', 'pypy-3.9', 'pypy-3.10', 'pypy-3.11'] + python-version: ['3.9', '3.10', '3.11', '3.12', '3.13', '3.14', 'pypy-3.9', 'pypy-3.10', 'pypy-3.11'] steps: - uses: actions/checkout@v4 diff --git a/pyproject.toml b/pyproject.toml index 7044c32..4169f83 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.black] line-length = 120 -target-version = ["py39", "py310", "py311", "py312", "py313"] +target-version = ["py39", "py310", "py311", "py312", "py313", "py314"] include = '\.pyi?$' exclude = ''' ( diff --git a/setup.py b/setup.py index d473e23..96dfe2d 100644 --- a/setup.py +++ b/setup.py @@ -33,6 +33,7 @@ def read_version(): "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: Software Development", From 25e3da16e2c64bd739580a0a228ccaadfb18fd9b Mon Sep 17 00:00:00 2001 From: Majid Hajiloo Date: Thu, 29 Jan 2026 23:21:16 +0330 Subject: [PATCH 2/5] migrate to pyproject.toml --- pyproject.toml | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++ setup.py | 61 ---------------------------------------------- 2 files changed, 66 insertions(+), 61 deletions(-) delete mode 100644 setup.py diff --git a/pyproject.toml b/pyproject.toml index 4169f83..d3a7687 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,3 +1,69 @@ +[build-system] +requires = ["setuptools>=80.0"] +build-backend = "setuptools.build_meta" + +[project] +name = "persiantools" +dynamic = ["version"] +description = "Jalali date and datetime with other tools" +readme = "README.md" +license = "MIT" +requires-python = ">=3.9" +authors = [ + { name = "Majid Hajiloo", email = "majid.hajiloo@gmail.com" } +] +keywords = [ + "jalali", + "shamsi", + "persian", + "digits", + "characters", + "converter", + "jalalidate", + "jalalidatetime", + "date", + "datetime", + "jdate", + "jdatetime", + "farsi", +] +classifiers = [ + "Intended Audience :: Developers", + "License :: OSI Approved :: MIT License", + "Natural Language :: Persian", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy", + "Topic :: Software Development", + "Topic :: Software Development :: Libraries", + "Topic :: Software Development :: Libraries :: Python Modules", + "Topic :: Software Development :: Localization", + "Topic :: Utilities", +] + +dependencies = [ + "tzdata; platform_system == 'Windows'", +] + +[project.urls] +Homepage = "https://github.com/majiidd/persiantools" +Source = "https://github.com/majiidd/persiantools" +Issues = "https://github.com/majiidd/persiantools/issues" + +[tool.setuptools.dynamic] +version = { attr = "persiantools.__version__" } + +[tool.setuptools.packages.find] +include = ["persiantools*"] + [tool.black] line-length = 120 target-version = ["py39", "py310", "py311", "py312", "py313", "py314"] diff --git a/setup.py b/setup.py deleted file mode 100644 index 96dfe2d..0000000 --- a/setup.py +++ /dev/null @@ -1,61 +0,0 @@ -import re - -from setuptools import setup - - -def readme(): - with open("README.md", encoding="utf-8") as f: - return f.read() - - -def read_version(): - with open("persiantools/__init__.py", encoding="utf-8") as f: - m = re.search(r"^__version__\s*=\s*['\"]([^'\"]+)['\"]", f.read(), re.M) - if not m: - raise RuntimeError("Cannot find __version__ in persiantools/__init__.py") - return m.group(1) - - -setup( - name="persiantools", - version=read_version(), - description="Jalali date and datetime with other tools", - long_description=readme(), - long_description_content_type="text/markdown", - classifiers=[ - "Intended Audience :: Developers", - "Natural Language :: Persian", - "Operating System :: OS Independent", - "Programming Language :: Python", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.12", - "Programming Language :: Python :: 3.13", - "Programming Language :: Python :: 3.14", - "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy", - "Topic :: Software Development", - "Topic :: Software Development :: Libraries", - "Topic :: Software Development :: Libraries :: Python Modules", - "Topic :: Software Development :: Localization", - "Topic :: Utilities", - ], - keywords="jalali shamsi persian digits characters converter jalalidate " - "jalalidatetime date datetime jdate jdatetime farsi", - url="https://github.com/majiidd/persiantools", - project_urls={ - "Source": "https://github.com/majiidd/persiantools", - "Issues": "https://github.com/majiidd/persiantools/issues", - }, - author="Majid Hajiloo", - author_email="majid.hajiloo@gmail.com", - license="MIT", - license_files=("LICENSE",), - packages=["persiantools"], - python_requires=">=3.9", - install_requires=["tzdata; platform_system == 'Windows'"], - include_package_data=True, - zip_safe=False, -) From 55064d6c1e62861669bc42a564c4c63ca74a7685 Mon Sep 17 00:00:00 2001 From: Majid Hajiloo Date: Thu, 29 Jan 2026 23:59:10 +0330 Subject: [PATCH 3/5] change ci.yml --- .github/workflows/ci.yml | 153 ++++++++++++++++++++++++--------------- 1 file changed, 94 insertions(+), 59 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 36686ab..7f948ae 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,28 +13,61 @@ concurrency: cancel-in-progress: true jobs: + lint: + name: Lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.13' + cache: 'pip' + + - name: Cache pre-commit + uses: actions/cache@v4 + with: + path: ~/.cache/pre-commit + key: pre-commit-${{ hashFiles('.pre-commit-config.yaml') }} + + - name: Install pre-commit + run: pip install pre-commit + + - name: Run pre-commit + run: pre-commit run --all-files + tests: - name: ${{ matrix.os }} / ${{ matrix.python-version }} + name: Tests / ${{ matrix.os }} / ${{ matrix.python-version }} runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: os: [ubuntu-latest, macos-latest, windows-latest] - python-version: ['3.9', '3.10', '3.11', '3.12', '3.13', '3.14', 'pypy-3.9', 'pypy-3.10', 'pypy-3.11'] + python-version: ['3.9', '3.10', '3.11', '3.12', '3.13', '3.14'] + include: + - os: ubuntu-latest + python-version: '3.15' + experimental: true + - os: ubuntu-latest + python-version: 'pypy-3.9' + - os: ubuntu-latest + python-version: 'pypy-3.10' + - os: ubuntu-latest + python-version: 'pypy-3.11' + continue-on-error: ${{ matrix.experimental || false }} steps: - uses: actions/checkout@v4 - with: - fetch-depth: 0 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} + allow-prereleases: ${{ matrix.experimental || false }} cache: 'pip' - name: Cache Pipenv virtualenv - id: cache-pipenv uses: actions/cache@v4 with: path: | @@ -48,8 +81,8 @@ jobs: - name: Install dependencies shell: bash env: - PIPENV_NOSPIN: "1" - PIPENV_VENV_IN_PROJECT: "1" + PIPENV_NOSPIN: '1' + PIPENV_VENV_IN_PROJECT: '1' run: | if [ "${{ runner.os }}" = "Windows" ]; then export PIPENV_PYTHON="${pythonLocation}\\python.exe" @@ -58,87 +91,89 @@ jobs: fi pipenv install --dev - - name: Display Python version + - name: Run tests env: - PIPENV_NOSPIN: "1" - PIPENV_VENV_IN_PROJECT: "1" - run: pipenv run python -V - - - name: Run tests (with coverage on Linux CPython 3.12) - if: ${{ runner.os == 'Linux' && matrix.python-version == '3.12' }} - env: - PIPENV_NOSPIN: "1" - PIPENV_VENV_IN_PROJECT: "1" - run: pipenv run pytest -ra --cov=persiantools --cov-report xml:coverage.xml tests/ + PIPENV_NOSPIN: '1' + PIPENV_VENV_IN_PROJECT: '1' + run: pipenv run pytest -ra tests/ - - name: Run tests (no coverage) - if: ${{ !(runner.os == 'Linux' && matrix.python-version == '3.12') }} + - name: Run tests with coverage + if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.13' env: - PIPENV_NOSPIN: "1" - PIPENV_VENV_IN_PROJECT: "1" - run: pipenv run pytest -ra tests/ + PIPENV_NOSPIN: '1' + PIPENV_VENV_IN_PROJECT: '1' + run: pipenv run pytest -ra --cov=persiantools --cov-report=xml tests/ - name: Upload coverage to Codecov - if: ${{ runner.os == 'Linux' && matrix.python-version == '3.12' }} - uses: codecov/codecov-action@v4 + if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.13' + uses: codecov/codecov-action@v5 with: - fail_ci_if_error: true files: coverage.xml + fail_ci_if_error: true token: ${{ secrets.CODECOV_TOKEN }} - lint: - name: Lint + build: + name: Build runs-on: ubuntu-latest + needs: [lint, tests] steps: - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Set up Python uses: actions/setup-python@v5 with: - python-version: '3.12' + python-version: '3.13' cache: 'pip' - - name: Install pre-commit - run: pip install pre-commit - - name: Cache pre-commit - uses: actions/cache@v4 + + - name: Install build dependencies + run: python -m pip install --upgrade pip build + + - name: Build sdist and wheel + run: python -m build + + - name: Upload build artifacts + uses: actions/upload-artifact@v4 with: - path: ~/.cache/pre-commit - key: pre-commit-${{ hashFiles('.pre-commit-config.yaml') }} - - name: Run pre-commit - run: pre-commit run --all-files + name: dist + path: dist/ + if-no-files-found: error - build-and-publish: + publish-test-pypi: + name: Publish to Test PyPI if: github.repository == 'majiidd/persiantools' && github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') runs-on: ubuntu-latest + needs: [build] + environment: test-pypi permissions: id-token: write - contents: read steps: - - uses: actions/checkout@v4 + - name: Download build artifacts + uses: actions/download-artifact@v4 with: - fetch-depth: 0 - - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: '3.12' - cache: 'pip' - - - name: Build sdist and wheel - run: | - python -m pip install --upgrade pip - python -m pip install --upgrade build - python -m build --sdist --wheel --outdir dist/ . + name: dist + path: dist/ - name: Publish to Test PyPI - if: always() uses: pypa/gh-action-pypi-publish@release/v1 with: repository-url: https://test.pypi.org/legacy/ - password: ${{ secrets.TEST_PYPI_API_TOKEN }} - verbose: true + + publish-pypi: + name: Publish to PyPI + if: github.repository == 'majiidd/persiantools' && github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') + runs-on: ubuntu-latest + needs: [build, publish-test-pypi] + environment: pypi + permissions: + id-token: write + steps: + - name: Download build artifacts + uses: actions/download-artifact@v4 + with: + name: dist + path: dist/ - name: Publish to PyPI uses: pypa/gh-action-pypi-publish@release/v1 - with: - password: ${{ secrets.PYPI_API_TOKEN }} - verbose: true From 9eb5082b08ee92b5701d9421c1369cc2f156d932 Mon Sep 17 00:00:00 2001 From: Majid Hajiloo Date: Fri, 30 Jan 2026 00:05:43 +0330 Subject: [PATCH 4/5] . --- pyproject.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index d3a7687..6c26395 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,7 +29,6 @@ keywords = [ ] classifiers = [ "Intended Audience :: Developers", - "License :: OSI Approved :: MIT License", "Natural Language :: Persian", "Operating System :: OS Independent", "Programming Language :: Python", From 6478d47b6baaa34fa9ca8f10a1199bcfedcb1fd6 Mon Sep 17 00:00:00 2001 From: Majid Hajiloo Date: Fri, 30 Jan 2026 00:22:40 +0330 Subject: [PATCH 5/5] Python 3.14 support --- .github/workflows/ci.yml | 1 + CHANGELOG.md | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7f948ae..2694a2a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -92,6 +92,7 @@ jobs: pipenv install --dev - name: Run tests + if: ${{ !(matrix.os == 'ubuntu-latest' && matrix.python-version == '3.13') }} env: PIPENV_NOSPIN: '1' PIPENV_VENV_IN_PROJECT: '1' diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f88518..2dc0d2e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [5.5.0](https://github.com/majiidd/persiantools/compare/5.4.0...5.5.0) - 2026-01-30 + +- Python 3.14 support. +- Migrated from `setup.py` to `pyproject.toml` (PEP 621). +- Improved CI/CD pipeline with job dependencies and parallel execution. +- Marked Python 3.15 as experimental with allowed failures. + ## [5.4.0](https://github.com/majiidd/persiantools/compare/5.3.0...5.4.0) - 2025-09-26 - Removed `pytz` dependency; migrated fully to `zoneinfo` and `datetime.timezone`.