diff --git a/news/200.bugfix.rst b/news/200.bugfix.rst
new file mode 100644
index 0000000..4a5caa7
--- /dev/null
+++ b/news/200.bugfix.rst
@@ -0,0 +1,1 @@
+Fixed an issue which caused build directories to be deleted before dependencies could be determined for editable source reqiurements.
diff --git a/news/202.bugfix.rst b/news/202.bugfix.rst
new file mode 100644
index 0000000..3cc180d
--- /dev/null
+++ b/news/202.bugfix.rst
@@ -0,0 +1,1 @@
+Fixed a bug which could cause parsing to fail for ``setup.cfg`` files on python 2.
diff --git a/src/requirementslib/models/requirements.py b/src/requirementslib/models/requirements.py
index eb12b04..1ec47f7 100644
--- a/src/requirementslib/models/requirements.py
+++ b/src/requirementslib/models/requirements.py
@@ -83,6 +83,7 @@ from .utils import (
     make_install_requirement,
     normalize_name,
     parse_extras,
+    read_source,
     specs_to_string,
     split_markers_from_line,
     split_ref_from_uri,
@@ -862,10 +863,16 @@ class Line(object):
     @cached_property
     def parsed_setup_cfg(self):
         # type: () -> Dict[Any, Any]
-        if self.is_local and self.path and is_installable_dir(self.path):
-            if self.setup_cfg:
-                return parse_setup_cfg(self.setup_cfg)
-        return {}
+        if not (
+            self.is_local
+            and self.path
+            and is_installable_dir(self.path)
+            and self.setup_cfg
+        ):
+            return {}
+        base_dir = os.path.dirname(os.path.abspath(self.setup_cfg))
+        setup_content = read_source(self.setup_cfg)
+        return parse_setup_cfg(setup_content, base_dir)
 
     @cached_property
     def parsed_setup_py(self):
diff --git a/src/requirementslib/models/setup_info.py b/src/requirementslib/models/setup_info.py
index 38cc838..8ad7373 100644
--- a/src/requirementslib/models/setup_info.py
+++ b/src/requirementslib/models/setup_info.py
@@ -5,6 +5,7 @@ import ast
 import atexit
 import contextlib
 import importlib
+import io
 import os
 import shutil
 import sys
@@ -280,14 +281,8 @@ def get_extras_from_setupcfg(parser):
     return extras
 
 
-def parse_setup_cfg(setup_cfg_path):
-    # type: (S) -> Dict[S, Union[S, None, Set[BaseRequirement], List[S], Dict[STRING_TYPE, Tuple[BaseRequirement]]]]
-    if not os.path.exists(setup_cfg_path):
-        raise FileNotFoundError(setup_cfg_path)
-    try:
-        return setuptools_parse_setup_cfg(setup_cfg_path)
-    except Exception:
-        pass
+def parse_setup_cfg(setup_cfg_contents, base_dir):
+    # type: (S, S) -> Dict[S, Union[S, None, Set[BaseRequirement], List[S], Dict[STRING_TYPE, Tuple[BaseRequirement]]]]
     default_opts = {
         "metadata": {"name": "", "version": ""},
         "options": {
@@ -300,9 +295,12 @@ def parse_setup_cfg(setup_cfg_path):
         },
     }
     parser = configparser.ConfigParser(default_opts)
-    parser.read(setup_cfg_path)
+    if six.PY2:
+        buff = io.BytesIO(setup_cfg_contents)
+        parser.readfp(buff)
+    else:
+        parser.read_string(setup_cfg_contents)
     results = {}
-    base_dir = os.path.dirname(os.path.abspath(setup_cfg_path))
     package_dir = get_package_dir_from_setupcfg(parser, base_dir=base_dir)
     name, version = get_name_and_version_from_setupcfg(parser, package_dir)
     results["name"] = name
@@ -1031,11 +1029,6 @@ class SetupInfo(object):
             self._version = info.get("version", None)
         return self._version
 
-    @classmethod
-    def get_setup_cfg(cls, setup_cfg_path):
-        # type: (S) -> Dict[S, Union[S, None, Set[BaseRequirement], List[S], Tuple[S, Tuple[BaseRequirement]]]]
-        return parse_setup_cfg(setup_cfg_path)
-
     @property
     def egg_base(self):
         # type: () -> S
@@ -1118,7 +1111,14 @@ class SetupInfo(object):
     def parse_setup_cfg(self):
         # type: () -> Dict[STRING_TYPE, Any]
         if self.setup_cfg is not None and self.setup_cfg.exists():
-            parsed = self.get_setup_cfg(self.setup_cfg.as_posix())
+            contents = self.setup_cfg.read_text()
+            base_dir = self.setup_cfg.absolute().parent.as_posix()
+            try:
+                parsed = setuptools_parse_setup_cfg(self.setup_cfg.as_posix())
+            except Exception:
+                if six.PY2:
+                    contents = self.setup_cfg.read_bytes()
+                parsed = parse_setup_cfg(contents, base_dir)
             if not parsed:
                 return {}
             return parsed
@@ -1481,6 +1481,12 @@ build-backend = "{1}"
             raise RequirementError(
                 "The file URL points to a directory not installable: {}".format(ireq.link)
             )
+        # this ensures the build dir is treated as the temporary build location
+        # and the source dir is treated as permanent / not deleted by pip
+        build_location_func = getattr(ireq, "build_location", None)
+        if build_location_func is None:
+            build_location_func = getattr(ireq, "ensure_build_location", None)
+        build_location_func(kwargs["build_dir"])
         ireq.ensure_has_source_dir(kwargs["src_dir"])
         src_dir = ireq.source_dir
 

Build locations are deleted for local source directories before they can be referenced
When building a local source package via `SetupInfo` on master, the build directory created is temporary and is deleted by pip before it can be referenced and inspected for dependencies
diff --git a/tests/unit/test_setup_info.py b/tests/unit/test_setup_info.py
index c04fb2a..1878d77 100644
--- a/tests/unit/test_setup_info.py
+++ b/tests/unit/test_setup_info.py
@@ -212,8 +212,11 @@ def test_ast_parser_finds_fully_qualified_setup(setup_py_dir):
 
 
 def test_setup_cfg_parser(setup_cfg_dir):
-    result = parse_setup_cfg(
-        (setup_cfg_dir / "package_with_multiple_extras/setup.cfg").as_posix()
-    )
+    setup_path = setup_cfg_dir / "package_with_multiple_extras/setup.cfg"
+    if six.PY2:
+        contents = setup_path.read_bytes()
+    else:
+        contents = setup_path.read_text()
+    result = parse_setup_cfg(contents, setup_path.parent.as_posix())
     assert result["version"] == "0.5.0"
     assert result["name"] == "test_package"

pip install -e .[dev,tests,typing]
parse_log_pytest
requirements.txt
pytest
3.6
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
alabaster==0.7.13
appdirs==1.4.4
Arpeggio==1.10.2
attrs==22.2.0
Babel==2.11.0
black==22.8.0
bleach==4.1.0
cached-property==1.5.2
Cerberus==1.3.5
certifi==2021.5.30
cffi==1.15.1
cfgv==3.3.1
charset-normalizer==2.0.12
click==8.0.4
click-default-group==1.2.4
cmarkgfm==2024.11.20
colorama==0.4.5
coverage==6.2
cryptography==40.0.2
dataclasses==0.8
decorator==4.4.2
distlib==0.3.9
docutils==0.18.1
execnet==1.9.0
filelock==3.4.1
findimports==2.2.0
first==2.0.2
flake8==5.0.4
flake8-bugbear==22.9.23
hypothesis==6.31.6
identify==2.4.4
idna==3.10
imagesize==1.4.1
importlab==0.8.1
importlib-metadata==4.2.0
importlib-resources==5.2.3
incremental==22.10.0
iniconfig==1.1.1
invoke==2.2.0
isort==5.10.1
jedi==0.19.2
jeepney==0.7.1
Jinja2==3.0.3
keyring==23.4.1
libcst==0.4.1
lxml==5.3.1
MarkupSafe==2.0.1
mccabe==0.7.0
mock==5.2.0
MonkeyType==22.2.0
mypy==0.971
mypy-extensions==1.0.0
mypytools==0.1.15
networkx==2.5.1
ninja==1.11.1.1
nodeenv==1.6.0
orderedmultidict==1.0.1
packaging==21.3
parso==0.8.4
parver==0.3.1
pathspec==0.9.0
pep517==0.13.1
pip-shims==0.7.3
pkginfo==1.10.0
platformdirs==2.4.0
plette==0.2.3
pluggy==1.0.0
pre-commit==2.17.0
prompt-toolkit==3.0.36
ptpython==3.0.22
py==1.11.0
pycodestyle==2.9.1
pycparser==2.21
pyflakes==2.5.0
Pygments==2.14.0
pyparsing==3.1.4
pytest==7.0.1
pytest-cov==4.0.0
pytest-timeout==2.1.0
pytest-xdist==3.0.2
pytype==2022.1.5
pytz==2025.2
PyYAML==6.0.1
readme-renderer==34.0
requests==2.27.1
requests-toolbelt==1.0.0
-e git+https://github.com/sarugaku/requirementslib.git@87237239f8e8a531b6dd10dbfcab94da34ebed2d#egg=requirementslib
rfc3986==1.5.0
rope==1.1.1
SecretStorage==3.3.3
six==1.17.0
snowballstemmer==2.2.0
sortedcontainers==2.4.0
Sphinx==5.3.0
sphinx-rtd-theme==2.0.0
sphinxcontrib-applehelp==1.0.2
sphinxcontrib-devhelp==1.0.2
sphinxcontrib-htmlhelp==2.0.0
sphinxcontrib-jquery==4.1
sphinxcontrib-jsmath==1.0.1
sphinxcontrib-qthelp==1.0.3
sphinxcontrib-serializinghtml==1.1.5
tabulate==0.8.10
toml==0.10.2
tomli==1.2.3
tomlkit==0.11.6
towncrier==21.9.0
tqdm==4.64.1
twine==3.8.0
typed-ast==1.5.5
typing==3.7.4.3
typing-inspect==0.9.0
typing_extensions==4.1.1
urllib3==1.26.20
virtualenv==20.16.2
vistir==0.5.6
vulture==2.8
watchdog==2.3.1
wcwidth==0.2.13
webencodings==0.5.1
zipp==3.6.0

name: requirementslib
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2021.5.30=py36h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.3=he6710b0_2
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=21.2.2=py36h06a4308_0
  - python=3.6.13=h12debd9_1
  - readline=8.2=h5eee18b_0
  - setuptools=58.0.4=py36h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.37.1=pyhd3eb1b0_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - alabaster==0.7.13
      - appdirs==1.4.4
      - arpeggio==1.10.2
      - attrs==22.2.0
      - babel==2.11.0
      - black==22.8.0
      - bleach==4.1.0
      - cached-property==1.5.2
      - cerberus==1.3.5
      - cffi==1.15.1
      - cfgv==3.3.1
      - charset-normalizer==2.0.12
      - click==8.0.4
      - click-default-group==1.2.4
      - cmarkgfm==2024.11.20
      - colorama==0.4.5
      - coverage==6.2
      - cryptography==40.0.2
      - dataclasses==0.8
      - decorator==4.4.2
      - distlib==0.3.9
      - docutils==0.18.1
      - execnet==1.9.0
      - filelock==3.4.1
      - findimports==2.2.0
      - first==2.0.2
      - flake8==5.0.4
      - flake8-bugbear==22.9.23
      - hypothesis==6.31.6
      - identify==2.4.4
      - idna==3.10
      - imagesize==1.4.1
      - importlab==0.8.1
      - importlib-metadata==4.2.0
      - importlib-resources==5.2.3
      - incremental==22.10.0
      - iniconfig==1.1.1
      - invoke==2.2.0
      - isort==5.10.1
      - jedi==0.19.2
      - jeepney==0.7.1
      - jinja2==3.0.3
      - keyring==23.4.1
      - libcst==0.4.1
      - lxml==5.3.1
      - markupsafe==2.0.1
      - mccabe==0.7.0
      - mock==5.2.0
      - monkeytype==22.2.0
      - mypy==0.971
      - mypy-extensions==1.0.0
      - mypytools==0.1.15
      - networkx==2.5.1
      - ninja==1.11.1.1
      - nodeenv==1.6.0
      - orderedmultidict==1.0.1
      - packaging==21.3
      - parso==0.8.4
      - parver==0.3.1
      - pathspec==0.9.0
      - pep517==0.13.1
      - pip-shims==0.7.3
      - pkginfo==1.10.0
      - platformdirs==2.4.0
      - plette==0.2.3
      - pluggy==1.0.0
      - pre-commit==2.17.0
      - prompt-toolkit==3.0.36
      - ptpython==3.0.22
      - py==1.11.0
      - pycodestyle==2.9.1
      - pycparser==2.21
      - pyflakes==2.5.0
      - pygments==2.14.0
      - pyparsing==3.1.4
      - pytest==7.0.1
      - pytest-cov==4.0.0
      - pytest-timeout==2.1.0
      - pytest-xdist==3.0.2
      - pytype==2022.1.5
      - pytz==2025.2
      - pyyaml==6.0.1
      - readme-renderer==34.0
      - requests==2.27.1
      - requests-toolbelt==1.0.0
      - rfc3986==1.5.0
      - rope==1.1.1
      - secretstorage==3.3.3
      - six==1.17.0
      - snowballstemmer==2.2.0
      - sortedcontainers==2.4.0
      - sphinx==5.3.0
      - sphinx-rtd-theme==2.0.0
      - sphinxcontrib-applehelp==1.0.2
      - sphinxcontrib-devhelp==1.0.2
      - sphinxcontrib-htmlhelp==2.0.0
      - sphinxcontrib-jquery==4.1
      - sphinxcontrib-jsmath==1.0.1
      - sphinxcontrib-qthelp==1.0.3
      - sphinxcontrib-serializinghtml==1.1.5
      - tabulate==0.8.10
      - toml==0.10.2
      - tomli==1.2.3
      - tomlkit==0.11.6
      - towncrier==21.9.0
      - tqdm==4.64.1
      - twine==3.8.0
      - typed-ast==1.5.5
      - typing==3.7.4.3
      - typing-extensions==4.1.1
      - typing-inspect==0.9.0
      - urllib3==1.26.20
      - virtualenv==20.16.2
      - vistir==0.5.6
      - vulture==2.8
      - watchdog==2.3.1
      - wcwidth==0.2.13
      - webencodings==0.5.1
      - zipp==3.6.0
prefix: /opt/conda/envs/requirementslib

tests/unit/test_setup_info.py::test_setup_cfg_parser
tests/unit/test_setup_info.py::test_local_req[test_artifact0] tests/unit/test_setup_info.py::test_local_req[test_artifact1] tests/unit/test_setup_info.py::test_without_extras tests/unit/test_setup_info.py::test_remote_req[https://github.com/requests/requests/archive/v2.20.1.zip-requests-requires0] tests/unit/test_setup_info.py::test_extras[package_with_multiple_extras-extras0-dependencies0] tests/unit/test_setup_info.py::test_remote_req[https://github.com/dropbox/pyannotate/archive/v1.0.4.zip-pyannotate-requires1] tests/unit/test_setup_info.py::test_extras[package_with_one_extra-extras1-dependencies1] tests/unit/test_setup_info.py::test_no_duplicate_egg_info
tests/unit/test_setup_info.py::test_ast_parser_finds_variables tests/unit/test_setup_info.py::test_ast_parser_finds_fully_qualified_setup
src/requirementslib/models/setup_info.py news/200.bugfix.rst news/202.bugfix.rst src/requirementslib/models/requirements.py
src/requirementslib/models/setup_info.py news/200.bugfix.rst news/202.bugfix.rst src/requirementslib/models/requirements.py