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

Update different details now we support Py>-3.6 only #440

Merged
merged 3 commits into from
Jul 21, 2024
Merged
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
6 changes: 1 addition & 5 deletions fades/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2015-2016 Facundo Batista, Nicolás Demarchi
# Copyright 2015-2024 Facundo Batista, Nicolás Demarchi
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General
Expand Down Expand Up @@ -26,7 +26,3 @@ class FadesError(Exception):

REPO_PYPI = 'pypi'
REPO_VCS = 'vcs'

# Not using http.server.HTTPStatus to support python < 3.5
HTTP_STATUS_NOT_FOUND = 404
HTTP_STATUS_OK = 200
9 changes: 6 additions & 3 deletions fades/envbuilder.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import pathlib
import shutil

from datetime import datetime
from datetime import datetime, timezone
from venv import EnvBuilder
from uuid import uuid4

Expand All @@ -32,6 +32,9 @@

logger = logging.getLogger(__name__)

# UTC can be imported directly from datetime from Python 3.11
UTC = timezone.utc


class _FadesEnvBuilder(EnvBuilder):
"""Create always a virtual environment.
Expand Down Expand Up @@ -199,7 +202,7 @@ def _create_initial_usage_file_if_not_exists(self):

def _write_venv_usage(self, file_, venv_data):
_, uuid = os.path.split(venv_data['env_path'])
file_.write('{} {}\n'.format(uuid, self._datetime_to_str(datetime.utcnow())))
file_.write('{} {}\n'.format(uuid, self._datetime_to_str(datetime.now(UTC))))

def _datetime_to_str(self, datetime_):
return datetime.strftime(datetime_, "%Y-%m-%dT%H:%M:%S.%f")
Expand All @@ -219,7 +222,7 @@ def clean_unused_venvs(self, max_days_to_keep):
called, this records will be deleted.
"""
with filelock(self.stat_file_lock):
now = datetime.utcnow()
now = datetime.now(UTC)
venvs_dict = self._get_compacted_dict_usage_from_file()
for venv_uuid, usage_date in venvs_dict.copy().items():
usage_date = self._str_to_datetime(usage_date)
Expand Down
10 changes: 5 additions & 5 deletions fades/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,14 @@
import logging
import subprocess
import tempfile
from http.server import HTTPStatus
from urllib import request, parse
from urllib.error import HTTPError

from packaging.requirements import Requirement
from packaging.version import Version

from fades import FadesError, HTTP_STATUS_NOT_FOUND, HTTP_STATUS_OK, _version
from fades import FadesError, _version

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -227,20 +228,19 @@ def _pypi_head_package(dependency):
try:
response = request.urlopen(req)
except HTTPError as http_error:
if http_error.code == HTTP_STATUS_NOT_FOUND:
if http_error.code == HTTPStatus.NOT_FOUND:
return False
else:
raise
if response.status == HTTP_STATUS_OK:
if response.status == HTTPStatus.OK:
logger.debug("%r exists in PyPI.", dependency)
return True
else:
# Maybe we are getting somethink like a redirect. In this case we are only
# warning to the user and trying to install the dependency.
# In the worst scenery fades will fail to install it.
logger.warning("Got a (unexpected) HTTP_STATUS=%r and reason=%r checking if %r exists",
response.status, response.reason, dependency)
return True
return True


def check_pypi_exists(dependencies):
Expand Down
15 changes: 4 additions & 11 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,37 +14,30 @@
#
# For further info, check https://github.com/PyAr/fades

import shutil
import uuid

from pytest import fixture


@fixture(scope="function")
def tmp_file(tmpdir_factory):
def tmp_file(tmp_path):
"""Fixture for a unique tmpfile for each test."""
dir_path = tmpdir_factory.mktemp("test")
yield str(dir_path.join("testfile")) # Converted to str to support python <3.6 versions
shutil.rmtree(str(dir_path))
yield str(tmp_path / "testfile") # XXX Facundo 2024-04-17: remove str() after #435


@fixture(scope="function")
def create_tmpfile(tmpdir_factory):
dir_path = tmpdir_factory.mktemp("test")
def create_tmpfile(tmp_path):

def add_content(lines):
"""Fixture for a unique tmpfile for each test."""
namefile = str(
dir_path.join("testfile_{}".format(uuid.uuid4()))
) # Converted to str to support python <3.6 versions
namefile = tmp_path / f"testfile_{uuid.uuid4()}"
with open(namefile, "w", encoding="utf-8") as f:
for line in lines:
f.write(line + "\n")

return namefile

yield add_content
shutil.rmtree(str(dir_path))


def pytest_addoption(parser):
Expand Down
12 changes: 6 additions & 6 deletions tests/test_envbuilder.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,11 +296,11 @@ def test_usage_record_is_recorded(self):
msg="Selected uuid is two times in file")

