Skip to content

Commit 94f078a

Browse files
committed
feat: remove python 3.9 support and upgrade dependencies
1 parent 1bcea5e commit 94f078a

File tree

8 files changed

+54
-53
lines changed

8 files changed

+54
-53
lines changed

.github/workflows/ci.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ jobs:
77
runs-on: ubuntu-latest
88
strategy:
99
matrix:
10-
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']
10+
python-version: ['3.10', '3.11', '3.12', '3.13']
1111
fail-fast: false
1212

1313
steps:
@@ -44,10 +44,10 @@ jobs:
4444
needs: test
4545
runs-on: ubuntu-latest
4646
steps:
47-
- name: Set up Python 3.9
47+
- name: Set up Python 3.10
4848
uses: actions/setup-python@v3
4949
with:
50-
python-version: '3.9'
50+
python-version: '3.10'
5151
- name: Install dependencies
5252
run: |
5353
python -m pip install --upgrade pip

.readthedocs.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ version: 2
88
build:
99
os: ubuntu-20.04
1010
tools:
11-
python: "3.9"
11+
python: "3.10"
1212

1313
# Build documentation in the docs/ directory with Sphinx
1414
sphinx:

CHANGELOG.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ v3.6.0
66

77
*Release date: In development*
88

9+
- Remove Python 3.9 support (Python 3.9 reached the end of its life on October 31st, 2025)
910
- Remove xcuitest deprecated `get_window_size` method and replaced it with `get_window_rect` in all mobile actions
1011
- Add text comparison methods based on AI libraries. To use them, install the `ai` extra dependency:
1112

requirements.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
requests~=2.27 # api tests
22
selenium~=4.0 # web tests
33
Appium-Python-Client>=2.3,<5.0 # mobile tests
4-
Pillow~=10.1 # visual testing
4+
Pillow~=12.0 # visual testing
55
screeninfo~=0.8
6-
lxml~=5.1
7-
Faker~=25.9
8-
phonenumbers~=8.13
6+
lxml~=6.0
7+
Faker~=38.0
8+
phonenumbers~=9.0

requirements_dev.txt

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
1-
pytest~=7.2
2-
coverage~=6.5
3-
coveralls~=3.3
1+
pytest~=9.0
2+
coverage~=7.11
3+
coveralls~=4.0
44
mock~=5.0
55
requests-mock~=1.10
66
Pygments~=2.14
7-
flake8~=6.0
8-
build~=0.10
7+
flake8~=7.3
8+
build~=1.3
99
wheel~=0.40
10-
twine~=4.0
11-
behave==1.2.6 # behave tests
12-
importlib_metadata==7.2.1
13-
spacy~=3.8.7
10+
twine~=6.2
11+
behave~=1.3 # behave tests
12+
importlib_metadata~=8.7
13+
spacy~=3.8
1414
sentence-transformers~=5.1
15-
transformers==4.56.2; python_version < '3.10' # Issue https://github.com/huggingface/transformers/issues/41339
16-
openai~=1.108
15+
openai~=2.7

setup.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,6 @@ def get_long_description():
9898
'License :: OSI Approved :: Apache Software License',
9999
'Natural Language :: English',
100100
'Operating System :: OS Independent',
101-
'Programming Language :: Python :: 3.9',
102101
'Programming Language :: Python :: 3.10',
103102
'Programming Language :: Python :: 3.11',
104103
'Programming Language :: Python :: 3.12',

toolium/test/utils/test_dataset_replace_param.py

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -173,56 +173,56 @@ def test_replace_param_timestamp_with_type_inference_forcing_str():
173173

174174
def test_replace_param_datetime():
175175
param = replace_param('[DATETIME]')
176-
assert datetime.datetime.strptime(param, '%Y-%m-%d %H:%M:%S.%f')
176+
assert datetime.datetime.strptime(param, '%Y-%m-%d %H:%M:%S.%f+00:00')
177177

178178

179179
def test_replace_param_datetime_language_ignored():
180180
param = replace_param('[DATETIME]', language='es')
181-
assert datetime.datetime.strptime(param, '%Y-%m-%d %H:%M:%S.%f')
181+
assert datetime.datetime.strptime(param, '%Y-%m-%d %H:%M:%S.%f+00:00')
182182

183183

184184
def test_replace_param_today_spanish():
185185
param = replace_param('[TODAY]', language='es')
186-
assert param == datetime.datetime.utcnow().strftime('%d/%m/%Y')
186+
assert param == datetime.datetime.now(datetime.timezone.utc).strftime('%d/%m/%Y')
187187

188188

189189
def test_replace_param_today_not_spanish():
190190
param = replace_param('[TODAY]', language='en')
191-
assert param == datetime.datetime.utcnow().strftime('%Y/%m/%d')
191+
assert param == datetime.datetime.now(datetime.timezone.utc).strftime('%Y/%m/%d')
192192

