Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 4 additions & 8 deletions .github/sync_labels.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@

This replacement only uses the Python standard library and reads exactly the
fields it needs, so additional fields in API responses can never break it
again. The only exception is TOML parsing on Python 3.10, which has no
:mod:`tomllib` and falls back to the ``tomli`` backport.
again. TOML parsing uses the standard library :mod:`tomllib`, available on
Python 3.11 and newer.

Requires Python 3.10+ (``pip install tomli`` on 3.10 only).
Requires Python 3.11+.

Usage
-----
Expand All @@ -41,16 +41,12 @@
from pathlib import Path
import re
import sys
import tomllib
from typing import Any
import urllib.error
import urllib.parse
import urllib.request

if sys.version_info >= (3, 11):
import tomllib
else: # Python 3.10: tomllib is not in the stdlib yet
import tomli as tomllib

API_VERSION = "2022-11-28"
USER_AGENT = "quickup-label-sync"
PER_PAGE = 100
Expand Down
2 changes: 0 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ jobs:
# Test all Python versions on Ubuntu (fastest)
# Test latest Python on macOS and Windows (catch OS-specific issues)
include:
- os: ubuntu-latest
python-version: "3.10"
- os: ubuntu-latest
python-version: "3.11"
- os: ubuntu-latest
Expand Down
10 changes: 0 additions & 10 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,6 @@ repos:
rev: v2.4.2
hooks:
- id: codespell
additional_dependencies:
- tomli

- repo: https://github.com/RobertCraigie/pyright-python
rev: v1.1.408
Expand All @@ -84,17 +82,9 @@ repos:
- "inquirer"
- "cyclopts"
- "pytest"
# .github/sync_labels.py falls back to tomli under Python 3.10, which
# is the interpreter this hook's venv uses in the 3.10 CI matrix job.
- "tomli"

- repo: https://github.com/asottile/pyupgrade
rev: v3.21.2
hooks:
- id: pyupgrade
args: ["--py312-plus"]
# The CI helper scripts must stay runnable on the workflow's interpreter,
# which is not necessarily 3.12+. pyupgrade --py312-plus rewrites away
# their `sys.version_info` guards (e.g. the tomllib/tomli fallback in
# .github/sync_labels.py), so leave them alone.
exclude: ^\.github/
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# QuickUp!

![Python Compatibility](https://img.shields.io/badge/python-3.10|3.11|3.12|3.13|3.14-blue.svg)
![Python Compatibility](https://img.shields.io/badge/python-3.11|3.12|3.13|3.14-blue.svg)
[![PyPI Version](https://img.shields.io/pypi/v/quickup.svg)](https://pypi.python.org/pypi/quickup)
[![Tests](https://github.com/matagus/quickup/actions/workflows/tests.yml/badge.svg)](https://github.com/matagus/quickup/actions/workflows/tests.yml)
[![Documentation Status](https://readthedocs.org/projects/quickup/badge/?version=latest)](https://quickup.readthedocs.io/en/latest/?badge=latest)
Expand Down Expand Up @@ -254,7 +254,7 @@ Use `--no-cache` to bypass cache and fetch fresh data from the API.

## Requirements

- Python 3.10+
- Python 3.11+
- ClickUp API token

## Dependencies
Expand Down
2 changes: 1 addition & 1 deletion docs/source/Installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Installation
System Requirements
-------------------

- Python 3.10 or higher
- Python 3.11 or higher
- ClickUp API token
- pip or uv package manager

Expand Down
2 changes: 1 addition & 1 deletion docs/source/contributing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ This generates coverage reports in:
- ``coverage.json`` - JSON format
- Terminal output - Human-readable summary

Run tests on specific Python versions (3.10-3.14):
Run tests on specific Python versions (3.11-3.14):

.. code-block:: bash

Expand Down
9 changes: 3 additions & 6 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ build-backend = "hatchling.build"
[project]
name = "QuickUp"
dynamic = ["version"]
requires-python = ">=3.10"
description = " A colorful command-line client for Clickup written in Python 3.10+."
requires-python = ">=3.11"
description = " A colorful command-line client for Clickup written in Python 3.11+."
readme = "README.md"
authors = [
{ name = "Matias Agustin Mendez", email = "matagus@gmail.com" },
Expand All @@ -23,7 +23,6 @@ classifiers = [
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
"Natural Language :: English",
"Programming Language :: Python",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
Expand All @@ -37,8 +36,6 @@ dependencies = [
[project.optional-dependencies]
dev = [
"pytest", "pytest-mock", "pytest-cov", "coverage",
# .github/sync_labels.py needs a TOML parser on Python 3.10 (no tomllib)
"tomli; python_version < '3.11'",
]
docs = [
"sphinx>=7.1.2,<8",
Expand Down Expand Up @@ -90,7 +87,7 @@ serve = "python -m http.server 8000 --directory docs/build"
dependencies = ["ipdb>=0.13.9", "line_profiler>=3.5.1"]

[[tool.hatch.envs.test.matrix]]
python = ["3.10", "3.11", "3.12", "3.13", "3.14"]
python = ["3.11", "3.12", "3.13", "3.14"]

[tool.hatch.envs.test.scripts]
test = "pytest {args:tests}"
Expand Down
8 changes: 4 additions & 4 deletions quickup/cli/api_client.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""API client wrapper for ClickUp API interactions."""

from datetime import datetime, timezone
from datetime import UTC, datetime
import sys

from colorist import Color
Expand Down Expand Up @@ -262,14 +262,14 @@ def get_current_sprint_list(team, space):
raise ListNotFoundError(hint="No lists found with 'sprint' or 'iteration' in the name")

# Prefer the sprint whose date range includes today
now = datetime.now(timezone.utc)
now = datetime.now(UTC)
for li in sprint_lists:
try:
start = getattr(li, "start_date", None)
due = getattr(li, "due_date", None)
if start and due:
start_dt = datetime.fromtimestamp(int(start) / 1000, tz=timezone.utc)
due_dt = datetime.fromtimestamp(int(due) / 1000, tz=timezone.utc)
start_dt = datetime.fromtimestamp(int(start) / 1000, tz=UTC)
due_dt = datetime.fromtimestamp(int(due) / 1000, tz=UTC)
if start_dt <= now <= due_dt:
return li
except (TypeError, ValueError):
Expand Down
6 changes: 3 additions & 3 deletions tests/test_sprint.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""Tests for QuickUp! sprint command."""

from datetime import datetime, timedelta, timezone
from datetime import UTC, datetime, timedelta
from unittest.mock import Mock, patch

import pytest
Expand Down Expand Up @@ -159,7 +159,7 @@ def test_case_insensitive_search(self):
def test_returns_active_sprint_by_date_range(self):
"""Test returning the sprint whose date range includes today, regardless of ID."""
mock_space = Mock(id="space-123")
now = datetime.now(timezone.utc)
now = datetime.now(UTC)

sprint_past = Mock()
sprint_past.name = "Sprint 1"
Expand Down Expand Up @@ -212,7 +212,7 @@ def test_falls_back_to_id_sort_when_no_dates(self):
def test_falls_back_to_id_sort_when_no_current_sprint(self):
"""Test fallback to ID sort when no sprint's date range includes today."""
mock_space = Mock(id="space-123")
now = datetime.now(timezone.utc)
now = datetime.now(UTC)

sprint_past = Mock()
sprint_past.name = "Sprint 1"
Expand Down
Loading