Skip to content

Commit

Permalink
pythongh-113356: Ignore errors in "._ABC.pth"
Browse files Browse the repository at this point in the history
On macOS the system can create a "._" file next to a
regular file when the system needs to store metadata
that is not supported by the filesystem (such as storing
extended attributes on an exFAT filesystem).

Those files are binary data and cause startup failures when
the base file is a ".pth" file.
  • Loading branch information
ronaldoussoren committed Dec 21, 2023
1 parent 93cf735 commit f6fe595
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 22 deletions.
55 changes: 33 additions & 22 deletions Lib/site.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,29 +176,40 @@ def addpackage(sitedir, name, known_paths):
except OSError:
return
with f:
for n, line in enumerate(f):
if line.startswith("#"):
continue
if line.strip() == "":
continue
try:
if line.startswith(("import ", "import\t")):
exec(line)
try:
for n, line in enumerate(f):
if line.startswith("#"):
continue
line = line.rstrip()
dir, dircase = makepath(sitedir, line)
if not dircase in known_paths and os.path.exists(dir):
sys.path.append(dir)
known_paths.add(dircase)
except Exception as exc:
print("Error processing line {:d} of {}:\n".format(n+1, fullname),
file=sys.stderr)
import traceback
for record in traceback.format_exception(exc):
for line in record.splitlines():
print(' '+line, file=sys.stderr)
print("\nRemainder of file ignored", file=sys.stderr)
break
if line.strip() == "":
continue
try:
if line.startswith(("import ", "import\t")):
exec(line)
continue
line = line.rstrip()
dir, dircase = makepath(sitedir, line)
if not dircase in known_paths and os.path.exists(dir):
sys.path.append(dir)
known_paths.add(dircase)
except Exception as exc:
print("Error processing line {:d} of {}:\n".format(n+1, fullname),
file=sys.stderr)
import traceback
for record in traceback.format_exception(exc):
for line in record.splitlines():
print(' '+line, file=sys.stderr)
print("\nRemainder of file ignored", file=sys.stderr)
break
except UnicodeDecodeError:
# MacOS can create files with a "._" prefix in the name
# next to the regular file when the system needs to store
# metadata (such as extended attributes) that the filesystem
# cannot store natively.
#
# Ignore errors when trying to parse these files.
if name.startswith("._") and os.path.exists(os.path.join(sitedir, name[2:])):
return
raise
if reset:
known_paths = None
return known_paths
Expand Down
14 changes: 14 additions & 0 deletions Lib/test/test_site.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,20 @@ def test_addpackage_import_bad_pth_file(self):
if isinstance(path, str):
self.assertNotIn("abc\x00def", path)

def test_addpackage_macOS_resources(self):
# GH-113356
pth_dir, pth_fn = self.make_pth("dummy\n")
resource_fork = os.path.join(pth_dir, "._" + pth_fn)
with open(resource_fork, "wb") as fp:
self.addCleanup(lambda: os.remove(resource_fork))
# Some random that that isn't valid UTF-8
fp.write(b"\xff\xff\xff")

with captured_stderr() as err_out:
self.assertFalse(site.addpackage(pth_dir, "._" + pth_fn, set()))
self.assertEqual(err_out.getvalue(), "")


def test_addsitedir(self):
# Same tests for test_addpackage since addsitedir() essentially just
# calls addpackage() for every .pth file in the directory
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Ignore "._" prefixed pth files when those cannot be parsed. These files are
created on macOS when the system tries store metadata that is not supported
by the filesystem (such as extended attributes on exFAT)

0 comments on commit f6fe595

Please sign in to comment.