193193

194194
def test_replace_param_today_offset():
195195
param = replace_param('[TODAY - 1 DAYS]', language='es')
196196
assert param == datetime.datetime.strftime(
197-
datetime.datetime.utcnow() - datetime.timedelta(days=1), '%d/%m/%Y')
197+
datetime.datetime.now(datetime.timezone.utc) - datetime.timedelta(days=1), '%d/%m/%Y')
198198

199199

200200
def test_replace_param_now_spanish():
201201
param = replace_param('[NOW]', language='es')
202-
assert param == datetime.datetime.utcnow().strftime('%d/%m/%Y %H:%M:%S')
202+
assert param == datetime.datetime.now(datetime.timezone.utc).strftime('%d/%m/%Y %H:%M:%S')
203203

204204

205205
def test_replace_param_now_not_spanish():
206206
param = replace_param('[NOW]', language='it')
207-
assert param == datetime.datetime.utcnow().strftime('%Y/%m/%d %H:%M:%S')
207+
assert param == datetime.datetime.now(datetime.timezone.utc).strftime('%Y/%m/%d %H:%M:%S')
208208

209209

210210
def test_replace_param_now_with_format():
211211
param = replace_param('[NOW(%Y-%m-%dT%H:%M:%SZ)]')
212-
assert param == datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ')
212+
assert param == datetime.datetime.now(datetime.timezone.utc).strftime('%Y-%m-%dT%H:%M:%SZ')
213213

214214

215215
def test_replace_param_now_with_format_and_decimals_limit():
216216
param = replace_param('[NOW(%Y-%m-%dT%H:%M:%S.%3fZ)]')
217217
param_till_dot = param[:param.find('.')]
218-
assert param_till_dot == datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S')
218+
assert param_till_dot == datetime.datetime.now(datetime.timezone.utc).strftime('%Y-%m-%dT%H:%M:%S')
219219
assert re.match(param_till_dot + r'\.\d{3}Z', param)
220220

221221

222222
def test_replace_param_now_with_format_and_decimals_limit_beyond_microseconds():
223223
param = replace_param('[NOW(%Y-%m-%dT%H:%M:%S.%12fZ)]')
224224
param_till_dot = param[:param.find('.')]
225-
assert param_till_dot == datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S')
225+
assert param_till_dot == datetime.datetime.now(datetime.timezone.utc).strftime('%Y-%m-%dT%H:%M:%S')
226226
assert re.match(param_till_dot + r'\.\d{12}Z', param)
227227

228228

@@ -239,92 +239,92 @@ def test_not_replace_param_now_with_invalid_closing_parenthesis_in_format():
239239
def test_replace_param_now_offset():
240240
param = replace_param('[NOW + 5 MINUTES]', language='es')
241241
assert param == datetime.datetime.strftime(
242-
datetime.datetime.utcnow() + datetime.timedelta(minutes=5), '%d/%m/%Y %H:%M:%S')
242+
datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(minutes=5), '%d/%m/%Y %H:%M:%S')
243243

244244

245245
def test_replace_param_now_offset_with_format():
246246
param = replace_param('[NOW(%Y-%m-%dT%H:%M:%SZ) + 5 MINUTES]')
247247
assert param == datetime.datetime.strftime(
248-
datetime.datetime.utcnow() + datetime.timedelta(minutes=5), '%Y-%m-%dT%H:%M:%SZ')
248+
datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(minutes=5), '%Y-%m-%dT%H:%M:%SZ')
249249

250250

251251
def test_replace_param_today_offset_and_more():
252252
param = replace_param('The day [TODAY - 1 DAYS] was yesterday', language='es')
253253
offset_date = datetime.datetime.strftime(
254-
datetime.datetime.utcnow() - datetime.timedelta(days=1), '%d/%m/%Y')
254+
datetime.datetime.now(datetime.timezone.utc) - datetime.timedelta(days=1), '%d/%m/%Y')
255255
assert param == f'The day {offset_date} was yesterday'
256256

257257

258258
def test_replace_param_today_offset_and_more_not_spanish():
259259
param = replace_param('The day [TODAY - 1 DAYS] was yesterday', language='it')
260260
offset_date = datetime.datetime.strftime(
261-
datetime.datetime.utcnow() - datetime.timedelta(days=1), '%Y/%m/%d')
261+
datetime.datetime.now(datetime.timezone.utc) - datetime.timedelta(days=1), '%Y/%m/%d')
262262
assert param == f'The day {offset_date} was yesterday'
263263

264264

