From 08588280940641c96c7718466d92c808b5ed445d Mon Sep 17 00:00:00 2001 From: AHReccese Date: Wed, 1 Jan 2025 20:33:48 -0500 Subject: [PATCH 01/17] refactor test cases --- tests/test_reserver.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/tests/test_reserver.py b/tests/test_reserver.py index b496773..7625094 100644 --- a/tests/test_reserver.py +++ b/tests/test_reserver.py @@ -1,9 +1,9 @@ +import os from reserver import PyPIUploader from reserver.reserver_func import get_random_name -import os -test_pypi_token = os.environ.get("TWINE_TEST_PASSWORD") pypi_token = os.environ.get("TWINE_PASSWORD") +test_pypi_token = os.environ.get("TWINE_TEST_PASSWORD") def test_package_exists(): # test reserved name @@ -15,31 +15,31 @@ def test_standard_module_conflict(): uploader = PyPIUploader(test_pypi_token, test_pypi=True) assert uploader.upload("os") == False -def test_batch_packages_names(): - # test batch of package names - uploader = PyPIUploader(test_pypi_token, test_pypi=True) - assert uploader.batch_upload(["numpy", "scikit-learn"]) == 0 - def test_valid_package_invalid_credentials(): # test not reserved name -> wrong credentials - wrong_pypi_token = "pypi-wrong-api-token" - uploader = PyPIUploader(wrong_pypi_token, test_pypi=True) + uploader = PyPIUploader("pypi-wrong-api-token", test_pypi=True) assert uploader.upload(get_random_name()) == False def test_valid_package_valid_credentials(): # test not reserved name -> correct credentials # uploader = PyPIUploader(test_pypi_token, test_pypi=True) - # uploader.upload(get_random_name()) + # assert uploader.upload(get_random_name()) == True assert True == True def test_module_conflict(): # try to reserve a name which conflicts with the module name of a previously taken package (the taken package itself has a different name, but it's module name has conflict)." - uploader = PyPIUploader(pypi_token, test_pypi=False) + uploader = PyPIUploader(test_pypi_token, test_pypi=True) assert uploader.upload("freeze") == False +def test_batch_packages_names(): + # test batch of package names + uploader = PyPIUploader(test_pypi_token, test_pypi=True) + assert uploader.batch_upload(["numpy", "scikit-learn"]) == 0 + def test_batch_upload(): # try to reserve two non taken package names with per package custom setup.py parameters - # uploader = PyPIUploader(test_pypi_token, True) + # make sure you are in "tests" directory + # uploader = PyPIUploader(test_pypi_token, test_pypi=True) # assert uploader.batch_upload( # [get_random_name(), get_random_name() + get_random_name()], # ["config.json", "config2.json"] From 77b1fa6407972d5fb58c13187632022531254d93 Mon Sep 17 00:00:00 2001 From: AHReccese Date: Wed, 1 Jan 2025 20:35:01 -0500 Subject: [PATCH 02/17] remove get request query because of `fastly` proxy --- reserver/reserver_func.py | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/reserver/reserver_func.py b/reserver/reserver_func.py index b824d18..ec50766 100644 --- a/reserver/reserver_func.py +++ b/reserver/reserver_func.py @@ -20,37 +20,6 @@ def get_random_name(): return sha256(str(time()).encode("utf-8")).hexdigest() -def does_package_exist(suggested_name, test_pypi): - """ - Check whether a package with the given name exists or not. - - :param suggested_name: given name to search in pypi(or test.pypi) - :type suggested_name: str - :param test_pypi: indicates to search in test.pypi or not - :type test_pypi: bool - :return: whether given name does exist in the pypi or not(as a boolean value) - """ - if not isinstance(suggested_name, str): - suggested_name = str(suggested_name) - if test_pypi: - url = PYPI_TEST_URL + "/" + suggested_name + "/" - else: - url = PYPI_MAIN_URL + "/" + suggested_name + "/" - - s = requests.Session() - retries = requests.adapters.Retry( - total=5, - backoff_factor=0.1, - status_forcelist=[500, 502, 503, 504] - ) - - s.mount('http://', requests.adapters.HTTPAdapter(max_retries=retries)) - s.mount('https://', requests.adapters.HTTPAdapter(max_retries=retries)) - - response = s.get(url, timeout=5) - return not response.status_code == 404 - - def get_package_parameter(parameter, user_parameters, regex=None): """ Get the value for the associated package parameter. From 4962c199cc4ddc8e9fb56b0811930766d4a6b77f Mon Sep 17 00:00:00 2001 From: AHReccese Date: Wed, 1 Jan 2025 20:38:21 -0500 Subject: [PATCH 03/17] remove `requests` and `chardet` dependencies --- dev-requirements.txt | 2 -- requirements.txt | 2 -- 2 files changed, 4 deletions(-) diff --git a/dev-requirements.txt b/dev-requirements.txt index 6504c7d..c42eb1c 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1,5 +1,4 @@ art==6.4 -requests==2.32.3 setuptools==75.6.0 wheel==0.45.1 twine==6.0.1 @@ -8,4 +7,3 @@ bandit>=1.5.1 pydocstyle>=3.0.0 pytest>=4.3.1 pytest-cov>=2.6.1 -chardet==5.2.0 diff --git a/requirements.txt b/requirements.txt index f5bf9df..abe875b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,4 @@ art>=5.3 -requests>=1.0.0 setuptools>=40.8.0 wheel>=0.35.0 twine>=3.5.0 -chardet>=4.0.0 From 97fca253227945eca9bdcb746bec6ba445dbf6c8 Mon Sep 17 00:00:00 2001 From: AHReccese Date: Wed, 1 Jan 2025 20:38:34 -0500 Subject: [PATCH 04/17] remove unused imports and re-order imports --- reserver/reserver_func.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/reserver/reserver_func.py b/reserver/reserver_func.py index ec50766..7cabba8 100644 --- a/reserver/reserver_func.py +++ b/reserver/reserver_func.py @@ -1,14 +1,12 @@ # -*- coding: utf-8 -*- """Reserver functions.""" import re -import requests -import requests.adapters -from .reserver_param import PYPI_TEST_URL, PYPI_MAIN_URL, PACKAGE_PARAMETERS, VALIDATIONS, OVERVIEW -from .reserver_param import INVALID_PACKAGE_PARAMETER_NAME_ERROR, INVALID_PACKAGE_PARAMETER_VALUE_ERROR -from .reserver_errors import ReserverBaseError -from hashlib import sha256 from time import time +from hashlib import sha256 from os import mkdir, rmdir +from .reserver_param import PACKAGE_PARAMETERS, VALIDATIONS, OVERVIEW +from .reserver_param import INVALID_PACKAGE_PARAMETER_NAME_ERROR, INVALID_PACKAGE_PARAMETER_VALUE_ERROR +from .reserver_errors import ReserverBaseError def get_random_name(): From ae585ca276e8da8814823efa6532c13de25ff433 Mon Sep 17 00:00:00 2001 From: AHReccese Date: Wed, 1 Jan 2025 20:38:48 -0500 Subject: [PATCH 05/17] remove unused params --- reserver/reserver_param.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/reserver/reserver_param.py b/reserver/reserver_param.py index 92921e8..5c0389d 100644 --- a/reserver/reserver_param.py +++ b/reserver/reserver_param.py @@ -5,8 +5,6 @@ """ RESERVER_VERSION = "0.3" RESERVER_NAME = "reserver" -PYPI_TEST_URL = "https://test.pypi.org/project" -PYPI_MAIN_URL = "https://pypi.org/project" PACKAGE_PARAMETERS = { "description": "This name has been reserved using Reserver", "author": "Development Team", From 14f62f70a3b54c2a5c25733ab31fb20564c5b69e Mon Sep 17 00:00:00 2001 From: AHReccese Date: Wed, 1 Jan 2025 20:39:25 -0500 Subject: [PATCH 06/17] accept direct param dict --- reserver/reserver_obj.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/reserver/reserver_obj.py b/reserver/reserver_obj.py index 5c908d1..0f4d547 100644 --- a/reserver/reserver_obj.py +++ b/reserver/reserver_obj.py @@ -71,15 +71,11 @@ def upload(self, package_name, user_parameters=None): :param package_name: package name :type package_name: str - :param user_parameters: path to the .json file containing user-defined package parameters - :type user_parameters: str + :param user_parameters: json file or path to the .json file containing user-defined package parameters + :type user_parameters: str | dict :return: True if the package is successfully reserved, False otherwise """ - if does_package_exist(package_name, self.test_pypi): - print("This package already exists in PyPI.") - return False - - if user_parameters is not None: + if not isinstance(user_parameters, dict) and user_parameters is not None: user_parameters = read_json(user_parameters) generate_template_setup_py(package_name, user_parameters) From 8d6457793079a164ca06fb38158a20dc0ffa0e46 Mon Sep 17 00:00:00 2001 From: AHReccese Date: Wed, 1 Jan 2025 20:39:41 -0500 Subject: [PATCH 07/17] mute warnings --- reserver/reserver_obj.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/reserver/reserver_obj.py b/reserver/reserver_obj.py index 0f4d547..9a07a37 100644 --- a/reserver/reserver_obj.py +++ b/reserver/reserver_obj.py @@ -94,7 +94,10 @@ def upload(self, package_name, user_parameters=None): # prevent from uploading any other previously build library in this path. if path.exists(generated_dist_folder): remove_dir(generated_dist_folder) - commands = [f'"{executable}" "{generated_setup_file_path}" sdist bdist_wheel'] + if platform.system() == "Windows": + commands = [f'"{executable}" "{generated_setup_file_path}" sdist bdist_wheel > nul 2>&1'] + else: + commands = [f'"{executable}" "{generated_setup_file_path}" sdist bdist_wheel > /dev/null 2>&1'] if self.test_pypi: commands += [ f'"{executable}" -m twine upload --repository testpypi "{generated_tar_gz_file}"', From 7fddd3fea69bebc498b80a41d4252e9c54955b15 Mon Sep 17 00:00:00 2001 From: AHReccese Date: Wed, 1 Jan 2025 20:40:00 -0500 Subject: [PATCH 08/17] mute twine steps logs --- reserver/reserver_obj.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/reserver/reserver_obj.py b/reserver/reserver_obj.py index 9a07a37..8ec2d8f 100644 --- a/reserver/reserver_obj.py +++ b/reserver/reserver_obj.py @@ -105,8 +105,8 @@ def upload(self, package_name, user_parameters=None): ] else: commands += [ - f'"{executable}" -m twine upload --verbose "{generated_tar_gz_file}"', - f'"{executable}" -m twine upload --verbose "{generated_wheel_file}"', + f'"{executable}" -m twine upload "{generated_tar_gz_file}"', + f'"{executable}" -m twine upload "{generated_wheel_file}"', ] # Run the commands publish_failed = False From fda66a8aac704e228763f5ec2c2d4adfb19d2b5b Mon Sep 17 00:00:00 2001 From: AHReccese Date: Wed, 1 Jan 2025 20:40:53 -0500 Subject: [PATCH 09/17] remove error message investigation, due to frequent change in pypi API --- reserver/reserver_obj.py | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/reserver/reserver_obj.py b/reserver/reserver_obj.py index 8ec2d8f..19dc027 100644 --- a/reserver/reserver_obj.py +++ b/reserver/reserver_obj.py @@ -120,19 +120,6 @@ def upload(self, package_name, user_parameters=None): except CalledProcessError as e: publish_failed = True error = e.output - try: - error = error.decode(chardet.detect(error)['encoding']) - except BaseException: - error = error.decode('utf-8') - if command == commands[-2]: - if "403" in error and "Invalid or non-existent authentication information" in error: - error = "Invalid or non-existent authentication information(PyPI API Key)." - if "400" in error and "too similar to an existing project" in error: - error = "Given package name is too similar to an existing project in PyPI." - if "400" in error and "isn't allowed." in error: - error = "Given package name has conflict with the module name of a previously taken package." - if "400" in error and "isn't allowed (conflict with Python Standard Library" in error: - error = "Given package name has conflict with Python Standard Library module name." break if "TWINE_USERNAME" in environ: From 24caae16f5ede5da99d125d4be4d60329ebf78a6 Mon Sep 17 00:00:00 2001 From: AHReccese Date: Wed, 1 Jan 2025 20:41:01 -0500 Subject: [PATCH 10/17] add comment --- reserver/reserver_obj.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/reserver/reserver_obj.py b/reserver/reserver_obj.py index 19dc027..d219e95 100644 --- a/reserver/reserver_obj.py +++ b/reserver/reserver_obj.py @@ -122,11 +122,12 @@ def upload(self, package_name, user_parameters=None): error = e.output break + # remove credential from env variables if "TWINE_USERNAME" in environ: environ.pop("TWINE_USERNAME") if "TWINE_PASSWORD" in environ: environ.pop("TWINE_PASSWORD") - + # remove previously generated files remove(generated_setup_file_path) remove_dir(generated_package_folder) remove_dir(generated_egginfo_file_path) From 8f0bcb1b48c29a8ad4af98415640029e630c6a5b Mon Sep 17 00:00:00 2001 From: AHReccese Date: Wed, 1 Jan 2025 20:41:17 -0500 Subject: [PATCH 11/17] refactor imports --- reserver/reserver_obj.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/reserver/reserver_obj.py b/reserver/reserver_obj.py index d219e95..3f01917 100644 --- a/reserver/reserver_obj.py +++ b/reserver/reserver_obj.py @@ -1,14 +1,15 @@ # -*- coding: utf-8 -*- """Reserver modules.""" import chardet +import platform from re import sub from sys import executable from os import environ, path, getcwd, remove from .reserver_errors import ReserverBaseError +from .reserver_func import generate_template_setup_py from subprocess import check_output, CalledProcessError from .reserver_param import UNEQUAL_PARAM_NAME_LENGTH_ERROR from .util import has_named_parameter, remove_dir, read_json -from .reserver_func import does_package_exist, generate_template_setup_py class PyPIUploader: From 6212637058a1ddf67e8ed09811f95487083fdddf Mon Sep 17 00:00:00 2001 From: AHReccese Date: Wed, 1 Jan 2025 20:45:51 -0500 Subject: [PATCH 12/17] remove chardet import --- reserver/reserver_obj.py | 1 - 1 file changed, 1 deletion(-) diff --git a/reserver/reserver_obj.py b/reserver/reserver_obj.py index 3f01917..86972ec 100644 --- a/reserver/reserver_obj.py +++ b/reserver/reserver_obj.py @@ -1,6 +1,5 @@ # -*- coding: utf-8 -*- """Reserver modules.""" -import chardet import platform from re import sub from sys import executable From 83259aa72f477d0e6ff9e8735d0c3b4e4d12c5a9 Mon Sep 17 00:00:00 2001 From: AHReccese Date: Wed, 1 Jan 2025 20:51:28 -0500 Subject: [PATCH 13/17] `CHANGELOG.md` updated --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7fc79d9..0feafb2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,11 +8,14 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Added - `ReserverBaseError` added in `reserver/__init__.py` ### Changed +- `upload` method in `reserver_obj.py` - `README.md` updated - `AUTHORS.md` updated - GitHub actions are limited to the `dev` and `main` branches - `generate_template_setup_py` method in `reserver_func.py` - `Python 3.13` added to `test.yml` +### Removed +- `does_package_exist` method in `reserver_func.py` ## [0.3] - 2024-08-28 ### Added - CLI tests added From efa01fb381ece30b8aeeb790d5bc890de99d71dd Mon Sep 17 00:00:00 2001 From: AHReccese Date: Mon, 6 Jan 2025 14:26:40 -0500 Subject: [PATCH 14/17] fix weird output in windows because of encoding --- reserver/reserver_obj.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/reserver/reserver_obj.py b/reserver/reserver_obj.py index 86972ec..990d164 100644 --- a/reserver/reserver_obj.py +++ b/reserver/reserver_obj.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- """Reserver modules.""" +import chardet import platform from re import sub from sys import executable @@ -120,7 +121,10 @@ def upload(self, package_name, user_parameters=None): except CalledProcessError as e: publish_failed = True error = e.output - break + try: + error = error.decode(chardet.detect(error)['encoding']) + except BaseException: + error = error.decode('utf-8') # remove credential from env variables if "TWINE_USERNAME" in environ: From 52559af081befeca7b6cd252eda0165e32478389 Mon Sep 17 00:00:00 2001 From: AHReccese Date: Mon, 6 Jan 2025 14:26:49 -0500 Subject: [PATCH 15/17] add `chardet` to requirements --- dev-requirements.txt | 1 + requirements.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/dev-requirements.txt b/dev-requirements.txt index c42eb1c..7b92796 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -7,3 +7,4 @@ bandit>=1.5.1 pydocstyle>=3.0.0 pytest>=4.3.1 pytest-cov>=2.6.1 +chardet==5.2.0 \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index abe875b..1a0e53c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,3 +2,4 @@ art>=5.3 setuptools>=40.8.0 wheel>=0.35.0 twine>=3.5.0 +chardet>=4.0.0 \ No newline at end of file From 2ee5db1a91f708a13a51b7563f640dcb52ed4de5 Mon Sep 17 00:00:00 2001 From: AHReccese Date: Mon, 6 Jan 2025 15:25:43 -0500 Subject: [PATCH 16/17] `CHANGELOG.md` updated --- CHANGELOG.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 93394cd..fe9d2f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,17 +13,17 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - `README.md` updated - `AUTHORS.md` updated - GitHub actions are limited to the `dev` and `main` branches -- `generate_template_setup_py` method in `reserver_func.py` +- `generate_template_setup_py` function in `reserver_func.py` - `Python 3.13` added to `test.yml` ### Removed -- `does_package_exist` method in `reserver_func.py` +- `does_package_exist` function in `reserver_func.py` ## [0.3] - 2024-08-28 ### Added - CLI tests added - `param` arg in CLI Handler - more testcases in conflict cases - `batch_upload` tests -- `read_json` method in `util.py` +- `read_json` function in `util.py` ### Changed - `README.md` updated - `upload` method in `reserver_obj.py` @@ -32,14 +32,14 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Added - `CLI` handler - `Python 3.6` support -- `has_named_parameter` method in `util.py` +- `has_named_parameter` function in `util.py` - `feature_request.yml` template - `config.yml` for issue template - `batch_upload` method in `PyPIUploader` - `SECURITY.md` ### Changed - `upload` method in `reserver_obj.py` -- `does_package_exist` method in `reserver_func.py` +- `does_package_exist` function in `reserver_func.py` - `test.yml` for `Python 3.6` support - Logo updated - Bug report template modified From 1cfd5dea8315ce416a667bfdd9c50b02ef55f686 Mon Sep 17 00:00:00 2001 From: AmirHosein Rostami <32750909+AHReccese@users.noreply.github.com> Date: Mon, 6 Jan 2025 17:50:47 -0500 Subject: [PATCH 17/17] Update dev-requirements.txt --- dev-requirements.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dev-requirements.txt b/dev-requirements.txt index 053d7f0..3b0e837 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1,5 +1,4 @@ art==6.4 -requests==2.32.3 setuptools==75.7.0 wheel==0.45.1 twine==6.0.1 @@ -8,4 +7,4 @@ bandit>=1.5.1 pydocstyle>=3.0.0 pytest>=4.3.1 pytest-cov>=2.6.1 -chardet==5.2.0 \ No newline at end of file +chardet==5.2.0