Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

drop support for Python 3.8 and update dependencies #798

Merged
merged 1 commit into from
Dec 4, 2024
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
3 changes: 1 addition & 2 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,14 @@ jobs:
- MacOS
- Windows
python-version:
- "3.8"
- "3.9"
- "3.10"
- "3.11"
- "3.12"
- "3.13"
include:
- os: Ubuntu
python-version: pypy-3.8
python-version: pypy-3.10
fail-fast: false
defaults:
run:
Expand Down
971 changes: 511 additions & 460 deletions poetry.lock

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ include = [
"Bug Tracker" = "https://github.com/python-poetry/poetry/issues"

[tool.poetry.dependencies]
python = "^3.8"
python = "^3.9"

[tool.poetry.group.dev.dependencies]
pre-commit = ">=2.15.0"
Expand Down Expand Up @@ -51,7 +51,7 @@ extend-exclude = [
fix = true
line-length = 88
src = ["src"]
target-version = "py38"
target-version = "py39"

[tool.ruff.lint]
extend-select = [
Expand Down
48 changes: 27 additions & 21 deletions src/poetry/core/_vendor/fastjsonschema/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,20 +42,22 @@
.. code-block:: bash

$ make performance
fast_compiled valid ==> 0.0464646
fast_compiled invalid ==> 0.0030227
fast_file valid ==> 0.0461219
fast_file invalid ==> 0.0030608
fast_not_compiled valid ==> 11.4627202
fast_not_compiled invalid ==> 2.5726230
jsonschema valid ==> 7.5844927
jsonschema invalid ==> 1.9204665
jsonschema_compiled valid ==> 0.6938364
jsonschema_compiled invalid ==> 0.0359244
jsonspec valid ==> 9.0715843
jsonspec invalid ==> 2.1650488
validictory valid ==> 0.4874793
validictory invalid ==> 0.0232244
fast_compiled valid ==> 0.0993900
fast_compiled invalid ==> 0.0041089
fast_compiled_without_exc valid ==> 0.0465258
fast_compiled_without_exc invalid ==> 0.0023688
fast_file valid ==> 0.0989483
fast_file invalid ==> 0.0041104
fast_not_compiled valid ==> 11.9572681
fast_not_compiled invalid ==> 2.9512092
jsonschema valid ==> 5.2233240
jsonschema invalid ==> 1.3227916
jsonschema_compiled valid ==> 0.4447982
jsonschema_compiled invalid ==> 0.0231333
jsonspec valid ==> 4.1450569
jsonspec invalid ==> 1.0485777
validictory valid ==> 0.2730411
validictory invalid ==> 0.0183669

This library follows and implements `JSON schema draft-04, draft-06, and draft-07
<http://json-schema.org>`_. Sometimes it's not perfectly clear, so I recommend also
Expand Down Expand Up @@ -123,7 +125,7 @@
)


def validate(definition, data, handlers={}, formats={}, use_default=True, use_formats=True):
def validate(definition, data, handlers={}, formats={}, use_default=True, use_formats=True, detailed_exceptions=True):
"""
Validation function for lazy programmers or for use cases when you need
to call validation only once, so you do not have to compile it first.
Expand All @@ -139,12 +141,12 @@ def validate(definition, data, handlers={}, formats={}, use_default=True, use_fo

Preferred is to use :any:`compile` function.
"""
return compile(definition, handlers, formats, use_default, use_formats)(data)
return compile(definition, handlers, formats, use_default, use_formats, detailed_exceptions)(data)


#TODO: Change use_default to False when upgrading to version 3.
# pylint: disable=redefined-builtin,dangerous-default-value,exec-used
def compile(definition, handlers={}, formats={}, use_default=True, use_formats=True):
def compile(definition, handlers={}, formats={}, use_default=True, use_formats=True, detailed_exceptions=True):
"""
Generates validation function for validating JSON schema passed in ``definition``.
Example:
Expand Down Expand Up @@ -200,13 +202,16 @@ def compile(definition, handlers={}, formats={}, use_default=True, use_formats=T
off by passing `use_formats=False`. When disabled, custom formats are
disabled as well. (Added in 2.19.0.)

If you don't need detailed exceptions, you can turn the details off and gain
additional performance by passing `detailed_exceptions=False`.

Exception :any:`JsonSchemaDefinitionException` is raised when generating the
code fails (bad definition).

Exception :any:`JsonSchemaValueException` is raised from generated function when
validation fails (data do not follow the definition).
"""
resolver, code_generator = _factory(definition, handlers, formats, use_default, use_formats)
resolver, code_generator = _factory(definition, handlers, formats, use_default, use_formats, detailed_exceptions)
global_state = code_generator.global_state
# Do not pass local state so it can recursively call itself.
exec(code_generator.func_code, global_state)
Expand All @@ -217,7 +222,7 @@ def compile(definition, handlers={}, formats={}, use_default=True, use_formats=T


# pylint: disable=dangerous-default-value
def compile_to_code(definition, handlers={}, formats={}, use_default=True, use_formats=True):
def compile_to_code(definition, handlers={}, formats={}, use_default=True, use_formats=True, detailed_exceptions=True):
"""
Generates validation code for validating JSON schema passed in ``definition``.
Example:
Expand All @@ -240,22 +245,23 @@ def compile_to_code(definition, handlers={}, formats={}, use_default=True, use_f
Exception :any:`JsonSchemaDefinitionException` is raised when generating the
code fails (bad definition).
"""
_, code_generator = _factory(definition, handlers, formats, use_default, use_formats)
_, code_generator = _factory(definition, handlers, formats, use_default, use_formats, detailed_exceptions)
return (
'VERSION = "' + VERSION + '"\n' +
code_generator.global_state_code + '\n' +
code_generator.func_code
)


def _factory(definition, handlers, formats={}, use_default=True, use_formats=True):
def _factory(definition, handlers, formats={}, use_default=True, use_formats=True, detailed_exceptions=True):
resolver = RefResolver.from_schema(definition, handlers=handlers, store={})
code_generator = _get_code_generator_class(definition)(
definition,
resolver=resolver,
formats=formats,
use_default=use_default,
use_formats=use_formats,
detailed_exceptions=detailed_exceptions,
)
return resolver, code_generator

Expand Down
27 changes: 15 additions & 12 deletions src/poetry/core/_vendor/fastjsonschema/draft04.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,15 @@ class CodeGeneratorDraft04(CodeGenerator):
# library. Some regexps are not 100% precise but good enough, fast and without dependencies.
FORMAT_REGEXS = {
'date-time': r'^\d{4}-[01]\d-[0-3]\d(t|T)[0-2]\d:[0-5]\d:[0-5]\d(?:\.\d+)?(?:[+-][0-2]\d:[0-5]\d|[+-][0-2]\d[0-5]\d|z|Z)\Z',
'email': r'^[^@]+@[^@]+\.[^@]+\Z',
'email': r'^(?!.*\.\..*@)[^@.][^@]*(?<!\.)@[^@]+\.[^@]+\Z',
'hostname': r'^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]{0,61}[A-Za-z0-9])\Z',
'ipv4': r'^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\Z',
'ipv4': r'^((25[0-5]|2[0-4][0-9]|1?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\Z',
'ipv6': r'^(?:(?:[0-9A-Fa-f]{1,4}:){6}(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|::(?:[0-9A-Fa-f]{1,4}:){5}(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(?:[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){4}(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){3}(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(?:(?:[0-9A-Fa-f]{1,4}:){,2}[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){2}(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(?:(?:[0-9A-Fa-f]{1,4}:){,3}[0-9A-Fa-f]{1,4})?::[0-9A-Fa-f]{1,4}:(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(?:(?:[0-9A-Fa-f]{1,4}:){,4}[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(?:(?:[0-9A-Fa-f]{1,4}:){,5}[0-9A-Fa-f]{1,4})?::[0-9A-Fa-f]{1,4}|(?:(?:[0-9A-Fa-f]{1,4}:){,6}[0-9A-Fa-f]{1,4})?::)\Z',
'uri': r'^\w+:(\/?\/?)[^\s]+\Z',
}

def __init__(self, definition, resolver=None, formats={}, use_default=True, use_formats=True):
super().__init__(definition, resolver)
def __init__(self, definition, resolver=None, formats={}, use_default=True, use_formats=True, detailed_exceptions=True):
super().__init__(definition, resolver, detailed_exceptions)
self._custom_formats = formats
self._use_formats = use_formats
self._use_default = use_default
Expand Down Expand Up @@ -211,8 +211,7 @@ def generate_not(self):
elif not_definition is False:
return
elif not not_definition:
with self.l('if {}:', self._variable):
self.exc('{name} must NOT match a disallowed definition', rule='not')
self.exc('{name} must NOT match a disallowed definition', rule='not')
else:
with self.l('try:', optimize=False):
self.generate_func_code_block(not_definition, self._variable, self._variable_name)
Expand All @@ -223,15 +222,15 @@ def generate_not(self):
def generate_min_length(self):
with self.l('if isinstance({variable}, str):'):
self.create_variable_with_length()
if not isinstance(self._definition['minLength'], int):
if not isinstance(self._definition['minLength'], (int, float)):
raise JsonSchemaDefinitionException('minLength must be a number')
with self.l('if {variable}_len < {minLength}:'):
self.exc('{name} must be longer than or equal to {minLength} characters', rule='minLength')

def generate_max_length(self):
with self.l('if isinstance({variable}, str):'):
self.create_variable_with_length()
if not isinstance(self._definition['maxLength'], int):
if not isinstance(self._definition['maxLength'], (int, float)):
raise JsonSchemaDefinitionException('maxLength must be a number')
with self.l('if {variable}_len > {maxLength}:'):
self.exc('{name} must be shorter than or equal to {maxLength} characters', rule='maxLength')
Expand Down Expand Up @@ -272,6 +271,7 @@ def generate_format(self):
self._generate_format(format_, format_ + '_re_pattern', format_regex)
# Format regex is used only in meta schemas.
elif format_ == 'regex':
self._extra_imports_lines = ['import re']
with self.l('try:', optimize=False):
self.l('re.compile({variable})')
with self.l('except Exception:'):
Expand Down Expand Up @@ -321,11 +321,14 @@ def generate_multiple_of(self):
self.l('quotient = {variable} / {multipleOf}')
with self.l('if int(quotient) != quotient:'):
self.exc('{name} must be multiple of {multipleOf}', rule='multipleOf')
# For example, 1e308 / 0.123456789
with self.l('if {variable} / {multipleOf} == float("inf"):'):
self.exc('inifinity reached', rule='multipleOf')

def generate_min_items(self):
self.create_variable_is_list()
with self.l('if {variable}_is_list:'):
if not isinstance(self._definition['minItems'], int):
if not isinstance(self._definition['minItems'], (int, float)):
raise JsonSchemaDefinitionException('minItems must be a number')
self.create_variable_with_length()
with self.l('if {variable}_len < {minItems}:'):
Expand All @@ -334,7 +337,7 @@ def generate_min_items(self):
def generate_max_items(self):
self.create_variable_is_list()
with self.l('if {variable}_is_list:'):
if not isinstance(self._definition['maxItems'], int):
if not isinstance(self._definition['maxItems'], (int, float)):
raise JsonSchemaDefinitionException('maxItems must be a number')
self.create_variable_with_length()
with self.l('if {variable}_len > {maxItems}:'):
Expand Down Expand Up @@ -440,7 +443,7 @@ def generate_items(self):
def generate_min_properties(self):
self.create_variable_is_dict()
with self.l('if {variable}_is_dict:'):
if not isinstance(self._definition['minProperties'], int):
if not isinstance(self._definition['minProperties'], (int, float)):
raise JsonSchemaDefinitionException('minProperties must be a number')
self.create_variable_with_length()
with self.l('if {variable}_len < {minProperties}:'):
Expand All @@ -449,7 +452,7 @@ def generate_min_properties(self):
def generate_max_properties(self):
self.create_variable_is_dict()
with self.l('if {variable}_is_dict:'):
if not isinstance(self._definition['maxProperties'], int):
if not isinstance(self._definition['maxProperties'], (int, float)):
raise JsonSchemaDefinitionException('maxProperties must be a number')
self.create_variable_with_length()
with self.l('if {variable}_len > {maxProperties}:'):
Expand Down
4 changes: 2 additions & 2 deletions src/poetry/core/_vendor/fastjsonschema/draft06.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ class CodeGeneratorDraft06(CodeGeneratorDraft04):
),
})

