diff --git a/.github/workflows/general.yaml b/.github/workflows/general.yaml index 646a7af4db..0330b3002c 100644 --- a/.github/workflows/general.yaml +++ b/.github/workflows/general.yaml @@ -4,11 +4,13 @@ on: push: branches: - main + - next tags: - v*.*.* pull_request: branches: - main + - next # schedule: # - cron: "0 3 * * *" @@ -21,7 +23,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"] + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] steps: - name: Checkout repository uses: actions/checkout@v5 @@ -30,8 +32,7 @@ jobs: with: python-version: ${{ matrix.python-version }} - name: Prepare environment - # https://github.com/pypa/hatch/issues/2193 - run: pip3 install hatch 'virtualenv<21' + run: pip3 install hatch - name: Prepare variables run: cp .env.example .env - name: Prepare secrets @@ -116,7 +117,7 @@ jobs: # Deploy deploy: - if: github.event_name == 'push' + if: github.event_name == 'push' && github.ref == 'refs/heads/main' runs-on: ubuntu-latest steps: - name: Checkout repository diff --git a/docs/getting-started.md b/docs/getting-started.md index dabe9520ac..4c8c3bd1c2 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -9,7 +9,8 @@ Let's get started with Frictionless! We will learn how to install and use the fr ## Installation -> The framework requires Python3.8+. Versioning follows the [SemVer Standard](https://semver.org/). +> The framework requires Python3.10+. Versioning follows the [SemVer + Standard](https://semver.org/). ```bash tabs=CLI pip install frictionless diff --git a/frictionless/conftest.py b/frictionless/conftest.py index 37e446f9f2..6b52094fb3 100644 --- a/frictionless/conftest.py +++ b/frictionless/conftest.py @@ -8,17 +8,6 @@ # TODO: stop using the Bugs section in the tests and split them among themed categories? -# Cleanups - -try: - # For python 3.8 only, that does not support pytest_cov v7 - from pytest_cov.embed import cleanup_on_sigterm - - cleanup_on_sigterm() -except ImportError: - pass - - # Fixtures diff --git a/frictionless/formats/csv/__spec__/test_parser.py b/frictionless/formats/csv/__spec__/test_parser.py index 3a17427091..2bf4bca368 100644 --- a/frictionless/formats/csv/__spec__/test_parser.py +++ b/frictionless/formats/csv/__spec__/test_parser.py @@ -1,5 +1,3 @@ -import sys - import pytest from frictionless import Detector, Dialect, formats, platform @@ -108,7 +106,6 @@ def test_csv_parser_buffer(): @pytest.mark.vcr -@pytest.mark.skipif(sys.version_info < (3, 10), reason="pytest-vcr bug in Python3.8/9") def test_csv_parser_remote(): with TableResource(path=BASEURL % "data/table.csv") as resource: assert resource.header == ["id", "name"] diff --git a/frictionless/formats/json/parsers/__spec__/test_json.py b/frictionless/formats/json/parsers/__spec__/test_json.py index cf473ca415..12a49af9a6 100644 --- a/frictionless/formats/json/parsers/__spec__/test_json.py +++ b/frictionless/formats/json/parsers/__spec__/test_json.py @@ -1,5 +1,4 @@ import json -import sys import pytest @@ -67,7 +66,6 @@ def test_json_parser_from_buffer_keyed(): @pytest.mark.vcr -@pytest.mark.skipif(sys.version_info < (3, 10), reason="pytest-vcr bug in Python3.8/9") def test_json_parser_from_remote(): with TableResource(path=BASEURL % "data/table.json") as resource: assert resource.header == ["id", "name"] @@ -78,7 +76,6 @@ def test_json_parser_from_remote(): @pytest.mark.vcr -@pytest.mark.skipif(sys.version_info < (3, 10), reason="pytest-vcr bug in Python3.8/9") def test_json_parser_from_remote_keyed(): with TableResource(path=BASEURL % "data/table.keyed.json") as resource: assert resource.dialect.to_descriptor() == {"json": {"keyed": True}} diff --git a/frictionless/formats/zip/__spec__/test_adapter.py b/frictionless/formats/zip/__spec__/test_adapter.py index d458b8075a..e64cf028e4 100644 --- a/frictionless/formats/zip/__spec__/test_adapter.py +++ b/frictionless/formats/zip/__spec__/test_adapter.py @@ -1,5 +1,4 @@ import os -import sys import zipfile import pytest @@ -40,7 +39,6 @@ def test_zip_adapter_to_zip_resource_path(tmpdir): @pytest.mark.vcr -@pytest.mark.skipif(sys.version_info < (3, 10), reason="pytest-vcr bug in Python3.8/9") def test_zip_adapter_to_zip_resource_remote_path(tmpdir): path = os.path.join(tmpdir, "package.zip") source = Package(resources=[Resource(path=BASEURL % "data/table.csv")]) diff --git a/frictionless/package/__spec__/test_general.py b/frictionless/package/__spec__/test_general.py index 0a95a60210..0f0ff72b52 100644 --- a/frictionless/package/__spec__/test_general.py +++ b/frictionless/package/__spec__/test_general.py @@ -1,4 +1,3 @@ -import sys import textwrap from collections.abc import Mapping from importlib import import_module @@ -127,7 +126,6 @@ def test_package_from_path_error_bad_json_not_dict(): @pytest.mark.vcr -@pytest.mark.skipif(sys.version_info < (3, 10), reason="pytest-vcr bug in Python3.8/9") def test_package_from_path_remote(): package = Package.from_descriptor(BASEURL % "data/package.json") assert package.basepath == BASEURL % "data" @@ -316,7 +314,6 @@ def test_package_validation_duplicate_resource_names_issue_942(): @pytest.mark.vcr -@pytest.mark.skipif(sys.version_info < (3, 10), reason="pytest-vcr bug in Python3.8/9") def test_package_remote_scheme_regression_for_resources_issue_1388(): package = Package.from_descriptor( "https://raw.githubusercontent.com/fdtester/test-write-package-with-dialect/main/datapackage.json" @@ -326,7 +323,6 @@ def test_package_remote_scheme_regression_for_resources_issue_1388(): @pytest.mark.vcr -@pytest.mark.skipif(sys.version_info < (3, 10), reason="pytest-vcr bug in Python3.8/9") def test_package_remote_windows_1505(): url = "https://raw.githubusercontent.com/transparencia-mg/datapackage-reprex/foreign-key-constraint/datapackage.json" package = Package(url) diff --git a/frictionless/package/__spec__/test_profile.py b/frictionless/package/__spec__/test_profile.py index b12f520ea7..ef9f5cd525 100644 --- a/frictionless/package/__spec__/test_profile.py +++ b/frictionless/package/__spec__/test_profile.py @@ -1,5 +1,3 @@ -import sys - import pytest import yaml @@ -9,7 +7,6 @@ @pytest.mark.vcr -@pytest.mark.skipif(sys.version_info < (3, 10), reason="pytest-vcr bug in Python3.8/9") def test_package_profiles_invalid_local(): profile = "data/profiles/camtrap.json" resource = Resource(name="table", path="data/table.csv") @@ -23,7 +20,6 @@ def test_package_profiles_invalid_local(): @pytest.mark.vcr -@pytest.mark.skipif(sys.version_info < (3, 10), reason="pytest-vcr bug in Python3.8/9") def test_package_profiles_invalid_local_from_descriptor(): profile = "data/profiles/camtrap.json" resource = Resource(name="table", path="data/table.csv") @@ -84,7 +80,6 @@ def test_package_profile_type(profile): @pytest.mark.vcr -@pytest.mark.skipif(sys.version_info < (3, 10), reason="pytest-vcr bug in Python3.8/9") def test_package_profiles_from_descriptor_standards_v1(): profile = "data/profiles/camtrap.json" resource = Resource(name="table", path="data/table.csv") @@ -114,8 +109,7 @@ def test_package_profiles_to_descriptor_standards_v1(): def test_package_preserver_profile_issue_1480(): - descriptor = yaml.safe_load( - """ + descriptor = yaml.safe_load(""" profile: tabular-data-package resources: - @@ -126,16 +120,14 @@ def test_package_preserver_profile_issue_1480(): mediatype: text/csv encoding: utf-8 schema: schema.json - """ - ) + """) package = Package(descriptor) assert package.profile == "tabular-data-package" assert package.get_resource("some-table").profile == "tabular-data-resource" def test_package_profile_tabular_requirements_issue_1484(): - descriptor = yaml.safe_load( - """ + descriptor = yaml.safe_load(""" profile: tabular-data-package resources: - @@ -145,8 +137,7 @@ def test_package_profile_tabular_requirements_issue_1484(): mediatype: text/csv encoding: utf-8 schema: schema.json - """ - ) + """) report = Package.validate_descriptor(descriptor) assert report.flatten(["type", "note"]) == [ [ @@ -157,8 +148,7 @@ def test_package_profile_tabular_requirements_issue_1484(): def test_package_profile_tabular_requirements_schema_issue_1484(): - descriptor = yaml.safe_load( - """ + descriptor = yaml.safe_load(""" profile: tabular-data-package resources: - @@ -168,8 +158,7 @@ def test_package_profile_tabular_requirements_schema_issue_1484(): format: csv mediatype: text/csv encoding: utf-8 - """ - ) + """) report = Package.validate_descriptor(descriptor) assert report.flatten(["type", "note"]) == [ [ diff --git a/frictionless/package/__spec__/test_security.py b/frictionless/package/__spec__/test_security.py index 8ece99764a..119e92fa28 100644 --- a/frictionless/package/__spec__/test_security.py +++ b/frictionless/package/__spec__/test_security.py @@ -1,5 +1,3 @@ -import sys - import pytest from frictionless import FrictionlessException, Package, Resource, platform, system @@ -46,7 +44,6 @@ def test_package_external_profile_invalid_local_from_descriptor_unsafe(): @pytest.mark.vcr -@pytest.mark.skipif(sys.version_info < (3, 10), reason="pytest-vcr bug in Python3.8/9") def test_package_external_profile_invalid_local_from_descriptor_unsafe_trusted(): profile = "data/../data/profiles/camtrap.json" resource = Resource(name="table", path="data/table.csv") diff --git a/frictionless/resource/__spec__/test_dereference.py b/frictionless/resource/__spec__/test_dereference.py index 3b4138a9f9..bb06add167 100644 --- a/frictionless/resource/__spec__/test_dereference.py +++ b/frictionless/resource/__spec__/test_dereference.py @@ -1,5 +1,3 @@ -import sys - import pytest from frictionless import Resource, platform @@ -61,7 +59,6 @@ def test_resource_dialect_schema_from_path(): @pytest.mark.vcr -@pytest.mark.skipif(sys.version_info < (3, 10), reason="pytest-vcr bug in Python3.8/9") @pytest.mark.skipif(platform.type == "windows", reason="Fix on Windows") def test_resource_dialect_schema_from_path_remote(): resource = Resource(BASEURL % "data/resource-with-dereferencing.json") diff --git a/frictionless/resource/__spec__/test_general.py b/frictionless/resource/__spec__/test_general.py index 5aa8667eed..6f5a8de6c3 100644 --- a/frictionless/resource/__spec__/test_general.py +++ b/frictionless/resource/__spec__/test_general.py @@ -1,4 +1,3 @@ -import sys import textwrap from importlib import import_module @@ -50,7 +49,6 @@ def test_resource_source_non_tabular(): @pytest.mark.vcr -@pytest.mark.skipif(sys.version_info < (3, 10), reason="pytest-vcr bug in Python3.8/9") def test_resource_source_non_tabular_remote(): path = BASEURL % "data/text.txt" with Resource(path) as resource: diff --git a/frictionless/resource/__spec__/test_read.py b/frictionless/resource/__spec__/test_read.py index 643110243a..745ace11fb 100644 --- a/frictionless/resource/__spec__/test_read.py +++ b/frictionless/resource/__spec__/test_read.py @@ -1,13 +1,8 @@ -import sys - -import pytest - from frictionless import Resource, resources # General -@pytest.mark.skipif(sys.version_info < (3, 7), reason="Requires Python3.7+") def test_resource_read_bytes(): resource = Resource(path="data/text.txt") bytes = resource.read_bytes() diff --git a/frictionless/resource/__spec__/test_scheme.py b/frictionless/resource/__spec__/test_scheme.py index 834d4f600f..5a94b6d965 100644 --- a/frictionless/resource/__spec__/test_scheme.py +++ b/frictionless/resource/__spec__/test_scheme.py @@ -1,5 +1,3 @@ -import sys - import pytest from frictionless import FrictionlessException, Resource @@ -16,7 +14,6 @@ def test_resource_scheme_file(): @pytest.mark.vcr -@pytest.mark.skipif(sys.version_info < (3, 10), reason="pytest-vcr bug in Python3.8/9") def test_resource_scheme_https(): with Resource(BASEURL % "data/table.csv") as resource: assert resource.scheme == "https" diff --git a/frictionless/resource/__spec__/test_security.py b/frictionless/resource/__spec__/test_security.py index 36c2fc2b3b..d04d7a688a 100644 --- a/frictionless/resource/__spec__/test_security.py +++ b/frictionless/resource/__spec__/test_security.py @@ -1,5 +1,4 @@ import os -import sys import pytest @@ -8,7 +7,6 @@ # General -@pytest.mark.skipif(sys.version_info < (3, 10), reason="pytest-vcr bug in Python3.8/9") def test_resource_source_path_error_bad_path_not_safe_absolute(): with pytest.raises(FrictionlessException) as excinfo: Resource({"name": "name", "path": os.path.abspath("data/table.csv")}) @@ -21,7 +19,6 @@ def test_resource_source_path_error_bad_path_not_safe_absolute(): assert reasons[0].note.count('table.csv" is not safe') -@pytest.mark.skipif(sys.version_info < (3, 10), reason="pytest-vcr bug in Python3.8/9") def test_resource_source_path_error_bad_path_not_safe_traversing(): with pytest.raises(FrictionlessException) as excinfo: Resource( @@ -43,7 +40,6 @@ def test_resource_source_path_error_bad_path_not_safe_traversing(): assert reasons[0].note.count('table.csv" is not safe') -@pytest.mark.skipif(sys.version_info < (3, 10), reason="pytest-vcr bug in Python3.8/9") def test_resource_dialect_from_path_error_path_not_safe(): dialect = os.path.abspath("data/dialect.json") with pytest.raises(FrictionlessException) as excinfo: @@ -57,7 +53,6 @@ def test_resource_dialect_from_path_error_path_not_safe(): assert reasons[0].note.count('dialect.json" is not safe') -@pytest.mark.skipif(sys.version_info < (3, 10), reason="pytest-vcr bug in Python3.8/9") def test_resource_schema_from_path_error_path_not_safe(): schema = os.path.abspath("data/schema.json") with pytest.raises(FrictionlessException) as excinfo: @@ -71,7 +66,6 @@ def test_resource_schema_from_path_error_path_not_safe(): assert reasons[0].note.count('schema.json" is not safe') -@pytest.mark.skipif(sys.version_info < (3, 10), reason="pytest-vcr bug in Python3.8/9") def test_resource_extrapaths_error_bad_path_not_safe_absolute(): extrapath = os.path.abspath("data/chunk2.csv") with pytest.raises(FrictionlessException) as excinfo: @@ -85,7 +79,6 @@ def test_resource_extrapaths_error_bad_path_not_safe_absolute(): assert reasons[0].note.count('chunk2.csv" is not safe') -@pytest.mark.skipif(sys.version_info < (3, 10), reason="pytest-vcr bug in Python3.8/9") @pytest.mark.skipif(platform.type == "windows", reason="Fix on Windows") def test_resource_extrapaths_error_bad_path_not_safe_traversing(): extrapath = "data/../chunk2.csv" @@ -100,7 +93,6 @@ def test_resource_extrapaths_error_bad_path_not_safe_traversing(): assert reasons[0].note.count('chunk2.csv" is not safe') -@pytest.mark.skipif(sys.version_info < (3, 10), reason="pytest-vcr bug in Python3.8/9") def test_resource_profiles_error_bad_path_not_safe_absolute(): profile = os.path.abspath("data/profiles/camtrap.json") with pytest.raises(FrictionlessException) as excinfo: @@ -114,7 +106,6 @@ def test_resource_profiles_error_bad_path_not_safe_absolute(): assert reasons[0].note.count('camtrap.json" is not safe') -@pytest.mark.skipif(sys.version_info < (3, 10), reason="pytest-vcr bug in Python3.8/9") @pytest.mark.skipif(platform.type == "windows", reason="Fix on Windows") def test_resource_profiles_error_bad_path_not_safe_traversing(): profile = "data/profiles/../profiles/camtrap.json" diff --git a/frictionless/resources/__spec__/table/test_compression.py b/frictionless/resources/__spec__/table/test_compression.py index 8647483257..031fa3f002 100644 --- a/frictionless/resources/__spec__/table/test_compression.py +++ b/frictionless/resources/__spec__/table/test_compression.py @@ -1,5 +1,3 @@ -import sys - import pytest from frictionless import FrictionlessException @@ -166,7 +164,6 @@ def test_resource_compression_error_invalid_zip(): assert error.note == "File is not a zip file" -@pytest.mark.skipif(sys.version_info < (3, 8), reason="Requires Python3.8+") def test_resource_compression_error_invalid_gz(): source = b"id,filename\n\1,dump" resource = TableResource(data=source, format="csv", compression="gz") diff --git a/frictionless/resources/__spec__/table/test_general.py b/frictionless/resources/__spec__/table/test_general.py index 3458988a62..25a310f2ec 100644 --- a/frictionless/resources/__spec__/table/test_general.py +++ b/frictionless/resources/__spec__/table/test_general.py @@ -78,7 +78,6 @@ def test_resource_from_path_yaml(): @pytest.mark.vcr -@pytest.mark.skipif(sys.version_info < (3, 10), reason="pytest-vcr bug in Python3.8/9") def test_resource_from_path_remote(): resource = TableResource.from_descriptor(BASEURL % "data/resource.json") assert resource.path == "table.csv" @@ -91,7 +90,6 @@ def test_resource_from_path_remote(): @pytest.mark.vcr -@pytest.mark.skipif(sys.version_info < (3, 10), reason="pytest-vcr bug in Python3.8/9") def test_resource_from_url_standards_v0(): resource = TableResource.from_descriptor( {"name": "name", "url": BASEURL % "data/table.csv"} @@ -103,7 +101,6 @@ def test_resource_from_url_standards_v0(): ] -@pytest.mark.skipif(sys.version_info < (3, 7), reason="Requires Python3.7+") def test_resource_source_path(): path = "data/table.csv" resource = TableResource.from_descriptor({"name": "name", "path": path}) @@ -155,7 +152,6 @@ def test_resource_source_path_and_basepath(): @pytest.mark.vcr -@pytest.mark.skipif(sys.version_info < (3, 10), reason="pytest-vcr bug in Python3.8/9") def test_resource_source_path_and_basepath_remote(): resource = TableResource(path="table.csv", basepath=BASEURL % "data") assert resource.normpath == BASEURL % "data/table.csv" @@ -166,7 +162,6 @@ def test_resource_source_path_and_basepath_remote(): @pytest.mark.vcr -@pytest.mark.skipif(sys.version_info < (3, 10), reason="pytest-vcr bug in Python3.8/9") def test_resource_source_path_remote_and_basepath_remote(): resource = TableResource(path=BASEURL % "data/table.csv", basepath=BASEURL % "data") assert resource.normpath == BASEURL % "data/table.csv" diff --git a/frictionless/resources/__spec__/table/test_schema.py b/frictionless/resources/__spec__/table/test_schema.py index b9bf3ba91a..7cba413cc4 100644 --- a/frictionless/resources/__spec__/table/test_schema.py +++ b/frictionless/resources/__spec__/table/test_schema.py @@ -1,5 +1,3 @@ -import sys - import pytest from frictionless import Detector, FrictionlessException, Schema, platform @@ -66,7 +64,6 @@ def test_resource_schema_source_data(): @pytest.mark.vcr -@pytest.mark.skipif(sys.version_info < (3, 10), reason="pytest-vcr bug in Python3.8/9") @pytest.mark.skipif(platform.type == "windows", reason="Fix on Windows") def test_resource_schema_source_remote(): descriptor = { diff --git a/frictionless/resources/__spec__/table/test_security.py b/frictionless/resources/__spec__/table/test_security.py index b0253b5d04..9ec0beddc7 100644 --- a/frictionless/resources/__spec__/table/test_security.py +++ b/frictionless/resources/__spec__/table/test_security.py @@ -1,5 +1,3 @@ -import sys - import pytest from frictionless import FrictionlessException, platform, system @@ -8,7 +6,6 @@ # Bugs -@pytest.mark.skipif(sys.version_info < (3, 10), reason="pytest-vcr bug in Python3.8/9") def test_resource_relative_parent_path_with_trusted_option_issue_171(): path = ( "data/../data/table.csv" diff --git a/frictionless/resources/__spec__/table/test_stats.py b/frictionless/resources/__spec__/table/test_stats.py index b31114e97c..716f41fe31 100644 --- a/frictionless/resources/__spec__/table/test_stats.py +++ b/frictionless/resources/__spec__/table/test_stats.py @@ -1,5 +1,3 @@ -import sys - import pytest from frictionless import Dialect @@ -30,7 +28,6 @@ def test_resource_stats_hash_compressed(): @pytest.mark.vcr -@pytest.mark.skipif(sys.version_info < (3, 10), reason="pytest-vcr bug in Python3.8/9") def test_resource_stats_hash_remote(): with TableResource(path=BASEURL % "data/doublequote.csv") as resource: resource.read_rows() @@ -53,7 +50,6 @@ def test_resource_stats_bytes_compressed(): @pytest.mark.vcr -@pytest.mark.skipif(sys.version_info < (3, 10), reason="pytest-vcr bug in Python3.8/9") def test_resource_stats_bytes_remote(): with TableResource(path=BASEURL % "data/doublequote.csv") as resource: resource.read_rows() @@ -70,7 +66,6 @@ def test_resource_stats_fields(): @pytest.mark.vcr -@pytest.mark.skipif(sys.version_info < (3, 10), reason="pytest-vcr bug in Python3.8/9") def test_resource_stats_fields_remote(): with TableResource(path=BASEURL % "data/doublequote.csv") as resource: resource.read_rows() @@ -87,7 +82,6 @@ def test_resource_stats_rows(): @pytest.mark.vcr -@pytest.mark.skipif(sys.version_info < (3, 10), reason="pytest-vcr bug in Python3.8/9") def test_resource_stats_rows_remote(): with TableResource(path=BASEURL % "data/doublequote.csv") as resource: resource.read_rows() diff --git a/frictionless/schema/__spec__/test_general.py b/frictionless/schema/__spec__/test_general.py index 52dd3abf31..360c59f67b 100644 --- a/frictionless/schema/__spec__/test_general.py +++ b/frictionless/schema/__spec__/test_general.py @@ -1,6 +1,5 @@ import io import json -import sys import textwrap from decimal import Decimal from importlib import import_module @@ -61,7 +60,6 @@ def test_schema_descriptor_path(): @pytest.mark.vcr -@pytest.mark.skipif(sys.version_info < (3, 10), reason="pytest-vcr bug in Python3.8/9") def test_schema_descriptor_url(): url = BASEURL % "data/schema.json" schema = Schema(url) @@ -209,7 +207,10 @@ def test_schema_primary_foreign_keys_as_array(): schema = Schema(descriptor) assert schema.primary_key == ["name"] assert schema.foreign_keys == [ - {"fields": ["parent_id"], "reference": {"resource": "resource", "fields": ["id"]}} + { + "fields": ["parent_id"], + "reference": {"resource": "resource", "fields": ["id"]}, + } ] @@ -221,13 +222,19 @@ def test_schema_primary_foreign_keys_as_string(): ], "primaryKey": "name", "foreignKeys": [ - {"fields": "parent_id", "reference": {"resource": "resource", "fields": "id"}} + { + "fields": "parent_id", + "reference": {"resource": "resource", "fields": "id"}, + } ], } schema = Schema(descriptor) assert schema.primary_key == ["name"] assert schema.foreign_keys == [ - {"fields": ["parent_id"], "reference": {"resource": "resource", "fields": ["id"]}} + { + "fields": ["parent_id"], + "reference": {"resource": "resource", "fields": ["id"]}, + } ] diff --git a/frictionless/schemes/multipart/__spec__/test_loader.py b/frictionless/schemes/multipart/__spec__/test_loader.py index e7aac1abfa..8a5578fead 100644 --- a/frictionless/schemes/multipart/__spec__/test_loader.py +++ b/frictionless/schemes/multipart/__spec__/test_loader.py @@ -1,5 +1,4 @@ import json -import sys import pytest @@ -41,7 +40,6 @@ def test_multipart_loader_resource(): @pytest.mark.vcr -@pytest.mark.skipif(sys.version_info < (3, 10), reason="pytest-vcr bug in Python3.8/9") @pytest.mark.skipif(platform.type == "windows", reason="Fix on Windows") def test_multipart_loader_resource_remote(): descriptor = { @@ -62,7 +60,6 @@ def test_multipart_loader_resource_remote(): @pytest.mark.vcr -@pytest.mark.skipif(sys.version_info < (3, 10), reason="pytest-vcr bug in Python3.8/9") @pytest.mark.skipif(platform.type == "windows", reason="Fix on Windows") def test_multipart_loader_resource_remote_both_path_and_basepath(): descriptor = { diff --git a/frictionless/schemes/remote/__spec__/test_loader.py b/frictionless/schemes/remote/__spec__/test_loader.py index 7c4800b3a3..119ababbe6 100644 --- a/frictionless/schemes/remote/__spec__/test_loader.py +++ b/frictionless/schemes/remote/__spec__/test_loader.py @@ -1,5 +1,3 @@ -import sys - import pytest from frictionless import Dialect, platform, schemes @@ -12,7 +10,6 @@ @pytest.mark.vcr -@pytest.mark.skipif(sys.version_info < (3, 10), reason="pytest-vcr bug in Python3.8/9") def test_remote_loader(): with TableResource(path=BASEURL % "data/table.csv") as resource: assert resource.header == ["id", "name"] @@ -23,7 +20,6 @@ def test_remote_loader(): @pytest.mark.vcr -@pytest.mark.skipif(sys.version_info < (3, 10), reason="pytest-vcr bug in Python3.8/9") def test_remote_loader_latin1(): # Github returns wrong encoding `utf-8` with TableResource(path=BASEURL % "data/latin1.csv") as resource: @@ -32,7 +28,6 @@ def test_remote_loader_latin1(): @pytest.mark.ci @pytest.mark.vcr -@pytest.mark.skipif(sys.version_info < (3, 10), reason="pytest-vcr bug in Python3.8/9") def test_remote_loader_big_file(): dialect = Dialect(header=False) with TableResource(path=BASEURL % "data/table-1MB.csv", dialect=dialect) as resource: @@ -48,7 +43,6 @@ def test_remote_loader_big_file(): @pytest.mark.vcr -@pytest.mark.skipif(sys.version_info < (3, 10), reason="pytest-vcr bug in Python3.8/9") def test_remote_loader_http_preload(): control = schemes.RemoteControl(http_preload=True) with TableResource(path=BASEURL % "data/table.csv", control=control) as resource: @@ -79,7 +73,6 @@ def test_remote_loader_write(requests_mock): @pytest.mark.vcr -@pytest.mark.skipif(sys.version_info < (3, 10), reason="pytest-vcr bug in Python3.8/9") def test_remote_loader_if_remote_basepath_and_file_scheme_issue_1388(): resource = TableResource(path="table.csv", scheme="file", basepath=BASEURL % "data") assert resource.read_rows() == [ diff --git a/frictionless/system/__spec__/test_system.py b/frictionless/system/__spec__/test_system.py index 3f6d7a9d59..4dfc3f6112 100644 --- a/frictionless/system/__spec__/test_system.py +++ b/frictionless/system/__spec__/test_system.py @@ -1,4 +1,3 @@ -import sys import pytest import requests @@ -13,7 +12,6 @@ @pytest.mark.vcr -@pytest.mark.skipif(sys.version_info < (3, 10), reason="pytest-vcr bug in Python3.8/9") def test_system_use_context_http_session(): session = requests.Session() with system.use_context(http_session=session): diff --git a/pyproject.toml b/pyproject.toml index 02bcad8eb3..3b31277b6a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ dynamic = ["version"] description = "Data management framework for Python that provides functionality to describe, extract, validate, and transform tabular data" license = "MIT" readme = "README.md" -requires-python = ">=3.8" +requires-python = ">=3.10" urls.homepage = "https://github.com/frictionlessdata/frictionless-py" urls.changelog = "https://github.com/frictionlessdata/framework/blob/main/CHANGELOG.md" authors = [ @@ -26,8 +26,6 @@ classifiers = [ "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", @@ -43,8 +41,7 @@ dependencies = [ "pyyaml>=5.3", "isodate>=0.6", "rfc3986>=1.4", - "chardet>=3.0; python_version<'3.10'", - "chardet>=6.0; python_version>='3.10'", + "chardet>=6.0", "pydantic>=2.0", "requests>=2.10", "humanize>=4.2", @@ -160,7 +157,7 @@ version = [ [[tool.hatch.envs.ci.matrix]] -python = ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13", "3.14"] +python = ["3.10", "3.11", "3.12", "3.13", "3.14"] [tool.hatch.envs.ci.scripts] spec = [