Dulwich does not support Dumb Git transport
See original GitHub issue- 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 (
-vvvoption) 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,
Issue Analytics
- State:
- Created 10 months ago
- Comments:21 (15 by maintainers)
Top Results From Across the Web
Python implementation of Git — dulwich 0.20.46 documentation
It aims to provide an interface to git repos (both local and remote) that doesn't call out to git directly but instead uses...
Read more >Python implementation of Git — dulwich 0.19.12 documentation
This is the Dulwich project. It aims to provide an interface to git repos (both local and remote) that doesn't call out to...
Read more >Transfer Protocols - Git SCM
This protocol is called “dumb” because it requires no Git-specific code on the server side during the transport process; the fetch process is...
Read more >dulwich Documentation
This is the Dulwich project. It aims to provide an interface to git repos (both local and remote) that doesn't call out to...
Read more >dulwich-users team mailing list archive - ListHelp
[PATCH] Allow accessing invalidly named refs, but don't allow ... 1) - return transport(host), "/"+path - # if its not git or git+ssh, ......
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
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