diff --git a/.github/workflows/pr-tests.yml b/.github/workflows/pr-tests.yml index c057de664..fa8041488 100644 --- a/.github/workflows/pr-tests.yml +++ b/.github/workflows/pr-tests.yml @@ -1,4 +1,6 @@ name: PR Tests +permissions: + contents: read on: pull_request: @@ -8,6 +10,8 @@ on: jobs: pr-tests: - uses: CitrineInformatics/common-gh-actions/.github/workflows/run-tests.yml@v1 + uses: CitrineInformatics/common-gh-actions/.github/workflows/run-tests.yml@v1.1 with: src: src/citrine + include_313: true + skip_38: false diff --git a/.gitignore b/.gitignore index 555271b2a..f4ec3857e 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,7 @@ wheels/ .installed.cfg *.egg MANIFEST +out/ # PyInstaller # Usually these files are written by a python script from a template @@ -46,6 +47,7 @@ coverage.xml *.cover .hypothesis/ .pytest_cache/ +prof/ # Translations *.mo diff --git a/setup.py b/setup.py index 848e1f4e0..d5f029112 100644 --- a/setup.py +++ b/setup.py @@ -46,5 +46,7 @@ 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', 'Programming Language :: Python :: 3.11', + 'Programming Language :: Python :: 3.12', + 'Programming Language :: Python :: 3.13', ], ) diff --git a/src/citrine/__version__.py b/src/citrine/__version__.py index dbea1a391..ce13706c4 100644 --- a/src/citrine/__version__.py +++ b/src/citrine/__version__.py @@ -1 +1 @@ -__version__ = "3.23.0" +__version__ = "3.23.1" diff --git a/src/citrine/resources/file_link.py b/src/citrine/resources/file_link.py index 824369449..e4e558d99 100644 --- a/src/citrine/resources/file_link.py +++ b/src/citrine/resources/file_link.py @@ -518,8 +518,7 @@ def _search_by_dataset_file_id(self, @staticmethod def _mime_type(file_path: Path): - # This string coercion is for supporting pathlib.Path objects in python < 3.8 - mime_type = mimetypes.guess_type(str(file_path))[0] + mime_type, _ = mimetypes.guess_type(file_path) if mime_type is None: mime_type = "application/octet-stream" return mime_type diff --git a/tests/resources/test_file_link.py b/tests/resources/test_file_link.py index 0a768a1cc..338559e97 100644 --- a/tests/resources/test_file_link.py +++ b/tests/resources/test_file_link.py @@ -1,4 +1,5 @@ from pathlib import Path +import platform from typing import Collection from uuid import uuid4, UUID @@ -39,19 +40,27 @@ def valid_data() -> dict: return FileLinkDataFactory(url='www.citrine.io', filename='materials.txt') -def test_mime_types(collection: FileCollection): - expected_xlsx = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" - expected_xls = "application/vnd.ms-excel" - expected_txt = "text/plain" - expected_unk = "application/octet-stream" - expected_csv = "text/csv" - - assert collection._mime_type(Path("asdf.xlsx")) == expected_xlsx - assert collection._mime_type(Path("asdf.XLSX")) == expected_xlsx - assert collection._mime_type(Path("asdf.xls")) == expected_xls - assert collection._mime_type(Path("asdf.TXT")) == expected_txt - assert collection._mime_type(Path("asdf.csv")) == expected_csv - assert collection._mime_type(Path("asdf.FAKE")) == expected_unk +@pytest.mark.parametrize( + ("filename", "mimetype"), + [ + pytest.param( + "asdf.xlsx", + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + marks=pytest.mark.xfail( + platform.system() == "Windows", + reason="windows-latest test servers omit xlsx from their registry", + strict=True + ) + ), + ("asdf.xls", "application/vnd.ms-excel"), + ("asdf.XLS", "application/vnd.ms-excel"), + ("asdf.TXT", "text/plain"), + ("asdf.csv", "text/csv"), + ("asdf.FAKE", "application/octet-stream"), + ], +) +def test_mime_types(collection: FileCollection, filename, mimetype): + assert collection._mime_type(Path(filename)) == mimetype def test_build_equivalence(collection, valid_data): @@ -77,9 +86,9 @@ def test_string_representation(valid_data): def test_from_path(): """Test the string representation.""" - path = '/some/path/with/file.txt' + path = Path.cwd() / 'some' / 'path' / 'with' / 'file.txt' assert FileLink.from_path(path).filename == 'file.txt' - assert FileLink.from_path(Path(path)).url == Path(path).as_uri() + assert FileLink.from_path(str(path)).url == path.as_uri() assert FileCollection._is_local_url(FileLink.from_path(path).url)