Add test for Git LFS repository cloning #10724
+81
−0
Open
Cirrus CI / Tests / FreeBSD (Python 3.11) / pytest
failed
Feb 9, 2026 in 5m 22s
Task Summary
Instruction pytest failed in 02:38
Details
✅ 00:05 clone
✅ 01:42 bootstrap_poetry
✅ 00:53 setup_environment
❌ 02:38 pytest
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/.cache/pypoetry/virtualenvs/poetry-XZqP7kBn-py3.11/lib/python3.11/site-packages/dulwich/lfs.py:636: in download
batch_resp = self.batch("download", [{"oid": oid, "size": size}], ref)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/.cache/pypoetry/virtualenvs/poetry-XZqP7kBn-py3.11/lib/python3.11/site-packages/dulwich/lfs.py:581: in batch
response = self._make_request(
/.cache/pypoetry/virtualenvs/poetry-XZqP7kBn-py3.11/lib/python3.11/site-packages/dulwich/lfs.py:548: in _make_request
response = pool_manager.request(method, url, headers=req_headers, body=data)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/.cache/pypoetry/virtualenvs/poetry-XZqP7kBn-py3.11/lib/python3.11/site-packages/urllib3/_request_methods.py:143: in request
return self.request_encode_body(
/.cache/pypoetry/virtualenvs/poetry-XZqP7kBn-py3.11/lib/python3.11/site-packages/urllib3/_request_methods.py:278: in request_encode_body
return self.urlopen(method, url, **extra_kw)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/.cache/pypoetry/virtualenvs/poetry-XZqP7kBn-py3.11/lib/python3.11/site-packages/urllib3/poolmanager.py:446: in urlopen
conn = self.connection_from_host(u.host, port=u.port, scheme=u.scheme)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <urllib3.poolmanager.PoolManager object at 0x2f96d861bb10>, host = None
port = None, scheme = 'file', pool_kwargs = None
def connection_from_host(
self,
host: str | None,
port: int | None = None,
scheme: str | None = "http",
pool_kwargs: dict[str, typing.Any] | None = None,
) -> HTTPConnectionPool:
"""
Get a :class:`urllib3.connectionpool.ConnectionPool` based on the host, port, and scheme.
If ``port`` isn't given, it will be derived from the ``scheme`` using
``urllib3.connectionpool.port_by_scheme``. If ``pool_kwargs`` is
provided, it is merged with the instance's ``connection_pool_kw``
variable and used to create the new connection pool, if one is
needed.
"""
if not host:
> raise LocationValueError("No host specified.")
E urllib3.exceptions.LocationValueError: No host specified.
/.cache/pypoetry/virtualenvs/poetry-XZqP7kBn-py3.11/lib/python3.11/site-packages/urllib3/poolmanager.py:308: LocationValueError
-------------- generated xml file: /tmp/cirrus-ci-build/junit.xml --------------
=========================== short test summary info ============================
SKIPPED [1] tests/utils/test_python_manager.py:104: Windows only
SKIPPED [1] tests/utils/env/test_env_manager.py:1269: requires darwin
SKIPPED [1] tests/integration/test_utils_vcs_git.py:324: HTTP authentication credentials not available
SKIPPED [1] tests/console/commands/test_run.py:158: Poetry only installs CMD script files for console scripts of editable dependencies on Windows
SKIPPED [1] tests/installation/test_executor.py:506: https://github.com/python-poetry/poetry/issues/7983
SKIPPED [1] tests/console/commands/self/test_sync.py:26: Only relevant for `poetry self install`
SKIPPED [1] tests/console/commands/test_sync.py:26: Only relevant for `poetry install`
SKIPPED [3] tests/console/commands/env/test_activate.py:54: Only Windows shells
FAILED tests/vcs/git/test_backend.py::test_clone_with_lfs_files - urllib3.exceptions.LocationValueError: No host specified.
============ 1 failed, 2933 passed, 10 skipped in 154.29s (0:02:34) ============Annotations
Check failure on line 149 in lfs.py
cirrus-ci / Tests / FreeBSD (Python 3.11) / pytest
lfs.py#L149
tests.vcs.git.test_backend.test_clone_with_lfs_files
Raw output
self = <dulwich.lfs.LFSStore object at 0x2f96d93538d0>
sha = '5afb784414f946b679ffef3b9b45da7915e3b95e1c56e6a9da0678ce98d3b271'
def open_object(self, sha: str) -> BinaryIO:
"""Open an object by sha."""
try:
> return open(self._sha_path(sha), "rb")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
E FileNotFoundError: [Errno 2] No such file or directory: '/tmp/pytest-of-root/pytest-0/popen-gw1/test_clone_with_lfs_files0/clone-root/clone-test/.git/lfs/objects/5a/fb/5afb784414f946b679ffef3b9b45da7915e3b95e1c56e6a9da0678ce98d3b271'
/.cache/pypoetry/virtualenvs/poetry-XZqP7kBn-py3.11/lib/python3.11/site-packages/dulwich/lfs.py:149: FileNotFoundError
The above exception was the direct cause of the following exception:
self = <dulwich.lfs.LFSFilterDriver object at 0x2f96d8619c10>
data = b'version https://git-lfs.github.com/spec/v1\noid sha256:5afb784414f946b679ffef3b9b45da7915e3b95e1c56e6a9da0678ce98d3b271\nsize 51\n'
path = b'large.bin'
def smudge(self, data: bytes, path: bytes = b"") -> bytes:
"""Convert LFS pointer to file content (smudge filter)."""
# Try to parse as LFS pointer
pointer = LFSPointer.from_bytes(data)
if pointer is None:
# Not an LFS pointer, return as-is
return data
# Validate the pointer
if not pointer.is_valid_oid():
return data
try:
# Read the actual content from LFS store
> with self.lfs_store.open_object(pointer.oid) as f:
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/.cache/pypoetry/virtualenvs/poetry-XZqP7kBn-py3.11/lib/python3.11/site-packages/dulwich/lfs.py:294:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <dulwich.lfs.LFSStore object at 0x2f96d93538d0>
sha = '5afb784414f946b679ffef3b9b45da7915e3b95e1c56e6a9da0678ce98d3b271'
def open_object(self, sha: str) -> BinaryIO:
"""Open an object by sha."""
try:
return open(self._sha_path(sha), "rb")
except FileNotFoundError as exc:
> raise KeyError(sha) from exc
E KeyError: '5afb784414f946b679ffef3b9b45da7915e3b95e1c56e6a9da0678ce98d3b271'
/.cache/pypoetry/virtualenvs/poetry-XZqP7kBn-py3.11/lib/python3.11/site-packages/dulwich/lfs.py:151: KeyError
During handling of the above exception, another exception occurred:
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/popen-gw1/test_clone_with_lfs_files0')
@pytest.mark.skip_git_mock
def test_clone_with_lfs_files(tmp_path: Path) -> None:
"""Test cloning a repository with Git LFS files (issue #8723)."""
from dulwich import porcelain
from dulwich.lfs import LFSStore
# Create a source repository with LFS support
source_path = tmp_path / "source-repo"
source_path.mkdir()
repo = Repo.init(str(source_path))
# Set up LFS in the repository
lfs_dir = source_path / ".git" / "lfs"
lfs_dir.mkdir(parents=True)
lfs_store = LFSStore.create(str(lfs_dir))
# Configure LFS URL in the repository config
config = repo.get_config()
config.set((b"lfs",), b"url", lfs_dir.as_uri().encode())
config.write_to_path()
# Configure .gitattributes to track large files with LFS
gitattributes = source_path / ".gitattributes"
gitattributes.write_text("*.bin filter=lfs diff=lfs merge=lfs -text\n")
porcelain.add(repo, str(gitattributes))
# Create a regular file
regular_file = source_path / "regular.txt"
regular_file.write_text("This is a regular file")
porcelain.add(repo, str(regular_file))
# Create an LFS file with a pointer
lfs_content = b"This is a large binary file content for LFS storage"
lfs_file = source_path / "large.bin"
# Store the actual content in LFS store and create pointer
lfs_object_id = lfs_store.write_object([lfs_content])
lfs_pointer = (
f"version https://git-lfs.github.com/spec/v1\n"
f"oid sha256:{lfs_object_id}\n"
f"size {len(lfs_content)}\n"
)
lfs_file.write_text(lfs_pointer)
porcelain.add(repo, str(lfs_file))
# Commit the files
porcelain.commit(
repo,
message=b"Add files with LFS support",
author=b"Test <test@example.com>",
committer=b"Test <test@example.com>",
)
# Clone the repository
source_root_dir = tmp_path / "clone-root"
source_root_dir.mkdir()
> Git.clone(
url=source_path.as_uri(),
source_root=source_root_dir,
name="clone-test",
)
/tmp/cirrus-ci-build/tests/vcs/git/test_backend.py:351:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/tmp/cirrus-ci-build/src/poetry/vcs/git/backend.py:556: in clone
local = cls._clone(url=url, refspec=refspec, target=target)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/tmp/cirrus-ci-build/src/poetry/vcs/git/backend.py:402: in _clone
local.get_worktree().reset_index()
/.cache/pypoetry/virtualenvs/poetry-XZqP7kBn-py3.11/lib/python3.11/site-packages/dulwich/worktree.py:744: in reset_index
return build_index_from_tree(
/.cache/pypoetry/virtualenvs/poetry-XZqP7kBn-py3.11/lib/python3.11/site-packages/dulwich/index.py:2030: in build_index_from_tree
obj = blob_normalizer.checkout_normalize(obj, entry.path)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/.cache/pypoetry/virtualenvs/poetry-XZqP7kBn-py3.11/lib/python3.11/site-packages/dulwich/filters.py:983: in checkout_normalize
filtered_data = filter_driver.smudge(blob.data, path)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/.cache/pypoetry/virtualenvs/poetry-XZqP7kBn-py3.11/lib/python3.11/site-packages/dulwich/lfs.py:299: in smudge
content = self._download_object(pointer)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/.cache/pypoetry/virtualenvs/poetry-XZqP7kBn-py3.11/lib/python3.11/site-packages/dulwich/lfs.py:327: in _download_object
content = client.download(pointer.oid, pointer.size)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/.cache/pypoetry/virtualenvs/poetry-XZqP7kBn-py3.11/lib/python3.11/site-packages/dulwich/lfs.py:636: in download
batch_resp = self.batch("download", [{"oid": oid, "size": size}], ref)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/.cache/pypoetry/virtualenvs/poetry-XZqP7kBn-py3.11/lib/python3.11/site-packages/dulwich/lfs.py:581: in batch
response = self._make_request(
/.cache/pypoetry/virtualenvs/poetry-XZqP7kBn-py3.11/lib/python3.11/site-packages/dulwich/lfs.py:548: in _make_request
response = pool_manager.request(method, url, headers=req_headers, body=data)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/.cache/pypoetry/virtualenvs/poetry-XZqP7kBn-py3.11/lib/python3.11/site-packages/urllib3/_request_methods.py:143: in request
return self.request_encode_body(
/.cache/pypoetry/virtualenvs/poetry-XZqP7kBn-py3.11/lib/python3.11/site-packages/urllib3/_request_methods.py:278: in request_encode_body
return self.urlopen(method, url, **extra_kw)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/.cache/pypoetry/virtualenvs/poetry-XZqP7kBn-py3.11/lib/python3.11/site-packages/urllib3/poolmanager.py:446: in urlopen
conn = self.connection_from_host(u.host, port=u.port, scheme=u.scheme)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <urllib3.poolmanager.PoolManager object at 0x2f96d861bb10>, host = None
port = None, scheme = 'file', pool_kwargs = None
def connection_from_host(
self,
host: str | None,
port: int | None = None,
scheme: str | None = "http",
pool_kwargs: dict[str, typing.Any] | None = None,
) -> HTTPConnectionPool:
"""
Get a :class:`urllib3.connectionpool.ConnectionPool` based on the host, port, and scheme.
If ``port`` isn't given, it will be derived from the ``scheme`` using
``urllib3.connectionpool.port_by_scheme``. If ``pool_kwargs`` is
provided, it is merged with the instance's ``connection_pool_kw``
variable and used to create the new connection pool, if one is
needed.
"""
if not host:
> raise LocationValueError("No host specified.")
E urllib3.exceptions.LocationValueError: No host specified.
/.cache/pypoetry/virtualenvs/poetry-XZqP7kBn-py3.11/lib/python3.11/site-packages/urllib3/poolmanager.py:308: LocationValueError
Loading