Repository: truera/trulens
Issue: [BUG] AttributeError: 'PosixPath' object has no attribute 'endswith'
Root cause: Environment Incompatibility

**Bug Description**
I get this error:

```bash
AttributeError: 'PosixPath' object has no attribute 'endswith'
```

**To Reproduce**
```py
from trulens_eval import Feedback
```

**Expected behavior**
The error should not happen.

**Relevant Logs/Tracebacks**
```bash
2024-07-31 14:42:51.823 Uncaught app exception
Traceback (most recent call last):
  File "/path/to/envs/prometeia/lib/python3.11/site-packages/streamlit/runtime/scriptrunner/script_runner.py", line 589, in _run_script
    exec(code, module.__dict__)
  File "/path/to/entrypoint.py", line 69, in <module>
    main()
  File "/path/to/entrypoint.py", line 64, in main
    pg.run()
  File "/path/to/envs/prometeia/lib/python3.11/site-packages/streamlit/navigation/page.py", line 286, in run
    exec(code, module.__dict__)
  File "/path/to/routes/chat.py", line 22, in <module>
    from promdc.backend.pipeline import Pipeline
  File "/path/to/pipeline.py", line 17, in <module>
    from .evaluation.evaluation import Evaluator
  File "/path/to/evaluation.py", line 1, in <module>
    from trulens_eval import Feedback
  File "/path/to/envs/prometeia/lib/python3.11/site-packages/trulens_eval/__init__.py", line 16, in <module>
    from trulens_eval.utils.imports import check_imports
  File "/path/to/envs/prometeia/lib/python3.11/site-packages/trulens_eval/utils/imports.py", line 20, in <module>
    from pip._internal.req import parse_requirements
  File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1138, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 1078, in _find_spec
  File "/path/to/envs/prometeia/lib/python3.11/site-packages/_distutils_hack/__init__.py", line 90, in find_spec
    return method()
           ^^^^^^^^
  File "/path/to/envs/prometeia/lib/python3.11/site-packages/_distutils_hack/__init__.py", line 138, in spec_for_pip
    if sys.version_info >= (3, 12) or self.pip_imported_during_build():
                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/path/to/envs/prometeia/lib/python3.11/site-packages/_distutils_hack/__init__.py", line 150, in pip_imported_during_build
    return any(
           ^^^^
  File "/path/to/envs/prometeia/lib/python3.11/site-packages/_distutils_hack/__init__.py", line 151, in <genexpr>
    cls.frame_file_is_setup(frame) for frame, line in traceback.walk_stack(None)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/path/to/envs/prometeia/lib/python3.11/site-packages/_distutils_hack/__init__.py", line 160, in frame_file_is_setup
    return frame.f_globals.get('__file__', '').endswith('setup.py')
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'PosixPath' object has no attribute 'endswith'
```

**Environment:**
 - OS: Mac OS, Apple M3
 - Python Version: 3.12
 - TruLens version: git+https://github.com/truera/trulens@v0.33.0#subdirectory=trulens_eval
 - Versions of other relevant installed libraries:
```bash
streamlit~=1.36.0
langchain~=0.2.5
langchain-openai~=0.1.7
langchain-community~=0.2.0
loguru~=0.7.2
pillow~=10.3.0
pypdf~=3.17.0
tiktoken~=0.7.0
azure-ai-formrecognizer~=3.3.2
pandas~=2.1.2
qdrant-client~=1.8.0
openai~=1.30.0
tabulate~=0.9.0
streamlit-datalist~=0.0.5
streamlit-extras~=0.4.0
streamlit_antd_components~=0.3.2
plotly~=5.22.0
natsort~=8.4.0
trulens-eval-0.33.0 @ git+https://github.com/truera/trulens@v0.33.0#subdirectory=trulens_eval
numpy~=1.26.4
```

**Context**
I am running a Streamlit environment.

@sfc-gh-chu @sfc-gh-jreini 


<!-- Greeting -->
Hello @lorenzobalzani 👋, I'm here to help you with any bugs, questions, or contributions you may have. Let's work together to resolve the issue you're experiencing.

<!-- Answer -->
The issue you're encountering is due to the use of `pip._internal.req.parse_requirements`, which is not reliable and can cause the `PosixPath` object error. You can resolve this by modifying the `requirements_of_file` function to use the `packaging.requirements` module instead.

Here's a modified version of the `requirements_of_file` function that avoids using `pip._internal.req.parse_requirements`:

```python
from packaging.requirements import Requirement
from pathlib import Path
from typing import Dict

def requirements_of_file(path: Path) -> Dict[str, Requirement]:
    """Get a dictionary of package names to requirements from a requirements file."""
    
    with path.open() as f:
        lines = f.readlines()

    mapping = {}
    for line in lines:
        line = line.strip()
        if line and not line.startswith("#"):
            req = Requirement(line)
            mapping[req.name] = req

    return mapping
```

To integrate this into your `setup.py` script, you can replace the `parse_requirements` calls with this function:

```python
from pathlib import Path

required_packages = list(
    map(
        lambda req: str(req),
        requirements_of_file(Path("trulens_eval/requirements.txt")).values()
    )
)
optional_packages = list(
    map(
        lambda req: str(req),
        requirements_of_file(Path("trulens_eval/requirements.optional.txt")).values()
    )
)
```

This approach should resolve the `PosixPath` issue and ensure compatibility with your environment <sup>[[1]](https://github.com/truera/trulens/blob/main/trulens_eval/trulens_eval/utils/imports.py)</sup><sup>[[2]](https://github.com/truera/trulens/blob/main/trulens_eval/setup.py)</sup>.


<!-- Dosu Comment Footer -->
*To continue talking to [Dosu](https://dosu.dev), mention @dosu.*


I do think that this LLM response does not resolve the issue @sfc-gh-dhuang.

Hey @lorenzobalzani I tried to reproduce error locally and could not do it. One question: you mentioned python version as 3.12 but the error trace mentions the version as 3.11. Could you please check the environment?

> Hey @lorenzobalzani I tried to reproduce error locally and could not do it. One question: you mentioned python version as 3.12 but the error trace mentions the version as 3.11. Could you please check the environment?

That's my bad, I've figured out the solution and forgot to update the post. I solved by using an environment with >= Python 3.12.