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

TypeError: unsupported operand type(s) for |: 'NoneType' and 'NoneType' #53

Open
zivshapiraintel opened this issue Nov 22, 2023 · 19 comments

Comments

@zivshapiraintel
Copy link

zivshapiraintel commented Nov 22, 2023

Describe the bug
Error when generating tests: TypeError: unsupported operand type(s) for |: 'NoneType' and 'NoneType'

To Reproduce
Steps to reproduce the behaviour:

  1. Use Pynguin version '0.34.0'
  2. Use the following (minimal) code as a subject for test generation:
import os
import numpy as np
import pandas as pd
import matplotlib
import matplotlib.pyplot as plt


class FilterCorrelatedFeatures:

    def __init__(self, corr_threshold=0.80):
        self.corr_threshold = corr_threshold
        self.correlated_features = []
        self.corr_matrix = pd.DataFrame()
  1. Use the following command line arguments to Pynguin:
    python -m pynguin --output-path . -v --project-path src/data_preprocessing/ --module-name hello

  2. Give the error (stack trace, etc) you are encountering: '...'
    pynguin-log.txt

Expected behavior
generate a simple test.

Screenshots
NA

Software Version (please complete the following information):

  • OS: [Ubuntu 20.04.6 LTS]
  • Python version [3.10.13]
  • Pynguin Version [0.34.0]
@zivshapiraintel
Copy link
Author

zivshapiraintel commented Nov 22, 2023

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

@jordan-gillard
Copy link

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?

@zivshapiraintel
Copy link
Author

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?

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.

stephanlukasczyk added a commit that referenced this issue Jan 16, 2024
Retrieving type hints for numpy-related modules seem to raise TypeErrors
inside the Python typing standard API.  Since we do not know how to deal
with them properly, we catch the errors, log them, and do not provide
any hints at all.
@stephanlukasczyk
Copy link
Member

I was able to reproduce and fix this particular issue in d811cac. 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.

@darioamorosodaragona-tuni

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 Generationgenerator.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 Generationgenerator.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__':                                                                   │
│   7sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])                         │
│ ❱ 8sys.exit(main())                                                                         │
│   9                                                                                              │
│                                                                                                  │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/cli.py:196 in main                                                                             │
│                                                                                                  │
│   193set_configuration(parsed.config)                                                       │
│   194if console is not None:                                                                │
│   195 │   │   with console.status("Running Pynguin..."):                                         │
│ ❱ 196 │   │   │   return run_pynguin().value                                                     │
│   197else:                                                                                  │
│   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 │                                                                                       │
│   106try:                                                                                   │
│   107 │   │   _LOGGER.info("Start Pynguin Test Generation…")                                     │
│ ❱ 108 │   │   return _run()                                                                      │
│   109finally:                                                                               │
│   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:                                                                  │
│ ❱ 506if (setup_result := _setup_and_check()) is None:                                       │
│   507 │   │   return ReturnCode.SETUP_FAILED                                                     │
│   508executor, 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.                                     │257tracer.disable()                                                                       │
│ ❱ 258if (test_cluster := _setup_test_cluster()) is None:                                    │
│   259 │   │   return None                                                                        │
│   260tracer.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:                                     │
│ ❱ 114test_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                                               │
│                                                                                                  │
│   1439Returns:                                                                              │
│   1440 │   │   A new test cluster for the given module                                           │
│   1441 │                                                                                      │
│ ❱ 1442return 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 │                                                                                      │
│   1417test_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                                                     │
│                                                                                                  │
│   1138for 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 │                                                                                         │
│   1212LOGGER.debug("Analysing method %s.%s", type_info.full_name, method_name)              │
│ ❱ 1213inferred_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    │
│                                                                                                  │
│    323with recursive ForwardRef.                                                            │
│    324 │                                                                                      │
│    325if isinstance(t, ForwardRef):                                                         │
│ ❱  326 │   │   return t._evaluate(globalns, localns, recursive_guard)                            │
│    327if 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'

@darioamorosodaragona-tuni

