11import functools
2+ import subprocess
3+ import sys
24import time
35from collections import defaultdict
46from datetime import datetime , timedelta
7+ from importlib import import_module
58from pathlib import Path
6- from typing import Optional
79
810import requests
911from jinja2 import Environment , FileSystemLoader
1012
13+ from sentry_sdk .utils import parse_version
14+
1115from dependencies import DEPENDENCIES
1216
17+ # TODO:
18+ # - encode lowest supported versions somewhere and consider them here
19+ # - put GROUPS someplace where both this script and split_tox_actions can use it
20+ # - allow to specify version dependent dependencies
21+ # - (optional) use a proper version parser for requires_python
22+ # - (optional) order by alphabet, not group then alphabet
23+
1324# Only consider package versions going back this far
1425CUTOFF = datetime .now () - timedelta (days = 365 * 5 )
1526
2233
2334PYPI_PROJECT_URL = "https://pypi.python.org/pypi/{project}/json"
2435PYPI_VERSION_URL = "https://pypi.python.org/pypi/{project}/{version}/json"
25-
2636CLASSIFIER_PREFIX = "Programming Language :: Python :: "
2737
38+ INTEGRATIONS_MIN_VERSIONS = {}
2839
2940GROUPS = {
3041 "Common" : [
@@ -133,30 +144,34 @@ def __init__(self, version, metadata=None):
133144 self .raw = version
134145 self .metadata = metadata
135146
136- self .major = None
137- self .minor = None
138- self .patch = None
139147 self .parsed = None
140-
141148 self .python_versions = []
142149
150+ if not self .raw .split ('.' )[- 1 ].isnumeric ():
151+ # TODO: allow some prereleases (only the most recent one, not too old and not when an equivalent/newer stable release is available)
152+ return
153+
143154 try :
144- parsed = version .split ("." )
145- if len (parsed ) == 3 and parsed [2 ].isnumeric ():
146- self .major , self .minor , self .patch = (int (p ) for p in parsed )
147- elif len (parsed ) == 2 and parsed [1 ].isnumeric ():
148- self .major , self .minor = (int (p ) for p in parsed )
155+ self .parsed = parse_version (version )
149156 except Exception :
150- # This will fail for e.g. prereleases, but we don't care about those
151- # for now
152- # TODO: add support for some prereleases (if not too old)
157+ print (f'Failed to parse version { version } ' )
153158 pass
154159
155- self .parsed = (self .major , self .minor , self .patch or 0 )
160+ @property
161+ def major (self ):
162+ return self .parsed [0 ]
163+
164+ @property
165+ def minor (self ):
166+ return self .parsed [1 ]
167+
168+ @property
169+ def patch (self ):
170+ return self .parsed [2 ] if len (self .parsed ) == 3 else 0
156171
157172 @property
158173 def valid (self ):
159- return self .major is not None and self . minor is not None
174+ return self .parsed is not None
160175
161176 @property
162177 def rendered_python_versions (self ):
@@ -294,8 +309,7 @@ def _requires_python_to_python_versions(
294309
295310
296311def determine_python_versions (
297- pypi_data : dict ,
298- version : Optional [Version ] = None ,
312+ pypi_data : dict
299313) -> list [str ]:
300314 package = pypi_data ["info" ]["name" ]
301315
@@ -361,13 +375,16 @@ def write_tox_file(packages: dict) -> None:
361375
362376
363377if __name__ == "__main__" :
378+ print ('Finding out the lowest and highest Python version supported by the SDK...' )
364379 sentry_sdk_python_support = determine_python_versions (fetch_package ("sentry_sdk" ))
365380 LOWEST_SUPPORTED_PYTHON_VERSION = sentry_sdk_python_support [0 ]
366381 HIGHEST_SUPPORTED_PYTHON_VERSION = sentry_sdk_python_support [- 1 ]
367382 print (
368- f"The SDK supports Python versions { LOWEST_SUPPORTED_PYTHON_VERSION } to { HIGHEST_SUPPORTED_PYTHON_VERSION } . Only considering framework releases that overlap... "
383+ f"The SDK supports Python versions { LOWEST_SUPPORTED_PYTHON_VERSION } to { HIGHEST_SUPPORTED_PYTHON_VERSION } ."
369384 )
370385
386+ print (INTEGRATIONS_MIN_VERSIONS )
387+
371388 packages = defaultdict (list )
372389
373390 for group , integrations in GROUPS .items ():
@@ -386,7 +403,7 @@ def write_tox_file(packages: dict) -> None:
386403
387404 releases = get_releases (pypi_data )
388405 if not releases :
389- print ("Found no releases." )
406+ print ("Found no supported releases." )
390407 continue
391408
392409 test_releases = pick_releases_to_test (releases )
@@ -400,8 +417,7 @@ def write_tox_file(packages: dict) -> None:
400417 release_pypi_data = fetch_release (package , release )
401418 release .python_versions = pick_python_versions_to_test (
402419 determine_python_versions (
403- release_pypi_data ,
404- release ,
420+ release_pypi_data
405421 )
406422 )
407423 if not release .python_versions :
0 commit comments