Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NXDRIVE-2967: Upgrade the deprecated datetime adapter.. #5445

Open
wants to merge 12 commits into
base: wip-NXDRIVE-2929-upgrade-python-from-3.9.5-to-3.12.3
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ jobs:
if: matrix.os == 'macos-latest'
run: |
wget https://www.apple.com/appleca/AppleIncRootCertificate.cer
echo "${{ secrets.CERT_APP_MACOS }}" | base64 --decode > developerID_application.cer
echo "${{ secrets.CERT_APP_MACOS }}" | base64 --decode > developerID_application.p12
echo "${{ secrets.PRIV_APP_MACOS }}" | base64 --decode > nuxeo-drive.priv

#- name: "[macOS] Downloading Python"
Expand Down
24 changes: 24 additions & 0 deletions docs/changes/5.5.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Release date: `2024-xx-xx`

- [NXDRIVE-2909](https://jira.nuxeo.com/browse/NXDRIVE-2909): Set container title when defining the Folder type from Document Type Selection using Direct Transfer
- [NXDRIVE-2915](https://jira.nuxeo.com/browse/NXDRIVE-2915): Translate "Document type" and "container type" labels on Direct Transfer popup
- [NXDRIVE-2925](https://jira.nuxeo.com/browse/NXDRIVE-2925): Ignore zero-byte files

### Task Management
- [NXDRIVE-2](https://jira.nuxeo.com/browse/NXDRIVE-2):
Expand All @@ -27,6 +28,8 @@ Release date: `2024-xx-xx`

- [NXDRIVE-2970](https://jira.nuxeo.com/browse/NXDRIVE-2970): Fix security issue: urllib3's Proxy-Authorization request header isn't stripped during cross-origin redirects
- [NXDRIVE-2971](https://jira.nuxeo.com/browse/NXDRIVE-2971): Fix security issue: pyca/cryptography has a vulnerable OpenSSL included in cryptography wheels
- [NXDRIVE-2954](https://jira.nuxeo.com/browse/NXDRIVE-2954): [Mac] Certificate needs to be renewed
- [NXDRIVE-2976](https://hyland.atlassian.net/browse/NXDRIVE-2976): Fix security issue: Black vulnerable to Regular Expression Denial of Service (ReDoS)

## Tests

Expand All @@ -38,23 +41,44 @@ Release date: `2024-xx-xx`

## Minor Changes

- Upgraded `altgraph` from 0.17 to 0.17.4
- Upgraded `authlib` from 1.3.0 to 1.3.1
- Upgraded `black` from 23.12.1 to 24.10.0
- Upgraded `boto3` from 1.34.17 to 1.35.21
- Upgraded `botocore` from 1.34.17 to 1.35.21
- Upgraded `build` from 1.2.1 to 1.2.2
- Upgraded `cachetools` from 5.3.3 to 5.5.0
- Upgraded `certifi` from 2023.7.22 to 2024.7.4
- Upgraded `cryptography` from 42.0.5 to 43.0.1
- Upgraded `docutils` from 0.20.1 to 0.21.2
- Upgraded `faker` from 22.0.0 to 29.0.0
- Upgraded `filelock` from 3.14.0 to 3.16.1
- Upgraded `flake8` from 6.1.0 to 7.1.1
- Upgraded `future` from 0.18.3 to 1.0.0
- Upgraded `mypy` from 1.10.0 to 1.11.2
- Upgraded `types-python-dateutil` from 2.8.19.20240106 to 2.9.0.20240906
- Upgraded `typing-extensions` from 4.9.0 to 4.12.2
- Upgraded `pefile` from 2023.2.7 to 2024.8.26
- Upgraded `platformdirs` from 4.2.2 to 4.3.6
- Upgraded `pre-commit` from 2.16.0 to 3.8.0
- Upgraded `pycodestyle` from 2.11.1 to 2.12.1
- Upgraded `pycparser` from 2.21 to 2.22
- Upgraded `py-cpuinfo` from 8.0.0 to 9.0.0
- Upgraded `pyflakes` from 3.1.0 to 3.2.0
- Upgraded `pyobjc-core` from 10.1 to 10.3.1
- Upgraded `pyobjc-framework-cocoa` from 10.1 to 10.3.1
- Upgraded `pyobjc-framework-coreservices` from 10.1 to 10.3.1
- Upgraded `pyobjc-framework-scriptingbridge` from 10.1 to 10.3.1
- Upgraded `pyobjc-framework-fsevents` from 10.1 to 10.3.1
- Upgraded `pyobjc-framework-systemconfiguration` from 10.1 to 10.3.1
- Upgraded `pytest-benchmark` from 3.4.1 to 4.0.0
- Upgraded `python-dateutil` from 2.8.2 to 2.9.0.post0
- Upgraded `responses` from 0.24.1 to 0.25.3
- Upgraded `requests` from 2.31.0 to 2.32.3
- Upgraded `send2trash` from 1.7.1 to 1.8.3
- Upgraded `setuptools` from 69.5.1 to 72.1.0
- Upgraded `urllib3` from 1.26.12 to 1.26.19
- Upgraded `watchdog` from 3.0.0 to 5.0.2
- Upgraded `zipp` from 3.18.0 to 3.20.0

## Technical Changes
Expand Down
1 change: 1 addition & 0 deletions nxdrive/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
In this file we cannot use a relative import here, else Drive will not start when packaged.
See https://github.com/pyinstaller/pyinstaller/issues/2560
"""

import locale
import platform
import signal
Expand Down
1 change: 1 addition & 0 deletions nxdrive/behavior.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
Allow or disallow server deletions.

"""

from types import SimpleNamespace

Behavior = SimpleNamespace(server_deletion=True)
1 change: 1 addition & 0 deletions nxdrive/client/local/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
""" API to access local resources for synchronization. """

from .base import FileInfo, get

# Get the local client related to the current OS
Expand Down
6 changes: 3 additions & 3 deletions nxdrive/client/local/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import unicodedata
import uuid
from contextlib import suppress
from datetime import datetime
from datetime import datetime, timezone
from logging import getLogger
from pathlib import Path
from tempfile import mkdtemp
Expand Down Expand Up @@ -263,12 +263,12 @@
stat_info = os_path.stat()
size = 0 if folderish else stat_info.st_size
try:
mtime = datetime.utcfromtimestamp(stat_info.st_mtime)
mtime = datetime.fromtimestamp(stat_info.st_mtime, tz=timezone.utc)
except (ValueError, OverflowError, OSError) as e:
log.warning(
f"{e} file path: {os_path}. st_mtime value: {stat_info.st_mtime}"
)
mtime = datetime.utcfromtimestamp(0)
mtime = datetime.fromtimestamp(0, tz=timezone.utc)

Check warning on line 271 in nxdrive/client/local/base.py

View check run for this annotation

Codecov / codecov/patch

nxdrive/client/local/base.py#L271

Added line #L271 was not covered by tests
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Error handling should use consistent timezone approach

Both the try and except blocks now use timezone-aware timestamps, but the error handling could be more consistent by using a common approach or constant for the fallback time.

Suggested change
mtime = datetime.fromtimestamp(0, tz=timezone.utc)
EPOCH = datetime(1970, 1, 1, tzinfo=timezone.utc)
mtime = EPOCH


# TODO Do we need to load it every time ?
remote_ref = self.get_remote_id(ref)
Expand Down
1 change: 1 addition & 0 deletions nxdrive/client/uploader/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Uploader used by the Remote client for all upload stuff.
"""

import json
from abc import abstractmethod
from logging import getLogger
Expand Down
1 change: 1 addition & 0 deletions nxdrive/client/uploader/direct_transfer.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Uploader used by the Direct Transfer feature.
"""

import json
from logging import getLogger
from pathlib import Path
Expand Down
1 change: 1 addition & 0 deletions nxdrive/client/uploader/sync.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Uploader used by the synchronization engine.
"""

from pathlib import Path
from typing import Any, Dict, Optional

Expand Down
12 changes: 10 additions & 2 deletions nxdrive/dao/base.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
"""
Query formatting in this file is based on http://www.sqlstyle.guide/
"""

from datetime import datetime, timezone
import sys
from contextlib import suppress
from logging import getLogger
Expand All @@ -18,14 +20,20 @@

log = getLogger(__name__)


class AutoRetryCursor(Cursor):
def adapt_datetime_iso(self, val):
return datetime.fromtimestamp(val.strftime('%s'), tz=timezone.utc)

Check warning on line 25 in nxdrive/dao/base.py

View check run for this annotation

Codecov / codecov/patch

nxdrive/dao/base.py#L25

Added line #L25 was not covered by tests
def execute(self, sql: str, parameters: Iterable[Any] = ()) -> Cursor:
count = 1
while True:
count += 1
try:
return super().execute(sql, parameters)
import sqlite3
# return super().execute(sql, parameters)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: The datetime parameter conversion logic should be simplified and the original super().execute() call restored

The current implementation with register_adapter could have unintended side effects. Consider moving the datetime conversion to a separate method and maintaining the original execution flow.

# new_param = tuple( datetime.fromtimestamp(param, tz=timezone.utc) if isinstance(param, datetime) else param for param in parameters )
new_param = tuple( sqlite3.register_adapter(param, self.adapt_datetime_iso) if isinstance(param, datetime) else param for param in parameters )

return super().execute(sql, new_param)
except OperationalError as exc:
log.info(
f"Retry locked database #{count}, {sql=}, {parameters=}",
Expand Down
1 change: 1 addition & 0 deletions nxdrive/dao/engine.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Query formatting in this file is based on http://www.sqlstyle.guide/
"""

import json
import os
import shutil
Expand Down
1 change: 1 addition & 0 deletions nxdrive/dao/manager.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Query formatting in this file is based on http://www.sqlstyle.guide/
"""

from logging import getLogger
from pathlib import Path
from sqlite3 import Cursor, IntegrityError, Row
Expand Down
4 changes: 1 addition & 3 deletions nxdrive/engine/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -838,9 +838,7 @@ def resume_transfer(
meth = (
self.dao.get_download
if nature == "download"
else self.dao.get_dt_upload
if is_direct_transfer
else self.dao.get_upload
else self.dao.get_dt_upload if is_direct_transfer else self.dao.get_upload
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Nested ternary operator could be simplified for better readability

Consider using an if/elif/else block to make the logic more explicit and easier to maintain.

            else:
                if is_direct_transfer:
                    meth = self.dao.get_dt_upload
                else:
                    meth = self.dao.get_upload

)
func = partial(meth, uid=uid) # type: ignore
self._resume_transfers(nature, func, is_direct_transfer=is_direct_transfer)
Expand Down
1 change: 1 addition & 0 deletions nxdrive/fatal_error.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Fatal error screen management using either Qt or OS-specific dialogs.
"""

import sys
from contextlib import suppress
from pathlib import Path
Expand Down
1 change: 1 addition & 0 deletions nxdrive/feature.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
Enable or disable the synchronization features.

"""

from types import SimpleNamespace
from typing import List

Expand Down
1 change: 1 addition & 0 deletions nxdrive/gui/application.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
""" Main Qt application handling OS events and system tray UI. """

import os
import webbrowser
from contextlib import suppress
Expand Down
12 changes: 11 additions & 1 deletion nxdrive/gui/folders_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,9 @@
txt += f" (+{self.overall_count - 1:,})"
return txt

def get_size(self, file_path: Path) -> bool:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): Return type hint is incorrect - method returns an integer not a boolean

return file_path.stat().st_size

Check warning on line 628 in nxdrive/gui/folders_dialog.py

View check run for this annotation

Codecov / codecov/patch

nxdrive/gui/folders_dialog.py#L628

Added line #L628 was not covered by tests

def _process_additionnal_local_paths(self, paths: List[str], /) -> None:
"""Append more local paths to the upload queue."""
for local_path in paths:
Expand All @@ -647,10 +650,17 @@
# Save the path
if path.is_dir():
for file_path, size in get_tree_list(path):
if self.get_size(file_path) == 0:

Check warning on line 653 in nxdrive/gui/folders_dialog.py

View check run for this annotation

Codecov / codecov/patch

nxdrive/gui/folders_dialog.py#L653

Added line #L653 was not covered by tests
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (performance): Redundant size check - file size is already available from get_tree_list()

Consider using the size value already provided by get_tree_list() instead of calling get_size() again.

Suggested change
if self.get_size(file_path) == 0:
if size == 0:

# ignoring zero byte files [NXDRIVE-2925]
continue

Check warning on line 655 in nxdrive/gui/folders_dialog.py

View check run for this annotation

Codecov / codecov/patch

nxdrive/gui/folders_dialog.py#L655

Added line #L655 was not covered by tests
self.paths[file_path] = size
else:
try:
self.paths[path] = path.stat().st_size
file_size = self.get_size(path)
if file_size == 0:

Check warning on line 660 in nxdrive/gui/folders_dialog.py

View check run for this annotation

Codecov / codecov/patch

nxdrive/gui/folders_dialog.py#L659-L660

Added lines #L659 - L660 were not covered by tests
# ignoring zero byte files [NXDRIVE-2925]
continue
self.paths[path] = file_size

Check warning on line 663 in nxdrive/gui/folders_dialog.py

View check run for this annotation

Codecov / codecov/patch

nxdrive/gui/folders_dialog.py#L662-L663

Added lines #L662 - L663 were not covered by tests
except OSError:
log.warning(f"Error calling stat() on {path!r}", exc_info=True)
continue
Expand Down
1 change: 1 addition & 0 deletions nxdrive/osi/darwin/pyNotificationCenter.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
""" Python integration macOS notification center. """

from typing import TYPE_CHECKING, Dict

from CoreServices import (
Expand Down
1 change: 1 addition & 0 deletions nxdrive/qt/constants.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Put here all PyQt constants used across the project.
"""

from .imports import (
QAbstractSocket,
QDialogButtonBox,
Expand Down
1 change: 1 addition & 0 deletions nxdrive/qt/imports.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Put here all PyQt imports used across the project.
"""

from PyQt5.QtCore import (
QT_VERSION_STR,
QAbstractListModel,
Expand Down
1 change: 1 addition & 0 deletions nxdrive/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
This state is set at the start of the application to know if it has crashed at the previous run.

"""

from types import SimpleNamespace

State = SimpleNamespace(about_to_quit=False, crash_details="", has_crashed=False)
1 change: 1 addition & 0 deletions nxdrive/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
Most of functions are pure enough to be decorated with a LRU cache.
Each *maxsize* is adjusted depending of the heavy use of the decorated function.
"""

import os
import os.path
import re
Expand Down
1 change: 1 addition & 0 deletions tests/benchmarks/test_safe_filename.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
If is not the most efficient for small ASCII-only filenames,
but it is the best when there are non-ASCII characters.
"""

import pytest

FILENAMES = [
Expand Down
1 change: 1 addition & 0 deletions tests/cleanup.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Cleanup old test users and workspaces."""

import env
from nuxeo.client import Nuxeo

Expand Down
4 changes: 0 additions & 4 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,6 @@ def no_warnings(recwarn):
continue
elif "Cryptography will be significantly faster" in message:
continue
elif "The default datetime adapter is deprecated as of Python 3.12" in message:
continue
elif "datetime.datetime" in message:
continue

warn = f"{warning.filename}:{warning.lineno} {message}"
print(warn, file=sys.stderr)
Expand Down
4 changes: 3 additions & 1 deletion tests/integration/windows/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,9 @@ def test_argument_log_filename(exe, tmp, file):
assert log.is_file()


@pytest.mark.parametrize("folder", ["azerty", "$alice", "léa", "mi Kaël", "こん ツリ ^^"])
@pytest.mark.parametrize(
"folder", ["azerty", "$alice", "léa", "mi Kaël", "こん ツリ ^^"]
)
def test_argument_nxdrive_home(exe, tmp, folder):
path = tmp()
path.mkdir(parents=True, exist_ok=True)
Expand Down
1 change: 1 addition & 0 deletions tests/markers.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Collection of pytest markers to ease test filtering."""

import os

import pytest
Expand Down
1 change: 1 addition & 0 deletions tests/old_functional/common.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
""" Common test utilities. """

import os
import sys
import tempfile
Expand Down
1 change: 1 addition & 0 deletions tests/old_functional/test_behavior.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Test application Behavior.
"""

from nxdrive.behavior import Behavior

from .. import ensure_no_exception
Expand Down
1 change: 1 addition & 0 deletions tests/old_functional/test_direct_transfer.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Test the Direct Transfer feature in different scenarii.
"""

import logging
import re
from pathlib import Path
Expand Down
1 change: 1 addition & 0 deletions tests/old_functional/test_local_changes_when_offline.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Test if changes made to local file system when Drive is offline sync's back
later when Drive becomes online.
"""

import pytest

from nxdrive.constants import WINDOWS
Expand Down
1 change: 1 addition & 0 deletions tests/old_functional/test_local_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

See NXDRIVE-742.
"""

import hashlib
import os
from pathlib import Path
Expand Down
1 change: 1 addition & 0 deletions tests/old_functional/test_synchronization_dedup.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Test behaviors when the server allows duplicates and not the client.
"""

from pathlib import Path

import pytest
Expand Down
1 change: 1 addition & 0 deletions tests/old_functional/test_transfer.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Test pause/resume transfers in different scenarii.
"""

import re
from unittest.mock import patch

Expand Down
1 change: 1 addition & 0 deletions tests/unit/test_autolock.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Test the Auto-Lock feature used heavily by Direct Edit.
"""

from pathlib import Path
from typing import List, Tuple
from unittest.mock import Mock, patch
Expand Down
Loading
Loading