265265
def test_replace_param_now_offset_and_more():
266266
param = replace_param('I will arrive at [NOW + 10 MINUTES] tomorrow', language='es')
267267
offset_datetime = datetime.datetime.strftime(
268-
datetime.datetime.utcnow() + datetime.timedelta(minutes=10), '%d/%m/%Y %H:%M:%S')
268+
datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(minutes=10), '%d/%m/%Y %H:%M:%S')
269269
assert param == f'I will arrive at {offset_datetime} tomorrow'
270270

271271

272272
def test_replace_param_now_offset_and_more_not_spanish():
273273
param = replace_param('I will arrive at [NOW + 10 MINUTES] tomorrow', language='it')
274274
offset_datetime = datetime.datetime.strftime(
275-
datetime.datetime.utcnow() + datetime.timedelta(minutes=10), '%Y/%m/%d %H:%M:%S')
275+
datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(minutes=10), '%Y/%m/%d %H:%M:%S')
276276
assert param == f'I will arrive at {offset_datetime} tomorrow'
277277

278278

279279
def test_replace_param_now_offset_with_format_and_more():
280280
param = replace_param('I will arrive at [NOW(%Y-%m-%dT%H:%M:%SZ) + 10 MINUTES] tomorrow')
281281
offset_datetime = datetime.datetime.strftime(
282-
datetime.datetime.utcnow() + datetime.timedelta(minutes=10), '%Y-%m-%dT%H:%M:%SZ')
282+
datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(minutes=10), '%Y-%m-%dT%H:%M:%SZ')
283283
assert param == f'I will arrive at {offset_datetime} tomorrow'
284284

285285

286286
def test_replace_param_now_offset_with_format_and_more_language_is_irrelevant():
287287
param = replace_param('I will arrive at [NOW(%Y-%m-%dT%H:%M:%SZ) + 10 MINUTES] tomorrow', language='ru')
288288
offset_datetime = datetime.datetime.strftime(
289-
datetime.datetime.utcnow() + datetime.timedelta(minutes=10), '%Y-%m-%dT%H:%M:%SZ')
289+
datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(minutes=10), '%Y-%m-%dT%H:%M:%SZ')
290290
assert param == f'I will arrive at {offset_datetime} tomorrow'
291291

292292

293293
def test_replace_param_today_offset_with_format_and_more_with_extra_spaces():
294294
param = replace_param('The date [NOW(%Y-%m-%dT%H:%M:%SZ) - 1 DAYS ] was yesterday')
295295
offset_date = datetime.datetime.strftime(
296-
datetime.datetime.utcnow() - datetime.timedelta(days=1), '%Y-%m-%dT%H:%M:%SZ')
296+
datetime.datetime.now(datetime.timezone.utc) - datetime.timedelta(days=1), '%Y-%m-%dT%H:%M:%SZ')
297297
assert param == f'The date {offset_date} was yesterday'
298298

299299

300300
def test_replace_param_today_offset_and_more_with_extra_spaces():
301301
param = replace_param('The day [TODAY - 1 DAYS ] was yesterday', language='es')
302302
offset_date = datetime.datetime.strftime(
303-
datetime.datetime.utcnow() - datetime.timedelta(days=1), '%d/%m/%Y')
303+
datetime.datetime.now(datetime.timezone.utc) - datetime.timedelta(days=1), '%d/%m/%Y')
304304
assert param == f'The day {offset_date} was yesterday'
305305

306306

307307
def test_replace_param_today_offset_and_more_at_the_end():
308308
param = replace_param('Yesterday was [TODAY - 1 DAYS]', language='es')
309309
offset_date = datetime.datetime.strftime(
310-
datetime.datetime.utcnow() - datetime.timedelta(days=1), '%d/%m/%Y')
310+
datetime.datetime.now(datetime.timezone.utc) - datetime.timedelta(days=1), '%d/%m/%Y')
311311
assert param == f'Yesterday was {offset_date}'
312312

313313

314314
def test_replace_param_today_offset_and_more_at_the_beginning():
315315
param = replace_param('[TODAY - 1 DAYS] is yesterday', language='es')
316316
offset_date = datetime.datetime.strftime(
317-
datetime.datetime.utcnow() - datetime.timedelta(days=1), '%d/%m/%Y')
317+
datetime.datetime.now(datetime.timezone.utc) - datetime.timedelta(days=1), '%d/%m/%Y')
318318
assert param == f'{offset_date} is yesterday'
319319

320320

