Repository: aboutcode-org/python-inspector (language: python)

Issue:
Issues with hard-coded .cache location
I've created an AppImage of scancode.io and I run into the following error when I try to run it:
```
  File "/tmp/.mount_scancoM6DHdp/usr/share/scancodeio/scanpipe/pipes/resolve.py", line 32, in <module>
    from python_inspector.resolve_cli import resolver_api
  File "/tmp/.mount_scancoM6DHdp/usr/lib/python3.8/dist-packages/python_inspector/resolve_cli.py", line 16, in <module>
    from python_inspector import utils_pypi
  File "/tmp/.mount_scancoM6DHdp/usr/lib/python3.8/dist-packages/python_inspector/utils_pypi.py", line 1649, in <module>
    CACHE = Cache()
  File "<attrs generated init python_inspector.utils_pypi.Cache>", line 3, in __init__
  File "/tmp/.mount_scancoM6DHdp/usr/lib/python3.8/dist-packages/python_inspector/utils_pypi.py", line 1609, in __attrs_post_init__
    os.makedirs(self.directory, exist_ok=True)
  File "/tmp/.mount_scancoM6DHdp/usr/lib/python3.8/os.py", line 213, in makedirs
    makedirs(head, exist_ok=exist_ok)
  File "/tmp/.mount_scancoM6DHdp/usr/lib/python3.8/os.py", line 223, in makedirs
    mkdir(name, mode)
OSError: [Errno 30] Read-only file system: '.cache'
```
Issues with hard-coded .cache location
I've created an AppImage of scancode.io and I run into the following error when I try to run it:
```
  File "/tmp/.mount_scancoM6DHdp/usr/share/scancodeio/scanpipe/pipes/resolve.py", line 32, in <module>
    from python_inspector.resolve_cli import resolver_api
  File "/tmp/.mount_scancoM6DHdp/usr/lib/python3.8/dist-packages/python_inspector/resolve_cli.py", line 16, in <module>
    from python_inspector import utils_pypi
  File "/tmp/.mount_scancoM6DHdp/usr/lib/python3.8/dist-packages/python_inspector/utils_pypi.py", line 1649, in <module>
    CACHE = Cache()
  File "<attrs generated init python_inspector.utils_pypi.Cache>", line 3, in __init__
  File "/tmp/.mount_scancoM6DHdp/usr/lib/python3.8/dist-packages/python_inspector/utils_pypi.py", line 1609, in __attrs_post_init__
    os.makedirs(self.directory, exist_ok=True)
  File "/tmp/.mount_scancoM6DHdp/usr/lib/python3.8/os.py", line 213, in makedirs
    makedirs(head, exist_ok=exist_ok)
  File "/tmp/.mount_scancoM6DHdp/usr/lib/python3.8/os.py", line 223, in makedirs
    mkdir(name, mode)
OSError: [Errno 30] Read-only file system: '.cache'
```
Issues with hard-coded .cache location
I've created an AppImage of scancode.io and I run into the following error when I try to run it:
```
  File "/tmp/.mount_scancoM6DHdp/usr/share/scancodeio/scanpipe/pipes/resolve.py", line 32, in <module>
    from python_inspector.resolve_cli import resolver_api
  File "/tmp/.mount_scancoM6DHdp/usr/lib/python3.8/dist-packages/python_inspector/resolve_cli.py", line 16, in <module>
    from python_inspector import utils_pypi
  File "/tmp/.mount_scancoM6DHdp/usr/lib/python3.8/dist-packages/python_inspector/utils_pypi.py", line 1649, in <module>
    CACHE = Cache()
  File "<attrs generated init python_inspector.utils_pypi.Cache>", line 3, in __init__
  File "/tmp/.mount_scancoM6DHdp/usr/lib/python3.8/dist-packages/python_inspector/utils_pypi.py", line 1609, in __attrs_post_init__
    os.makedirs(self.directory, exist_ok=True)
  File "/tmp/.mount_scancoM6DHdp/usr/lib/python3.8/os.py", line 213, in makedirs
    makedirs(head, exist_ok=exist_ok)
  File "/tmp/.mount_scancoM6DHdp/usr/lib/python3.8/os.py", line 223, in makedirs
    mkdir(name, mode)
OSError: [Errno 30] Read-only file system: '.cache'
```