As explained in #53 (comment), in the same way as d811cac 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 Generationgenerator.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 Generationgenerator.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__':                                                                   │
│   7sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])                         │
│ ❱ 8sys.exit(main())                                                                         │
│   9                                                                                              │
│                                                                                                  │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/cli.py:196 in main                                                                             │
│                                                                                                  │
│   193set_configuration(parsed.config)                                                       │
│   194if console is not None:                                                                │
│   195 │   │   with console.status("Running Pynguin..."):                                         │
│ ❱ 196 │   │   │   return run_pynguin().value                                                     │
│   197else:                                                                                  │
│   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 │                                                                                          │
│   106try:                                                                                   │
│   107 │   │   _LOGGER.info("Start Pynguin Test Generation…")                                     │
│ ❱ 108 │   │   return _run()                                                                      │
│   109finally:                                                                               │
│   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:                                                                  │
│ ❱ 506if (setup_result := _setup_and_check()) is None:                                       │
│   507 │   │   return ReturnCode.SETUP_FAILED                                                     │
│   508executor, 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.                                     │257tracer.disable()                                                                       │
│ ❱ 258if (test_cluster := _setup_test_cluster()) is None:                                    │
│   259 │   │   return None                                                                        │
│   260tracer.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:                                     │
│ ❱ 114test_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                                               │
│                                                                                                  │
│   1439Returns:                                                                              │
│   1440 │   │   A new test cluster for the given module                                           │
│   1441 │                                                                                         │
│ ❱ 1442return 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 │                                                                                         │
│   1417test_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                                                     │
│                                                                                                  │
│   1105else:                                                                                 │
│   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."""                                 │
│ ❱ 3247return 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                                                                                    │
│                                                                                                  │
│   2992def 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 │                                                                                         │
│   2460if _signature_is_builtin(obj):                                                        │
│ ❱ 2461 │   │   return _signature_from_builtin(sigcls, obj,                                       │
│   2462 │   │   │   │   │   │   │   │   │      skip_bound_arg=skip_bound_arg)                     │
│   2463 │                                                                                         │
│   2464if isinstance(obj, functools.partial):                                                │
│                                                                                                  │
│ /Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/inspect.py:2271 in             │
│ _signature_from_builtin                                                                          │
│                                                                                                  │
│   2268 │                                                                                         │
│   2269s = getattr(func, "__text_signature__", None)                                         │
│   2270if not s:                                                                             │
│ ❱ 2271 │   │   raise ValueError("no signature found for builtin {!r}".format(func))              │
│   2272 │                                                                                         │
│   2273return _signature_fromstr(cls, func, s, skip_bound_arg)                               │
│   2274                                                                                           │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
ValueError: no signature found for builtin <slot wrapper '__init__' of 'pandas._libs.interval.IntervalTree' objects>

@stephanlukasczyk
Copy link
Member

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...

@darioamorosodaragona-tuni
Copy link

darioamorosodaragona-tuni commented Jan 31, 2024

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.

@stephanlukasczyk
Copy link
Member

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.

@darioamorosodaragona-tuni
Copy link

darioamorosodaragona-tuni commented Jan 31, 2024

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 Generationgenerator.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:83Running Pynguin...

@zivshapiraintel
Copy link
Author

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.

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.

@stephanlukasczyk
Copy link
Member

Could you try today's release? It contains two fixes (see #57 and #59) that might be related. Looking forward to your replies.

@zivshapiraintel
Copy link
Author

@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'

@stephanlukasczyk
Copy link
Member

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.

@stephanlukasczyk
Copy link
Member

stephanlukasczyk commented Feb 26, 2024

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

@zivshapiraintel
Copy link
Author

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

@stephanlukasczyk
Copy link
Member

OK, I can reproduce the issue on Linux, when using the Python, numpy, and pandas versions you've mentioned. I'll keep you updated.

@zivshapiraintel
Copy link
Author

zivshapiraintel commented Feb 26, 2024

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>

@zivshapiraintel
Copy link
Author

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants