diff --git a/.github/workflows/release-pypi.yaml b/.github/workflows/release-pypi.yaml
index 366e264f2..9b562cb6a 100644
--- a/.github/workflows/release-pypi.yaml
+++ b/.github/workflows/release-pypi.yaml
@@ -26,6 +26,6 @@ jobs:
- name: Show Python version
run: python --version
- - uses: cucumber/action-publish-pypi@v2.0.0
+ - uses: cucumber/action-publish-pypi@v3.0.0
with:
working-directory: "python"
diff --git a/.github/workflows/test-python.yml b/.github/workflows/test-python.yml
index 67caa8103..76db6ecff 100644
--- a/.github/workflows/test-python.yml
+++ b/.github/workflows/test-python.yml
@@ -32,12 +32,12 @@ jobs:
# - windows-latest
- macos-13
python-version:
+ - '3.13'
- '3.12'
- '3.11'
- '3.10'
- '3.9'
- - '3.8'
- - 'pypy-3.8'
+ - 'pypy-3.9'
steps:
- uses: actions/checkout@v4
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 924ae61e5..7f0f59af8 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -7,3 +7,19 @@ repos:
hooks:
- id: black
files: "^python/"
+ - repo: https://github.com/asottile/pyupgrade
+ rev: v3.18.0
+ hooks:
+ - id: pyupgrade
+ files: "^python/"
+ args: [ "--py39-plus" ]
+ - repo: https://github.com/pycqa/flake8
+ rev: "7.1.1"
+ hooks:
+ - id: flake8
+ files: "^python/"
+ args: [ "--toml-config=python/pyproject.toml" ]
+ additional_dependencies: [
+ "flake8-pyproject",
+ "flake8-bugbear",
+ ]
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6591009bd..90ece85e1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,8 @@ This project adheres to [Semantic Versioning](http://semver.org).
This document is formatted according to the principles of [Keep A CHANGELOG](http://keepachangelog.com).
## [Unreleased]
+
+## [30.0.0] - 2024-10-24
### Added
- [PHP, Java, Ruby, JavaScript] update dependency messages up to v26
- [Python] Added type annotations ([#283](https://github.com/cucumber/gherkin/pull/283))
@@ -24,10 +26,9 @@ This document is formatted according to the principles of [Keep A CHANGELOG](htt
- [.NET] Update System.Text.Json to 6.0.10
### Removed
-- [Python] Drop compatibility for python 2. Supported python versions are 3.8, 3.9, 3.10, 3.12
+- [Python] Drop compatibility for python 2 and python 3.8. Supported python versions: 3.9, 3.10, 3.11, 3.12, 3.13
- [Python] Removed installation of `gherkin` script. It was used for internal acceptance tests only.
-
## [29.0.0] - 2024-08-12
### Added
- (i18n) Added Gujarati translation for "Rule" ([#249](https://github.com/cucumber/gherkin/pull/249))
@@ -688,7 +689,8 @@ This document is formatted according to the principles of [Keep A CHANGELOG](htt
### Changed
- First release
-[Unreleased]: https://github.com/cucumber/gherkin/compare/v29.0.0...HEAD
+[Unreleased]: https://github.com/cucumber/gherkin/compare/v30.0.0...HEAD
+[30.0.0]: https://github.com/cucumber/gherkin/compare/v29.0.0...v30.0.0
[29.0.0]: https://github.com/cucumber/gherkin/compare/v28.0.0...v29.0.0
[28.0.0]: https://github.com/cucumber/gherkin/compare/v27.0.0...v28.0.0
[27.0.0]: https://github.com/cucumber/gherkin/compare/v26.2.0...v27.0.0
diff --git a/c/VERSION b/c/VERSION
index f1e4903d1..8dd5c17a1 100644
--- a/c/VERSION
+++ b/c/VERSION
@@ -1 +1 @@
-29.0.0
+30.0.0
diff --git a/dotnet/Gherkin/Gherkin.csproj b/dotnet/Gherkin/Gherkin.csproj
index 2ee4f6483..b2aefc0aa 100644
--- a/dotnet/Gherkin/Gherkin.csproj
+++ b/dotnet/Gherkin/Gherkin.csproj
@@ -10,7 +10,7 @@
- 29.0.0
+ 30.0.0
$(VersionNumber)-$(SnapshotSuffix)
$(VersionNumber)
@@ -19,7 +19,7 @@
Gherkin Parser
Gherkin
Cucumber Ltd, Gaspar Nagy
- Copyright © Cucumber Ltd, Gaspar Nagy
+ Copyright © Cucumber Ltd, Gaspar Nagy
Cross-platform parser for the Gherkin language, used by Cucumber, SpecFlow and other Cucumber-based tools to parse feature files.
specflow gherkin cucumber
https://github.com/cucumber/gherkin
@@ -37,7 +37,7 @@
-
+
diff --git a/elixir/mix.exs b/elixir/mix.exs
index 81406d5f9..3d3f76bd9 100644
--- a/elixir/mix.exs
+++ b/elixir/mix.exs
@@ -6,7 +6,7 @@ defmodule CucumberGherkin.MixProject do
def project do
[
app: :cucumber_gherkin,
- version: "29.0.0",
+ version: "30.0.0",
name: "CucumberGherkin",
description: description(),
package: package(),
diff --git a/go/gherkin-generate-tokens/gherkin-generate-tokens.go b/go/gherkin-generate-tokens/gherkin-generate-tokens.go
index 2eefd2987..4c754388d 100644
--- a/go/gherkin-generate-tokens/gherkin-generate-tokens.go
+++ b/go/gherkin-generate-tokens/gherkin-generate-tokens.go
@@ -2,7 +2,7 @@ package main
import (
"fmt"
- gherkin "github.com/cucumber/gherkin/go/v29"
+ gherkin "github.com/cucumber/gherkin/go/v30"
"io"
"os"
"strings"
diff --git a/go/go.mod b/go/go.mod
index 6d40e7723..94265b9dd 100644
--- a/go/go.mod
+++ b/go/go.mod
@@ -1,4 +1,4 @@
-module github.com/cucumber/gherkin/go/v29
+module github.com/cucumber/gherkin/go/v30
require (
github.com/cucumber/messages/go/v24 v24.1.0
diff --git a/go/main/main.go b/go/main/main.go
index dc7d35944..a792cd4e4 100644
--- a/go/main/main.go
+++ b/go/main/main.go
@@ -9,7 +9,7 @@ import (
"encoding/json"
"flag"
"fmt"
- gherkin "github.com/cucumber/gherkin/go/v29"
+ gherkin "github.com/cucumber/gherkin/go/v30"
"github.com/cucumber/messages/go/v24"
"os"
)
diff --git a/java/pom.xml b/java/pom.xml
index 9452a1c89..65554e3b6 100644
--- a/java/pom.xml
+++ b/java/pom.xml
@@ -8,14 +8,14 @@
4.2.0
gherkin
- 29.0.1-SNAPSHOT
+ 30.0.1-SNAPSHOT
jar
Gherkin
Gherkin parser
https://github.com/cucumber/gherkin
- 1723455193
+ 1729755133
io.cucumber.gherkin
@@ -31,14 +31,14 @@
com.fasterxml.jackson
jackson-bom
- 2.18.0
+ 2.18.1
pom
import
org.junit
junit-bom
- 5.11.2
+ 5.11.3
pom
import
@@ -49,7 +49,7 @@
io.cucumber
messages
- [19.1.4,27.0.0)
+ [19.1.4,28.0.0)
diff --git a/javascript/package-lock.json b/javascript/package-lock.json
index 62543438d..34bb2618a 100644
--- a/javascript/package-lock.json
+++ b/javascript/package-lock.json
@@ -1,22 +1,22 @@
{
"name": "@cucumber/gherkin",
- "version": "29.0.0",
+ "version": "30.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@cucumber/gherkin",
- "version": "29.0.0",
+ "version": "30.0.0",
"license": "MIT",
"dependencies": {
"@cucumber/messages": ">=19.1.4 <=26"
},
"devDependencies": {
"@types/mocha": "10.0.9",
- "@types/node": "20.16.11",
+ "@types/node": "20.17.6",
"commander": "^12.0.0",
- "core-js": "3.38.1",
- "mocha": "10.7.3",
+ "core-js": "3.39.0",
+ "mocha": "10.8.2",
"ts-node": "10.9.2",
"typescript": "5.6.3"
}
@@ -101,9 +101,9 @@
"license": "MIT"
},
"node_modules/@types/node": {
- "version": "20.16.11",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.11.tgz",
- "integrity": "sha512-y+cTCACu92FyA5fgQSAI8A1H429g7aSK2HsO7K4XYUWc4dY5IUz55JSDIYT6/VsOLfGy8vmvQYC2hfb0iF16Uw==",
+ "version": "20.17.6",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.6.tgz",
+ "integrity": "sha512-VEI7OdvK2wP7XHnsuXbAJnEpEkF6NjSN45QJlL4VGqZSXsnicpesdTWsg9RISeSdYd3yeRj/y3k5KGjUXYnFwQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -347,11 +347,12 @@
}
},
"node_modules/core-js": {
- "version": "3.38.1",
- "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.38.1.tgz",
- "integrity": "sha512-OP35aUorbU3Zvlx7pjsFdu1rGNnD4pgw/CWoYzRY3t2EzoVT7shKHY1dlAy3f41cGIO7ZDPQimhGFTlEYkG/Hw==",
+ "version": "3.39.0",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.39.0.tgz",
+ "integrity": "sha512-raM0ew0/jJUqkJ0E6e8UDtl+y/7ktFivgWvqw8dNSQeNWoSDLvQ1H/RN3aPXB9tBd4/FhyR4RDPGhsNIMsAn7g==",
"dev": true,
"hasInstallScript": true,
+ "license": "MIT",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/core-js"
@@ -685,10 +686,11 @@
}
},
"node_modules/mocha": {
- "version": "10.7.3",
- "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.7.3.tgz",
- "integrity": "sha512-uQWxAu44wwiACGqjbPYmjo7Lg8sFrS3dQe7PP2FQI+woptP4vZXSMcfMyFL/e1yFEeEpV4RtyTpZROOKmxis+A==",
+ "version": "10.8.2",
+ "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.8.2.tgz",
+ "integrity": "sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"ansi-colors": "^4.1.3",
"browser-stdout": "^1.3.1",
diff --git a/javascript/package.json b/javascript/package.json
index 0a57954ce..187d0b597 100644
--- a/javascript/package.json
+++ b/javascript/package.json
@@ -1,6 +1,6 @@
{
"name": "@cucumber/gherkin",
- "version": "29.0.0",
+ "version": "30.0.0",
"description": "Gherkin parser",
"main": "dist/src/index.js",
"types": "dist/src/index.d.ts",
@@ -32,10 +32,10 @@
"homepage": "https://github.com/cucumber/gherkin",
"devDependencies": {
"@types/mocha": "10.0.9",
- "@types/node": "20.16.11",
+ "@types/node": "20.17.6",
"commander": "^12.0.0",
- "core-js": "3.38.1",
- "mocha": "10.7.3",
+ "core-js": "3.39.0",
+ "mocha": "10.8.2",
"ts-node": "10.9.2",
"typescript": "5.6.3"
},
diff --git a/perl/VERSION b/perl/VERSION
index f1e4903d1..8dd5c17a1 100644
--- a/perl/VERSION
+++ b/perl/VERSION
@@ -1 +1 @@
-29.0.0
+30.0.0
diff --git a/perl/cpanfile b/perl/cpanfile
index fd1383c21..e02249081 100644
--- a/perl/cpanfile
+++ b/perl/cpanfile
@@ -5,7 +5,7 @@ requires "Class::XSAccessor";
requires "Cucumber::Messages", ">= 22.0.0, < 23.0.0";
requires "Data::UUID";
requires "Getopt::Long", "2.58";
-requires "List::Util", "1.66";
+requires "List::Util", "1.68";
on 'test' => sub {
requires "Path::Class";
diff --git a/python/gherkin/ast_builder.py b/python/gherkin/ast_builder.py
index 212f5156a..15a50a55c 100644
--- a/python/gherkin/ast_builder.py
+++ b/python/gherkin/ast_builder.py
@@ -1,6 +1,6 @@
from __future__ import annotations
-from typing import TypedDict, cast, TypeVar, Union, List
+from typing import TypedDict, cast, TypeVar, Union
from .ast_node import AstNode
from .errors import AstBuilderException
@@ -140,7 +140,7 @@ def get_description(node: AstNode) -> str:
@staticmethod
def get_steps(node: AstNode) -> list[Step]:
- return cast(List[Step], node.get_items("Step"))
+ return cast(list[Step], node.get_items("Step"))
def transform_node(
self, node: AstNode
@@ -247,7 +247,7 @@ def transform_node(
examples_line = examples_node.get_token("ExamplesLine")
description = self.get_description(examples_node)
examples_table_rows = cast(
- List[TableRow], examples_node.get_single("ExamplesTable")
+ list[TableRow], examples_node.get_single("ExamplesTable")
)
table_header = examples_table_rows[0] if examples_table_rows else None
table_body = examples_table_rows[1:] if examples_table_rows else []
diff --git a/python/gherkin/dialect.py b/python/gherkin/dialect.py
index c637a0211..3178cc94b 100644
--- a/python/gherkin/dialect.py
+++ b/python/gherkin/dialect.py
@@ -2,7 +2,7 @@
import os
import json
-from typing import TypedDict, List
+from typing import TypedDict
from typing_extensions import Self
@@ -14,17 +14,17 @@
DialectSpec = TypedDict(
"DialectSpec",
{
- "and": List[str],
- "background": List[str],
- "but": List[str],
- "examples": List[str],
- "feature": List[str],
- "given": List[str],
- "rule": List[str],
- "scenario": List[str],
- "scenarioOutline": List[str],
- "then": List[str],
- "when": List[str],
+ "and": list[str],
+ "background": list[str],
+ "but": list[str],
+ "examples": list[str],
+ "feature": list[str],
+ "given": list[str],
+ "rule": list[str],
+ "scenario": list[str],
+ "scenarioOutline": list[str],
+ "then": list[str],
+ "when": list[str],
},
)
diff --git a/python/gherkin/gherkin_line.py b/python/gherkin/gherkin_line.py
index 66c8001d1..e9a72b800 100644
--- a/python/gherkin/gherkin_line.py
+++ b/python/gherkin/gherkin_line.py
@@ -54,7 +54,7 @@ def table_cells(self) -> list[Cell]:
return cells
@staticmethod
- def split_table_cells(row: str) -> Generator[tuple[str, int], None, None]:
+ def split_table_cells(row: str) -> Generator[tuple[str, int]]:
"""
An iterator returning all the table cells in a row with their positions,
accounting for escaping.
diff --git a/python/gherkin/stream/gherkin_events.py b/python/gherkin/stream/gherkin_events.py
index c966d7f89..81c5148fe 100644
--- a/python/gherkin/stream/gherkin_events.py
+++ b/python/gherkin/stream/gherkin_events.py
@@ -27,9 +27,7 @@ class Error(TypedDict):
parseError: ParseError
-def create_errors(
- errors: Iterable[ParserException], uri: str
-) -> Generator[Error, None, None]:
+def create_errors(errors: Iterable[ParserException], uri: str) -> Generator[Error]:
for error in errors:
yield {
"parseError": {
@@ -60,11 +58,9 @@ def __init__(self, options: Options) -> None:
self.parser = Parser(ast_builder=AstBuilder(self.id_generator))
self.compiler = Compiler(self.id_generator)
- def enum(self, source_event: Event) -> Generator[
- Event | Error | GherkinDocumentEnvelope | PickleEnvelope,
- None,
- None,
- ]:
+ def enum(
+ self, source_event: Event
+ ) -> Generator[Event | Error | GherkinDocumentEnvelope | PickleEnvelope,]:
uri = source_event["source"]["uri"]
source = source_event["source"]["data"]
diff --git a/python/pyproject.toml b/python/pyproject.toml
index b7f98aebd..ad673f149 100644
--- a/python/pyproject.toml
+++ b/python/pyproject.toml
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "gherkin-official"
-version = "29.0.0"
+version = "30.0.0"
description = "Gherkin parser (official, by Cucumber team)"
readme = "README.md"
requires-python = ">=3.8"
@@ -48,4 +48,11 @@ packages = ["gherkin"]
force-exclude = """(
(python/)?gherkin/parser.py
)"""
-target-version = ["py38", "py39", "py310", "py311", "py312", "py313"]
+target-version = ["py39", "py310", "py311", "py312", "py313"]
+
+[tool.flake8]
+# E1: indentation: already covered by `black`
+# E2: whitespace: already covered by `black`
+# E3: blank line: already covered by `black`
+# E501: line length: already covered by `black`
+extend-ignore = "E1,E2,E3,E501"
\ No newline at end of file
diff --git a/python/test/count_symbols_test.py b/python/test/count_symbols_test.py
index 0d41f7553..b449ff49b 100644
--- a/python/test/count_symbols_test.py
+++ b/python/test/count_symbols_test.py
@@ -1,6 +1,3 @@
-# coding=utf-8
-
-
def test_count_length_of_astral_point_symbols_correctly():
string = "\U0001f63b"
assert 1 == len(string)
diff --git a/python/test/gherkin_in_markdown_token_matcher_test.py b/python/test/gherkin_in_markdown_token_matcher_test.py
index d7bf579ee..570e62de0 100644
--- a/python/test/gherkin_in_markdown_token_matcher_test.py
+++ b/python/test/gherkin_in_markdown_token_matcher_test.py
@@ -107,7 +107,7 @@ def test_it_matches_4_ticks_doctring_separator():
)
assert tm.match_Other(t2)
assert t2.matched_type == "Other"
- assert t2.matched_keyword == None
+ assert t2.matched_keyword is None
assert t2.matched_text == "```"
t3 = Token(
diff --git a/python/test/gherkin_test.py b/python/test/gherkin_test.py
index ee3023b18..7f243cabc 100644
--- a/python/test/gherkin_test.py
+++ b/python/test/gherkin_test.py
@@ -1,4 +1,3 @@
-# coding=utf-8
from gherkin.token_scanner import TokenScanner
from gherkin.token_matcher import TokenMatcher
from gherkin.parser import Parser
diff --git a/python/test/pickles_test/compiler_test.py b/python/test/pickles_test/compiler_test.py
index 4c2702284..8081f767b 100644
--- a/python/test/pickles_test/compiler_test.py
+++ b/python/test/pickles_test/compiler_test.py
@@ -1,4 +1,3 @@
-# coding=utf-8
import json
import textwrap
diff --git a/python/tox.ini b/python/tox.ini
index 6033180ac..23dce337d 100644
--- a/python/tox.ini
+++ b/python/tox.ini
@@ -13,7 +13,7 @@
# ============================================================================
[tox]
-envlist = py312, py311, py310, py39, py38
+envlist = py313, py312, py311, py310, py39
# -----------------------------------------------------------------------------
# TEST ENVIRONMENTS:
diff --git a/ruby/VERSION b/ruby/VERSION
index f1e4903d1..8dd5c17a1 100644
--- a/ruby/VERSION
+++ b/ruby/VERSION
@@ -1 +1 @@
-29.0.0
+30.0.0