Discussion / hints:

Fix patch:
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index bb606251..e09087a5 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -1,6 +1,11 @@
 Changelog
 =========
 
+next-version
+------------
+
+- Create PyPI cache location in the home directory if a cache directory cannot be made at the project root.
+
 
 v0.9.3
 ------
@@ -8,7 +13,7 @@ v0.9.3
 - Add support for recursive requirements.
 - Add python 3.11 as a valid python version in choices.
 - Operating system and python version are now required fields in CLI.
-- Add dot versions (3.6, 3.7, 3.8, 3.9, 3.10, 3.11, 2.7) with 
+- Add dot versions (3.6, 3.7, 3.8, 3.9, 3.10, 3.11, 2.7) with
   current python version choices for CLI (36, 37, 38, 39, 310, 311, 27).
 
 
@@ -109,7 +114,7 @@ v0.6.3
 ------
 
 - Ensure to filter out top level dependencies on the basis of their environment markers
-- Do not ignore files on basis of name 
+- Do not ignore files on basis of name
 
 
 v0.6.2
@@ -123,7 +128,7 @@ v0.6.1
 ------
 
 - Use latest ScanCode toolkit packagedcode including the ability to collect
-  extra index URLs from requirements.txt 
+  extra index URLs from requirements.txt
 - Use new pipdeptree-like format for improved compatibility
 - Rename command line tool name from "dad" to "python-inspector"
 
diff --git a/Makefile b/Makefile
index a11ed207..7d6ec8b8 100644
--- a/Makefile
+++ b/Makefile
@@ -33,7 +33,7 @@ valid: isort black
 check:
 	@echo "-> Run pycodestyle (PEP8) validation"
 	@${ACTIVATE} pycodestyle --max-line-length=110 \
-	   --exclude=.eggs,etc/scripts,src/_packagedcode,venv,lib,thirdparty,docs .
+	   --exclude=.eggs,etc/scripts,src/_packagedcode,venv/,lib/,thirdparty/,docs/,.cache/ .
 	@echo "-> Run isort imports ordering validation"
 	@${ACTIVATE} isort --sl --check-only -l 100 setup.py src tests --skip-glob "*/_packagedcode/*"
 	@echo "-> Run black validation"
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index 7e82103e..f9ccf5e2 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -11,24 +11,23 @@ jobs:
       parameters:
           job_name: ubuntu18_cpython
           image_name: ubuntu-18.04
-          python_versions: ['3.8', '3.9', '3.10']
+          python_versions: ['3.7', '3.8', '3.9', '3.10', '3.11']
           test_suites:
-              all: |
-                venv/bin/pytest -n 2 -vvs --reruns 2
+              all: venv/bin/pytest -n 2 -vvs --reruns 2
 
     - template: etc/ci/azure-posix.yml
       parameters:
           job_name: ubuntu20_cpython
           image_name: ubuntu-20.04
-          python_versions: ['3.8', '3.9', '3.10']
+          python_versions: ['3.7', '3.8', '3.9', '3.10', '3.11']
           test_suites:
               all: venv/bin/pytest -n 2 -vvs --reruns 2
 
     - template: etc/ci/azure-posix.yml
       parameters:
-          job_name: macos12_cpython
-          image_name: macos-12
-          python_versions: ['3.8', '3.9', '3.10']
+          job_name: ubuntu22_cpython
+          image_name: ubuntu-22.04
+          python_versions: ['3.7', '3.8', '3.9', '3.10', '3.11']
           test_suites:
               all: venv/bin/pytest -n 2 -vvs --reruns 2
 