def test_usage_file_is_compacted_when_though_no_venv_is_removed(self):
old_date = datetime.utcnow()
old_date = datetime.now()
new_date = old_date + timedelta(days=1)

with patch('fades.envbuilder.datetime') as mock_datetime:
mock_datetime.utcnow.return_value = old_date
mock_datetime.now.return_value = old_date
mock_datetime.strptime.side_effect = lambda *args, **kw: datetime.strptime(*args, **kw)
mock_datetime.strftime.side_effect = lambda *args, **kw: datetime.strftime(*args, **kw)

Expand All @@ -312,7 +312,7 @@ def test_usage_file_is_compacted_when_though_no_venv_is_removed(self):
venv = self.venvscache.get_venv(uuid=self.uuids[0])
manager.store_usage_stat(venv, self.venvscache)

mock_datetime.utcnow.return_value = new_date
mock_datetime.now.return_value = new_date
manager.store_usage_stat(venv, self.venvscache)

lines = self.get_usage_lines(manager)
Expand Down Expand Up @@ -351,11 +351,11 @@ def test_general_error_exception(self):
self.assertEqual(str(cm.exception), "General error while running external venv")

def test_when_a_venv_is_removed_it_is_removed_from_everywhere(self):
old_date = datetime.utcnow()
old_date = datetime.now()
new_date = old_date + timedelta(days=5)

with patch('fades.envbuilder.datetime') as mock_datetime:
mock_datetime.utcnow.return_value = old_date
mock_datetime.now.return_value = old_date
mock_datetime.strptime.side_effect = lambda *args, **kw: datetime.strptime(*args, **kw)
mock_datetime.strftime.side_effect = lambda *args, **kw: datetime.strftime(*args, **kw)

Expand All @@ -367,7 +367,7 @@ def test_when_a_venv_is_removed_it_is_removed_from_everywhere(self):
venv = self.venvscache.get_venv(uuid=self.uuids[0])
manager.store_usage_stat(venv, self.venvscache)

mock_datetime.utcnow.return_value = new_date
mock_datetime.now.return_value = new_date
manager.store_usage_stat(venv, self.venvscache)

lines = self.get_usage_lines(manager)
Expand Down
15 changes: 7 additions & 8 deletions tests/test_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
import sys
import tempfile
import unittest

from http.server import HTTPStatus
from unittest.mock import patch
from urllib.error import HTTPError
from urllib.request import Request
Expand All @@ -31,8 +31,7 @@
import pytest
from xdg import BaseDirectory

from fades import HTTP_STATUS_NOT_FOUND, HTTP_STATUS_OK, helpers
from fades import parsing
from fades import helpers, parsing


PATH_TO_EXAMPLES = "tests/examples/"
Expand Down Expand Up @@ -307,7 +306,7 @@ def test_exists(self):

with patch('urllib.request.urlopen') as mock_urlopen:
with patch('http.client.HTTPResponse') as mock_http_response:
mock_http_response.status = HTTP_STATUS_OK
mock_http_response.status = HTTPStatus.OK
mock_urlopen.return_value = mock_http_response

exists = helpers.check_pypi_exists(deps)
Expand All @@ -319,7 +318,7 @@ def test_all_exists(self):

with patch('urllib.request.urlopen') as mock_urlopen:
with patch('http.client.HTTPResponse') as mock_http_response:
mock_http_response.status = HTTP_STATUS_OK
mock_http_response.status = HTTPStatus.OK
mock_urlopen.side_effect = [mock_http_response] * 3

exists = helpers.check_pypi_exists(dependencies)
Expand All @@ -330,7 +329,7 @@ def test_doesnt_exists(self):
dependency = parsing.parse_manual(["foo"])

with patch('urllib.request.urlopen') as mock_urlopen:
mock_http_error = HTTPError("url", HTTP_STATUS_NOT_FOUND, "mgs", {}, io.BytesIO())
mock_http_error = HTTPError("url", HTTPStatus.NOT_FOUND, "mgs", {}, io.BytesIO())
mock_urlopen.side_effect = mock_http_error

exists = helpers.check_pypi_exists(dependency)
Expand All @@ -343,8 +342,8 @@ def test_one_doesnt_exists(self):

with patch('urllib.request.urlopen') as mock_urlopen:
with patch('http.client.HTTPResponse') as mock_http_response:
mock_http_error = HTTPError("url", HTTP_STATUS_NOT_FOUND, "mgs", {}, io.BytesIO())
mock_http_response.status = HTTP_STATUS_OK
mock_http_error = HTTPError("url", HTTPStatus.NOT_FOUND, "mgs", {}, io.BytesIO())
mock_http_response.status = HTTPStatus.OK
mock_urlopen.side_effect = [mock_http_response, mock_http_error]

exists = helpers.check_pypi_exists(dependencies)
Expand Down
Loading