Open zivshapiraintel opened 1 year ago
issue seems to be with addingimport pandas
(2.1.3). Just by importing it, without even using it in the__init__
method, the error above occurs
issue seems to be with adding
import pandas
(2.1.3). Just by importing it, without even using it in the__init__
method, the error above occurs
I see in the logs that you're using a globally installed Python interpreter. This could be a case of a misconfigured Python environment. Does this error still occur if you create a virtual environment, install all dependencies (including Pynguin), and run the same command?
issue seems to be with adding
import pandas
(2.1.3). Just by importing it, without even using it in the__init__
method, the error above occursI see in the logs that you're using a globally installed Python interpreter. This could be a case of a misconfigured Python environment. Does this error still occur if you create a virtual environment, install all dependencies (including Pynguin), and run the same command?
Hi @jordan-gillard . I an running on a Jenkins agent, so I don't need to setup a virtual env. Without the pandas import, it's ok, so I don't think that the issue is with Python.
I was able to reproduce and fix this particular issue in d811cacc59f73c84e9cd83ceb466ec308c66410b. However, there is yet another issue (at least on my machine) that causes failure: some numpy
module cannot be found for whatever reason I do not really understand.
Code that uses numpy
or pandas
still causes struggles to Pynguin for various reasons, unfortunately.
I have the same problem.
command:
(.venv_3.10) (base) ncdaam@vkwmr6cjkv-mac LogicalCouplingTool % pynguin --project-path . --output-path ./tests/developer_coupling/ --module-name coupling.developer_coupling -v > pynguin.txt
Output:
[22:50:02] INFO Start Pynguin Test Generation… generator.py:107
INFO Collecting static constants from module under test generator.py:208
INFO Constants found: 207 generator.py:213
INFO Setting up runtime collection of constants generator.py:220
[22:50:06] INFO Stop Pynguin Test Generation… generator.py:110
╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/bin/pynguin:8 in <module> │
│ │
│ 5 from pynguin.cli import main │
│ 6 if __name__ == '__main__': │
│ 7 │ sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) │
│ ❱ 8 │ sys.exit(main()) │
│ 9 │
│ │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/cli.py:196 in main │
│ │
│ 193 │ set_configuration(parsed.config) │
│ 194 │ if console is not None: │
│ 195 │ │ with console.status("Running Pynguin..."): │
│ ❱ 196 │ │ │ return run_pynguin().value │
│ 197 │ else: │
│ 198 │ │ return run_pynguin().value │
│ 199 │
│ │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/generator.py:108 in run_pynguin │
│ │
│ 105 │ │
│ 106 │ try: │
│ 107 │ │ _LOGGER.info("Start Pynguin Test Generation…") │
│ ❱ 108 │ │ return _run() │
│ 109 │ finally: │
│ 110 │ │ _LOGGER.info("Stop Pynguin Test Generation…") │
│ 111 │
│ │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/generator.py:506 in _run │
│ │
│ 503 │
│ 504 │
│ 505 def _run() -> ReturnCode: │
│ ❱ 506 │ if (setup_result := _setup_and_check()) is None: │
│ 507 │ │ return ReturnCode.SETUP_FAILED │
│ 508 │ executor, test_cluster, constant_provider = setup_result │
│ 509 │ # traces slices for test cases after execution │
│ │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/generator.py:258 in _setup_and_check │
│ │
│ 255 │ │
│ 256 │ # Analyzing the SUT should not cause any coverage. │
│ 257 │ tracer.disable() │
│ ❱ 258 │ if (test_cluster := _setup_test_cluster()) is None: │
│ 259 │ │ return None │
│ 260 │ tracer.enable() │
│ 261 │
│ │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/generator.py:114 in _setup_test_cluster │
│ │
│ 111 │
│ 112 │
│ 113 def _setup_test_cluster() -> ModuleTestCluster | None: │
│ ❱ 114 │ test_cluster = generate_test_cluster( │
│ 115 │ │ config.configuration.module_name, │
│ 116 │ │ config.configuration.type_inference.type_inference_strategy, │
│ 117 │ │ query_type4py=config.configuration.type_inference.type4py, │
│ │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/analyses/module.py:1442 in generate_test_cluster │
│ │
│ 1439 │ Returns: │
│ 1440 │ │ A new test cluster for the given module │
│ 1441 │ │
│ ❱ 1442 │ return analyse_module( │
│ 1443 │ │ parse_module(module_name, query_type4py=query_type4py), │
│ 1444 │ │ type_inference_strategy, │
│ 1445 │ │ query_type4py=query_type4py, │
│ │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/analyses/module.py:1418 in analyse_module │
│ │
│ 1415 │ │ A test cluster for the module │
│ 1416 │ │
│ 1417 │ test_cluster = ModuleTestCluster(linenos=parsed_module.linenos) │
│ ❱ 1418 │ __resolve_dependencies( │
│ 1419 │ │ root_module=parsed_module, │
│ 1420 │ │ type_inference_strategy=type_inference_strategy, │
│ 1421 │ │ test_cluster=test_cluster, │
│ │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/analyses/module.py:1291 in __resolve_dependencies │
│ │
│ 1288 │ │ │ continue │
│ 1289 │ │ │
│ 1290 │ │ # Analyze all classes found in the current module │
│ ❱ 1291 │ │ __analyse_included_classes( │
│ 1292 │ │ │ module=current_module, │
│ 1293 │ │ │ root_module_name=root_module.module_name, │
│ 1294 │ │ │ type_inference_strategy=type_inference_strategy, │
│ │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/analyses/module.py:1351 in __analyse_included_classes │
│ │
│ 1348 │ │ │
│ 1349 │ │ type_info = test_cluster.type_system.to_type_info(current) │
│ 1350 │ │ │
│ ❱ 1351 │ │ __analyse_class( │
│ 1352 │ │ │ type_info=type_info, │
│ 1353 │ │ │ type_inference_strategy=type_inference_strategy, │
│ 1354 │ │ │ module_tree=parse_results[current.__module__].syntax_tree, │
│ │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/analyses/module.py:1141 in __analyse_class │
│ │
│ 1138 │ for method_name, method in inspect.getmembers( │
│ 1139 │ │ type_info.raw_type, inspect.isfunction │
│ 1140 │ ): │
│ ❱ 1141 │ │ __analyse_method( │
│ 1142 │ │ │ type_info=type_info, │
│ 1143 │ │ │ method_name=method_name, │
│ 1144 │ │ │ method=method, │
│ │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/analyses/module.py:1213 in __analyse_method │
│ │
│ 1210 │ │ return │
│ 1211 │ │
│ 1212 │ LOGGER.debug("Analysing method %s.%s", type_info.full_name, method_name) │
│ ❱ 1213 │ inferred_signature = test_cluster.type_system.infer_type_info( │
│ 1214 │ │ method, │
│ 1215 │ │ type4py_data=find_predicted_signature( │
│ 1216 │ │ │ type4py_data, type_info.qualname + "." + method_name, type_info.qualname │
│ │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/analyses/typesystem.py:1526 in infer_type_info │
│ │
│ 1523 │ │ │
│ 1524 │ │ match type_inference_strategy: │
│ 1525 │ │ │ case config.TypeInferenceStrategy.TYPE_HINTS: │
│ ❱ 1526 │ │ │ │ return self.infer_signature( │
│ 1527 │ │ │ │ │ method, type4py_data, self.type_hints_provider │
│ 1528 │ │ │ │ ) │
│ 1529 │ │ │ case config.TypeInferenceStrategy.NONE: │
│ │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/analyses/typesystem.py:1589 in infer_signature │
│ │
│ 1586 │ │ │ The inference result │
│ 1587 │ │ │
│ 1588 │ │ method_signature = inspect.signature(method) │
│ ❱ 1589 │ │ hints = type_hint_provider(method) │
│ 1590 │ │ parameters: dict[str, ProperType] = {} │
│ 1591 │ │ type4py_parameters: dict[str, list[ProperType]] = {} │
│ 1592 │ │ type4py_parameters_for_statistics: dict[str, list[ProperType]] = {} │
│ │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/analyses/typesystem.py:1561 in type_hints_provider │
│ │
│ 1558 │ │ │ A dict mapping parameter names to type hints. │
│ 1559 │ │ │
│ 1560 │ │ try: │
│ ❱ 1561 │ │ │ hints = get_type_hints(method) │
│ 1562 │ │ │ # Sadly there is no guarantee that resolving the type hints actually works. │
│ 1563 │ │ │ # If the developers annotated something with an erroneous type hint we fall │
│ 1564 │ │ │ # back to no type hints, i.e., use Any. │
│ │
│ /Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/typing.py:1849 in │
│ get_type_hints │
│ │
│ 1846 │ │ │ │ is_argument=not isinstance(obj, types.ModuleType), │
│ 1847 │ │ │ │ is_class=False, │
│ 1848 │ │ │ ) │
│ ❱ 1849 │ │ value = _eval_type(value, globalns, localns) │
│ 1850 │ │ if name in defaults and defaults[name] is None: │
│ 1851 │ │ │ value = Optional[value] │
│ 1852 │ │ hints[name] = value │
│ │
│ /Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/typing.py:326 in _eval_type │
│ │
│ 323 │ with recursive ForwardRef. │
│ 324 │ │
│ 325 │ if isinstance(t, ForwardRef): │
│ ❱ 326 │ │ return t._evaluate(globalns, localns, recursive_guard) │
│ 327 │ if isinstance(t, (_GenericAlias, GenericAlias, types.UnionType)): │
│ 328 │ │ ev_args = tuple(_eval_type(a, globalns, localns, recursive_guard) for a in t.__a │
│ 329 │ │ if ev_args == t.__args__: │
│ │
│ /Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/typing.py:691 in _evaluate │
│ │
│ 688 │ │ │ │ │ sys.modules.get(self.__forward_module__, None), '__dict__', globalns │
│ 689 │ │ │ │ ) │
│ 690 │ │ │ type_ = _type_check( │
│ ❱ 691 │ │ │ │ eval(self.__forward_code__, globalns, localns), │
│ 692 │ │ │ │ "Forward references must evaluate to types.", │
│ 693 │ │ │ │ is_argument=self.__forward_is_argument__, │
│ 694 │ │ │ │ is_class=self.__forward_is_class__, │
│ in <module>:1 │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
TypeError: unsupported operand type(s) for |: 'NoneType' and 'NoneType'
As explained in https://github.com/se2p/pynguin/issues/53#issuecomment-1893427840, in the same way as https://github.com/se2p/pynguin/commit/d811cacc59f73c84e9cd83ceb466ec308c66410b I added TypeError in the except
branch of type_hints_provider
.
@staticmethod
def type_hints_provider(method: Callable) -> dict[str, Any]:
"""Provides PEP484-style type information, if available.
Args:
method: The method for which we want type hints.
Returns:
A dict mapping parameter names to type hints.
"""
try:
hints = get_type_hints(method)
# Sadly there is no guarantee that resolving the type hints actually works.
# If the developers annotated something with an erroneous type hint we fall
# back to no type hints, i.e., use Any.
# The import used in the type hint could also be conditional on
# typing.TYPE_CHECKING, e.g., to avoid circular imports, in which case this
# also fails.
except (AttributeError, NameError, TypeError):
hints = {}
return hints
But I encountered another problem:
[23:20:47] INFO Start Pynguin Test Generation… generator.py:107
INFO Collecting static constants from module under test generator.py:208
INFO Constants found: 207 generator.py:213
INFO Setting up runtime collection of constants generator.py:220
[23:20:59] INFO Stop Pynguin Test Generation… generator.py:110
╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/bin/pynguin:8 in <module> │
│ │
│ 5 from pynguin.cli import main │
│ 6 if __name__ == '__main__': │
│ 7 │ sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) │
│ ❱ 8 │ sys.exit(main()) │
│ 9 │
│ │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/cli.py:196 in main │
│ │
│ 193 │ set_configuration(parsed.config) │
│ 194 │ if console is not None: │
│ 195 │ │ with console.status("Running Pynguin..."): │
│ ❱ 196 │ │ │ return run_pynguin().value │
│ 197 │ else: │
│ 198 │ │ return run_pynguin().value │
│ 199 │
│ │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/generator.py:108 in run_pynguin │
│ │
│ 105 │ │
│ 106 │ try: │
│ 107 │ │ _LOGGER.info("Start Pynguin Test Generation…") │
│ ❱ 108 │ │ return _run() │
│ 109 │ finally: │
│ 110 │ │ _LOGGER.info("Stop Pynguin Test Generation…") │
│ 111 │
│ │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/generator.py:506 in _run │
│ │
│ 503 │
│ 504 │
│ 505 def _run() -> ReturnCode: │
│ ❱ 506 │ if (setup_result := _setup_and_check()) is None: │
│ 507 │ │ return ReturnCode.SETUP_FAILED │
│ 508 │ executor, test_cluster, constant_provider = setup_result │
│ 509 │ # traces slices for test cases after execution │
│ │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/generator.py:258 in _setup_and_check │
│ │
│ 255 │ │
│ 256 │ # Analyzing the SUT should not cause any coverage. │
│ 257 │ tracer.disable() │
│ ❱ 258 │ if (test_cluster := _setup_test_cluster()) is None: │
│ 259 │ │ return None │
│ 260 │ tracer.enable() │
│ 261 │
│ │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/generator.py:114 in _setup_test_cluster │
│ │
│ 111 │
│ 112 │
│ 113 def _setup_test_cluster() -> ModuleTestCluster | None: │
│ ❱ 114 │ test_cluster = generate_test_cluster( │
│ 115 │ │ config.configuration.module_name, │
│ 116 │ │ config.configuration.type_inference.type_inference_strategy, │
│ 117 │ │ query_type4py=config.configuration.type_inference.type4py, │
│ │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/analyses/module.py:1442 in generate_test_cluster │
│ │
│ 1439 │ Returns: │
│ 1440 │ │ A new test cluster for the given module │
│ 1441 │ │
│ ❱ 1442 │ return analyse_module( │
│ 1443 │ │ parse_module(module_name, query_type4py=query_type4py), │
│ 1444 │ │ type_inference_strategy, │
│ 1445 │ │ query_type4py=query_type4py, │
│ │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/analyses/module.py:1418 in analyse_module │
│ │
│ 1415 │ │ A test cluster for the module │
│ 1416 │ │
│ 1417 │ test_cluster = ModuleTestCluster(linenos=parsed_module.linenos) │
│ ❱ 1418 │ __resolve_dependencies( │
│ 1419 │ │ root_module=parsed_module, │
│ 1420 │ │ type_inference_strategy=type_inference_strategy, │
│ 1421 │ │ test_cluster=test_cluster, │
│ │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/analyses/module.py:1291 in __resolve_dependencies │
│ │
│ 1288 │ │ │ continue │
│ 1289 │ │ │
│ 1290 │ │ # Analyze all classes found in the current module │
│ ❱ 1291 │ │ __analyse_included_classes( │
│ 1292 │ │ │ module=current_module, │
│ 1293 │ │ │ root_module_name=root_module.module_name, │
│ 1294 │ │ │ type_inference_strategy=type_inference_strategy, │
│ │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/analyses/module.py:1351 in __analyse_included_classes │
│ │
│ 1348 │ │ │
│ 1349 │ │ type_info = test_cluster.type_system.to_type_info(current) │
│ 1350 │ │ │
│ ❱ 1351 │ │ __analyse_class( │
│ 1352 │ │ │ type_info=type_info, │
│ 1353 │ │ │ type_inference_strategy=type_inference_strategy, │
│ 1354 │ │ │ module_tree=parse_results[current.__module__].syntax_tree, │
│ │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/analyses/module.py:1108 in __analyse_class │
│ │
│ 1105 │ else: │
│ 1106 │ │ generic = GenericConstructor( │
│ 1107 │ │ │ type_info, │
│ ❱ 1108 │ │ │ test_cluster.type_system.infer_type_info( │
│ 1109 │ │ │ │ type_info.raw_type.__init__, │
│ 1110 │ │ │ │ type4py_data=find_predicted_signature( │
│ 1111 │ │ │ │ │ type4py_data, type_info.qualname + ".__init__", type_info.qualname │
│ │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/analyses/typesystem.py:1526 in infer_type_info │
│ │
│ 1523 │ │ │
│ 1524 │ │ match type_inference_strategy: │
│ 1525 │ │ │ case config.TypeInferenceStrategy.TYPE_HINTS: │
│ ❱ 1526 │ │ │ │ return self.infer_signature( │
│ 1527 │ │ │ │ │ method, type4py_data, self.type_hints_provider │
│ 1528 │ │ │ │ ) │
│ 1529 │ │ │ case config.TypeInferenceStrategy.NONE: │
│ │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/analyses/typesystem.py:1588 in infer_signature │
│ │
│ 1585 │ │ Returns: │
│ 1586 │ │ │ The inference result │
│ 1587 │ │ │
│ ❱ 1588 │ │ method_signature = inspect.signature(method) │
│ 1589 │ │ hints = type_hint_provider(method) │
│ 1590 │ │ parameters: dict[str, ProperType] = {} │
│ 1591 │ │ type4py_parameters: dict[str, list[ProperType]] = {} │
│ │
│ /Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/inspect.py:3247 in signature │
│ │
│ 3244 │
│ 3245 def signature(obj, *, follow_wrapped=True, globals=None, locals=None, eval_str=False): │
│ 3246 │ """Get a signature object for the passed callable.""" │
│ ❱ 3247 │ return Signature.from_callable(obj, follow_wrapped=follow_wrapped, │
│ 3248 │ │ │ │ │ │ │ │ globals=globals, locals=locals, eval_str=eval_str) │
│ 3249 │
│ 3250 │
│ │
│ /Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/inspect.py:2995 in │
│ from_callable │
│ │
│ 2992 │ def from_callable(cls, obj, *, │
│ 2993 │ │ │ │ │ follow_wrapped=True, globals=None, locals=None, eval_str=False): │
│ 2994 │ │ """Constructs Signature for the given callable object.""" │
│ ❱ 2995 │ │ return _signature_from_callable(obj, sigcls=cls, │
│ 2996 │ │ │ │ │ │ │ │ │ │ follow_wrapper_chains=follow_wrapped, │
│ 2997 │ │ │ │ │ │ │ │ │ │ globals=globals, locals=locals, eval_str=eval_st │
│ 2998 │
│ │
│ /Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/inspect.py:2461 in │
│ _signature_from_callable │
│ │
│ 2458 │ │ │ │ │ │ │ │ │ │ globals=globals, locals=locals, eval_str=eval_st │
│ 2459 │ │
│ 2460 │ if _signature_is_builtin(obj): │
│ ❱ 2461 │ │ return _signature_from_builtin(sigcls, obj, │
│ 2462 │ │ │ │ │ │ │ │ │ skip_bound_arg=skip_bound_arg) │
│ 2463 │ │
│ 2464 │ if isinstance(obj, functools.partial): │
│ │
│ /Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/inspect.py:2271 in │
│ _signature_from_builtin │
│ │
│ 2268 │ │
│ 2269 │ s = getattr(func, "__text_signature__", None) │
│ 2270 │ if not s: │
│ ❱ 2271 │ │ raise ValueError("no signature found for builtin {!r}".format(func)) │
│ 2272 │ │
│ 2273 │ return _signature_fromstr(cls, func, s, skip_bound_arg) │
│ 2274 │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
ValueError: no signature found for builtin <slot wrapper '__init__' of 'pandas._libs.interval.IntervalTree' objects>
Wow, yet another exception from deep within the inspect
library. One could, of course, also catch the ValueError
, like the others, but I doubt that this is more than a hacky workaround. It would be interesting, if there is a specific property to a callable, such that one could prevent this error by not querying the inspect
library, if such a (hypothetical) property holds. Probably, it's related to these Pandas modules...
Fixed changing the import (issue related to #35).
From
import pandas
to
from pandas import DataFrame
Maybe could be useful adding this in the doc.
While I expect that this would mitigate the issue, I'd probably not consider it a fix that would work in practice. The reason why it's working is due to Python's import system: import pandas
imports everything exported by the __init__.py
from pandas
, which is a lot, especially, since it's a transitive process. from pandas import DataFrame
only imports the DataFrame
class, i.e., way fewer things.
The problem I have with this, and that's why I do not think, it's good to put it into the documentation, is that almost every tutorial in the world that I've seen and that is using Pandas has the line import pandas as pd
, which is essentially the same as import pandas
but only defines the name pd
as an alias to pandas
. Thus, the problem might occur on all these examples. Therefore, I need to think about a proper fix for this, anyway.
Yes, but in the meantime those using Pynguin may have information on a workaround to generate test cases even if pandas is used in production code.
P.s My Pynguin build has been stuck on Iteration 154 for 20 minutes, do you suggest waiting or stopping the process?
(.venv_3.10) (base) ncdaam@vkwmr6cjkv-mac LogicalCouplingTool % pynguin --project-path . --output-path ./tests/developer_coupling/ --module-name coupling.developer_coupling -v
[12:26:51] INFO Start Pynguin Test Generation… generator.py:107
INFO Collecting static constants from module under test generator.py:208
INFO Constants found: 206 generator.py:213
INFO Setting up runtime collection of constants generator.py:220
[12:26:58] INFO Analyzed project to create test cluster module.py:1318
INFO Modules: 49 module.py:1319
INFO Functions: 109 module.py:1320
INFO Classes: 166 module.py:1321
INFO Using seed 1706700409493336000 generator.py:194
INFO Using strategy: Algorithm.DYNAMOSA generationalgorithmfactory.py:302
INFO Instantiated 47 fitness functions generationalgorithmfactory.py:393
INFO Using CoverageArchive generationalgorithmfactory.py:346
INFO Using selection function: Selection.TOURNAMENT_SELECTION generationalgorithmfactory.py:321
INFO No stopping condition configured! generationalgorithmfactory.py:119
INFO Using fallback timeout of 600 seconds generationalgorithmfactory.py:120
INFO Using crossover function: SinglePointRelativeCrossOver generationalgorithmfactory.py:334
INFO Using ranking function: RankBasedPreferenceSorting generationalgorithmfactory.py:354
INFO Start generating test cases generator.py:517
INFO Initial Population, Coverage: 0.063830 searchobserver.py:77
INFO Iteration: 1, Coverage: 0.063830 searchobserver.py:83
INFO Iteration: 2, Coverage: 0.063830 searchobserver.py:83
INFO Iteration: 3, Coverage: 0.085106 searchobserver.py:83
INFO Iteration: 4, Coverage: 0.085106 searchobserver.py:83
INFO Iteration: 5, Coverage: 0.085106 searchobserver.py:83
INFO Iteration: 6, Coverage: 0.085106 searchobserver.py:83
INFO Iteration: 7, Coverage: 0.085106 searchobserver.py:83
INFO Iteration: 8, Coverage: 0.085106 searchobserver.py:83
INFO Iteration: 9, Coverage: 0.085106 searchobserver.py:83
INFO Iteration: 10, Coverage: 0.085106 searchobserver.py:83
INFO Iteration: 11, Coverage: 0.085106 searchobserver.py:83
INFO Iteration: 12, Coverage: 0.085106 searchobserver.py:83
INFO Iteration: 13, Coverage: 0.085106 searchobserver.py:83
INFO Iteration: 14, Coverage: 0.085106 searchobserver.py:83
[12:27:04] INFO Iteration: 15, Coverage: 0.085106 searchobserver.py:83
INFO Iteration: 16, Coverage: 0.085106 searchobserver.py:83
[12:27:05] INFO Iteration: 17, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 18, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 19, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 20, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 21, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 22, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 23, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 24, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 25, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 26, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 27, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 28, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 29, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 30, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 31, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 32, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 33, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 34, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 35, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 36, Coverage: 0.106383 searchobserver.py:83
[12:27:13] INFO Iteration: 37, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 38, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 39, Coverage: 0.106383 searchobserver.py:83
[12:27:15] INFO Iteration: 40, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 41, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 42, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 43, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 44, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 45, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 46, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 47, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 48, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 49, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 50, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 51, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 52, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 53, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 54, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 55, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 56, Coverage: 0.106383 searchobserver.py:83
[12:27:22] INFO Iteration: 57, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 58, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 59, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 60, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 61, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 62, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 63, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 64, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 65, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 66, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 67, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 68, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 69, Coverage: 0.106383 searchobserver.py:83
[12:27:26] INFO Iteration: 70, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 71, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 72, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 73, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 74, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 75, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 76, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 77, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 78, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 79, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 80, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 81, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 82, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 83, Coverage: 0.106383 searchobserver.py:83
[12:27:30] INFO Iteration: 84, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 85, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 86, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 87, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 88, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 89, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 90, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 91, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 92, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 93, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 94, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 95, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 96, Coverage: 0.106383 searchobserver.py:83
INFO Iteration: 97, Coverage: 0.170213 searchobserver.py:83
INFO Iteration: 98, Coverage: 0.170213 searchobserver.py:83
INFO Iteration: 99, Coverage: 0.170213 searchobserver.py:83
INFO Iteration: 100, Coverage: 0.170213 searchobserver.py:83
INFO Iteration: 101, Coverage: 0.191489 searchobserver.py:83
INFO Iteration: 102, Coverage: 0.191489 searchobserver.py:83
INFO Iteration: 103, Coverage: 0.191489 searchobserver.py:83
INFO Iteration: 104, Coverage: 0.191489 searchobserver.py:83
INFO Iteration: 105, Coverage: 0.191489 searchobserver.py:83
INFO Iteration: 106, Coverage: 0.191489 searchobserver.py:83
INFO Iteration: 107, Coverage: 0.191489 searchobserver.py:83
INFO Iteration: 108, Coverage: 0.191489 searchobserver.py:83
INFO Iteration: 109, Coverage: 0.191489 searchobserver.py:83
INFO Iteration: 110, Coverage: 0.191489 searchobserver.py:83
INFO Iteration: 111, Coverage: 0.191489 searchobserver.py:83
INFO Iteration: 112, Coverage: 0.191489 searchobserver.py:83
INFO Iteration: 113, Coverage: 0.191489 searchobserver.py:83
INFO Iteration: 114, Coverage: 0.191489 searchobserver.py:83
INFO Iteration: 115, Coverage: 0.191489 searchobserver.py:83
INFO Iteration: 116, Coverage: 0.191489 searchobserver.py:83
INFO Iteration: 117, Coverage: 0.191489 searchobserver.py:83
INFO Iteration: 118, Coverage: 0.191489 searchobserver.py:83
INFO Iteration: 119, Coverage: 0.191489 searchobserver.py:83
[12:27:44] INFO Iteration: 120, Coverage: 0.191489 searchobserver.py:83
INFO Iteration: 121, Coverage: 0.191489 searchobserver.py:83
INFO Iteration: 122, Coverage: 0.191489 searchobserver.py:83
INFO Iteration: 123, Coverage: 0.191489 searchobserver.py:83
INFO Iteration: 124, Coverage: 0.191489 searchobserver.py:83
INFO Iteration: 125, Coverage: 0.191489 searchobserver.py:83
INFO Iteration: 126, Coverage: 0.191489 searchobserver.py:83
INFO Iteration: 127, Coverage: 0.191489 searchobserver.py:83
INFO Iteration: 128, Coverage: 0.191489 searchobserver.py:83
INFO Iteration: 129, Coverage: 0.191489 searchobserver.py:83
INFO Iteration: 130, Coverage: 0.191489 searchobserver.py:83
INFO Iteration: 131, Coverage: 0.212766 searchobserver.py:83
INFO Iteration: 132, Coverage: 0.212766 searchobserver.py:83
[12:27:51] INFO Iteration: 133, Coverage: 0.212766 searchobserver.py:83
INFO Iteration: 134, Coverage: 0.212766 searchobserver.py:83
INFO Iteration: 135, Coverage: 0.212766 searchobserver.py:83
INFO Iteration: 136, Coverage: 0.212766 searchobserver.py:83
[12:27:55] INFO Iteration: 137, Coverage: 0.212766 searchobserver.py:83
[12:27:56] INFO Iteration: 138, Coverage: 0.212766 searchobserver.py:83
INFO Iteration: 139, Coverage: 0.276596 searchobserver.py:83
INFO Iteration: 140, Coverage: 0.276596 searchobserver.py:83
INFO Iteration: 141, Coverage: 0.276596 searchobserver.py:83
INFO Iteration: 142, Coverage: 0.276596 searchobserver.py:83
INFO Iteration: 143, Coverage: 0.276596 searchobserver.py:83
INFO Iteration: 144, Coverage: 0.276596 searchobserver.py:83
INFO Iteration: 145, Coverage: 0.276596 searchobserver.py:83
INFO Iteration: 146, Coverage: 0.276596 searchobserver.py:83
INFO Iteration: 147, Coverage: 0.276596 searchobserver.py:83
INFO Iteration: 148, Coverage: 0.276596 searchobserver.py:83
INFO Iteration: 149, Coverage: 0.361702 searchobserver.py:83
INFO Iteration: 150, Coverage: 0.361702 searchobserver.py:83
INFO Iteration: 151, Coverage: 0.361702 searchobserver.py:83
INFO Iteration: 152, Coverage: 0.361702 searchobserver.py:83
INFO Iteration: 153, Coverage: 0.361702 searchobserver.py:83
INFO Iteration: 154, Coverage: 0.361702 searchobserver.py:83
⠹ Running Pynguin...
While I expect that this would mitigate the issue, I'd probably not consider it a fix that would work in practice. The reason why it's working is due to Python's import system:
import pandas
imports everything exported by the__init__.py
frompandas
, which is a lot, especially, since it's a transitive process.from pandas import DataFrame
only imports theDataFrame
class, i.e., way fewer things.The problem I have with this, and that's why I do not think, it's good to put it into the documentation, is that almost every tutorial in the world that I've seen and that is using Pandas has the line
import pandas as pd
, which is essentially the same asimport pandas
but only defines the namepd
as an alias topandas
. Thus, the problem might occur on all these examples. Therefore, I need to think about a proper fix for this, anyway.
completely agree with you, this is how pandas is most often imported. It happens a lot in our code, so this is how I spotted the issue originally.
Could you try today's release? It contains two fixes (see #57 and #59) that might be related. Looking forward to your replies.
@stephanlukasczyk I tried the release 0.35.0. When I am using pandas and numpy inside def
, then pynguin works. When they are imported before the Class (place the imports at the beginning of the file, as the only change), then I get an error.
import pandas as pd import numpy as np
python3 -m pynguin --output-path .\tmp\pynguin-res\ -v --project-path . --module-name hello --maximum-iterations 100
[09:10:30] INFO Start Pynguin Test Generation… generator.py:107
INFO Collecting static constants from module under test generator.py:208
INFO No constants found generator.py:211
INFO Setting up runtime collection of constants generator.py:220
[09:11:18] INFO Stop Pynguin Test Generation… generator.py:110
╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮
│ C:\Program │
│ Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\lib\runpy. │
│ py:196 in _run_module_as_main │
│ │
│ 193 │ main_globals = sys.modules["__main__"].__dict__ │
│ 194 │ if alter_argv: │
│ 195 │ │ sys.argv[0] = mod_spec.origin │
│ ❱ 196 │ return _run_code(code, main_globals, None, │
│ 197 │ │ │ │ │ "__main__", mod_spec) │
│ 198 │
│ 199 def run_module(mod_name, init_globals=None, │
│ │
│ C:\Program │
│ Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\lib\runpy. │
│ py:86 in _run_code │
│ │
│ 83 │ │ │ │ │ __loader__ = loader, │
│ 84 │ │ │ │ │ __package__ = pkg_name, │
│ 85 │ │ │ │ │ __spec__ = mod_spec) │
│ ❱ 86 │ exec(code, run_globals) │
│ 87 │ return run_globals │
│ 88 │
│ 89 def _run_module_code(code, init_globals=None, │
│ │
│ C:\Users\zshapira\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\Loca │
│ lCache\local-packages\Python310\site-packages\pynguin\__main__.py:17 in <module> │
│ │
│ 14 │
│ 15 │
│ 16 if __name__ == "__main__": │
│ ❱ 17 │ sys.exit(main(sys.argv)) │
│ 18 │
│ │
│ C:\Users\zshapira\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\Loca │
│ lCache\local-packages\Python310\site-packages\pynguin\cli.py:193 in main │
│ │
│ 190 │ set_configuration(parsed.config) │
│ 191 │ if console is not None: │
│ 192 │ │ with console.status("Running Pynguin..."): │
│ ❱ 193 │ │ │ return run_pynguin().value │
│ 194 │ else: │
│ 195 │ │ return run_pynguin().value │
│ 196 │
│ │
│ C:\Users\zshapira\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\Loca │
│ lCache\local-packages\Python310\site-packages\pynguin\generator.py:108 in run_pynguin │
│ │
│ 105 │ """ │
│ 106 │ try: │
│ 107 │ │ _LOGGER.info("Start Pynguin Test Generation…") │
│ ❱ 108 │ │ return _run() │
│ 109 │ finally: │
│ 110 │ │ _LOGGER.info("Stop Pynguin Test Generation…") │
│ 111 │
│ │
│ C:\Users\zshapira\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\Loca │
│ lCache\local-packages\Python310\site-packages\pynguin\generator.py:507 in _run │
│ │
│ 504 │
│ 505 │
│ 506 def _run() -> ReturnCode: │
│ ❱ 507 │ if (setup_result := _setup_and_check()) is None: │
│ 508 │ │ return ReturnCode.SETUP_FAILED │
│ 509 │ executor, test_cluster, constant_provider = setup_result │
│ 510 │ # traces slices for test cases after execution │
│ │
│ C:\Users\zshapira\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\Loca │
│ lCache\local-packages\Python310\site-packages\pynguin\generator.py:258 in _setup_and_check │
│ │
│ 255 │ │
│ 256 │ # Analyzing the SUT should not cause any coverage. │
│ 257 │ tracer.disable() │
│ ❱ 258 │ if (test_cluster := _setup_test_cluster()) is None: │
│ 259 │ │ return None │
│ 260 │ tracer.enable() │
│ 261 │
│ │
│ C:\Users\zshapira\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\Loca │
│ lCache\local-packages\Python310\site-packages\pynguin\generator.py:114 in _setup_test_cluster │
│ │
│ 111 │
│ 112 │
│ 113 def _setup_test_cluster() -> ModuleTestCluster | None: │
│ ❱ 114 │ test_cluster = generate_test_cluster( │
│ 115 │ │ config.configuration.module_name, │
│ 116 │ │ config.configuration.type_inference.type_inference_strategy, │
│ 117 │ │ query_type4py=config.configuration.type_inference.type4py, │
│ │
│ C:\Users\zshapira\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\Loca │
│ lCache\local-packages\Python310\site-packages\pynguin\analyses\module.py:1501 in │
│ generate_test_cluster │
│ │
│ 1498 │ Returns: │
│ 1499 │ │ A new test cluster for the given module │
│ 1500 │ """ │
│ ❱ 1501 │ return analyse_module( │
│ 1502 │ │ parse_module(module_name, query_type4py=query_type4py), │
│ 1503 │ │ type_inference_strategy, │
│ 1504 │ │ query_type4py=query_type4py, │
│ │
│ C:\Users\zshapira\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\Loca │
│ lCache\local-packages\Python310\site-packages\pynguin\analyses\module.py:1476 in analyse_module │
│ │
│ 1473 │ │ A test cluster for the module │
│ 1474 │ """ │
│ 1475 │ test_cluster = ModuleTestCluster(linenos=parsed_module.linenos) │
│ ❱ 1476 │ __resolve_dependencies( │
│ 1477 │ │ root_module=parsed_module, │
│ 1478 │ │ type_inference_strategy=type_inference_strategy, │
│ 1479 │ │ test_cluster=test_cluster, │
│ │
│ C:\Users\zshapira\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\Loca │
│ lCache\local-packages\Python310\site-packages\pynguin\analyses\module.py:1341 in │
│ __resolve_dependencies │
│ │
│ 1338 │ │ ) │
│ 1339 │ │ │
│ 1340 │ │ # Analyze all functions found in the current module │
│ ❱ 1341 │ │ __analyse_included_functions( │
│ 1342 │ │ │ module=current_module, │
│ 1343 │ │ │ root_module_name=root_module.module_name, │
│ 1344 │ │ │ type_inference_strategy=type_inference_strategy, │
│ │
│ C:\Users\zshapira\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\Loca │
│ lCache\local-packages\Python310\site-packages\pynguin\analyses\module.py:1452 in │
│ __analyse_included_functions │
│ │
│ 1449 │ │ │ func_name=current.__qualname__, │
│ 1450 │ │ │ func=current, │
│ 1451 │ │ │ type_inference_strategy=type_inference_strategy, │
│ ❱ 1452 │ │ │ module_tree=parse_results[current.__module__].syntax_tree, │
│ 1453 │ │ │ type4py_data=parse_results[current.__module__].type4py_data, │
│ 1454 │ │ │ test_cluster=test_cluster, │
│ 1455 │ │ │ add_to_test=current.__module__ == root_module_name, │
│ │
│ C:\Users\zshapira\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\Loca │
│ lCache\local-packages\Python310\site-packages\pynguin\analyses\module.py:1285 in __missing__ │
│ │
│ 1282 │ │
│ 1283 │ def __missing__(self, key): │
│ 1284 │ │ # Parse module on demand │
│ ❱ 1285 │ │ res = self[key] = parse_module(key, query_type4py=self._query_type4py) │
│ 1286 │ │ return res │
│ 1287 │
│ 1288 │
│ │
│ C:\Users\zshapira\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\Loca │
│ lCache\local-packages\Python310\site-packages\pynguin\analyses\module.py:284 in parse_module │
│ │
│ 281 │ Returns: │
│ 282 │ │ A tuple of the imported module type and its optional AST │
│ 283 │ """ │
│ ❱ 284 │ module = import_module(module_name) │
│ 285 │ type4py_data: Type4pyData | None = None │
│ 286 │ syntax_tree: astroid.Module | None = None │
│ 287 │ linenos: int = -1 │
│ │
│ C:\Users\zshapira\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\Loca │
│ lCache\local-packages\Python310\site-packages\pynguin\analyses\module.py:244 in import_module │
│ │
│ 241 │ │ The imported module │
│ 242 │ """ │
│ 243 │ try: │
│ ❱ 244 │ │ return importlib.import_module(module_name) │
│ 245 │ except ModuleNotFoundError as error: │
│ 246 │ │ try: │
│ 247 │ │ │ package_name, submodule_name = module_name.rsplit(".", 1) │
│ │
│ C:\Program │
│ Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\lib\import │
│ lib\__init__.py:117 in import_module │
│ │
│ 114 │ │
│ 115 │ """ │
│ 116 │ level = 0 │
│ ❱ 117 │ if name.startswith('.'): │
│ 118 │ │ if not package: │
│ 119 │ │ │ msg = ("the 'package' argument is required to perform a relative " │
│ 120 │ │ │ │ "import for {!r}") │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
AttributeError: 'NoneType' object has no attribute 'startswith'
OK, so this becomes even more strange. Using an absolutely minimal example
import numpy as pd
import pandas as pd
def foo(a: int) -> int:
return a
with Pynguin 0.35.0 and Python 3.10.13 on an Intel Mac works like a charm. No warning, no errors, one test case.
Using the example from your initial posting lets Pynguin start, it then yields some warnings/errors:
WARNING Unexpectedly had no exception name raised and no exception in context. syntaxtree.py:223
ERROR While getting the types of exceptions in the handler, expected to find an syntaxtree.py:341
ast.Name, ast.Tuple, or ast.Attribute,but got <ast.Call object at
0x14f337bb0>
ERROR While getting the types of exceptions in the handler, expected to find an syntaxtree.py:341
ast.Name, ast.Tuple, or ast.Attribute,but got <ast.Call object at
0x14f28cd30>
However, it continues further, yields information about the collected modules, functions, and classes, and starts generating tests. Then, the Python crashes with some call stack. Hence, I cannot directly replicate your issue, but I'll try on other machines whether I can reproduce it there.
With this, I'll reopen the issue because it definitely needs further investigation, although I need to admit that I currently have no real idea on what the actual cause of the problem is and how to fix it. I'll keep you updated.
Interesting observation: if I run the exact same thing on a Debian 12.5 machine, I also get the aforementioned warning and error messages in the log output, however, there is no crash and Pynguin generates a (more or less reasonable) test case:
# Test cases automatically generated by Pynguin (https://www.pynguin.eu).
# Please check them before you use them.
import pytest
import hello as module_0
def test_case_0:
filter_correlated_features_0 = module_0.FilterCorrelatedFeatures()
assert filter_correlated_features_0.corr_threshold == pytest.approx(
0.8, abs=0.01, rel=0.01
)
filter_correlated_features_1 = module_0.FilterCorrelatedFeatures(
filter_correlated_features_0
)
Unfortunately, I do not have any Windows machine to figure out whether it is something Windows specific 😞 Perhaps, if I find the issue on macOS, it could fix the issue on Windows, too.
Edit: Additional library version: numpy==1.26.4
, pandas==2.2.1
, and matplotlib==3.8.3
OK, so this becomes even more strange. Using an absolutely minimal example
import numpy as pd import pandas as pd def foo(a: int) -> int: return a
with Pynguin 0.35.0 and Python 3.10.13 on an Intel Mac works like a charm. No warning, no errors, one test case.
Using the example from your initial posting lets Pynguin start, it then yields some warnings/errors:
WARNING Unexpectedly had no exception name raised and no exception in context. syntaxtree.py:223 ERROR While getting the types of exceptions in the handler, expected to find an syntaxtree.py:341 ast.Name, ast.Tuple, or ast.Attribute,but got <ast.Call object at 0x14f337bb0> ERROR While getting the types of exceptions in the handler, expected to find an syntaxtree.py:341 ast.Name, ast.Tuple, or ast.Attribute,but got <ast.Call object at 0x14f28cd30>
However, it continues further, yields information about the collected modules, functions, and classes, and starts generating tests. Then, the Python crashes with some call stack. Hence, I cannot directly replicate your issue, but I'll try on other machines whether I can reproduce it there.
With this, I'll reopen the issue because it definitely needs further investigation, although I need to admit that I currently have no real idea on what the actual cause of the problem is and how to fix it. I'll keep you updated.
I ran the minimal example and got the same error, that I posted before (AttributeError: 'NoneType' object has no attribute 'startswith'). When moving the imports under the def
, then pynguin works just fine and generates 1 test.
in the former case, importlib seems to not get any module name, so name is None.
Windows 11 Intel Core python 3.10.11 numpy 1.23.5 pandas 1.5.3
OK, I can reproduce the issue on Linux, when using the Python, numpy, and pandas versions you've mentioned. I'll keep you updated.
If it helps you out, I upgraded my pandas and numpy to your versions (only change) and now I get the same success when the imports are inside the def. When I move them outside the def (first 2 lines in the file), I now get a unit test, but during the run I get these errors, similar to what you got:
[14:10:51] ERROR While getting the types of exceptions in the handler, expected to find an ast.Name, syntaxtree.py:341
ast.Tuple, or ast.Attribute,but got <ast.Call object at 0x000001CED7BDBEE0>
ERROR While getting the types of exceptions in the handler, expected to find an ast.Name, syntaxtree.py:341
ast.Tuple, or ast.Attribute,but got <ast.Call object at 0x000001CED7B6FA30>
note: if I comment out pandas (leaving only the numpy import), I don't get the above error. using above and here your minimal example @stephanlukasczyk
Describe the bug Error when generating tests:
TypeError: unsupported operand type(s) for |: 'NoneType' and 'NoneType'
To Reproduce Steps to reproduce the behaviour:
class FilterCorrelatedFeatures: