Merge branch 'next' into add_notebook_support

This commit is contained in:
Fernando-crz 2023-10-23 17:01:12 -03:00 committed by GitHub
commit 67d134e466
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 50 additions and 12 deletions

View File

@ -61,7 +61,6 @@ REGEXP = [
re.compile(r"^from ((?!\.+).*?) import (?:.*)$"), re.compile(r"^from ((?!\.+).*?) import (?:.*)$"),
] ]
@contextmanager @contextmanager
def _open(filename=None, mode="r"): def _open(filename=None, mode="r"):
"""Open a file or ``sys.stdout`` depending on the provided filename. """Open a file or ``sys.stdout`` depending on the provided filename.
@ -211,7 +210,11 @@ def generate_requirements_file(path, imports, symbol):
) )
fmt = "{name}" + symbol + "{version}" fmt = "{name}" + symbol + "{version}"
out_file.write( out_file.write(
"\n".join(fmt.format(**item) if item["version"] else "{name}".format(**item) for item in imports) + "\n" "\n".join(
fmt.format(**item) if item["version"] else "{name}".format(**item)
for item in imports
)
+ "\n"
) )
@ -309,7 +312,7 @@ def get_import_local(imports, encoding=None):
# had to use second method instead of the previous one, # had to use second method instead of the previous one,
# because we have a list in the 'exports' field # because we have a list in the 'exports' field
# https://stackoverflow.com/questions/9427163/remove-duplicate-dict-in-list-in-python # https://stackoverflow.com/questions/9427163/remove-duplicate-dict-in-list-in-python
result_unique = [i for n, i in enumerate(result) if i not in result[n + 1 :]] result_unique = [i for n, i in enumerate(result) if i not in result[n + 1:]]
return result_unique return result_unique
@ -354,6 +357,9 @@ def parse_requirements(file_):
delimiter, get module name by element index, create a dict consisting of delimiter, get module name by element index, create a dict consisting of
module:version, and add dict to list of parsed modules. module:version, and add dict to list of parsed modules.
If file ´file_´ is not found in the system, the program will print a
helpful message and end its execution immediately.
Args: Args:
file_: File to parse. file_: File to parse.
@ -370,9 +376,12 @@ def parse_requirements(file_):
try: try:
f = open(file_, "r") f = open(file_, "r")
except OSError: except FileNotFoundError:
logging.error("Failed on file: {}".format(file_)) print(f"File {file_} was not found. Please, fix it and run again.")
raise sys.exit(1)
except OSError as error:
logging.error(f"There was an error opening the file {file_}: {str(error)}")
raise error
else: else:
try: try:
data = [x.strip() for x in f.readlines() if x != "\n"] data = [x.strip() for x in f.readlines() if x != "\n"]
@ -485,8 +494,15 @@ def init(args):
if extra_ignore_dirs: if extra_ignore_dirs:
extra_ignore_dirs = extra_ignore_dirs.split(",") extra_ignore_dirs = extra_ignore_dirs.split(",")
path = args["--savepath"] if args["--savepath"] else os.path.join(input_path, "requirements.txt") path = (
if not args["--print"] and not args["--savepath"] and not args["--force"] and os.path.exists(path): args["--savepath"] if args["--savepath"] else os.path.join(input_path, "requirements.txt")
)
if (
not args["--print"]
and not args["--savepath"]
and not args["--force"]
and os.path.exists(path)
):
logging.warning("requirements.txt already exists, " "use --force to overwrite it") logging.warning("requirements.txt already exists, " "use --force to overwrite it")
return return
@ -546,7 +562,9 @@ def init(args):
if scheme in ["compat", "gt", "no-pin"]: if scheme in ["compat", "gt", "no-pin"]:
imports, symbol = dynamic_versioning(scheme, imports) imports, symbol = dynamic_versioning(scheme, imports)
else: else:
raise ValueError("Invalid argument for mode flag, " "use 'compat', 'gt' or 'no-pin' instead") raise ValueError(
"Invalid argument for mode flag, " "use 'compat', 'gt' or 'no-pin' instead"
)
else: else:
symbol = "==" symbol = "=="

View File

@ -8,11 +8,12 @@ test_pipreqs
Tests for `pipreqs` module. Tests for `pipreqs` module.
""" """
import io from io import StringIO
import sys from unittest.mock import patch
import unittest import unittest
import os import os
import requests import requests
import sys
from pipreqs import pipreqs from pipreqs import pipreqs
@ -80,6 +81,8 @@ class TestPipreqs(unittest.TestCase):
"original": os.path.join(os.path.dirname(__file__), "_data/test.py"), "original": os.path.join(os.path.dirname(__file__), "_data/test.py"),
"notebook": os.path.join(os.path.dirname(__file__), "_data_notebook/test.ipynb"), "notebook": os.path.join(os.path.dirname(__file__), "_data_notebook/test.ipynb"),
} }
self.non_existing_filepath = "xpto"
def test_get_all_imports(self): def test_get_all_imports(self):
imports = pipreqs.get_all_imports(self.project) imports = pipreqs.get_all_imports(self.project)
@ -479,7 +482,7 @@ class TestPipreqs(unittest.TestCase):
It should print to stdout the same content as requeriments.txt It should print to stdout the same content as requeriments.txt
""" """
capturedOutput = io.StringIO() capturedOutput = StringIO()
sys.stdout = capturedOutput sys.stdout = capturedOutput
pipreqs.init( pipreqs.init(
@ -583,6 +586,23 @@ class TestPipreqs(unittest.TestCase):
self.assertListEqual(parsed_requirements, expected_parsed_requirements) self.assertListEqual(parsed_requirements, expected_parsed_requirements)
@patch("sys.exit")
def test_parse_requirements_handles_file_not_found(self, exit_mock):
captured_output = StringIO()
sys.stdout = captured_output
# This assertion is needed, because since "sys.exit" is mocked, the program won't end,
# and the code that is after the except block will be run
with self.assertRaises(UnboundLocalError):
pipreqs.parse_requirements(self.non_existing_filepath)
exit_mock.assert_called_once_with(1)
printed_text = captured_output.getvalue().strip()
sys.stdout = sys.__stdout__
self.assertEqual(printed_text, "File xpto was not found. Please, fix it and run again.")
def tearDown(self): def tearDown(self):
""" """
Remove requiremnts.txt files that were written Remove requiremnts.txt files that were written