18
18
19
19
from __future__ import absolute_import
20
20
21
+ from functools import wraps
21
22
import os
22
23
import pathlib
23
24
import re
24
25
import shutil
26
+ import time
25
27
from typing import Dict , List
26
28
import warnings
27
29
100
102
101
103
CURRENT_DIRECTORY = pathlib .Path (__file__ ).parent .absolute ()
102
104
105
+
106
+ def _calculate_duration (func ):
107
+ """This decorator prints the execution time for the decorated function."""
108
+
109
+ @wraps (func )
110
+ def wrapper (* args , ** kwargs ):
111
+ start = time .monotonic ()
112
+ result = func (* args , ** kwargs )
113
+ end = time .monotonic ()
114
+ total_seconds = round (end - start )
115
+ hours = total_seconds // 3600 # Integer division to get hours
116
+ remaining_seconds = total_seconds % 3600 # Modulo to find remaining seconds
117
+ minutes = remaining_seconds // 60
118
+ seconds = remaining_seconds % 60
119
+ human_time = f"{ hours :} :{ minutes :0>2} :{ seconds :0>2} "
120
+ print (f"Session ran in { total_seconds } seconds ({ human_time } )" )
121
+ return result
122
+
123
+ return wrapper
124
+
125
+
103
126
nox .options .sessions = [
104
127
"unit" ,
105
128
"system" ,
118
141
119
142
120
143
@nox .session (python = DEFAULT_PYTHON_VERSION )
144
+ @_calculate_duration
121
145
def lint (session ):
122
146
"""Run linters.
123
147
124
148
Returns a failure if the linters find linting errors or sufficiently
125
149
serious code quality issues.
126
150
"""
127
151
session .install (FLAKE8_VERSION , BLACK_VERSION )
152
+ session .run ("python" , "-m" , "pip" , "freeze" )
128
153
session .run (
129
154
"black" ,
130
155
"--check" ,
@@ -134,16 +159,19 @@ def lint(session):
134
159
135
160
136
161
@nox .session (python = DEFAULT_PYTHON_VERSION )
162
+ @_calculate_duration
137
163
def blacken (session ):
138
164
"""Run black. Format code to uniform standard."""
139
165
session .install (BLACK_VERSION )
166
+ session .run ("python" , "-m" , "pip" , "freeze" )
140
167
session .run (
141
168
"black" ,
142
169
* LINT_PATHS ,
143
170
)
144
171
145
172
146
173
@nox .session (python = DEFAULT_PYTHON_VERSION )
174
+ @_calculate_duration
147
175
def format (session ):
148
176
"""
149
177
Run isort to sort imports. Then run black
@@ -152,6 +180,7 @@ def format(session):
152
180
session .install (BLACK_VERSION , ISORT_VERSION )
153
181
# Use the --fss option to sort imports using strict alphabetical order.
154
182
# See https://pycqa.github.io/isort/docs/configuration/options.html#force-sort-within-sections
183
+ session .run ("python" , "-m" , "pip" , "freeze" )
155
184
session .run (
156
185
"isort" ,
157
186
"--fss" ,
@@ -164,9 +193,11 @@ def format(session):
164
193
165
194
166
195
@nox .session (python = DEFAULT_PYTHON_VERSION )
196
+ @_calculate_duration
167
197
def lint_setup_py (session ):
168
198
"""Verify that setup.py is valid (including RST check)."""
169
199
session .install ("docutils" , "pygments" )
200
+ session .run ("python" , "-m" , "pip" , "freeze" )
170
201
session .run ("python" , "setup.py" , "check" , "--restructuredtext" , "--strict" )
171
202
172
203
@@ -203,6 +234,7 @@ def install_unittest_dependencies(session, *constraints):
203
234
"protobuf_implementation" ,
204
235
["python" , "upb" , "cpp" ],
205
236
)
237
+ @_calculate_duration
206
238
def unit (session , protobuf_implementation , install_extras = True ):
207
239
# Install all test dependencies, then install this package in-place.
208
240
@@ -229,6 +261,7 @@ def unit(session, protobuf_implementation, install_extras=True):
229
261
session .install ("protobuf<4" )
230
262
231
263
# Run py.test against the unit tests.
264
+ session .run ("python" , "-m" , "pip" , "freeze" )
232
265
session .run (
233
266
"py.test" ,
234
267
"--quiet" ,
@@ -278,6 +311,7 @@ def install_systemtest_dependencies(session, *constraints):
278
311
279
312
280
313
@nox .session (python = SYSTEM_TEST_PYTHON_VERSIONS )
314
+ @_calculate_duration
281
315
def system (session ):
282
316
"""Run the system test suite."""
283
317
constraints_path = str (
@@ -300,6 +334,7 @@ def system(session):
300
334
session .skip ("System tests were not found" )
301
335
302
336
install_systemtest_dependencies (session , "-c" , constraints_path )
337
+ session .run ("python" , "-m" , "pip" , "freeze" )
303
338
304
339
# Run py.test against the system tests.
305
340
if system_test_exists :
@@ -321,6 +356,7 @@ def system(session):
321
356
322
357
323
358
@nox .session (python = SYSTEM_TEST_PYTHON_VERSIONS )
359
+ @_calculate_duration
324
360
def system_noextras (session ):
325
361
"""Run the system test suite."""
326
362
constraints_path = str (
@@ -345,6 +381,7 @@ def system_noextras(session):
345
381
global SYSTEM_TEST_EXTRAS_BY_PYTHON
346
382
SYSTEM_TEST_EXTRAS_BY_PYTHON = False
347
383
install_systemtest_dependencies (session , "-c" , constraints_path )
384
+ session .run ("python" , "-m" , "pip" , "freeze" )
348
385
349
386
# Run py.test against the system tests.
350
387
if system_test_exists :
@@ -366,6 +403,7 @@ def system_noextras(session):
366
403
367
404
368
405
@nox .session (python = SYSTEM_TEST_PYTHON_VERSIONS [- 1 ])
406
+ @_calculate_duration
369
407
def compliance (session ):
370
408
"""Run the SQLAlchemy dialect-compliance system tests"""
371
409
constraints_path = str (
@@ -418,19 +456,22 @@ def compliance(session):
418
456
419
457
420
458
@nox .session (python = DEFAULT_PYTHON_VERSION )
459
+ @_calculate_duration
421
460
def cover (session ):
422
461
"""Run the final coverage report.
423
462
424
463
This outputs the coverage report aggregating coverage from the unit
425
464
test runs (not system test runs), and then erases coverage data.
426
465
"""
427
466
session .install ("coverage" , "pytest-cov" )
467
+ session .run ("python" , "-m" , "pip" , "freeze" )
428
468
session .run ("coverage" , "report" , "--show-missing" , "--fail-under=100" )
429
469
430
470
session .run ("coverage" , "erase" )
431
471
432
472
433
473
@nox .session (python = "3.10" )
474
+ @_calculate_duration
434
475
def docs (session ):
435
476
"""Build the docs for this library."""
436
477
@@ -453,6 +494,7 @@ def docs(session):
453
494
)
454
495
455
496
shutil .rmtree (os .path .join ("docs" , "_build" ), ignore_errors = True )
497
+ session .run ("python" , "-m" , "pip" , "freeze" )
456
498
session .run (
457
499
"sphinx-build" ,
458
500
"-W" , # warnings as errors
@@ -468,6 +510,7 @@ def docs(session):
468
510
469
511
470
512
@nox .session (python = "3.10" )
513
+ @_calculate_duration
471
514
def docfx (session ):
472
515
"""Build the docfx yaml files for this library."""
473
516
@@ -490,6 +533,7 @@ def docfx(session):
490
533
)
491
534
492
535
shutil .rmtree (os .path .join ("docs" , "_build" ), ignore_errors = True )
536
+ session .run ("python" , "-m" , "pip" , "freeze" )
493
537
session .run (
494
538
"sphinx-build" ,
495
539
"-T" , # show full traceback on exception
@@ -520,6 +564,7 @@ def docfx(session):
520
564
"protobuf_implementation" ,
521
565
["python" , "upb" , "cpp" ],
522
566
)
567
+ @_calculate_duration
523
568
def prerelease_deps (session , protobuf_implementation ):
524
569
"""Run all tests with prerelease versions of dependencies installed."""
525
570
@@ -581,6 +626,7 @@ def prerelease_deps(session, protobuf_implementation):
581
626
"requests" ,
582
627
]
583
628
session .install (* other_deps )
629
+ session .run ("python" , "-m" , "pip" , "freeze" )
584
630
585
631
# Print out prerelease package versions
586
632
session .run (
0 commit comments