321321
def test_replace_param_today_offsets_and_more():
322322
param = replace_param(
323323
'The day [TODAY - 1 DAYS] was yesterday and I have an appointment at [NOW + 10 MINUTES]', language='es')
324324
offset_date = datetime.datetime.strftime(
325-
datetime.datetime.utcnow() - datetime.timedelta(days=1), '%d/%m/%Y')
325+
datetime.datetime.now(datetime.timezone.utc) - datetime.timedelta(days=1), '%d/%m/%Y')
326326
offset_datetime = datetime.datetime.strftime(
327-
datetime.datetime.utcnow() + datetime.timedelta(minutes=10), '%d/%m/%Y %H:%M:%S')
327+
datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(minutes=10), '%d/%m/%Y %H:%M:%S')
328328
assert param == f'The day {offset_date} was yesterday and I have an appointment at {offset_datetime}'
329329

330330

@@ -333,9 +333,9 @@ def test_replace_param_now_offsets_with_format_and_more():
333333
'The date [NOW(%Y-%m-%dT%H:%M:%SZ) - 1 DAYS] was yesterday '
334334
'and I have an appointment at [NOW(%Y-%m-%dT%H:%M:%SZ) + 10 MINUTES]')
335335
offset_date = datetime.datetime.strftime(
336-
datetime.datetime.utcnow() - datetime.timedelta(days=1), '%Y-%m-%dT%H:%M:%SZ')
336+
datetime.datetime.now(datetime.timezone.utc) - datetime.timedelta(days=1), '%Y-%m-%dT%H:%M:%SZ')
337337
offset_datetime = datetime.datetime.strftime(
338-
datetime.datetime.utcnow() + datetime.timedelta(minutes=10), '%Y-%m-%dT%H:%M:%SZ')
338+
datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(minutes=10), '%Y-%m-%dT%H:%M:%SZ')
339339
assert param == f'The date {offset_date} was yesterday and I have an appointment at {offset_datetime}'
340340

341341

@@ -344,9 +344,9 @@ def test_replace_param_now_offsets_with_and_without_format_and_more():
344344
'The date [NOW(%Y-%m-%dT%H:%M:%SZ) - 1 DAYS] was yesterday '
345345
'and I have an appointment at [NOW + 10 MINUTES]', language='es')
346346
offset_date = datetime.datetime.strftime(
347-
datetime.datetime.utcnow() - datetime.timedelta(days=1), '%Y-%m-%dT%H:%M:%SZ')
347+
datetime.datetime.now(datetime.timezone.utc) - datetime.timedelta(days=1), '%Y-%m-%dT%H:%M:%SZ')
348348
offset_datetime = datetime.datetime.strftime(
349-
datetime.datetime.utcnow() + datetime.timedelta(minutes=10), '%d/%m/%Y %H:%M:%S')
349+
datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(minutes=10), '%d/%m/%Y %H:%M:%S')
350350
assert param == f'The date {offset_date} was yesterday and I have an appointment at {offset_datetime}'
351351

352352

toolium/utils/dataset.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -203,12 +203,14 @@ def _replace_param_replacement(param, language):
203203
# make sure random is not made up of digits only, by forcing the first char to be a letter
204204
'[RANDOM]': ''.join([r.choice(string.ascii_lowercase), *(r.choice(alphanums) for i in range(7))]),
205205
'[RANDOM_PHONE_NUMBER]': _get_random_phone_number,
206-
'[TIMESTAMP]': str(int(datetime.datetime.timestamp(datetime.datetime.utcnow()))),
207-
'[DATETIME]': str(datetime.datetime.utcnow()),
208-
'[NOW]': str(datetime.datetime.utcnow().strftime(date_format)),
209-
'[TODAY]': str(datetime.datetime.utcnow().strftime(date_day_format)),
206+
'[TIMESTAMP]': str(int(datetime.datetime.timestamp(datetime.datetime.now(datetime.timezone.utc)))),
207+
'[DATETIME]': str(datetime.datetime.now(datetime.timezone.utc)),
208+
'[NOW]': str(datetime.datetime.now(datetime.timezone.utc).strftime(date_format)),
209+
'[TODAY]': str(datetime.datetime.now(datetime.timezone.utc).strftime(date_day_format)),
210210
r'\[ROUND:(.*?)::(\d*)\]': _get_rounded_float_number
211211
}
212+
a = datetime.datetime.now(datetime.timezone.utc)
213+
b = datetime.datetime.utcnow()
212214

213215
# append date expressions found in param to the replacement dict
214216
date_expressions = _find_param_date_expressions(param)
@@ -344,7 +346,7 @@ def _date_matcher():
344346
return re.match(r'\[(NOW(?:\((?:.*)\)|)|TODAY)(?:\s*([\+|-]\s*\d+)\s*(\w+)\s*)?\]', param)
345347

346348
def _offset_datetime(amount, units):
347-
now = datetime.datetime.utcnow()
349+
now = datetime.datetime.now(datetime.timezone.utc)
348350
if not amount or not units:
349351
return now
350352
the_amount = int(amount.replace(' ', ''))

0 commit comments

Comments
 (0)