|
18 | 18 | import re |
19 | 19 |
|
20 | 20 | from packaging import markers |
21 | | -from packaging import specifiers |
22 | 21 |
|
23 | 22 | from openstack_requirements import project |
24 | 23 | from openstack_requirements import requirement |
@@ -303,130 +302,3 @@ def validate( |
303 | 302 | ) |
304 | 303 |
|
305 | 304 | return failed |
306 | | - |
307 | | - |
308 | | -def _find_constraint(req, constraints): |
309 | | - """Return the constraint matching the markers for req. |
310 | | -
|
311 | | - Given a requirement, find the constraint with matching markers. |
312 | | - If none match, find a constraint without any markers at all. |
313 | | - Otherwise return None. |
314 | | - """ |
315 | | - if req.markers: |
316 | | - req_markers = markers.Marker(req.markers) |
317 | | - for constraint_setting, _ in constraints: |
318 | | - if constraint_setting.markers == req.markers: |
319 | | - return constraint_setting |
320 | | - if not constraint_setting.markers: |
321 | | - # There is no point in performing the complex |
322 | | - # comparison for a constraint that has no markers, so |
323 | | - # we skip it here. If we find no closer match then the |
324 | | - # loop at the end of the function will look for a |
325 | | - # constraint without a marker and use that. |
326 | | - continue |
327 | | - # NOTE(dhellmann): This is a very naive attempt to check |
328 | | - # marker compatibility that relies on internal |
329 | | - # implementation details of the packaging library. The |
330 | | - # best way to ensure the constraint and requirements match |
331 | | - # is to use the same marker string in the corresponding |
332 | | - # lines. |
333 | | - c_markers = markers.Marker(constraint_setting.markers) |
334 | | - env = { |
335 | | - str(var): str(val) |
336 | | - for var, op, val in c_markers._markers # WARNING: internals |
337 | | - } |
338 | | - if req_markers.evaluate(env): |
339 | | - return constraint_setting |
340 | | - # Try looking for a constraint without any markers. |
341 | | - for constraint_setting, _ in constraints: |
342 | | - if not constraint_setting.markers: |
343 | | - return constraint_setting |
344 | | - return None |
345 | | - |
346 | | - |
347 | | -def validate_lower_constraints(req_list, constraints, denylist): |
348 | | - """Return True if there is an error. |
349 | | -
|
350 | | - :param reqs: RequirementsList for the head of the branch |
351 | | - :param constraints: Parsed lower-constraints.txt or None |
352 | | -
|
353 | | - """ |
354 | | - if constraints is None: |
355 | | - return False |
356 | | - |
357 | | - parsed_constraints = requirement.parse(constraints) |
358 | | - |
359 | | - failed = False |
360 | | - |
361 | | - for fname, freqs in req_list.reqs_by_file.items(): |
362 | | - |
363 | | - if fname == 'doc/requirements.txt': |
364 | | - # Skip things that are not needed for unit or functional |
365 | | - # tests. |
366 | | - continue |
367 | | - |
368 | | - print("Validating lower constraints of {}".format(fname)) |
369 | | - |
370 | | - for name, reqs in freqs.items(): |
371 | | - |
372 | | - if name in denylist: |
373 | | - continue |
374 | | - |
375 | | - if name not in parsed_constraints: |
376 | | - print('ERROR: Package {!r} is used in {} ' |
377 | | - 'but not in lower-constraints.txt'.format( |
378 | | - name, fname)) |
379 | | - failed = True |
380 | | - continue |
381 | | - |
382 | | - for req in reqs: |
383 | | - spec = specifiers.SpecifierSet(req.specifiers) |
384 | | - # FIXME(dhellmann): This will only find constraints |
385 | | - # where the markers match the requirements list |
386 | | - # exactly, so we can't do things like use different |
387 | | - # constrained versions for different versions of |
388 | | - # python 3 if the requirement range is expressed as |
389 | | - # python_version>3.0. We can support different |
390 | | - # versions if there is a different requirement |
391 | | - # specification for each version of python. I don't |
392 | | - # really know how smart we want this to be, because |
393 | | - # I'm not sure we want to support extremely |
394 | | - # complicated dependency sets. |
395 | | - constraint_setting = _find_constraint( |
396 | | - req, |
397 | | - parsed_constraints[name], |
398 | | - ) |
399 | | - if not constraint_setting: |
400 | | - print('ERROR: Unable to find constraint for {} ' |
401 | | - 'matching {!r} or without any markers.'.format( |
402 | | - name, req.markers)) |
403 | | - failed = True |
404 | | - continue |
405 | | - |
406 | | - version = constraint_setting.specifiers.lstrip('=') |
407 | | - |
408 | | - if not spec.contains(version): |
409 | | - print('ERROR: Package {!r} is constrained to {} ' |
410 | | - 'which is incompatible with the settings {} ' |
411 | | - 'from {}.'.format( |
412 | | - name, version, req, fname)) |
413 | | - failed = True |
414 | | - |
415 | | - min = [ |
416 | | - s |
417 | | - for s in req.specifiers.split(',') |
418 | | - if '>' in s |
419 | | - ] |
420 | | - if not min: |
421 | | - # No minimum specified. Ignore this and let some |
422 | | - # other validation trap the error. |
423 | | - continue |
424 | | - |
425 | | - expected = min[0].lstrip('>=') |
426 | | - if version != expected: |
427 | | - print('ERROR: Package {!r} is constrained to {} ' |
428 | | - 'which does not match ' |
429 | | - 'the minimum version specifier {} in {}'.format( |
430 | | - name, version, expected, fname)) |
431 | | - failed = True |
432 | | - return failed |
0 commit comments