@@ -36,7 +35,15 @@ jobs:
       parameters:
           job_name: macos11_cpython
           image_name: macos-11
-          python_versions: ['3.8', '3.9', '3.10']
+          python_versions: ['3.7', '3.8', '3.9', '3.10', '3.11']
+          test_suites:
+              all: venv/bin/pytest -n 2 -vvs --reruns 2
+
+    - template: etc/ci/azure-posix.yml
+      parameters:
+          job_name: macos12_cpython
+          image_name: macos-12
+          python_versions: ['3.7', '3.8', '3.9', '3.10', '3.11']
           test_suites:
               all: venv/bin/pytest -n 2 -vvs --reruns 2
 
@@ -44,14 +51,14 @@ jobs:
       parameters:
           job_name: win2019_cpython
           image_name: windows-2019
-          python_versions: ['3.8', '3.9', '3.10']
+          python_versions: ['3.7', '3.8', '3.9', '3.10', '3.11']
           test_suites:
-              all: venv\Scripts\pytest -n 2 -vvs --reruns 2
+              all: venv\Scripts\pytest -n 2 -vvs  --reruns 2
 
     - template: etc/ci/azure-win.yml
       parameters:
           job_name: win2022_cpython
           image_name: windows-2022
-          python_versions: ['3.8', '3.9', '3.10']
+          python_versions: ['3.7', '3.8', '3.9', '3.10', '3.11']
           test_suites:
               all: venv\Scripts\pytest -n 2 -vvs --reruns 2
diff --git a/configure b/configure
index 32e02f55..926a894e 100755
--- a/configure
+++ b/configure
@@ -36,7 +36,7 @@ DOCS_REQUIREMENTS="--editable .[docs] --constraint requirements.txt"
 VIRTUALENV_DIR=venv
 
 # Cleanable files and directories to delete with the --clean option
-CLEANABLE="build venv"
+CLEANABLE="build dist venv .cache .eggs"
 
 # extra  arguments passed to pip
 PIP_EXTRA_ARGS=" "
diff --git a/configure.bat b/configure.bat
index 41547cc5..5e95b311 100644
--- a/configure.bat
+++ b/configure.bat
@@ -34,7 +34,7 @@ set "DOCS_REQUIREMENTS=--editable .[docs] --constraint requirements.txt"
 set "VIRTUALENV_DIR=venv"
 
 @rem # Cleanable files and directories to delete with the --clean option
-set "CLEANABLE=build venv"
+set "CLEANABLE=build dist venv .cache .eggs"
 
 @rem # extra  arguments passed to pip
 set "PIP_EXTRA_ARGS= "
diff --git a/pyproject.toml b/pyproject.toml
index cde79074..3ca4f153 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
 [tool.setuptools_scm]
 # this is used populated when creating a git archive
 # and when there is .git dir and/or there is no git installed
-fallback_version = "9999.$Format:%h-%cs$"
+fallback_version = "9999.9999.99"
 
 [tool.pytest.ini_options]
 norecursedirs = [
diff --git a/src/python_inspector/utils_pypi.py b/src/python_inspector/utils_pypi.py
index f7e21d1a..df14920f 100644
--- a/src/python_inspector/utils_pypi.py
+++ b/src/python_inspector/utils_pypi.py
@@ -11,6 +11,7 @@
 import email
 import itertools
 import os
+import pathlib
 import re
 import shutil
 import tempfile
@@ -174,7 +175,16 @@ def get_python_dot_version(version):
     ],
 }
 