def __init__(self, definition, resolver=None, formats={}, use_default=True, use_formats=True):
super().__init__(definition, resolver, formats, use_default, use_formats)
def __init__(self, definition, resolver=None, formats={}, use_default=True, use_formats=True, detailed_exceptions=True):
super().__init__(definition, resolver, formats, use_default, use_formats, detailed_exceptions)
self._json_keywords_to_function.update((
('exclusiveMinimum', self.generate_exclusive_minimum),
('exclusiveMaximum', self.generate_exclusive_maximum),
Expand Down
8 changes: 4 additions & 4 deletions src/poetry/core/_vendor/fastjsonschema/draft07.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@

class CodeGeneratorDraft07(CodeGeneratorDraft06):
FORMAT_REGEXS = dict(CodeGeneratorDraft06.FORMAT_REGEXS, **{
'date': r'^(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})\Z',
'date': r'^(?P<year>\d{4})-(?P<month>(0[1-9]|1[0-2]))-(?P<day>(0[1-9]|[12]\d|3[01]))\Z',
'iri': r'^\w+:(\/?\/?)[^\s]+\Z',
'iri-reference': r'^(\w+:(\/?\/?))?[^#\\\s]*(#[^\\\s]*)?\Z',
'idn-email': r'^[^@]+@[^@]+\.[^@]+\Z',
#'idn-hostname': r'',
'idn-hostname': r'^(?!-)(xn--)?[a-zA-Z0-9][a-zA-Z0-9-_]{0,61}[a-zA-Z0-9]{0,1}\.(?!-)(xn--)?([a-zA-Z0-9\-]{1,50}|[a-zA-Z0-9-]{1,30}\.[a-zA-Z]{2,})$',
'relative-json-pointer': r'^(?:0|[1-9][0-9]*)(?:#|(?:\/(?:[^~/]|~0|~1)*)*)\Z',
#'regex': r'',
'time': (
Expand All @@ -17,8 +17,8 @@ class CodeGeneratorDraft07(CodeGeneratorDraft06):
),
})

def __init__(self, definition, resolver=None, formats={}, use_default=True, use_formats=True):
super().__init__(definition, resolver, formats, use_default, use_formats)
def __init__(self, definition, resolver=None, formats={}, use_default=True, use_formats=True, detailed_exceptions=True):
super().__init__(definition, resolver, formats, use_default, use_formats, detailed_exceptions)
# pylint: disable=duplicate-code
self._json_keywords_to_function.update((
('if', self.generate_if_then_else),
Expand Down
7 changes: 6 additions & 1 deletion src/poetry/core/_vendor/fastjsonschema/generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,11 @@ class CodeGenerator:

INDENT = 4 # spaces

def __init__(self, definition, resolver=None):
def __init__(self, definition, resolver=None, detailed_exceptions=True):
self._code = []
self._compile_regexps = {}
self._custom_formats = {}
self._detailed_exceptions = detailed_exceptions

# Any extra library should be here to be imported only once.
# Lines are imports to be printed in the file and objects
Expand Down Expand Up @@ -266,6 +267,10 @@ def exc(self, msg, *args, append_to_msg=None, rule=None):
"""
Short-cut for creating raising exception in the code.
"""
if not self._detailed_exceptions:
self.l('raise JsonSchemaValueException("'+msg+'")', *args)
return

arg = '"'+msg+'"'
if append_to_msg:
arg += ' + (' + append_to_msg + ')'
Expand Down
2 changes: 2 additions & 0 deletions src/poetry/core/_vendor/fastjsonschema/ref_resolver.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ def resolve_remote(uri, handlers):
result = json.loads(req.read().decode(encoding),)
except ValueError as exc:
raise JsonSchemaDefinitionException('{} failed to decode: {}'.format(uri, exc))
finally:
req.close()
return result


Expand Down
2 changes: 1 addition & 1 deletion src/poetry/core/_vendor/fastjsonschema/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
VERSION = '2.20.0'
VERSION = '2.21.1'
2 changes: 1 addition & 1 deletion src/poetry/core/_vendor/lark/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from .utils import logger
from .visitors import Discard, Transformer, Transformer_NonRecursive, Visitor, v_args

__version__: str = "1.1.9"
__version__: str = "1.2.2"

__all__ = (
"GrammarError",
Expand Down
5 changes: 1 addition & 4 deletions src/poetry/core/_vendor/lark/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,7 @@
from .lexer import Lexer
from .grammar import Rule
from typing import Union, Type
if sys.version_info >= (3, 8):
from typing import Literal
else:
from typing_extensions import Literal
from typing import Literal
if sys.version_info >= (3, 10):
from typing import TypeAlias
else:
Expand Down
Loading
Loading