se2p / pynguin

The PYthoN General UnIt Test geNerator is a test-generation tool for Python
https://www.pynguin.eu
MIT License
1.24k stars 76 forks source link

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

Open zivshapiraintel opened 1 year ago

zivshapiraintel commented 1 year ago

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()

4. Use the following command line arguments to Pynguin: 
`python -m pynguin --output-path . -v --project-path src/data_preprocessing/ --module-name hello`

5. Give the error (stack trace, etc) you are encountering: '...'
[pynguin-log.txt](https://github.com/se2p/pynguin/files/13433889/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 commented 1 year ago

issue seems to be with addingimport pandas (2.1.3). Just by importing it, without even using it in the__init__ method, the error above occurs

jordan-gillard commented 11 months ago

issue seems to be with addingimport pandas (2.1.3). Just by importing it, without even using it in the__init__ method, the error above occurs

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 commented 11 months ago

issue seems to be with addingimport pandas (2.1.3). Just by importing it, without even using it in the__init__ method, the error above occurs

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 commented 10 months ago

I was able to reproduce and fix this particular issue in d811cacc59f73c84e9cd83ceb466ec308c66410b. However, there is yet another issue (at least on my machine) that causes failure: some numpy module cannot be found for whatever reason I do not really understand.

Code that uses numpy or pandas still causes struggles to Pynguin for various reasons, unfortunately.

darioamorosodaragona-tuni commented 10 months ago

I have the same problem.

command:

(.venv_3.10) (base) ncdaam@vkwmr6cjkv-mac LogicalCouplingTool % pynguin --project-path . --output-path ./tests/developer_coupling/ --module-name coupling.developer_coupling -v > pynguin.txt

Output:

[22:50:02] INFO     Start Pynguin Test Generation…                                                                                                              generator.py:107
           INFO     Collecting static constants from module under test                                                                                          generator.py:208
           INFO     Constants found: 207                                                                                                                        generator.py:213
           INFO     Setting up runtime collection of constants                                                                                                  generator.py:220
[22:50:06] INFO     Stop Pynguin Test Generation…                                                                                                               generator.py:110
╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/bin/pynguin:8 in <module>           │
│                                                                                                  │
│   5 from pynguin.cli import main                                                                 │
│   6 if __name__ == '__main__':                                                                   │
│   7 │   sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])                         │
│ ❱ 8 │   sys.exit(main())                                                                         │
│   9                                                                                              │
│                                                                                                  │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/cli.py:196 in main                                                                             │
│                                                                                                  │
│   193 │   set_configuration(parsed.config)                                                       │
│   194 │   if console is not None:                                                                │
│   195 │   │   with console.status("Running Pynguin..."):                                         │
│ ❱ 196 │   │   │   return run_pynguin().value                                                     │
│   197 │   else:                                                                                  │
│   198 │   │   return run_pynguin().value                                                         │
│   199                                                                                            │
│                                                                                                  │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/generator.py:108 in run_pynguin                                                                │
│                                                                                                  │
│   105 │                                                                                       │
│   106 │   try:                                                                                   │
│   107 │   │   _LOGGER.info("Start Pynguin Test Generation…")                                     │
│ ❱ 108 │   │   return _run()                                                                      │
│   109 │   finally:                                                                               │
│   110 │   │   _LOGGER.info("Stop Pynguin Test Generation…")                                      │
│   111                                                                                            │
│                                                                                                  │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/generator.py:506 in _run                                                                       │
│                                                                                                  │
│   503                                                                                            │
│   504                                                                                            │
│   505 def _run() -> ReturnCode:                                                                  │
│ ❱ 506 │   if (setup_result := _setup_and_check()) is None:                                       │
│   507 │   │   return ReturnCode.SETUP_FAILED                                                     │
│   508 │   executor, test_cluster, constant_provider = setup_result                               │
│   509 │   # traces slices for test cases after execution                                         │
│                                                                                                  │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/generator.py:258 in _setup_and_check                                                           │
│                                                                                                  │
│   255 │                                                                                          │
│   256 │   # Analyzing the SUT should not cause any coverage.                                     │
│   257 │   tracer.disable()                                                                       │
│ ❱ 258 │   if (test_cluster := _setup_test_cluster()) is None:                                    │
│   259 │   │   return None                                                                        │
│   260 │   tracer.enable()                                                                        │
│   261                                                                                            │
│                                                                                                  │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/generator.py:114 in _setup_test_cluster                                                        │
│                                                                                                  │
│   111                                                                                            │
│   112                                                                                            │
│   113 def _setup_test_cluster() -> ModuleTestCluster | None:                                     │
│ ❱ 114 │   test_cluster = generate_test_cluster(                                                  │
│   115 │   │   config.configuration.module_name,                                                  │
│   116 │   │   config.configuration.type_inference.type_inference_strategy,                       │
│   117 │   │   query_type4py=config.configuration.type_inference.type4py,                         │
│                                                                                                  │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/analyses/module.py:1442 in generate_test_cluster                                               │
│                                                                                                  │
│   1439 │   Returns:                                                                              │
│   1440 │   │   A new test cluster for the given module                                           │
│   1441 │                                                                                      │
│ ❱ 1442 │   return analyse_module(                                                                │
│   1443 │   │   parse_module(module_name, query_type4py=query_type4py),                           │
│   1444 │   │   type_inference_strategy,                                                          │
│   1445 │   │   query_type4py=query_type4py,                                                      │
│                                                                                                  │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/analyses/module.py:1418 in analyse_module                                                      │
│                                                                                                  │
│   1415 │   │   A test cluster for the module                                                     │
│   1416 │                                                                                      │
│   1417 │   test_cluster = ModuleTestCluster(linenos=parsed_module.linenos)                       │
│ ❱ 1418 │   __resolve_dependencies(                                                               │
│   1419 │   │   root_module=parsed_module,                                                        │
│   1420 │   │   type_inference_strategy=type_inference_strategy,                                  │
│   1421 │   │   test_cluster=test_cluster,                                                        │
│                                                                                                  │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/analyses/module.py:1291 in __resolve_dependencies                                              │
│                                                                                                  │
│   1288 │   │   │   continue                                                                      │
│   1289 │   │                                                                                     │
│   1290 │   │   # Analyze all classes found in the current module                                 │
│ ❱ 1291 │   │   __analyse_included_classes(                                                       │
│   1292 │   │   │   module=current_module,                                                        │
│   1293 │   │   │   root_module_name=root_module.module_name,                                     │
│   1294 │   │   │   type_inference_strategy=type_inference_strategy,                              │
│                                                                                                  │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/analyses/module.py:1351 in __analyse_included_classes                                          │
│                                                                                                  │
│   1348 │   │                                                                                     │
│   1349 │   │   type_info = test_cluster.type_system.to_type_info(current)                        │
│   1350 │   │                                                                                     │
│ ❱ 1351 │   │   __analyse_class(                                                                  │
│   1352 │   │   │   type_info=type_info,                                                          │
│   1353 │   │   │   type_inference_strategy=type_inference_strategy,                              │
│   1354 │   │   │   module_tree=parse_results[current.__module__].syntax_tree,                    │
│                                                                                                  │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/analyses/module.py:1141 in __analyse_class                                                     │
│                                                                                                  │
│   1138 │   for method_name, method in inspect.getmembers(                                        │
│   1139 │   │   type_info.raw_type, inspect.isfunction                                            │
│   1140 │   ):                                                                                    │
│ ❱ 1141 │   │   __analyse_method(                                                                 │
│   1142 │   │   │   type_info=type_info,                                                          │
│   1143 │   │   │   method_name=method_name,                                                      │
│   1144 │   │   │   method=method,                                                                │
│                                                                                                  │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/analyses/module.py:1213 in __analyse_method                                                    │
│                                                                                                  │
│   1210 │   │   return                                                                            │
│   1211 │                                                                                         │
│   1212 │   LOGGER.debug("Analysing method %s.%s", type_info.full_name, method_name)              │
│ ❱ 1213 │   inferred_signature = test_cluster.type_system.infer_type_info(                        │
│   1214 │   │   method,                                                                           │
│   1215 │   │   type4py_data=find_predicted_signature(                                            │
│   1216 │   │   │   type4py_data, type_info.qualname + "." + method_name, type_info.qualname      │
│                                                                                                  │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/analyses/typesystem.py:1526 in infer_type_info                                                 │
│                                                                                                  │
│   1523 │   │                                                                                  │
│   1524 │   │   match type_inference_strategy:                                                    │
│   1525 │   │   │   case config.TypeInferenceStrategy.TYPE_HINTS:                                 │
│ ❱ 1526 │   │   │   │   return self.infer_signature(                                              │
│   1527 │   │   │   │   │   method, type4py_data, self.type_hints_provider                        │
│   1528 │   │   │   │   )                                                                         │
│   1529 │   │   │   case config.TypeInferenceStrategy.NONE:                                       │
│                                                                                                  │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/analyses/typesystem.py:1589 in infer_signature                                                 │
│                                                                                                  │
│   1586 │   │   │   The inference result                                                          │
│   1587 │   │                                                                                  │
│   1588 │   │   method_signature = inspect.signature(method)                                      │
│ ❱ 1589 │   │   hints = type_hint_provider(method)                                                │
│   1590 │   │   parameters: dict[str, ProperType] = {}                                            │
│   1591 │   │   type4py_parameters: dict[str, list[ProperType]] = {}                              │
│   1592 │   │   type4py_parameters_for_statistics: dict[str, list[ProperType]] = {}               │
│                                                                                                  │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/analyses/typesystem.py:1561 in type_hints_provider                                             │
│                                                                                                  │
│   1558 │   │   │   A dict mapping parameter names to type hints.                                 │
│   1559 │   │                                                                                  │
│   1560 │   │   try:                                                                              │
│ ❱ 1561 │   │   │   hints = get_type_hints(method)                                                │
│   1562 │   │   │   # Sadly there is no guarantee that resolving the type hints actually works.   │
│   1563 │   │   │   # If the developers annotated something with an erroneous type hint we fall   │
│   1564 │   │   │   # back to no type hints, i.e., use Any.                                       │
│                                                                                                  │
│ /Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/typing.py:1849 in              │
│ get_type_hints                                                                                   │
│                                                                                                  │
│   1846 │   │   │   │   is_argument=not isinstance(obj, types.ModuleType),                        │
│   1847 │   │   │   │   is_class=False,                                                           │
│   1848 │   │   │   )                                                                             │
│ ❱ 1849 │   │   value = _eval_type(value, globalns, localns)                                      │
│   1850 │   │   if name in defaults and defaults[name] is None:                                   │
│   1851 │   │   │   value = Optional[value]                                                       │
│   1852 │   │   hints[name] = value                                                               │
│                                                                                                  │
│ /Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/typing.py:326 in _eval_type    │
│                                                                                                  │
│    323 │   with recursive ForwardRef.                                                            │
│    324 │                                                                                      │
│    325 │   if isinstance(t, ForwardRef):                                                         │
│ ❱  326 │   │   return t._evaluate(globalns, localns, recursive_guard)                            │
│    327 │   if isinstance(t, (_GenericAlias, GenericAlias, types.UnionType)):                     │
│    328 │   │   ev_args = tuple(_eval_type(a, globalns, localns, recursive_guard) for a in t.__a  │
│    329 │   │   if ev_args == t.__args__:                                                         │
│                                                                                                  │
│ /Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/typing.py:691 in _evaluate     │
│                                                                                                  │
│    688 │   │   │   │   │   sys.modules.get(self.__forward_module__, None), '__dict__', globalns  │
│    689 │   │   │   │   )                                                                         │
│    690 │   │   │   type_ = _type_check(                                                          │
│ ❱  691 │   │   │   │   eval(self.__forward_code__, globalns, localns),                           │
│    692 │   │   │   │   "Forward references must evaluate to types.",                             │
│    693 │   │   │   │   is_argument=self.__forward_is_argument__,                                 │
│    694 │   │   │   │   is_class=self.__forward_is_class__,                                       │
│ in <module>:1                                                                                    │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
TypeError: unsupported operand type(s) for |: 'NoneType' and 'NoneType'
darioamorosodaragona-tuni commented 10 months ago

As explained in https://github.com/se2p/pynguin/issues/53#issuecomment-1893427840, in the same way as https://github.com/se2p/pynguin/commit/d811cacc59f73c84e9cd83ceb466ec308c66410b I added TypeError in the except branch of type_hints_provider.

@staticmethod
    def type_hints_provider(method: Callable) -> dict[str, Any]:
        """Provides PEP484-style type information, if available.

        Args:
            method: The method for which we want type hints.

        Returns:
            A dict mapping parameter names to type hints.
        """
        try:
            hints = get_type_hints(method)
            # Sadly there is no guarantee that resolving the type hints actually works.
            # If the developers annotated something with an erroneous type hint we fall
            # back to no type hints, i.e., use Any.
            # The import used in the type hint could also be conditional on
            # typing.TYPE_CHECKING, e.g., to avoid circular imports, in which case this
            # also fails.
        except (AttributeError, NameError, TypeError):
            hints = {}
        return hints

But I encountered another problem:

[23:20:47] INFO     Start Pynguin Test Generation…                                                                                                              generator.py:107
           INFO     Collecting static constants from module under test                                                                                          generator.py:208
           INFO     Constants found: 207                                                                                                                        generator.py:213
           INFO     Setting up runtime collection of constants                                                                                                  generator.py:220
[23:20:59] INFO     Stop Pynguin Test Generation…                                                                                                               generator.py:110
╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/bin/pynguin:8 in <module>           │
│                                                                                                  │
│   5 from pynguin.cli import main                                                                 │
│   6 if __name__ == '__main__':                                                                   │
│   7 │   sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])                         │
│ ❱ 8 │   sys.exit(main())                                                                         │
│   9                                                                                              │
│                                                                                                  │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/cli.py:196 in main                                                                             │
│                                                                                                  │
│   193 │   set_configuration(parsed.config)                                                       │
│   194 │   if console is not None:                                                                │
│   195 │   │   with console.status("Running Pynguin..."):                                         │
│ ❱ 196 │   │   │   return run_pynguin().value                                                     │
│   197 │   else:                                                                                  │
│   198 │   │   return run_pynguin().value                                                         │
│   199                                                                                            │
│                                                                                                  │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/generator.py:108 in run_pynguin                                                                │
│                                                                                                  │
│   105 │                                                                                          │
│   106 │   try:                                                                                   │
│   107 │   │   _LOGGER.info("Start Pynguin Test Generation…")                                     │
│ ❱ 108 │   │   return _run()                                                                      │
│   109 │   finally:                                                                               │
│   110 │   │   _LOGGER.info("Stop Pynguin Test Generation…")                                      │
│   111                                                                                            │
│                                                                                                  │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/generator.py:506 in _run                                                                       │
│                                                                                                  │
│   503                                                                                            │
│   504                                                                                            │
│   505 def _run() -> ReturnCode:                                                                  │
│ ❱ 506 │   if (setup_result := _setup_and_check()) is None:                                       │
│   507 │   │   return ReturnCode.SETUP_FAILED                                                     │
│   508 │   executor, test_cluster, constant_provider = setup_result                               │
│   509 │   # traces slices for test cases after execution                                         │
│                                                                                                  │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/generator.py:258 in _setup_and_check                                                           │
│                                                                                                  │
│   255 │                                                                                          │
│   256 │   # Analyzing the SUT should not cause any coverage.                                     │
│   257 │   tracer.disable()                                                                       │
│ ❱ 258 │   if (test_cluster := _setup_test_cluster()) is None:                                    │
│   259 │   │   return None                                                                        │
│   260 │   tracer.enable()                                                                        │
│   261                                                                                            │
│                                                                                                  │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/generator.py:114 in _setup_test_cluster                                                        │
│                                                                                                  │
│   111                                                                                            │
│   112                                                                                            │
│   113 def _setup_test_cluster() -> ModuleTestCluster | None:                                     │
│ ❱ 114 │   test_cluster = generate_test_cluster(                                                  │
│   115 │   │   config.configuration.module_name,                                                  │
│   116 │   │   config.configuration.type_inference.type_inference_strategy,                       │
│   117 │   │   query_type4py=config.configuration.type_inference.type4py,                         │
│                                                                                                  │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/analyses/module.py:1442 in generate_test_cluster                                               │
│                                                                                                  │
│   1439 │   Returns:                                                                              │
│   1440 │   │   A new test cluster for the given module                                           │
│   1441 │                                                                                         │
│ ❱ 1442 │   return analyse_module(                                                                │
│   1443 │   │   parse_module(module_name, query_type4py=query_type4py),                           │
│   1444 │   │   type_inference_strategy,                                                          │
│   1445 │   │   query_type4py=query_type4py,                                                      │
│                                                                                                  │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/analyses/module.py:1418 in analyse_module                                                      │
│                                                                                                  │
│   1415 │   │   A test cluster for the module                                                     │
│   1416 │                                                                                         │
│   1417 │   test_cluster = ModuleTestCluster(linenos=parsed_module.linenos)                       │
│ ❱ 1418 │   __resolve_dependencies(                                                               │
│   1419 │   │   root_module=parsed_module,                                                        │
│   1420 │   │   type_inference_strategy=type_inference_strategy,                                  │
│   1421 │   │   test_cluster=test_cluster,                                                        │
│                                                                                                  │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/analyses/module.py:1291 in __resolve_dependencies                                              │
│                                                                                                  │
│   1288 │   │   │   continue                                                                      │
│   1289 │   │                                                                                     │
│   1290 │   │   # Analyze all classes found in the current module                                 │
│ ❱ 1291 │   │   __analyse_included_classes(                                                       │
│   1292 │   │   │   module=current_module,                                                        │
│   1293 │   │   │   root_module_name=root_module.module_name,                                     │
│   1294 │   │   │   type_inference_strategy=type_inference_strategy,                              │
│                                                                                                  │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/analyses/module.py:1351 in __analyse_included_classes                                          │
│                                                                                                  │
│   1348 │   │                                                                                     │
│   1349 │   │   type_info = test_cluster.type_system.to_type_info(current)                        │
│   1350 │   │                                                                                     │
│ ❱ 1351 │   │   __analyse_class(                                                                  │
│   1352 │   │   │   type_info=type_info,                                                          │
│   1353 │   │   │   type_inference_strategy=type_inference_strategy,                              │
│   1354 │   │   │   module_tree=parse_results[current.__module__].syntax_tree,                    │
│                                                                                                  │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/analyses/module.py:1108 in __analyse_class                                                     │
│                                                                                                  │
│   1105 │   else:                                                                                 │
│   1106 │   │   generic = GenericConstructor(                                                     │
│   1107 │   │   │   type_info,                                                                    │
│ ❱ 1108 │   │   │   test_cluster.type_system.infer_type_info(                                     │
│   1109 │   │   │   │   type_info.raw_type.__init__,                                              │
│   1110 │   │   │   │   type4py_data=find_predicted_signature(                                    │
│   1111 │   │   │   │   │   type4py_data, type_info.qualname + ".__init__", type_info.qualname    │
│                                                                                                  │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/analyses/typesystem.py:1526 in infer_type_info                                                 │
│                                                                                                  │
│   1523 │   │                                                                                     │
│   1524 │   │   match type_inference_strategy:                                                    │
│   1525 │   │   │   case config.TypeInferenceStrategy.TYPE_HINTS:                                 │
│ ❱ 1526 │   │   │   │   return self.infer_signature(                                              │
│   1527 │   │   │   │   │   method, type4py_data, self.type_hints_provider                        │
│   1528 │   │   │   │   )                                                                         │
│   1529 │   │   │   case config.TypeInferenceStrategy.NONE:                                       │
│                                                                                                  │
│ /Users/ncdaam/PycharmProjects/LogicalCouplingTool/.venv_3.10/lib/python3.10/site-packages/pyngui │
│ n/analyses/typesystem.py:1588 in infer_signature                                                 │
│                                                                                                  │
│   1585 │   │   Returns:                                                                          │
│   1586 │   │   │   The inference result                                                          │
│   1587 │   │                                                                                     │
│ ❱ 1588 │   │   method_signature = inspect.signature(method)                                      │
│   1589 │   │   hints = type_hint_provider(method)                                                │
│   1590 │   │   parameters: dict[str, ProperType] = {}                                            │
│   1591 │   │   type4py_parameters: dict[str, list[ProperType]] = {}                              │
│                                                                                                  │
│ /Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/inspect.py:3247 in signature   │
│                                                                                                  │
│   3244                                                                                           │
│   3245 def signature(obj, *, follow_wrapped=True, globals=None, locals=None, eval_str=False):    │
│   3246 │   """Get a signature object for the passed callable."""                                 │
│ ❱ 3247 │   return Signature.from_callable(obj, follow_wrapped=follow_wrapped,                    │
│   3248 │   │   │   │   │   │   │   │      globals=globals, locals=locals, eval_str=eval_str)     │
│   3249                                                                                           │
│   3250                                                                                           │
│                                                                                                  │
│ /Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/inspect.py:2995 in             │
│ from_callable                                                                                    │
│                                                                                                  │
│   2992 │   def from_callable(cls, obj, *,                                                        │
│   2993 │   │   │   │   │     follow_wrapped=True, globals=None, locals=None, eval_str=False):    │
│   2994 │   │   """Constructs Signature for the given callable object."""                         │
│ ❱ 2995 │   │   return _signature_from_callable(obj, sigcls=cls,                                  │
│   2996 │   │   │   │   │   │   │   │   │   │   follow_wrapper_chains=follow_wrapped,             │
│   2997 │   │   │   │   │   │   │   │   │   │   globals=globals, locals=locals, eval_str=eval_st  │
│   2998                                                                                           │
│                                                                                                  │
│ /Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/inspect.py:2461 in             │
│ _signature_from_callable                                                                         │
│                                                                                                  │
│   2458 │   │   │   │   │   │   │   │   │   │   globals=globals, locals=locals, eval_str=eval_st  │
│   2459 │                                                                                         │
│   2460 │   if _signature_is_builtin(obj):                                                        │
│ ❱ 2461 │   │   return _signature_from_builtin(sigcls, obj,                                       │
│   2462 │   │   │   │   │   │   │   │   │      skip_bound_arg=skip_bound_arg)                     │
│   2463 │                                                                                         │
│   2464 │   if isinstance(obj, functools.partial):                                                │
│                                                                                                  │
│ /Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/inspect.py:2271 in             │
│ _signature_from_builtin                                                                          │
│                                                                                                  │
│   2268 │                                                                                         │
│   2269 │   s = getattr(func, "__text_signature__", None)                                         │
│   2270 │   if not s:                                                                             │
│ ❱ 2271 │   │   raise ValueError("no signature found for builtin {!r}".format(func))              │
│   2272 │                                                                                         │
│   2273 │   return _signature_fromstr(cls, func, s, skip_bound_arg)                               │
│   2274                                                                                           │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
ValueError: no signature found for builtin <slot wrapper '__init__' of 'pandas._libs.interval.IntervalTree' objects>
stephanlukasczyk commented 10 months ago

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 commented 10 months ago

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 commented 10 months ago

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 commented 10 months ago

Yes, but in the meantime those using Pynguin may have information on a workaround to generate test cases even if pandas is used in production code.

P.s My Pynguin build has been stuck on Iteration 154 for 20 minutes, do you suggest waiting or stopping the process?

(.venv_3.10) (base) ncdaam@vkwmr6cjkv-mac LogicalCouplingTool % pynguin --project-path . --output-path ./tests/developer_coupling/ --module-name coupling.developer_coupling -v 
[12:26:51] INFO     Start Pynguin Test Generation…                                                                                                              generator.py:107
           INFO     Collecting static constants from module under test                                                                                          generator.py:208
           INFO     Constants found: 206                                                                                                                        generator.py:213
           INFO     Setting up runtime collection of constants                                                                                                  generator.py:220
[12:26:58] INFO     Analyzed project to create test cluster                                                                                                       module.py:1318
           INFO     Modules:      49                                                                                                                              module.py:1319
           INFO     Functions:   109                                                                                                                              module.py:1320
           INFO     Classes:     166                                                                                                                              module.py:1321
           INFO     Using seed 1706700409493336000                                                                                                              generator.py:194
           INFO     Using strategy: Algorithm.DYNAMOSA                                                                                         generationalgorithmfactory.py:302
           INFO     Instantiated 47 fitness functions                                                                                          generationalgorithmfactory.py:393
           INFO     Using CoverageArchive                                                                                                      generationalgorithmfactory.py:346
           INFO     Using selection function: Selection.TOURNAMENT_SELECTION                                                                   generationalgorithmfactory.py:321
           INFO     No stopping condition configured!                                                                                          generationalgorithmfactory.py:119
           INFO     Using fallback timeout of 600 seconds                                                                                      generationalgorithmfactory.py:120
           INFO     Using crossover function: SinglePointRelativeCrossOver                                                                     generationalgorithmfactory.py:334
           INFO     Using ranking function: RankBasedPreferenceSorting                                                                         generationalgorithmfactory.py:354
           INFO     Start generating test cases                                                                                                                 generator.py:517
           INFO     Initial Population, Coverage: 0.063830                                                                                                  searchobserver.py:77
           INFO     Iteration:       1, Coverage: 0.063830                                                                                                  searchobserver.py:83
           INFO     Iteration:       2, Coverage: 0.063830                                                                                                  searchobserver.py:83
           INFO     Iteration:       3, Coverage: 0.085106                                                                                                  searchobserver.py:83
           INFO     Iteration:       4, Coverage: 0.085106                                                                                                  searchobserver.py:83
           INFO     Iteration:       5, Coverage: 0.085106                                                                                                  searchobserver.py:83
           INFO     Iteration:       6, Coverage: 0.085106                                                                                                  searchobserver.py:83
           INFO     Iteration:       7, Coverage: 0.085106                                                                                                  searchobserver.py:83
           INFO     Iteration:       8, Coverage: 0.085106                                                                                                  searchobserver.py:83
           INFO     Iteration:       9, Coverage: 0.085106                                                                                                  searchobserver.py:83
           INFO     Iteration:      10, Coverage: 0.085106                                                                                                  searchobserver.py:83
           INFO     Iteration:      11, Coverage: 0.085106                                                                                                  searchobserver.py:83
           INFO     Iteration:      12, Coverage: 0.085106                                                                                                  searchobserver.py:83
           INFO     Iteration:      13, Coverage: 0.085106                                                                                                  searchobserver.py:83
           INFO     Iteration:      14, Coverage: 0.085106                                                                                                  searchobserver.py:83
[12:27:04] INFO     Iteration:      15, Coverage: 0.085106                                                                                                  searchobserver.py:83
           INFO     Iteration:      16, Coverage: 0.085106                                                                                                  searchobserver.py:83
[12:27:05] INFO     Iteration:      17, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      18, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      19, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      20, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      21, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      22, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      23, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      24, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      25, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      26, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      27, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      28, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      29, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      30, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      31, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      32, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      33, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      34, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      35, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      36, Coverage: 0.106383                                                                                                  searchobserver.py:83
[12:27:13] INFO     Iteration:      37, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      38, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      39, Coverage: 0.106383                                                                                                  searchobserver.py:83
[12:27:15] INFO     Iteration:      40, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      41, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      42, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      43, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      44, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      45, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      46, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      47, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      48, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      49, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      50, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      51, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      52, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      53, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      54, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      55, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      56, Coverage: 0.106383                                                                                                  searchobserver.py:83
[12:27:22] INFO     Iteration:      57, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      58, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      59, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      60, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      61, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      62, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      63, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      64, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      65, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      66, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      67, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      68, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      69, Coverage: 0.106383                                                                                                  searchobserver.py:83
[12:27:26] INFO     Iteration:      70, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      71, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      72, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      73, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      74, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      75, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      76, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      77, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      78, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      79, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      80, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      81, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      82, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      83, Coverage: 0.106383                                                                                                  searchobserver.py:83
[12:27:30] INFO     Iteration:      84, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      85, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      86, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      87, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      88, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      89, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      90, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      91, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      92, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      93, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      94, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      95, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      96, Coverage: 0.106383                                                                                                  searchobserver.py:83
           INFO     Iteration:      97, Coverage: 0.170213                                                                                                  searchobserver.py:83
           INFO     Iteration:      98, Coverage: 0.170213                                                                                                  searchobserver.py:83
           INFO     Iteration:      99, Coverage: 0.170213                                                                                                  searchobserver.py:83
           INFO     Iteration:     100, Coverage: 0.170213                                                                                                  searchobserver.py:83
           INFO     Iteration:     101, Coverage: 0.191489                                                                                                  searchobserver.py:83
           INFO     Iteration:     102, Coverage: 0.191489                                                                                                  searchobserver.py:83
           INFO     Iteration:     103, Coverage: 0.191489                                                                                                  searchobserver.py:83
           INFO     Iteration:     104, Coverage: 0.191489                                                                                                  searchobserver.py:83
           INFO     Iteration:     105, Coverage: 0.191489                                                                                                  searchobserver.py:83
           INFO     Iteration:     106, Coverage: 0.191489                                                                                                  searchobserver.py:83
           INFO     Iteration:     107, Coverage: 0.191489                                                                                                  searchobserver.py:83
           INFO     Iteration:     108, Coverage: 0.191489                                                                                                  searchobserver.py:83
           INFO     Iteration:     109, Coverage: 0.191489                                                                                                  searchobserver.py:83
           INFO     Iteration:     110, Coverage: 0.191489                                                                                                  searchobserver.py:83
           INFO     Iteration:     111, Coverage: 0.191489                                                                                                  searchobserver.py:83
           INFO     Iteration:     112, Coverage: 0.191489                                                                                                  searchobserver.py:83
           INFO     Iteration:     113, Coverage: 0.191489                                                                                                  searchobserver.py:83
           INFO     Iteration:     114, Coverage: 0.191489                                                                                                  searchobserver.py:83
           INFO     Iteration:     115, Coverage: 0.191489                                                                                                  searchobserver.py:83
           INFO     Iteration:     116, Coverage: 0.191489                                                                                                  searchobserver.py:83
           INFO     Iteration:     117, Coverage: 0.191489                                                                                                  searchobserver.py:83
           INFO     Iteration:     118, Coverage: 0.191489                                                                                                  searchobserver.py:83
           INFO     Iteration:     119, Coverage: 0.191489                                                                                                  searchobserver.py:83
[12:27:44] INFO     Iteration:     120, Coverage: 0.191489                                                                                                  searchobserver.py:83
           INFO     Iteration:     121, Coverage: 0.191489                                                                                                  searchobserver.py:83
           INFO     Iteration:     122, Coverage: 0.191489                                                                                                  searchobserver.py:83
           INFO     Iteration:     123, Coverage: 0.191489                                                                                                  searchobserver.py:83
           INFO     Iteration:     124, Coverage: 0.191489                                                                                                  searchobserver.py:83
           INFO     Iteration:     125, Coverage: 0.191489                                                                                                  searchobserver.py:83
           INFO     Iteration:     126, Coverage: 0.191489                                                                                                  searchobserver.py:83
           INFO     Iteration:     127, Coverage: 0.191489                                                                                                  searchobserver.py:83
           INFO     Iteration:     128, Coverage: 0.191489                                                                                                  searchobserver.py:83
           INFO     Iteration:     129, Coverage: 0.191489                                                                                                  searchobserver.py:83
           INFO     Iteration:     130, Coverage: 0.191489                                                                                                  searchobserver.py:83
           INFO     Iteration:     131, Coverage: 0.212766                                                                                                  searchobserver.py:83
           INFO     Iteration:     132, Coverage: 0.212766                                                                                                  searchobserver.py:83
[12:27:51] INFO     Iteration:     133, Coverage: 0.212766                                                                                                  searchobserver.py:83
           INFO     Iteration:     134, Coverage: 0.212766                                                                                                  searchobserver.py:83
           INFO     Iteration:     135, Coverage: 0.212766                                                                                                  searchobserver.py:83
           INFO     Iteration:     136, Coverage: 0.212766                                                                                                  searchobserver.py:83
[12:27:55] INFO     Iteration:     137, Coverage: 0.212766                                                                                                  searchobserver.py:83
[12:27:56] INFO     Iteration:     138, Coverage: 0.212766                                                                                                  searchobserver.py:83
           INFO     Iteration:     139, Coverage: 0.276596                                                                                                  searchobserver.py:83
           INFO     Iteration:     140, Coverage: 0.276596                                                                                                  searchobserver.py:83
           INFO     Iteration:     141, Coverage: 0.276596                                                                                                  searchobserver.py:83
           INFO     Iteration:     142, Coverage: 0.276596                                                                                                  searchobserver.py:83
           INFO     Iteration:     143, Coverage: 0.276596                                                                                                  searchobserver.py:83
           INFO     Iteration:     144, Coverage: 0.276596                                                                                                  searchobserver.py:83
           INFO     Iteration:     145, Coverage: 0.276596                                                                                                  searchobserver.py:83
           INFO     Iteration:     146, Coverage: 0.276596                                                                                                  searchobserver.py:83
           INFO     Iteration:     147, Coverage: 0.276596                                                                                                  searchobserver.py:83
           INFO     Iteration:     148, Coverage: 0.276596                                                                                                  searchobserver.py:83
           INFO     Iteration:     149, Coverage: 0.361702                                                                                                  searchobserver.py:83
           INFO     Iteration:     150, Coverage: 0.361702                                                                                                  searchobserver.py:83
           INFO     Iteration:     151, Coverage: 0.361702                                                                                                  searchobserver.py:83
           INFO     Iteration:     152, Coverage: 0.361702                                                                                                  searchobserver.py:83
           INFO     Iteration:     153, Coverage: 0.361702                                                                                                  searchobserver.py:83
           INFO     Iteration:     154, Coverage: 0.361702                                                                                                  searchobserver.py:83
⠹ Running Pynguin...
zivshapiraintel commented 10 months ago

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 commented 9 months ago

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

zivshapiraintel commented 9 months ago

@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 commented 9 months ago

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 commented 9 months ago

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 commented 9 months ago

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 commented 9 months ago

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 commented 9 months ago

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 commented 9 months ago

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