From 081a024d63d2cc39a4cfd56de36cc86ec38ba928 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Alexandre?= <59508016+upALX@users.noreply.github.com> Date: Fri, 4 Apr 2025 21:50:59 -0300 Subject: [PATCH 1/5] updating readme doc with new flag to use only venv packages --- README.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/README.rst b/README.rst index 45dce6a..60358c5 100644 --- a/README.rst +++ b/README.rst @@ -47,6 +47,7 @@ Usage Options: --use-local Use ONLY local package info instead of querying PyPI + --only-venv Use ONLY venv packages instead local system --pypi-server Use custom PyPi server --proxy Use Proxy, parameter will be passed to requests library. You can also just set the environments parameter in your terminal: From 7c946be04a52b1be3ff78cc58ec926b13740823e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Alexandre?= <59508016+upALX@users.noreply.github.com> Date: Thu, 10 Apr 2025 18:00:17 -0300 Subject: [PATCH 2/5] adding only venv use feature --- .gitignore | 2 ++ pipreqs/__main__.py | 4 ++++ pipreqs/pipreqs.py | 31 ++++++++++++++++++++++++++----- 3 files changed, 32 insertions(+), 5 deletions(-) create mode 100644 pipreqs/__main__.py diff --git a/.gitignore b/.gitignore index 45a067a..74c1245 100644 --- a/.gitignore +++ b/.gitignore @@ -53,3 +53,5 @@ Session.vim *~ /pipreqs/*.bak + +.venv \ No newline at end of file diff --git a/pipreqs/__main__.py b/pipreqs/__main__.py new file mode 100644 index 0000000..bd8961a --- /dev/null +++ b/pipreqs/__main__.py @@ -0,0 +1,4 @@ +from pipreqs import pipreqs + +if __name__ == "__main__": + pipreqs.main() diff --git a/pipreqs/pipreqs.py b/pipreqs/pipreqs.py index dceda96..4e91680 100644 --- a/pipreqs/pipreqs.py +++ b/pipreqs/pipreqs.py @@ -12,6 +12,7 @@ Arguments: Options: --use-local Use ONLY local package info instead of querying PyPI. + --only-venv Use ONLY venv packages instead local system. --pypi-server Use custom PyPi server. --proxy Use Proxy, parameter will be passed to requests library. You can also just set the environments @@ -260,10 +261,26 @@ def get_imports_info(imports, pypi_server="https://pypi.python.org/pypi/", proxy return result -def get_locally_installed_packages(encoding="utf-8"): +def get_locally_installed_packages(use_venv_packages: bool, encoding="utf-8"): packages = [] ignore = ["tests", "_tests", "egg", "EGG", "info"] - for path in sys.path: + + venv_path = os.environ.get("VIRTUAL_ENV") + paths_to_search = [] + if use_venv_packages and venv_path: + lib_path = os.path.join(venv_path, "lib") + if os.path.isdir(lib_path): + for entry in os.listdir(lib_path): + site_packages = os.path.join(lib_path, entry, "site-packages") + if os.path.isdir(site_packages): + paths_to_search.append(site_packages) + break + else: + if use_venv_packages and not venv_path: + logging.warning("You specified to use only the virtual environment packages, but no virtual environment is currently active.") + paths_to_search = sys.path + + for path in paths_to_search: for root, dirs, files in os.walk(path): for item in files: if "top_level" in item: @@ -301,8 +318,9 @@ def get_locally_installed_packages(encoding="utf-8"): return packages -def get_import_local(imports, encoding="utf-8"): - local = get_locally_installed_packages() +def get_import_local(imports, use_venv_packages: bool, encoding="utf-8"): + local = get_locally_installed_packages(use_venv_packages=use_venv_packages) + print('LOCAL: ', local) result = [] for item in imports: # search through local packages @@ -313,6 +331,7 @@ def get_import_local(imports, encoding="utf-8"): if item in package["exports"] or item == package["name"]: result.append(package) + print(result) # removing duplicates of package/version # had to use second method instead of the previous one, # because we have a list in the 'exports' field @@ -551,7 +570,9 @@ def init(args): if args["--use-local"]: logging.debug("Getting package information ONLY from local installation.") - imports = get_import_local(candidates, encoding=encoding) + print(candidates) + imports = get_import_local(candidates, args["--only-venv"], encoding=encoding) + print(imports) else: logging.debug("Getting packages information from Local/PyPI") local = get_import_local(candidates, encoding=encoding) From 68dd38a4c8da56faa621ff0cd075c5c3b8e4b7d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Alexandre?= <59508016+upALX@users.noreply.github.com> Date: Thu, 10 Apr 2025 18:51:54 -0300 Subject: [PATCH 3/5] Adding only venv use case test --- pipreqs/pipreqs.py | 5 ++--- tests/_data_ignore/requirements.txt | 12 ++++++++++++ tests/_data_notebook/requirements.txt | 1 + tests/test_pipreqs.py | 17 +++++++++++++++++ 4 files changed, 32 insertions(+), 3 deletions(-) create mode 100644 tests/_data_ignore/requirements.txt create mode 100644 tests/_data_notebook/requirements.txt diff --git a/pipreqs/pipreqs.py b/pipreqs/pipreqs.py index 4e91680..23e2d9e 100644 --- a/pipreqs/pipreqs.py +++ b/pipreqs/pipreqs.py @@ -50,6 +50,7 @@ from docopt import docopt import requests from yarg import json2package from yarg.exceptions import HTTPError +from typing import Optional from pipreqs import __version__ @@ -318,9 +319,8 @@ def get_locally_installed_packages(use_venv_packages: bool, encoding="utf-8"): return packages -def get_import_local(imports, use_venv_packages: bool, encoding="utf-8"): +def get_import_local(imports, use_venv_packages: Optional[bool]=False, encoding="utf-8"): local = get_locally_installed_packages(use_venv_packages=use_venv_packages) - print('LOCAL: ', local) result = [] for item in imports: # search through local packages @@ -331,7 +331,6 @@ def get_import_local(imports, use_venv_packages: bool, encoding="utf-8"): if item in package["exports"] or item == package["name"]: result.append(package) - print(result) # removing duplicates of package/version # had to use second method instead of the previous one, # because we have a list in the 'exports' field diff --git a/tests/_data_ignore/requirements.txt b/tests/_data_ignore/requirements.txt new file mode 100644 index 0000000..bc9d530 --- /dev/null +++ b/tests/_data_ignore/requirements.txt @@ -0,0 +1,12 @@ +asposestorage==1.0.2 +beautifulsoup4==4.13.3 +boto==2.49.0 +docopt==0.6.2 +Flask==3.1.0 +ipython==8.12.3 +nose==1.3.7 +peewee==3.17.9 +pyflakes==3.1.0 +Requests==2.32.3 +SQLAlchemy==2.0.40 +ujson==5.10.0 diff --git a/tests/_data_notebook/requirements.txt b/tests/_data_notebook/requirements.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tests/_data_notebook/requirements.txt @@ -0,0 +1 @@ + diff --git a/tests/test_pipreqs.py b/tests/test_pipreqs.py index 5e046e0..7eeaee5 100644 --- a/tests/test_pipreqs.py +++ b/tests/test_pipreqs.py @@ -156,6 +156,22 @@ class TestPipreqs(unittest.TestCase): for item in imports_with_info: self.assertTrue(item["name"].lower() in self.local) + @patch("pipreqs.pipreqs.get_locally_installed_packages") + def test_get_import_local_only_from_venv(self, mock_get_local_packages): + mock_get_local_packages.return_value = [ + {"name": "requests", "version": "2.31.0", "exports": ["requests"]}, + {"name": "docopt", "version": "0.6.2", "exports": ["docopt"]}, + ] + + imports = {"requests": "2.31.0", "docopt": "0.6.2", "flask": "3.0.2"} + + result = pipreqs.get_import_local(imports, use_venv_packages=True) + + self.assertEqual(result, [ + {"name": "requests", "version": "2.31.0", "exports": ["requests"]}, + {"name": "docopt", "version": "0.6.2", "exports": ["docopt"]}, + ]) + def test_init(self): """ Test that all modules we will test upon are in requirements file @@ -194,6 +210,7 @@ class TestPipreqs(unittest.TestCase): "--savepath": None, "--print": False, "--use-local": True, + "--only-venv": False, "--force": True, "--proxy": None, "--pypi-server": None, From 07d7d457b9d2c5c9a23a9518475aed1a97e43a9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Alexandre?= <59508016+upALX@users.noreply.github.com> Date: Thu, 10 Apr 2025 19:46:28 -0300 Subject: [PATCH 4/5] Passing for the PR guidelines --- pipreqs/pipreqs.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pipreqs/pipreqs.py b/pipreqs/pipreqs.py index 23e2d9e..0a05aa6 100644 --- a/pipreqs/pipreqs.py +++ b/pipreqs/pipreqs.py @@ -278,7 +278,10 @@ def get_locally_installed_packages(use_venv_packages: bool, encoding="utf-8"): break else: if use_venv_packages and not venv_path: - logging.warning("You specified to use only the virtual environment packages, but no virtual environment is currently active.") + logging.warning( + "You specified to use only the virtual environment packages, " + "but no virtual environment is currently active." + ) paths_to_search = sys.path for path in paths_to_search: @@ -319,7 +322,7 @@ def get_locally_installed_packages(use_venv_packages: bool, encoding="utf-8"): return packages -def get_import_local(imports, use_venv_packages: Optional[bool]=False, encoding="utf-8"): +def get_import_local(imports, use_venv_packages: Optional[bool] = False, encoding="utf-8"): local = get_locally_installed_packages(use_venv_packages=use_venv_packages) result = [] for item in imports: From eeccc1cf1fdfe547424dfd457bc91781e804fff9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Alexandre?= <59508016+upALX@users.noreply.github.com> Date: Thu, 10 Apr 2025 20:49:54 -0300 Subject: [PATCH 5/5] adding changes after run tests --- tests/_data_ignore/requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/_data_ignore/requirements.txt b/tests/_data_ignore/requirements.txt index bc9d530..dd5edfd 100644 --- a/tests/_data_ignore/requirements.txt +++ b/tests/_data_ignore/requirements.txt @@ -7,6 +7,7 @@ ipython==8.12.3 nose==1.3.7 peewee==3.17.9 pyflakes==3.1.0 +pyflakes==3.3.2 Requests==2.32.3 SQLAlchemy==2.0.40 ujson==5.10.0