-CACHE_THIRDPARTY_DIR = ".cache/thirdparty"
+CACHE_THIRDPARTY_DIR = os.environ.get("PYTHON_INSPECTOR_CACHE_DIR")
+if not CACHE_THIRDPARTY_DIR:
+    CACHE_THIRDPARTY_DIR = ".cache/python_inspector"
+    try:
+        os.makedirs(CACHE_THIRDPARTY_DIR, exist_ok=True)
+    except Exception:
+        home = pathlib.Path.home()
+        CACHE_THIRDPARTY_DIR = str(home / ".cache/python_inspector")
+        os.makedirs(CACHE_THIRDPARTY_DIR, exist_ok=True)
+
 
 ################################################################################
 


Test patch:
diff --git a/tests/data/azure-devops.req-310-expected.json b/tests/data/azure-devops.req-310-expected.json
index 66c88a8b..027e9619 100644
--- a/tests/data/azure-devops.req-310-expected.json
+++ b/tests/data/azure-devops.req-310-expected.json
@@ -4,7 +4,7 @@
     "tool_homepageurl": "https://github.com/nexB/python-inspector",
     "tool_version": "0.9.3",
     "options": [
-      "--requirement /home/tg1999/Desktop/python-inspector-1/tests/data/azure-devops.req.txt",
+      "--requirement /home/jono/nexb/src/python-inspector/tests/data/azure-devops.req.txt",
       "--index-url https://pypi.org/simple",
       "--python-version 310",
       "--operating-system linux",
@@ -17,7 +17,7 @@
   "files": [
     {
       "type": "file",
-      "path": "/home/tg1999/Desktop/python-inspector-1/tests/data/azure-devops.req.txt",
+      "path": "/home/jono/nexb/src/python-inspector/tests/data/azure-devops.req.txt",
       "package_data": [
         {
           "type": "pypi",
diff --git a/tests/data/azure-devops.req-38-expected.json b/tests/data/azure-devops.req-38-expected.json
index f8839807..db55717e 100644
--- a/tests/data/azure-devops.req-38-expected.json
+++ b/tests/data/azure-devops.req-38-expected.json
@@ -4,7 +4,7 @@
     "tool_homepageurl": "https://github.com/nexB/python-inspector",
     "tool_version": "0.9.3",
     "options": [
-      "--requirement /home/tg1999/Desktop/python-inspector-1/tests/data/azure-devops.req.txt",
+      "--requirement /home/jono/nexb/src/python-inspector/tests/data/azure-devops.req.txt",
       "--index-url https://pypi.org/simple",
       "--python-version 38",
       "--operating-system linux",
@@ -17,7 +17,7 @@
   "files": [
     {
       "type": "file",
-      "path": "/home/tg1999/Desktop/python-inspector-1/tests/data/azure-devops.req.txt",
+      "path": "/home/jono/nexb/src/python-inspector/tests/data/azure-devops.req.txt",
       "package_data": [
         {
           "type": "pypi",
diff --git a/tests/data/insecure-setup-2/setup.py-expected.json b/tests/data/insecure-setup-2/setup.py-expected.json
index 1d39896e..75b587b0 100644
--- a/tests/data/insecure-setup-2/setup.py-expected.json
+++ b/tests/data/insecure-setup-2/setup.py-expected.json
@@ -16,7 +16,7 @@
   "files": [
     {
       "type": "file",
-      "path": "/home/tg1999/Desktop/python-inspector-1/tests/data/insecure-setup-2/setup.py",
+      "path": "/home/jono/nexb/src/python-inspector/tests/data/insecure-setup-2/setup.py",
       "package_data": [
         {
           "type": "pypi",
diff --git a/tests/test_api.py b/tests/test_api.py
index a554af1a..ce24e0e1 100644
--- a/tests/test_api.py
+++ b/tests/test_api.py
@@ -14,9 +14,9 @@
 
 import pytest
 from commoncode.testcase import FileDrivenTesting
+from test_cli import check_json_results
 
 from python_inspector.resolve_cli import resolver_api
-from tests.test_cli import check_json_results
 
 test_env = FileDrivenTesting()
 test_env.test_data_dir = os.path.join(os.path.dirname(__file__), "data")