From 93a9749d23e8867014bdebceb1aa5fdc05bae93e Mon Sep 17 00:00:00 2001 From: Thomas H Date: Fri, 23 Aug 2024 10:42:13 -0400 Subject: [PATCH 1/5] Add .vscode to .gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index e3312579..059c6188 100644 --- a/.gitignore +++ b/.gitignore @@ -139,3 +139,6 @@ cython_debug/ # setuptools_scm upath/_version.py + +# vscode workspace settings +.vscode/ From 3e019835b0c1218afcf977aff33e17bc5229aff0 Mon Sep 17 00:00:00 2001 From: Thomas H Date: Fri, 23 Aug 2024 10:42:59 -0400 Subject: [PATCH 2/5] Add tests for stat time values --- upath/tests/test_stat.py | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/upath/tests/test_stat.py b/upath/tests/test_stat.py index 66d9668c..6b91e987 100644 --- a/upath/tests/test_stat.py +++ b/upath/tests/test_stat.py @@ -25,15 +25,35 @@ def test_stat_as_info(pth_file): def test_stat_atime(pth_file): - assert isinstance(pth_file.stat().st_atime, (float, int)) + atime = pth_file.stat().st_atime + assert isinstance(atime, (float, int)) + + +@pytest.mark.xfail(reason="fsspec does not return 'atime'") +def test_stat_atime_value(pth_file): + atime = pth_file.stat().st_atime + assert atime > 0 def test_stat_mtime(pth_file): - assert isinstance(pth_file.stat().st_mtime, (float, int)) + mtime = pth_file.stat().st_mtime + assert isinstance(mtime, (float, int)) + + +def test_stat_mtime_value(pth_file): + mtime = pth_file.stat().st_mtime + assert mtime > 0 def test_stat_ctime(pth_file): - assert isinstance(pth_file.stat().st_ctime, (float, int)) + ctime = pth_file.stat().st_ctime + assert isinstance(ctime, (float, int)) + + +@pytest.mark.xfail(reason="fsspec returns 'created' but not 'ctime'") +def test_stat_ctime_value(pth_file): + ctime = pth_file.stat().st_ctime + assert ctime > 0 def test_stat_seq_interface(pth_file): From 36edb80e468d8940478173246d80642a691af1ec Mon Sep 17 00:00:00 2001 From: Thomas H Date: Fri, 23 Aug 2024 10:43:08 -0400 Subject: [PATCH 3/5] Add tests for birthtime --- upath/tests/test_stat.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/upath/tests/test_stat.py b/upath/tests/test_stat.py index 6b91e987..4922ae1e 100644 --- a/upath/tests/test_stat.py +++ b/upath/tests/test_stat.py @@ -56,6 +56,16 @@ def test_stat_ctime_value(pth_file): assert ctime > 0 +def test_stat_birthtime(pth_file): + birthtime = pth_file.stat().st_birthtime + assert isinstance(birthtime, (float, int)) + + +def test_stat_birthtime_value(pth_file): + birthtime = pth_file.stat().st_birthtime + assert birthtime > 0 + + def test_stat_seq_interface(pth_file): assert len(tuple(pth_file.stat())) == os.stat_result.n_sequence_fields assert isinstance(pth_file.stat().index(0), int) From f5075a9cb1f4b538a098fa81797fb24a2f417822 Mon Sep 17 00:00:00 2001 From: Thomas H Date: Fri, 23 Aug 2024 10:43:22 -0400 Subject: [PATCH 4/5] Move birthtime implementation --- upath/_stat.py | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/upath/_stat.py b/upath/_stat.py index f2cbece7..5e03440c 100644 --- a/upath/_stat.py +++ b/upath/_stat.py @@ -281,6 +281,26 @@ def st_ctime(self) -> int | float: pass return self._seq[9] + @property + def st_birthtime(self) -> int | float: + """time of creation""" + for key in [ + "birthtime", + "created", + "creation_time", + "timeCreated", + "created_at" + ]: + try: + raw_value = self._info[key] + except KeyError: + continue + try: + return _convert_value_to_timestamp(raw_value) + except (TypeError, ValueError): + pass + raise AttributeError("birthtime") + # --- extra fields ------------------------------------------------ def __getattr__(self, item): @@ -288,22 +308,6 @@ def __getattr__(self, item): return 0 # fallback default value raise AttributeError(item) - if "st_birthtime" in _fields_extra: - - @property - def st_birthtime(self) -> int | float: - """time of creation""" - for key in ["created", "creation_time", "timeCreated", "created_at"]: - try: - raw_value = self._info[key] - except KeyError: - continue - try: - return _convert_value_to_timestamp(raw_value) - except (TypeError, ValueError): - pass - return 0 - # --- os.stat_result tuple interface ------------------------------ def __len__(self) -> int: From d607d0464c4055127f446b1f9c733f6d5e9a7d9b Mon Sep 17 00:00:00 2001 From: Andreas Poehlmann Date: Fri, 23 Aug 2024 19:28:33 +0200 Subject: [PATCH 5/5] upath._stat: fix linter error --- upath/_stat.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/upath/_stat.py b/upath/_stat.py index 5e03440c..5a4f0b1f 100644 --- a/upath/_stat.py +++ b/upath/_stat.py @@ -289,7 +289,7 @@ def st_birthtime(self) -> int | float: "created", "creation_time", "timeCreated", - "created_at" + "created_at", ]: try: raw_value = self._info[key]