diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index e019e146d..04693dd52 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -20,7 +20,6 @@ jobs: - MacOS - Windows python-version: - - "3.9" - "3.10" - "3.11" - "3.12" diff --git a/poetry.lock b/poetry.lock index 7a693d3d9..8892fdcb8 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 2.1.4 and should not be changed by hand. +# This file is automatically @generated by Poetry 2.2.1 and should not be changed by hand. [[package]] name = "attrs" @@ -307,7 +307,7 @@ description = "Backport of PEP 654 (exception groups)" optional = false python-versions = ">=3.7" groups = ["test"] -markers = "python_version < \"3.11\"" +markers = "python_version == \"3.10\"" files = [ {file = "exceptiongroup-1.3.0-py3-none-any.whl", hash = "sha256:4d111e6e0c13d0644cad6ddaa7ed0261a0b36971f6d23e7ec9b4b9097da78a10"}, {file = "exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88"}, @@ -1082,7 +1082,7 @@ files = [ {file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"}, {file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"}, ] -markers = {test = "python_full_version <= \"3.11.0a6\"", typing = "python_version < \"3.11\""} +markers = {test = "python_full_version <= \"3.11.0a6\"", typing = "python_version == \"3.10\""} [[package]] name = "tomli-w" @@ -1131,7 +1131,7 @@ files = [ {file = "typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548"}, {file = "typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466"}, ] -markers = {dev = "python_version < \"3.13\"", test = "python_version < \"3.11\""} +markers = {dev = "python_version < \"3.13\"", test = "python_version == \"3.10\""} [[package]] name = "urllib3" @@ -1220,5 +1220,5 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.1" -python-versions = ">=3.9, <4.0" -content-hash = "b85df75947dc8c45d16bd84ac4d75bb62321a6e9a2731ce68c1076718144b0ee" +python-versions = ">=3.10, <4.0" +content-hash = "437e649b0f66ac351ed6f434aff1a4ed3b27bc8ef0ab859775734d9b548e2ca8" diff --git a/pyproject.toml b/pyproject.toml index 0aada3ebb..01b665a50 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,7 +15,7 @@ maintainers = [ { name = "Bartosz Sokorski", email = "b.sokorski@gmail.com" }, ] license = "MIT" -requires-python = ">=3.9, <4.0" +requires-python = ">=3.10, <4.0" readme = "README.md" keywords = ["packaging", "dependency", "poetry"] dynamic = ["classifiers"] @@ -64,7 +64,6 @@ extend-exclude = [ fix = true line-length = 88 src = ["src"] -target-version = "py39" [tool.ruff.lint] extend-select = [ diff --git a/src/poetry/core/_vendor/lark/LICENSE b/src/poetry/core/_vendor/lark/LICENSE index 9201da2ed..aaf210b1d 100644 --- a/src/poetry/core/_vendor/lark/LICENSE +++ b/src/poetry/core/_vendor/lark/LICENSE @@ -1,18 +1,18 @@ -Copyright © 2017 Erez Shinan - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +Copyright © 2017 Erez Shinan + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/src/poetry/core/_vendor/lark/grammars/common.lark b/src/poetry/core/_vendor/lark/grammars/common.lark index e15b163f7..d2e86d17c 100644 --- a/src/poetry/core/_vendor/lark/grammars/common.lark +++ b/src/poetry/core/_vendor/lark/grammars/common.lark @@ -1,59 +1,59 @@ -// Basic terminals for common use - - -// -// Numbers -// - -DIGIT: "0".."9" -HEXDIGIT: "a".."f"|"A".."F"|DIGIT - -INT: DIGIT+ -SIGNED_INT: ["+"|"-"] INT -DECIMAL: INT "." INT? | "." INT - -// float = /-?\d+(\.\d+)?([eE][+-]?\d+)?/ -_EXP: ("e"|"E") SIGNED_INT -FLOAT: INT _EXP | DECIMAL _EXP? -SIGNED_FLOAT: ["+"|"-"] FLOAT - -NUMBER: FLOAT | INT -SIGNED_NUMBER: ["+"|"-"] NUMBER - -// -// Strings -// -_STRING_INNER: /.*?/ -_STRING_ESC_INNER: _STRING_INNER /(? ignore - | "%import" import_path ["->" name] -> import - | "%import" import_path name_list -> multi_import - | "%override" rule -> override_rule - | "%declare" name+ -> declare - -!import_path: "."? name ("." name)* -name_list: "(" name ("," name)* ")" - -?expansions: alias (_VBAR alias)* - -?alias: expansion ["->" RULE] - -?expansion: expr* - -?expr: atom [OP | "~" NUMBER [".." NUMBER]] - -?atom: "(" expansions ")" - | "[" expansions "]" -> maybe - | value - -?value: STRING ".." STRING -> literal_range - | name - | (REGEXP | STRING) -> literal - | name "{" value ("," value)* "}" -> template_usage - -name: RULE - | TOKEN - -_VBAR: _NL? "|" -OP: /[+*]|[?](?![a-z])/ -RULE: /!?[_?]?[a-z][_a-z0-9]*/ -TOKEN: /_?[A-Z][_A-Z0-9]*/ -STRING: _STRING "i"? -REGEXP: /\/(?!\/)(\\\/|\\\\|[^\/])*?\/[imslux]*/ -_NL: /(\r?\n)+\s*/ - -%import common.ESCAPED_STRING -> _STRING -%import common.SIGNED_INT -> NUMBER -%import common.WS_INLINE - -COMMENT: /\s*/ "//" /[^\n]/* | /\s*/ "#" /[^\n]/* - -%ignore WS_INLINE -%ignore COMMENT +# Lark grammar of Lark's syntax +# Note: Lark is not bootstrapped, its parser is implemented in load_grammar.py + +start: (_item? _NL)* _item? + +_item: rule + | token + | statement + +rule: RULE rule_params priority? ":" expansions +token: TOKEN token_params priority? ":" expansions + +rule_params: ["{" RULE ("," RULE)* "}"] +token_params: ["{" TOKEN ("," TOKEN)* "}"] + +priority: "." NUMBER + +statement: "%ignore" expansions -> ignore + | "%import" import_path ["->" name] -> import + | "%import" import_path name_list -> multi_import + | "%override" rule -> override_rule + | "%declare" name+ -> declare + +!import_path: "."? name ("." name)* +name_list: "(" name ("," name)* ")" + +?expansions: alias (_VBAR alias)* + +?alias: expansion ["->" RULE] + +?expansion: expr* + +?expr: atom [OP | "~" NUMBER [".." NUMBER]] + +?atom: "(" expansions ")" + | "[" expansions "]" -> maybe + | value + +?value: STRING ".." STRING -> literal_range + | name + | (REGEXP | STRING) -> literal + | name "{" value ("," value)* "}" -> template_usage + +name: RULE + | TOKEN + +_VBAR: _NL? "|" +OP: /[+*]|[?](?![a-z])/ +RULE: /!?[_?]?[a-z][_a-z0-9]*/ +TOKEN: /_?[A-Z][_A-Z0-9]*/ +STRING: _STRING "i"? +REGEXP: /\/(?!\/)(\\\/|\\\\|[^\/])*?\/[imslux]*/ +_NL: /(\r?\n)+\s*/ + +%import common.ESCAPED_STRING -> _STRING +%import common.SIGNED_INT -> NUMBER +%import common.WS_INLINE + +COMMENT: /\s*/ "//" /[^\n]/* | /\s*/ "#" /[^\n]/* + +%ignore WS_INLINE +%ignore COMMENT diff --git a/src/poetry/core/_vendor/lark/grammars/python.lark b/src/poetry/core/_vendor/lark/grammars/python.lark index 70ffad7e3..8a75966b2 100644 --- a/src/poetry/core/_vendor/lark/grammars/python.lark +++ b/src/poetry/core/_vendor/lark/grammars/python.lark @@ -1,302 +1,302 @@ -// Python 3 grammar for Lark - -// This grammar should parse all python 3.x code successfully. - -// Adapted from: https://docs.python.org/3/reference/grammar.html - -// Start symbols for the grammar: -// single_input is a single interactive statement; -// file_input is a module or sequence of commands read from an input file; -// eval_input is the input for the eval() functions. -// NB: compound_stmt in single_input is followed by extra NEWLINE! -// - -single_input: _NEWLINE | simple_stmt | compound_stmt _NEWLINE -file_input: (_NEWLINE | stmt)* -eval_input: testlist _NEWLINE* - -decorator: "@" dotted_name [ "(" [arguments] ")" ] _NEWLINE -decorators: decorator+ -decorated: decorators (classdef | funcdef | async_funcdef) - -async_funcdef: "async" funcdef -funcdef: "def" name "(" [parameters] ")" ["->" test] ":" suite - -parameters: paramvalue ("," paramvalue)* ["," SLASH ("," paramvalue)*] ["," [starparams | kwparams]] - | starparams - | kwparams - -SLASH: "/" // Otherwise the it will completely disappear and it will be undisguisable in the result -starparams: (starparam | starguard) poststarparams -starparam: "*" typedparam -starguard: "*" -poststarparams: ("," paramvalue)* ["," kwparams] -kwparams: "**" typedparam ","? - -?paramvalue: typedparam ("=" test)? -?typedparam: name (":" test)? - - -lambdef: "lambda" [lambda_params] ":" test -lambdef_nocond: "lambda" [lambda_params] ":" test_nocond -lambda_params: lambda_paramvalue ("," lambda_paramvalue)* ["," [lambda_starparams | lambda_kwparams]] - | lambda_starparams - | lambda_kwparams -?lambda_paramvalue: name ("=" test)? -lambda_starparams: "*" [name] ("," lambda_paramvalue)* ["," [lambda_kwparams]] -lambda_kwparams: "**" name ","? - - -?stmt: simple_stmt | compound_stmt -?simple_stmt: small_stmt (";" small_stmt)* [";"] _NEWLINE -?small_stmt: (expr_stmt | assign_stmt | del_stmt | pass_stmt | flow_stmt | import_stmt | global_stmt | nonlocal_stmt | assert_stmt) -expr_stmt: testlist_star_expr -assign_stmt: annassign | augassign | assign - -annassign: testlist_star_expr ":" test ["=" test] -assign: testlist_star_expr ("=" (yield_expr|testlist_star_expr))+ -augassign: testlist_star_expr augassign_op (yield_expr|testlist) -!augassign_op: "+=" | "-=" | "*=" | "@=" | "/=" | "%=" | "&=" | "|=" | "^=" | "<<=" | ">>=" | "**=" | "//=" -?testlist_star_expr: test_or_star_expr - | test_or_star_expr ("," test_or_star_expr)+ ","? -> tuple - | test_or_star_expr "," -> tuple - -// For normal and annotated assignments, additional restrictions enforced by the interpreter -del_stmt: "del" exprlist -pass_stmt: "pass" -?flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | yield_stmt -break_stmt: "break" -continue_stmt: "continue" -return_stmt: "return" [testlist] -yield_stmt: yield_expr -raise_stmt: "raise" [test ["from" test]] -import_stmt: import_name | import_from -import_name: "import" dotted_as_names -// note below: the ("." | "...") is necessary because "..." is tokenized as ELLIPSIS -import_from: "from" (dots? dotted_name | dots) "import" ("*" | "(" import_as_names ")" | import_as_names) -!dots: "."+ -import_as_name: name ["as" name] -dotted_as_name: dotted_name ["as" name] -import_as_names: import_as_name ("," import_as_name)* [","] -dotted_as_names: dotted_as_name ("," dotted_as_name)* -dotted_name: name ("." name)* -global_stmt: "global" name ("," name)* -nonlocal_stmt: "nonlocal" name ("," name)* -assert_stmt: "assert" test ["," test] - -?compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | match_stmt - | with_stmt | funcdef | classdef | decorated | async_stmt -async_stmt: "async" (funcdef | with_stmt | for_stmt) -if_stmt: "if" test ":" suite elifs ["else" ":" suite] -elifs: elif_* -elif_: "elif" test ":" suite -while_stmt: "while" test ":" suite ["else" ":" suite] -for_stmt: "for" exprlist "in" testlist ":" suite ["else" ":" suite] -try_stmt: "try" ":" suite except_clauses ["else" ":" suite] [finally] - | "try" ":" suite finally -> try_finally -finally: "finally" ":" suite -except_clauses: except_clause+ -except_clause: "except" [test ["as" name]] ":" suite -// NB compile.c makes sure that the default except clause is last - - -with_stmt: "with" with_items ":" suite -with_items: with_item ("," with_item)* -with_item: test ["as" name] - -match_stmt: "match" test ":" _NEWLINE _INDENT case+ _DEDENT - -case: "case" pattern ["if" test] ":" suite - -?pattern: sequence_item_pattern "," _sequence_pattern -> sequence_pattern - | as_pattern -?as_pattern: or_pattern ("as" NAME)? -?or_pattern: closed_pattern ("|" closed_pattern)* -?closed_pattern: literal_pattern - | NAME -> capture_pattern - | "_" -> any_pattern - | attr_pattern - | "(" as_pattern ")" - | "[" _sequence_pattern "]" -> sequence_pattern - | "(" (sequence_item_pattern "," _sequence_pattern)? ")" -> sequence_pattern - | "{" (mapping_item_pattern ("," mapping_item_pattern)* ","?)?"}" -> mapping_pattern - | "{" (mapping_item_pattern ("," mapping_item_pattern)* ",")? "**" NAME ","? "}" -> mapping_star_pattern - | class_pattern - -literal_pattern: inner_literal_pattern - -?inner_literal_pattern: "None" -> const_none - | "True" -> const_true - | "False" -> const_false - | STRING -> string - | number - -attr_pattern: NAME ("." NAME)+ -> value - -name_or_attr_pattern: NAME ("." NAME)* -> value - -mapping_item_pattern: (literal_pattern|attr_pattern) ":" as_pattern - -_sequence_pattern: (sequence_item_pattern ("," sequence_item_pattern)* ","?)? -?sequence_item_pattern: as_pattern - | "*" NAME -> star_pattern - -class_pattern: name_or_attr_pattern "(" [arguments_pattern ","?] ")" -arguments_pattern: pos_arg_pattern ["," keyws_arg_pattern] - | keyws_arg_pattern -> no_pos_arguments - -pos_arg_pattern: as_pattern ("," as_pattern)* -keyws_arg_pattern: keyw_arg_pattern ("," keyw_arg_pattern)* -keyw_arg_pattern: NAME "=" as_pattern - - - -suite: simple_stmt | _NEWLINE _INDENT stmt+ _DEDENT - -?test: or_test ("if" or_test "else" test)? - | lambdef - | assign_expr - -assign_expr: name ":=" test - -?test_nocond: or_test | lambdef_nocond - -?or_test: and_test ("or" and_test)* -?and_test: not_test_ ("and" not_test_)* -?not_test_: "not" not_test_ -> not_test - | comparison -?comparison: expr (comp_op expr)* -star_expr: "*" expr - -?expr: or_expr -?or_expr: xor_expr ("|" xor_expr)* -?xor_expr: and_expr ("^" and_expr)* -?and_expr: shift_expr ("&" shift_expr)* -?shift_expr: arith_expr (_shift_op arith_expr)* -?arith_expr: term (_add_op term)* -?term: factor (_mul_op factor)* -?factor: _unary_op factor | power - -!_unary_op: "+"|"-"|"~" -!_add_op: "+"|"-" -!_shift_op: "<<"|">>" -!_mul_op: "*"|"@"|"/"|"%"|"//" -// <> isn't actually a valid comparison operator in Python. It's here for the -// sake of a __future__ import described in PEP 401 (which really works :-) -!comp_op: "<"|">"|"=="|">="|"<="|"<>"|"!="|"in"|"not" "in"|"is"|"is" "not" - -?power: await_expr ("**" factor)? -?await_expr: AWAIT? atom_expr -AWAIT: "await" - -?atom_expr: atom_expr "(" [arguments] ")" -> funccall - | atom_expr "[" subscriptlist "]" -> getitem - | atom_expr "." name -> getattr - | atom - -?atom: "(" yield_expr ")" - | "(" _tuple_inner? ")" -> tuple - | "(" comprehension{test_or_star_expr} ")" -> tuple_comprehension - | "[" _exprlist? "]" -> list - | "[" comprehension{test_or_star_expr} "]" -> list_comprehension - | "{" _dict_exprlist? "}" -> dict - | "{" comprehension{key_value} "}" -> dict_comprehension - | "{" _exprlist "}" -> set - | "{" comprehension{test} "}" -> set_comprehension - | name -> var - | number - | string_concat - | "(" test ")" - | "..." -> ellipsis - | "None" -> const_none - | "True" -> const_true - | "False" -> const_false - - -?string_concat: string+ - -_tuple_inner: test_or_star_expr (("," test_or_star_expr)+ [","] | ",") - -?test_or_star_expr: test - | star_expr - -?subscriptlist: subscript - | subscript (("," subscript)+ [","] | ",") -> subscript_tuple -?subscript: test | ([test] ":" [test] [sliceop]) -> slice -sliceop: ":" [test] -?exprlist: (expr|star_expr) - | (expr|star_expr) (("," (expr|star_expr))+ [","]|",") -?testlist: test | testlist_tuple -testlist_tuple: test (("," test)+ [","] | ",") -_dict_exprlist: (key_value | "**" expr) ("," (key_value | "**" expr))* [","] - -key_value: test ":" test - -_exprlist: test_or_star_expr ("," test_or_star_expr)* [","] - -classdef: "class" name ["(" [arguments] ")"] ":" suite - - - -arguments: argvalue ("," argvalue)* ("," [ starargs | kwargs])? - | starargs - | kwargs - | comprehension{test} - -starargs: stararg ("," stararg)* ("," argvalue)* ["," kwargs] -stararg: "*" test -kwargs: "**" test ("," argvalue)* - -?argvalue: test ("=" test)? - - -comprehension{comp_result}: comp_result comp_fors [comp_if] -comp_fors: comp_for+ -comp_for: [ASYNC] "for" exprlist "in" or_test -ASYNC: "async" -?comp_if: "if" test_nocond - -// not used in grammar, but may appear in "node" passed from Parser to Compiler -encoding_decl: name - -yield_expr: "yield" [testlist] - | "yield" "from" test -> yield_from - -number: DEC_NUMBER | HEX_NUMBER | BIN_NUMBER | OCT_NUMBER | FLOAT_NUMBER | IMAG_NUMBER -string: STRING | LONG_STRING - -// Other terminals - -_NEWLINE: ( /\r?\n[\t ]*/ | COMMENT )+ - -%ignore /[\t \f]+/ // WS -%ignore /\\[\t \f]*\r?\n/ // LINE_CONT -%ignore COMMENT -%declare _INDENT _DEDENT - - -// Python terminals - -!name: NAME | "match" | "case" -NAME: /[^\W\d]\w*/ -COMMENT: /#[^\n]*/ - -STRING: /([ubf]?r?|r[ubf])("(?!"").*?(?" test] ":" suite + +parameters: paramvalue ("," paramvalue)* ["," SLASH ("," paramvalue)*] ["," [starparams | kwparams]] + | starparams + | kwparams + +SLASH: "/" // Otherwise the it will completely disappear and it will be undisguisable in the result +starparams: (starparam | starguard) poststarparams +starparam: "*" typedparam +starguard: "*" +poststarparams: ("," paramvalue)* ["," kwparams] +kwparams: "**" typedparam ","? + +?paramvalue: typedparam ("=" test)? +?typedparam: name (":" test)? + + +lambdef: "lambda" [lambda_params] ":" test +lambdef_nocond: "lambda" [lambda_params] ":" test_nocond +lambda_params: lambda_paramvalue ("," lambda_paramvalue)* ["," [lambda_starparams | lambda_kwparams]] + | lambda_starparams + | lambda_kwparams +?lambda_paramvalue: name ("=" test)? +lambda_starparams: "*" [name] ("," lambda_paramvalue)* ["," [lambda_kwparams]] +lambda_kwparams: "**" name ","? + + +?stmt: simple_stmt | compound_stmt +?simple_stmt: small_stmt (";" small_stmt)* [";"] _NEWLINE +?small_stmt: (expr_stmt | assign_stmt | del_stmt | pass_stmt | flow_stmt | import_stmt | global_stmt | nonlocal_stmt | assert_stmt) +expr_stmt: testlist_star_expr +assign_stmt: annassign | augassign | assign + +annassign: testlist_star_expr ":" test ["=" test] +assign: testlist_star_expr ("=" (yield_expr|testlist_star_expr))+ +augassign: testlist_star_expr augassign_op (yield_expr|testlist) +!augassign_op: "+=" | "-=" | "*=" | "@=" | "/=" | "%=" | "&=" | "|=" | "^=" | "<<=" | ">>=" | "**=" | "//=" +?testlist_star_expr: test_or_star_expr + | test_or_star_expr ("," test_or_star_expr)+ ","? -> tuple + | test_or_star_expr "," -> tuple + +// For normal and annotated assignments, additional restrictions enforced by the interpreter +del_stmt: "del" exprlist +pass_stmt: "pass" +?flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | yield_stmt +break_stmt: "break" +continue_stmt: "continue" +return_stmt: "return" [testlist] +yield_stmt: yield_expr +raise_stmt: "raise" [test ["from" test]] +import_stmt: import_name | import_from +import_name: "import" dotted_as_names +// note below: the ("." | "...") is necessary because "..." is tokenized as ELLIPSIS +import_from: "from" (dots? dotted_name | dots) "import" ("*" | "(" import_as_names ")" | import_as_names) +!dots: "."+ +import_as_name: name ["as" name] +dotted_as_name: dotted_name ["as" name] +import_as_names: import_as_name ("," import_as_name)* [","] +dotted_as_names: dotted_as_name ("," dotted_as_name)* +dotted_name: name ("." name)* +global_stmt: "global" name ("," name)* +nonlocal_stmt: "nonlocal" name ("," name)* +assert_stmt: "assert" test ["," test] + +?compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | match_stmt + | with_stmt | funcdef | classdef | decorated | async_stmt +async_stmt: "async" (funcdef | with_stmt | for_stmt) +if_stmt: "if" test ":" suite elifs ["else" ":" suite] +elifs: elif_* +elif_: "elif" test ":" suite +while_stmt: "while" test ":" suite ["else" ":" suite] +for_stmt: "for" exprlist "in" testlist ":" suite ["else" ":" suite] +try_stmt: "try" ":" suite except_clauses ["else" ":" suite] [finally] + | "try" ":" suite finally -> try_finally +finally: "finally" ":" suite +except_clauses: except_clause+ +except_clause: "except" [test ["as" name]] ":" suite +// NB compile.c makes sure that the default except clause is last + + +with_stmt: "with" with_items ":" suite +with_items: with_item ("," with_item)* +with_item: test ["as" name] + +match_stmt: "match" test ":" _NEWLINE _INDENT case+ _DEDENT + +case: "case" pattern ["if" test] ":" suite + +?pattern: sequence_item_pattern "," _sequence_pattern -> sequence_pattern + | as_pattern +?as_pattern: or_pattern ("as" NAME)? +?or_pattern: closed_pattern ("|" closed_pattern)* +?closed_pattern: literal_pattern + | NAME -> capture_pattern + | "_" -> any_pattern + | attr_pattern + | "(" as_pattern ")" + | "[" _sequence_pattern "]" -> sequence_pattern + | "(" (sequence_item_pattern "," _sequence_pattern)? ")" -> sequence_pattern + | "{" (mapping_item_pattern ("," mapping_item_pattern)* ","?)?"}" -> mapping_pattern + | "{" (mapping_item_pattern ("," mapping_item_pattern)* ",")? "**" NAME ","? "}" -> mapping_star_pattern + | class_pattern + +literal_pattern: inner_literal_pattern + +?inner_literal_pattern: "None" -> const_none + | "True" -> const_true + | "False" -> const_false + | STRING -> string + | number + +attr_pattern: NAME ("." NAME)+ -> value + +name_or_attr_pattern: NAME ("." NAME)* -> value + +mapping_item_pattern: (literal_pattern|attr_pattern) ":" as_pattern + +_sequence_pattern: (sequence_item_pattern ("," sequence_item_pattern)* ","?)? +?sequence_item_pattern: as_pattern + | "*" NAME -> star_pattern + +class_pattern: name_or_attr_pattern "(" [arguments_pattern ","?] ")" +arguments_pattern: pos_arg_pattern ["," keyws_arg_pattern] + | keyws_arg_pattern -> no_pos_arguments + +pos_arg_pattern: as_pattern ("," as_pattern)* +keyws_arg_pattern: keyw_arg_pattern ("," keyw_arg_pattern)* +keyw_arg_pattern: NAME "=" as_pattern + + + +suite: simple_stmt | _NEWLINE _INDENT stmt+ _DEDENT + +?test: or_test ("if" or_test "else" test)? + | lambdef + | assign_expr + +assign_expr: name ":=" test + +?test_nocond: or_test | lambdef_nocond + +?or_test: and_test ("or" and_test)* +?and_test: not_test_ ("and" not_test_)* +?not_test_: "not" not_test_ -> not_test + | comparison +?comparison: expr (comp_op expr)* +star_expr: "*" expr + +?expr: or_expr +?or_expr: xor_expr ("|" xor_expr)* +?xor_expr: and_expr ("^" and_expr)* +?and_expr: shift_expr ("&" shift_expr)* +?shift_expr: arith_expr (_shift_op arith_expr)* +?arith_expr: term (_add_op term)* +?term: factor (_mul_op factor)* +?factor: _unary_op factor | power + +!_unary_op: "+"|"-"|"~" +!_add_op: "+"|"-" +!_shift_op: "<<"|">>" +!_mul_op: "*"|"@"|"/"|"%"|"//" +// <> isn't actually a valid comparison operator in Python. It's here for the +// sake of a __future__ import described in PEP 401 (which really works :-) +!comp_op: "<"|">"|"=="|">="|"<="|"<>"|"!="|"in"|"not" "in"|"is"|"is" "not" + +?power: await_expr ("**" factor)? +?await_expr: AWAIT? atom_expr +AWAIT: "await" + +?atom_expr: atom_expr "(" [arguments] ")" -> funccall + | atom_expr "[" subscriptlist "]" -> getitem + | atom_expr "." name -> getattr + | atom + +?atom: "(" yield_expr ")" + | "(" _tuple_inner? ")" -> tuple + | "(" comprehension{test_or_star_expr} ")" -> tuple_comprehension + | "[" _exprlist? "]" -> list + | "[" comprehension{test_or_star_expr} "]" -> list_comprehension + | "{" _dict_exprlist? "}" -> dict + | "{" comprehension{key_value} "}" -> dict_comprehension + | "{" _exprlist "}" -> set + | "{" comprehension{test} "}" -> set_comprehension + | name -> var + | number + | string_concat + | "(" test ")" + | "..." -> ellipsis + | "None" -> const_none + | "True" -> const_true + | "False" -> const_false + + +?string_concat: string+ + +_tuple_inner: test_or_star_expr (("," test_or_star_expr)+ [","] | ",") + +?test_or_star_expr: test + | star_expr + +?subscriptlist: subscript + | subscript (("," subscript)+ [","] | ",") -> subscript_tuple +?subscript: test | ([test] ":" [test] [sliceop]) -> slice +sliceop: ":" [test] +?exprlist: (expr|star_expr) + | (expr|star_expr) (("," (expr|star_expr))+ [","]|",") +?testlist: test | testlist_tuple +testlist_tuple: test (("," test)+ [","] | ",") +_dict_exprlist: (key_value | "**" expr) ("," (key_value | "**" expr))* [","] + +key_value: test ":" test + +_exprlist: test_or_star_expr ("," test_or_star_expr)* [","] + +classdef: "class" name ["(" [arguments] ")"] ":" suite + + + +arguments: argvalue ("," argvalue)* ("," [ starargs | kwargs])? + | starargs + | kwargs + | comprehension{test} + +starargs: stararg ("," stararg)* ("," argvalue)* ["," kwargs] +stararg: "*" test +kwargs: "**" test ("," argvalue)* + +?argvalue: test ("=" test)? + + +comprehension{comp_result}: comp_result comp_fors [comp_if] +comp_fors: comp_for+ +comp_for: [ASYNC] "for" exprlist "in" or_test +ASYNC: "async" +?comp_if: "if" test_nocond + +// not used in grammar, but may appear in "node" passed from Parser to Compiler +encoding_decl: name + +yield_expr: "yield" [testlist] + | "yield" "from" test -> yield_from + +number: DEC_NUMBER | HEX_NUMBER | BIN_NUMBER | OCT_NUMBER | FLOAT_NUMBER | IMAG_NUMBER +string: STRING | LONG_STRING + +// Other terminals + +_NEWLINE: ( /\r?\n[\t ]*/ | COMMENT )+ + +%ignore /[\t \f]+/ // WS +%ignore /\\[\t \f]*\r?\n/ // LINE_CONT +%ignore COMMENT +%declare _INDENT _DEDENT + + +// Python terminals + +!name: NAME | "match" | "case" +NAME: /[^\W\d]\w*/ +COMMENT: /#[^\n]*/ + +STRING: /([ubf]?r?|r[ubf])("(?!"").*?(?= "3.9" -lark==1.2.2 ; python_version >= "3.9" -packaging==25.0 ; python_version >= "3.9" -tomli==2.2.1 ; python_version >= "3.9" +fastjsonschema==2.21.2 ; python_version >= "3.10" +lark==1.2.2 ; python_version >= "3.10" +packaging==25.0 ; python_version >= "3.10" +tomli==2.2.1 ; python_version >= "3.10" diff --git a/src/poetry/core/constraints/generic/constraint.py b/src/poetry/core/constraints/generic/constraint.py index ce4657a06..111ffda57 100644 --- a/src/poetry/core/constraints/generic/constraint.py +++ b/src/poetry/core/constraints/generic/constraint.py @@ -2,7 +2,7 @@ import operator -from typing import Callable +from collections.abc import Callable from typing import ClassVar from poetry.core.constraints.generic.any_constraint import AnyConstraint diff --git a/src/poetry/core/constraints/version/util.py b/src/poetry/core/constraints/version/util.py index d81d11cd1..164c005f1 100644 --- a/src/poetry/core/constraints/version/util.py +++ b/src/poetry/core/constraints/version/util.py @@ -1,5 +1,6 @@ from __future__ import annotations +from itertools import pairwise from typing import TYPE_CHECKING from poetry.core.constraints.version.version_range import VersionRange @@ -41,7 +42,7 @@ def constraint_regions(constraints: list[VersionConstraint]) -> list[VersionRang VersionRange(None, start[0], include_max=start[1]), ] - for low, high in zip(edges, edges[1:]): + for low, high in pairwise(edges): version_range = VersionRange( low[0], high[0], diff --git a/src/poetry/core/factory.py b/src/poetry/core/factory.py index d01610054..288a4f03a 100644 --- a/src/poetry/core/factory.py +++ b/src/poetry/core/factory.py @@ -9,7 +9,6 @@ from typing import TYPE_CHECKING from typing import Any from typing import Literal -from typing import Union from packaging.licenses import InvalidLicenseExpression from packaging.licenses import canonicalize_license_expression @@ -28,10 +27,8 @@ from poetry.core.poetry import Poetry from poetry.core.pyproject.toml import PyProjectTOML - DependencyConstraint = Union[str, Mapping[str, Any]] - DependencyConfig = Mapping[ - str, Union[list[DependencyConstraint], DependencyConstraint] - ] + DependencyConstraint = str | Mapping[str, Any] + DependencyConfig = Mapping[str, list[DependencyConstraint] | DependencyConstraint] logger = logging.getLogger(__name__) diff --git a/src/poetry/core/utils/helpers.py b/src/poetry/core/utils/helpers.py index d9127831b..afba58dbc 100644 --- a/src/poetry/core/utils/helpers.py +++ b/src/poetry/core/utils/helpers.py @@ -2,7 +2,6 @@ import shutil import stat -import sys import tempfile import time import unicodedata @@ -29,18 +28,11 @@ def module_name(name: str) -> str: @contextmanager def temporary_directory(*args: Any, **kwargs: Any) -> Iterator[Path]: - if sys.version_info >= (3, 10): - # mypy reports an error if ignore_cleanup_errors is - # specified literally in the call - kwargs["ignore_cleanup_errors"] = True - with tempfile.TemporaryDirectory(*args, **kwargs) as name: - yield Path(name) - else: - name = tempfile.mkdtemp(*args, **kwargs) - try: - yield Path(name) - finally: - robust_rmtree(name) + # mypy reports an error if ignore_cleanup_errors is + # specified literally in the call + kwargs["ignore_cleanup_errors"] = True + with tempfile.TemporaryDirectory(*args, **kwargs) as name: + yield Path(name) def parse_requires(requires: str) -> list[str]: diff --git a/src/poetry/core/version/markers.py b/src/poetry/core/version/markers.py index 4e2e211fe..2c361422a 100644 --- a/src/poetry/core/version/markers.py +++ b/src/poetry/core/version/markers.py @@ -13,7 +13,6 @@ from typing import ClassVar from typing import Generic from typing import TypeVar -from typing import Union from packaging.utils import canonicalize_name @@ -229,7 +228,7 @@ def __eq__(self, other: object) -> bool: SingleMarkerConstraint = TypeVar( - "SingleMarkerConstraint", bound=Union[BaseConstraint, VersionConstraint] + "SingleMarkerConstraint", bound=BaseConstraint | VersionConstraint ) @@ -344,7 +343,7 @@ def __hash__(self) -> int: return hash(self._key) -class SingleMarker(SingleMarkerLike[Union[BaseConstraint, VersionConstraint]]): +class SingleMarker(SingleMarkerLike[BaseConstraint | VersionConstraint]): _CONSTRAINT_RE_PATTERN_1 = re.compile( r"(?i)^(?P~=|!=|>=?|<=?|==?=?|not in |in )?\s*(?P.+)$" ) diff --git a/src/poetry/core/version/pep440/segments.py b/src/poetry/core/version/pep440/segments.py index bd641271b..3f0df9023 100644 --- a/src/poetry/core/version/pep440/segments.py +++ b/src/poetry/core/version/pep440/segments.py @@ -3,8 +3,6 @@ import dataclasses from typing import TYPE_CHECKING -from typing import Optional -from typing import Union if TYPE_CHECKING: @@ -162,4 +160,4 @@ def next_phase(self) -> ReleaseTag | None: return self.__class__(phase=_phase, number=0) -LocalSegmentType = Optional[Union[str, int, tuple[Union[str, int], ...]]] +LocalSegmentType = str | int | tuple[str | int, ...] | None diff --git a/tests/conftest.py b/tests/conftest.py index 5ab1331cd..fee9fda99 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -6,7 +6,6 @@ from pathlib import Path from typing import TYPE_CHECKING -from typing import Callable import pytest import virtualenv @@ -16,6 +15,7 @@ if TYPE_CHECKING: + from collections.abc import Callable from collections.abc import Iterator from pytest import Config diff --git a/tests/testutils.py b/tests/testutils.py index 411058ac4..8b1596209 100644 --- a/tests/testutils.py +++ b/tests/testutils.py @@ -2,7 +2,6 @@ import shutil import subprocess -import sys import tarfile import tempfile import zipfile @@ -64,9 +63,8 @@ def subprocess_run(*args: str, **kwargs: Any) -> subprocess.CompletedProcess[str """ Helper method to run a subprocess. Asserts for success. """ - encoding = "locale" if sys.version_info >= (3, 10) else None result = subprocess.run( - args, text=True, encoding=encoding, capture_output=True, **kwargs + args, text=True, encoding="locale", capture_output=True, **kwargs ) assert result.returncode == 0 return result diff --git a/tests/utils/test_helpers.py b/tests/utils/test_helpers.py index 95252f420..4960819f7 100644 --- a/tests/utils/test_helpers.py +++ b/tests/utils/test_helpers.py @@ -1,6 +1,5 @@ from __future__ import annotations -import sys import tempfile from pathlib import Path @@ -127,8 +126,7 @@ def test_utils_helpers_readme_content_type( assert readme_content_type(readme) == content_type -@pytest.mark.skipif(sys.version_info < (3, 10), reason="Requires Python 3.10 or higher") -def test_temporary_directory_python_3_10_or_newer(mocker: MockerFixture) -> None: +def test_temporary_directory(mocker: MockerFixture) -> None: mocked_rmtree = mocker.patch("shutil.rmtree") mocked_temp_dir = mocker.patch("tempfile.TemporaryDirectory") mocked_mkdtemp = mocker.patch("tempfile.mkdtemp") @@ -143,8 +141,7 @@ def test_temporary_directory_python_3_10_or_newer(mocker: MockerFixture) -> None mocked_temp_dir.assert_called_with(ignore_cleanup_errors=True) -@pytest.mark.skipif(sys.version_info < (3, 10), reason="Requires Python 3.10 or higher") -def test_temporary_directory_python_3_10_or_newer_ensure_cleanup_on_error( +def test_temporary_directory_ensure_cleanup_on_error( mocker: MockerFixture, ) -> None: mocked_rmtree = mocker.patch("shutil.rmtree") @@ -166,49 +163,6 @@ def test_temporary_directory_python_3_10_or_newer_ensure_cleanup_on_error( mocked_temp_dir.assert_called_with(ignore_cleanup_errors=True) -@pytest.mark.skipif( - sys.version_info >= (3, 10), reason="Not supported on Python 3.10 or higher" -) -def test_temporary_directory_python_3_9_or_older(mocker: MockerFixture) -> None: - mocked_rmtree = mocker.patch("shutil.rmtree") - mocked_temp_dir = mocker.patch("tempfile.TemporaryDirectory") - mocked_mkdtemp = mocker.patch("tempfile.mkdtemp") - - mocked_mkdtemp.return_value = "hello from test" - - with temporary_directory() as tmp: - assert tmp == Path("hello from test") - - assert mocked_rmtree.called - assert mocked_mkdtemp.called - assert not mocked_temp_dir.called - - -@pytest.mark.skipif( - sys.version_info >= (3, 10), reason="Not supported on Python 3.10 or higher" -) -def test_temporary_directory_python_3_9_or_older_ensure_cleanup_on_error( - mocker: MockerFixture, -) -> None: - mocked_rmtree = mocker.patch("shutil.rmtree") - mocked_temp_dir = mocker.patch("tempfile.TemporaryDirectory") - mocked_mkdtemp = mocker.patch("tempfile.mkdtemp") - - mocked_mkdtemp.return_value = "hello from test" - - with ( - pytest.raises(Exception, match="Something went wrong"), - temporary_directory() as tmp, - ): - assert tmp == Path("hello from test") - - raise Exception("Something went wrong") - - assert mocked_rmtree.called - assert mocked_mkdtemp.called - assert not mocked_temp_dir.called - - def test_robust_rmtree(mocker: MockerFixture) -> None: mocked_rmtree = mocker.patch("shutil.rmtree") diff --git a/vendors/poetry.lock b/vendors/poetry.lock index 131fe0e7e..7fdbe0d2c 100644 --- a/vendors/poetry.lock +++ b/vendors/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 2.1.4 and should not be changed by hand. +# This file is automatically @generated by Poetry 2.2.1 and should not be changed by hand. [[package]] name = "fastjsonschema" @@ -89,5 +89,5 @@ files = [ [metadata] lock-version = "2.1" -python-versions = ">=3.9" -content-hash = "6fa7a0923b44d12dab42d32d1dd8cd4d7538c96a8386f44291fd99df5807196b" +python-versions = ">=3.10" +content-hash = "889ba60cd3a1c0991131992d1bdc26d414bfbabdd9257c1ae16414cccd305597" diff --git a/vendors/pyproject.toml b/vendors/pyproject.toml index af367accf..b796ac139 100644 --- a/vendors/pyproject.toml +++ b/vendors/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "vendors" -requires-python = ">=3.9" +requires-python = ">=3.10" dynamic = [ "version", "dependencies" ] [tool.poetry]