poetry: Dulwich does not support Dumb Git transport
- Poetry version: 1.2.2
- Python version: 3.10.6
- OS version and name: Windows 10
- pyproject.toml: https://gist.github.com/rruiter87/1c74ca0c3fbf78cd2b59845d8ee4f5b6
- I am on the latest stable Poetry version, installed using a recommended method.
- I have searched the issues of this repo and believe that this is not a duplicate.
- I have consulted the FAQ and blog for any relevant entries or release notes.
- If an exception occurs when executing a command, I executed it again in debug mode (
-vvv
option) and have included the output below.
Issue
I’m unable to add git dependencies both via https and ssh. If I just do a regular git clone <repo>
it works for ssh.
HTTPS
❯ poetry add git+https://github.com:mbuesch/pyprofibus.git -vvv
Using virtualenv: C:\Users\rruiter\Miniconda3\envs\profinet310
[keyring.backend] Loading KWallet
[keyring.backend] Loading SecretService
[keyring.backend] Loading Windows
[keyring.backend] Loading chainer
[keyring.backend] Loading libsecret
[keyring.backend] Loading macOS
[urllib3.connectionpool] Starting new HTTPS connection (1): github.com:443
[urllib3.connectionpool] https://github.com:443 "GET /mbuesch/pyprofibus.git/info/refs?service=git-upload-pack HTTP/1.1" 200 None
Cloning https://github.com/mbuesch/pyprofibus.git at 'HEAD' to C:\Users\rruiter\Miniconda3\envs\profinet310\src\pyprofibus
[urllib3.connectionpool] Starting new HTTPS connection (1): git.bues.ch:443
[urllib3.connectionpool] https://git.bues.ch:443 "GET /git/crcgen.git/info/refs?service=git-upload-pack HTTP/1.1" 200 817
Stack trace:
23 ~\AppData\Roaming\pypoetry\venv\lib\site-packages\cleo\application.py:329 in run
327│
328│ try:
→ 329│ exit_code = self._run(io)
330│ except Exception as e:
331│ if not self._catch_exceptions:
22 ~\AppData\Roaming\pypoetry\venv\lib\site-packages\poetry\console\application.py:185 in _run
183│ self._load_plugins(io)
184│
→ 185│ exit_code: int = super()._run(io)
186│ return exit_code
187│
21 ~\AppData\Roaming\pypoetry\venv\lib\site-packages\cleo\application.py:423 in _run
421│ io.input.set_stream(stream)
422│
→ 423│ exit_code = self._run_command(command, io)
424│ self._running_command = None
425│
20 ~\AppData\Roaming\pypoetry\venv\lib\site-packages\cleo\application.py:465 in _run_command
463│
464│ if error is not None:
→ 465│ raise error
466│
467│ return event.exit_code
19 ~\AppData\Roaming\pypoetry\venv\lib\site-packages\cleo\application.py:449 in _run_command
447│
448│ if event.command_should_run():
→ 449│ exit_code = command.run(io)
450│ else:
451│ exit_code = ConsoleCommandEvent.RETURN_CODE_DISABLED
18 ~\AppData\Roaming\pypoetry\venv\lib\site-packages\cleo\commands\base_command.py:119 in run
117│ io.input.validate()
118│
→ 119│ status_code = self.execute(io)
120│
121│ if status_code is None:
17 ~\AppData\Roaming\pypoetry\venv\lib\site-packages\cleo\commands\command.py:83 in execute
81│
82│ try:
→ 83│ return self.handle()
84│ except KeyboardInterrupt:
85│ return 1
16 ~\AppData\Roaming\pypoetry\venv\lib\site-packages\poetry\console\commands\add.py:158 in handle
156│ return 0
157│
→ 158│ requirements = self._determine_requirements(
159│ packages,
160│ allow_prereleases=self.option("allow-prereleases"),
15 ~\AppData\Roaming\pypoetry\venv\lib\site-packages\poetry\console\commands\init.py:357 in _determine_requirements
355│
356│ result = []
→ 357│ for requirement in self._parse_requirements(requires):
358│ if "git" in requirement or "url" in requirement or "path" in requirement:
359│ result.append(requirement)
14 ~\AppData\Roaming\pypoetry\venv\lib\site-packages\poetry\console\commands\init.py:416 in _parse_requirements
414│ cwd = Path.cwd()
415│
→ 416│ return [
417│ parse_dependency_specification(
418│ requirement=requirement,
13 ~\AppData\Roaming\pypoetry\venv\lib\site-packages\poetry\console\commands\init.py:417 in <listcomp>
415│
416│ return [
→ 417│ parse_dependency_specification(
418│ requirement=requirement,
419│ env=self.env if isinstance(self, EnvCommand) else None,
12 ~\AppData\Roaming\pypoetry\venv\lib\site-packages\poetry\utils\dependency_specification.py:216 in parse_dependency_specification
214│
215│ specification = (
→ 216│ _parse_dependency_specification_url(requirement, env=env)
217│ or _parse_dependency_specification_path(requirement, cwd=cwd)
218│ or _parse_dependency_specification_simple(requirement)
11 ~\AppData\Roaming\pypoetry\venv\lib\site-packages\poetry\utils\dependency_specification.py:68 in _parse_dependency_specification_url
66│
67│ if url_parsed.scheme in ["git+https", "git+ssh"]:
→ 68│ return _parse_dependency_specification_git_url(requirement, env)
69│
70│ if url_parsed.scheme in ["http", "https"]:
10 ~\AppData\Roaming\pypoetry\venv\lib\site-packages\poetry\utils\dependency_specification.py:49 in _parse_dependency_specification_git_url
47│
48│ source_root = env.path.joinpath("src") if env else None
→ 49│ package = Provider.get_package_from_vcs(
50│ "git",
51│ url=url.url,
9 ~\AppData\Roaming\pypoetry\venv\lib\site-packages\poetry\puzzle\provider.py:341 in get_package_from_vcs
339│ raise ValueError(f"Unsupported VCS dependency {vcs}")
340│
→ 341│ return _get_package_from_git(
342│ url=url,
343│ branch=branch,
8 ~\AppData\Roaming\pypoetry\venv\lib\site-packages\poetry\puzzle\provider.py:95 in _get_package_from_git
93│ source_root: Path | None = None,
94│ ) -> Package:
→ 95│ source = Git.clone(
96│ url=url,
97│ source_root=source_root,
7 ~\AppData\Roaming\pypoetry\venv\lib\site-packages\poetry\vcs\git\backend.py:427 in clone
425│ if not cls.is_using_legacy_client():
426│ local = cls._clone(url=url, refspec=refspec, target=target)
→ 427│ cls._clone_submodules(repo=local)
428│ return local
429│ except HTTPUnauthorized:
6 ~\AppData\Roaming\pypoetry\venv\lib\site-packages\poetry\vcs\git\backend.py:356 in _clone_submodules
354│ continue
355│
→ 356│ cls.clone(
357│ url=url.decode("utf-8"),
358│ source_root=source_root,
5 ~\AppData\Roaming\pypoetry\venv\lib\site-packages\poetry\vcs\git\backend.py:426 in clone
424│ try:
425│ if not cls.is_using_legacy_client():
→ 426│ local = cls._clone(url=url, refspec=refspec, target=target)
427│ cls._clone_submodules(repo=local)
428│ return local
4 ~\AppData\Roaming\pypoetry\venv\lib\site-packages\poetry\vcs\git\backend.py:258 in _clone
256│ local = Repo(str(target))
257│
→ 258│ remote_refs = cls._fetch_remote_refs(url=url, local=local)
259│
260│ logger.debug(
3 ~\AppData\Roaming\pypoetry\venv\lib\site-packages\poetry\vcs\git\backend.py:201 in _fetch_remote_refs
199│
200│ with local:
→ 201│ result: FetchPackResult = client.fetch(
202│ path,
203│ local,
2 ~\AppData\Roaming\pypoetry\venv\lib\site-packages\dulwich\client.py:837 in fetch
835│ f, commit, abort = target.object_store.add_pack()
836│ try:
→ 837│ result = self.fetch_pack(
838│ path,
839│ determine_wants,
1 ~\AppData\Roaming\pypoetry\venv\lib\site-packages\dulwich\client.py:2076 in fetch_pack
2074│ """
2075│ url = self._get_url(path)
→ 2076│ refs, server_capabilities, url = self._discover_references(
2077│ b"git-upload-pack", url
2078│ )
AttributeError
'NoneType' object has no attribute 'startswith'
at ~\AppData\Roaming\pypoetry\venv\lib\site-packages\dulwich\client.py:1946 in _discover_references
1942│ )
1943│ base_url = resp.redirect_location[: -len(tail)]
1944│
1945│ try:
→ 1946│ self.dumb = not resp.content_type.startswith("application/x-git-")
1947│ if not self.dumb:
1948│ proto = Protocol(read, None)
1949│ # The first line should mention the service
1950│ try:
SSH
❯ poetry add git+ssh://github.com:mbuesch/pyprofibus.git -vvv
Using virtualenv: C:\Users\rruiter\Miniconda3\envs\profinet310
Stack trace:
3 ~\AppData\Roaming\pypoetry\venv\lib\site-packages\dulwich\client.py:1149 in fetch_pack
1147│ with proto:
1148│ try:
→ 1149│ refs, server_capabilities = read_pkt_refs(proto.read_pkt_seq())
1150│ except HangupException as exc:
1151│ raise _remote_error_from_stderr(stderr) from exc
2 ~\AppData\Roaming\pypoetry\venv\lib\site-packages\dulwich\client.py:253 in read_pkt_refs
251│ refs = {}
252│ # Receive refs from server
→ 253│ for pkt in pkt_seq:
254│ (sha, ref) = pkt.rstrip(b"\n").split(None, 1)
255│ if sha == b"ERR":
1 ~\AppData\Roaming\pypoetry\venv\lib\site-packages\dulwich\protocol.py:277 in read_pkt_seq
275│ flush-pkt.
276│ """
→ 277│ pkt = self.read_pkt_line()
278│ while pkt:
279│ yield pkt
HangupException
The remote server unexpectedly closed the connection.
at ~\AppData\Roaming\pypoetry\venv\lib\site-packages\dulwich\protocol.py:220 in read_pkt_line
216│
217│ try:
218│ sizestr = read(4)
219│ if not sizestr:
→ 220│ raise HangupException()
221│ size = int(sizestr, 16)
222│ if size == 0:
223│ if self.report_activity:
224│ self.report_activity(4, "read")
The following error occurred when trying to handle this error:
Stack trace:
20 ~\AppData\Roaming\pypoetry\venv\lib\site-packages\cleo\application.py:329 in run
327│
328│ try:
→ 329│ exit_code = self._run(io)
330│ except Exception as e:
331│ if not self._catch_exceptions:
19 ~\AppData\Roaming\pypoetry\venv\lib\site-packages\poetry\console\application.py:185 in _run
183│ self._load_plugins(io)
184│
→ 185│ exit_code: int = super()._run(io)
186│ return exit_code
187│
18 ~\AppData\Roaming\pypoetry\venv\lib\site-packages\cleo\application.py:423 in _run
421│ io.input.set_stream(stream)
422│
→ 423│ exit_code = self._run_command(command, io)
424│ self._running_command = None
425│
17 ~\AppData\Roaming\pypoetry\venv\lib\site-packages\cleo\application.py:465 in _run_command
463│
464│ if error is not None:
→ 465│ raise error
466│
467│ return event.exit_code
16 ~\AppData\Roaming\pypoetry\venv\lib\site-packages\cleo\application.py:449 in _run_command
447│
448│ if event.command_should_run():
→ 449│ exit_code = command.run(io)
450│ else:
451│ exit_code = ConsoleCommandEvent.RETURN_CODE_DISABLED
15 ~\AppData\Roaming\pypoetry\venv\lib\site-packages\cleo\commands\base_command.py:119 in run
117│ io.input.validate()
118│
→ 119│ status_code = self.execute(io)
120│
121│ if status_code is None:
14 ~\AppData\Roaming\pypoetry\venv\lib\site-packages\cleo\commands\command.py:83 in execute
81│
82│ try:
→ 83│ return self.handle()
84│ except KeyboardInterrupt:
85│ return 1
13 ~\AppData\Roaming\pypoetry\venv\lib\site-packages\poetry\console\commands\add.py:158 in handle
156│ return 0
157│
→ 158│ requirements = self._determine_requirements(
159│ packages,
160│ allow_prereleases=self.option("allow-prereleases"),
12 ~\AppData\Roaming\pypoetry\venv\lib\site-packages\poetry\console\commands\init.py:357 in _determine_requirements
355│
356│ result = []
→ 357│ for requirement in self._parse_requirements(requires):
358│ if "git" in requirement or "url" in requirement or "path" in requirement:
359│ result.append(requirement)
11 ~\AppData\Roaming\pypoetry\venv\lib\site-packages\poetry\console\commands\init.py:416 in _parse_requirements
414│ cwd = Path.cwd()
415│
→ 416│ return [
417│ parse_dependency_specification(
418│ requirement=requirement,
10 ~\AppData\Roaming\pypoetry\venv\lib\site-packages\poetry\console\commands\init.py:417 in <listcomp>
415│
416│ return [
→ 417│ parse_dependency_specification(
418│ requirement=requirement,
419│ env=self.env if isinstance(self, EnvCommand) else None,
9 ~\AppData\Roaming\pypoetry\venv\lib\site-packages\poetry\utils\dependency_specification.py:216 in parse_dependency_specification
214│
215│ specification = (
→ 216│ _parse_dependency_specification_url(requirement, env=env)
217│ or _parse_dependency_specification_path(requirement, cwd=cwd)
218│ or _parse_dependency_specification_simple(requirement)
8 ~\AppData\Roaming\pypoetry\venv\lib\site-packages\poetry\utils\dependency_specification.py:68 in _parse_dependency_specification_url
66│
67│ if url_parsed.scheme in ["git+https", "git+ssh"]:
→ 68│ return _parse_dependency_specification_git_url(requirement, env)
69│
70│ if url_parsed.scheme in ["http", "https"]:
7 ~\AppData\Roaming\pypoetry\venv\lib\site-packages\poetry\utils\dependency_specification.py:49 in _parse_dependency_specification_git_url
47│
48│ source_root = env.path.joinpath("src") if env else None
→ 49│ package = Provider.get_package_from_vcs(
50│ "git",
51│ url=url.url,
6 ~\AppData\Roaming\pypoetry\venv\lib\site-packages\poetry\puzzle\provider.py:341 in get_package_from_vcs
339│ raise ValueError(f"Unsupported VCS dependency {vcs}")
340│
→ 341│ return _get_package_from_git(
342│ url=url,
343│ branch=branch,
5 ~\AppData\Roaming\pypoetry\venv\lib\site-packages\poetry\puzzle\provider.py:95 in _get_package_from_git
93│ source_root: Path | None = None,
94│ ) -> Package:
→ 95│ source = Git.clone(
96│ url=url,
97│ source_root=source_root,
4 ~\AppData\Roaming\pypoetry\venv\lib\site-packages\poetry\vcs\git\backend.py:426 in clone
424│ try:
425│ if not cls.is_using_legacy_client():
→ 426│ local = cls._clone(url=url, refspec=refspec, target=target)
427│ cls._clone_submodules(repo=local)
428│ return local
3 ~\AppData\Roaming\pypoetry\venv\lib\site-packages\poetry\vcs\git\backend.py:258 in _clone
256│ local = Repo(str(target))
257│
→ 258│ remote_refs = cls._fetch_remote_refs(url=url, local=local)
259│
260│ logger.debug(
2 ~\AppData\Roaming\pypoetry\venv\lib\site-packages\poetry\vcs\git\backend.py:201 in _fetch_remote_refs
199│
200│ with local:
→ 201│ result: FetchPackResult = client.fetch(
202│ path,
203│ local,
1 ~\AppData\Roaming\pypoetry\venv\lib\site-packages\dulwich\client.py:837 in fetch
835│ f, commit, abort = target.object_store.add_pack()
836│ try:
→ 837│ result = self.fetch_pack(
838│ path,
839│ determine_wants,
HangupException
d\\rruiter@github.com: Permission denied (publickey).
at ~\AppData\Roaming\pypoetry\venv\lib\site-packages\dulwich\client.py:1151 in fetch_pack
1147│ with proto:
1148│ try:
1149│ refs, server_capabilities = read_pkt_refs(proto.read_pkt_seq())
1150│ except HangupException as exc:
→ 1151│ raise _remote_error_from_stderr(stderr) from exc
1152│ (
1153│ negotiated_capabilities,
1154│ symrefs,
1155│ agent,
About this issue
- Original URL
- State: open
- Created 2 years ago
- Comments: 21 (15 by maintainers)
Glancing over the comments here, it looks like the cause was a mix of two things: an invalidly formatted URL and lack of dumb remote repository support in dulwich (masked by incorrect handling of a missing Content-Type header).
The None Content-Type is an error handling bug; I agree Dulwich should raise a different exception, but it’s not the root cause of the issues @rruiter87 is hitting
https://git.bues.ch/git/crcgen.git/
is what stood out to me specifically, however, I did not realize it was a public repo; my bad. It looks like this is a submodule using the ‘dumb’ HTTP transport – I’m honestly not sure if Dulwich supports dumb HTTP as it’s generally considered deprecated, but it helps that everything is publicly visible.SSH no, HTTPS yes
I set the option with
SSH 🔴
HTTPS 🟢