MagicStack / MagicStack/uvloop
OSError: [Errno 6] No such device or address: '/proc/self/fd/1' when using asyncio.create_subprocess_*
Dieses Issue hat noch niemand übernommen.
- Vorherrschende Sprache
- Cython
- Sterne
- 11.9k
- Forks
- 616
- PR-Merge-Kennzahlen
- Keine gemergten PRs in 30 T.
Beschreibung
- uvloop==0.16.0 and uvloop==0.17.0:
- python3.8.10 and python3.10.5:
- Platform: Ubuntu20.04:
- Can you reproduce the bug with
PYTHONASYNCIODEBUGin env? -> Yes, but there is not more output: - Does uvloop behave differently from vanilla asyncio? How? It uses socket instead of pipe for the file descriptors of the subprocess. This gives me an OSError6:
Uvloop does not handle subprocess pipes properly. It doesn not matter if I use asyncio.subprocess.PIPE or subprocess.PIPE. How can I access stdout/stderr of a asyncio subprocess? Is this behavior intended?
Running the proof of concept:
import asyncio, subprocess
async def poc():
proc = await asyncio.create_subprocess_shell(
"ls -lsh /proc/self/fd",
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
)
stdout, stderr = await proc.communicate()
print(stdout, stderr)
proc = await asyncio.create_subprocess_shell(
"python3 -c \"f=open('/proc/self/fd/1', 'w'); f.write('test')\"", stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE
)
stdout, stderr = await proc.communicate()
print(stdout, stderr)
async def poc1():
proc = await asyncio.create_subprocess_shell(
"ls -lsh /proc/self/fd",
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
)
stdout, stderr = await proc.communicate()
print(stdout, stderr)
proc = await asyncio.create_subprocess_shell(
"python3 -c \"f=open('/proc/self/fd/1', 'w'); f.write('test')\"", stdout=subprocess.PIPE, stderr=subprocess.PIPE
)
stdout, stderr = await proc.communicate()
print(stdout, stderr)
print("Default loop")
asyncio.run(poc())
asyncio.run(poc1())
import uvloop
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
print("uvloop")
print("asyncio pipe")
asyncio.run(poc())
print("subprocess pipe")
asyncio.run(poc1())
Yields the following output:
Default loop
b'total 0\n0 lrwx------ 1 peter peter 64 Sep 22 12:19 0 -> /dev/pts/10\n0 l-wx------ 1 peter peter 64 Sep 22 12:19 1 -> pipe:[8435934]\n0 l-wx------ 1 peter peter 64 Sep 22 12:19 2 -> pipe:[8435935]\n0 lr-x------ 1 peter peter 64 Sep 22 12:19 3 -> /proc/625365/fd\n' b''
b'test' b''
b'total 0\n0 lrwx------ 1 peter peter 64 Sep 22 12:19 0 -> /dev/pts/10\n0 l-wx------ 1 peter peter 64 Sep 22 12:19 1 -> pipe:[8435942]\n0 l-wx------ 1 peter peter 64 Sep 22 12:19 2 -> pipe:[8435943]\n0 lr-x------ 1 peter peter 64 Sep 22 12:19 3 -> /proc/625371/fd\n' b''
b'test' b''
uvloop
asyncio pipe
b'total 0\n0 lrwx------ 1 peter peter 64 Sep 22 12:19 0 -> /dev/pts/10\n0 lrwx------ 1 peter peter 64 Sep 22 12:19 1 -> socket:[8435953]\n0 lrwx------ 1 peter peter 64 Sep 22 12:19 2 -> socket:[8435955]\n0 lr-x------ 1 peter peter 64 Sep 22 12:19 3 -> /proc/625376/fd\n' b''
b'' b'Traceback (most recent call last):\n File "<string>", line 1, in <module>\nOSError: [Errno 6] No such device or address: \'/proc/self/fd/1\'\n'
subprocess pipe
b'total 0\n0 lrwx------ 1 peter peter 64 Sep 22 12:19 0 -> /dev/pts/10\n0 lrwx------ 1 peter peter 64 Sep 22 12:19 1 -> socket:[8396454]\n0 lrwx------ 1 peter peter 64 Sep 22 12:19 2 -> socket:[8396456]\n0 lr-x------ 1 peter peter 64 Sep 22 12:19 3 -> /proc/625380/fd\n' b''
b'' b'Traceback (most recent call last):\n File "<string>", line 1, in <module>\nOSError: [Errno 6] No such device or address: \'/proc/self/fd/1\'\n'
As we can see, once uvloop is running the calls that worked earlier are crashing. The observable difference is that uvloop maps sockets to stdout/stderr whereas default asyncio uses pipes
Beitragsleitfaden
Für dieses Repository ist kein Beitragsleitfaden indexiert
Erste Schritte
- Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
- Forke das Repository und arbeite in einem Branch.
- Öffne einen Pull Request, der die Issue-Nummer nennt.
Rechercherichtung
Beginne damit, den bereitgestellten Proof of Concept mit vanilla asyncio und uvloop auszuführen, wobei der Fokus auf asyncio.create_subprocess_shell, der PIPE-Verarbeitung und uvloop.EventLoopPolicy liegt. Vergleiche die stdout- und stderr-Dateideskriptoren sowie die Fehlerausgabe; abgeschlossen ist dies, wenn das gemeldete Verhalten der Subprozess-Pipe verstanden ist und die Reproduktion nicht mehr den OSError erzeugt.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- python
- Bereich
- networking
- Issue-Typ
- Bug
- Schwierigkeit
- 4/5
- Geschätzter Aufwand
- 3-5 Tage
- Aktivitätsstatus
- Veraltet
- Klarheit
- Größtenteils klar
- Anfängerfreundlichkeit
- 38/100