Code Monkey home page Code Monkey logo

winloop's Introduction

Code style: black

Winloop

An Alternative library for uvloop compatibility with windows because let's face it. Window's python asyncio standard libaray is garabage escpecially when Windows Defender decides to eat half your ram. I never really liked the fact that I couldn't make anything run faster escpecially when you have fiber internet connections in place and you've done all the optimizations you could possibly think of. It always felt disappointing when libuv is available for windows but windows was never compatible with uvloop.

Because nobody was willing to step in after so many years of waiting, I went ahead and downloaded the source code for uvloop and started modifying the source code to be windows compatible by carefully removing and changing parts that were not made for windows. Many hours of research went into making this library exist.

The differences with uvloop is that forking has been fully disabled and some smaller api calls had to be changed, error handling has been carefully modified and subprocesses instead release the gil instead of forking out...

There is a performance increase of about 5 times vs using the WindowsSelectorEventLoopPolicy and WindowsProactorEventLoopPolicy which have been known to trigger ssl problems in python 3.9. Winloop is a very good replacement for solving those ssl problem as well. This library also has comparable performance to it's brother uvloop.

How to install Winloop on your Windows Operating System

pip install winloop

You can also clone the reposity and build the extension yourself by running the command below if you wish to use or build this library locally, Note that you will need Cython and The Visual C++ extensions to compile this library on your own.

python setup.py build_ext --inplace

Issues Reporting

If you find any bugs with this library be sure to open up an issue to our github repo. Me and other contributors will be happy try to help you figure out and diagnose your problems.

Making pull requests

We encourage anyone to make pull-requests to winloop from spelling mistakes to vulnerability patches. Every little bit helps keep this library maintained and alive. Make sure that you are able to compile the library with the steps shown above. We plan to implement a nightly workflow to verify one's pull request in the future.

try:
    import aiohttp
    import aiohttp.web
except ImportError:
    skip_tests = True
else:
    skip_tests = False

import asyncio
import unittest
import weakref
import winloop
import sys

class TestAioHTTP(unittest.TestCase):
    def __init__(self, methodName: str = "test_aiohttp_basic_1") -> None:
        super().__init__(methodName)


    def setUp(self):
        self.loop = asyncio.get_event_loop()

    def test_aiohttp_basic_1(self):
        PAYLOAD = '<h1>It Works!</h1>' * 10000

        async def on_request(request):
            return aiohttp.web.Response(text=PAYLOAD)

        asyncio.set_event_loop(self.loop)
        app = aiohttp.web.Application()
        app.router.add_get('/', on_request)

        runner = aiohttp.web.AppRunner(app)
        self.loop.run_until_complete(runner.setup())
        site = aiohttp.web.TCPSite(runner, '0.0.0.0', '10000')
        self.loop.run_until_complete(site.start())
        port = site._server.sockets[0].getsockname()[1]

        async def test():
            # Make sure we're using the correct event loop.
            self.assertIs(asyncio.get_event_loop(), self.loop)

            for addr in (('localhost', port),
                         ('127.0.0.1', port)):
                async with aiohttp.ClientSession() as client:
                    async with client.get('http://{}:{}'.format(*addr)) as r:
                        self.assertEqual(r.status, 200)
                        result = await r.text()
                        self.assertEqual(result, PAYLOAD)

        self.loop.run_until_complete(test())
        self.loop.run_until_complete(runner.cleanup())

    def test_aiohttp_graceful_shutdown(self):
        async def websocket_handler(request):
            ws = aiohttp.web.WebSocketResponse()
            await ws.prepare(request)
            request.app['websockets'].add(ws)
            try:
                async for msg in ws:
                    await ws.send_str(msg.data)
            finally:
                request.app['websockets'].discard(ws)
            return ws

        async def on_shutdown(app):
            for ws in set(app['websockets']):
                await ws.close(
                    code=aiohttp.WSCloseCode.GOING_AWAY,
                    message='Server shutdown')

        asyncio.set_event_loop(self.loop)
        app = aiohttp.web.Application()
        app.router.add_get('/', websocket_handler)
        app.on_shutdown.append(on_shutdown)
        app['websockets'] = weakref.WeakSet()

        runner = aiohttp.web.AppRunner(app)
        self.loop.run_until_complete(runner.setup())
        site = aiohttp.web.TCPSite(runner, '0.0.0.0', '10000')
        self.loop.run_until_complete(site.start())
        port = site._server.sockets[0].getsockname()[1]

        async def client():
            async with aiohttp.ClientSession() as client:
                async with client.ws_connect(
                        'http://127.0.0.1:{}'.format(port)) as ws:
                    await ws.send_str("hello")
                    async for msg in ws:
                        assert msg.data == "hello"

        client_task = asyncio.ensure_future(client())

        async def stop():
            await asyncio.sleep(0.1)
            try:
                await asyncio.wait_for(runner.cleanup(), timeout=0.1)
            except Exception as e:
                print(e)
            finally:
                try:
                    client_task.cancel()
                    await client_task
                except asyncio.CancelledError:
                    pass

        self.loop.run_until_complete(stop())



if __name__ == "__main__":
    # print("tesing without winloop")
    # asyncio.DefaultEventLoopPolicy = asyncio.WindowsSelectorEventLoopPolicy
    # asyncio.DefaultEventLoopPolicy = asyncio.WindowsProactorEventLoopPolicy
    unittest.main()
    # Looks like winloop might be 3x faster than the Proctor Event Loop , THAT's A HUGE IMPROVEMENT!
    print("testing again but with winloop enabled")
    winloop.install()
    unittest.main()

The benchmarks for the code above are as follows

Benchmarks

TCP Connections


Asyncio Event Loop Policy Time (in Seconds)
WinLoopPolicy 0.493s
WindowsProactorEventLoopPolicy 2.510s
WindowsSelectorEventLoopPolicy 2.723s

That's a massive increase and jump from just TCP alone I'll be posting more benchmarks soon as I modify more of the current test suites made by uvloop...

How to Use Winloop with Fastapi

This was a cool little script I put together Just to make fastapi that much faster to handle

# TODO this code example is deprecated
from fastapi import FastAPI
from fastapi.responses import HTMLResponse
import winloop
import uvicorn
import asyncio
import datetime

app = FastAPI()

@app.on_event("startup")
def make_assertion():
    # Check to make sure that we bypassed the original eventloop Policy....
    assert isinstance(asyncio.get_event_loop_policy(), winloop.WinLoopPolicy)


@app.get("/test")
async def test_get_request():
    return HTMLResponse("<html><body><h1>FAST API WORKS WITH WINLOOP!</h1></body></html>")


# starllete will use asyncio.to_thread() so that this can remain asynchronous
@app.get("/date")
def test_dynamic_response():
    return str(datetime.datetime.now())


# Although tricky to pass and is not normal, it does in fact work...
if __name__ == "__main__":
    winloop.install()
    # Winloop's eventlooppolicy will be passed to uvicorn after this point...
    loop = asyncio.get_event_loop()
    config = uvicorn.Config(app=app,port=10000,loop=loop)
    server = uvicorn.Server(config)
    asyncio.run(server.serve())

How To Use Winloop When Uvloop is not available

# Here's A small Example of using winloop when uvloop is not available to us
import sys
import aiohttp
import asyncio

async def main():
    async with aiohttp.ClientSession("https://httpbin.org") as client:
        async with client.get("/ip") as resp:
            print(await resp.json())

if __name__ == "__main__":
    if sys.platform in ('win32', 'cygwin', 'cli'):
        from winloop import run
    else:
        # if we're on apple or linux do this instead
        from uvloop import run
    run(main())

TODO-List

  • Update Fastapi Example to a more recent version of fastapi

  • Contact uvicorn about this issue I have a funny feeling something is going on here...

  • Nightly Builds And Test Suite Workflows for anyone wanting to use newer unreleased versions.

  • Drop All DEF Macros, I'm currently seeking help on replacements for macros where all the variables are known about at compile-time

  • Adding in the necessary hooks for pyinstaller to compile this fast library to executable code even though hooks have been known to inflate the size of the .exe files. This is because calling hidden-imports for all the __init__.py modules might annoy some developers. (Luckily I'm aware of this issue because I've been doing this myself...)

  • write a workflow for compiling libuv on different versions of windows when distributing out pypi wheels.

  • write a workflow for nightly builds if necessary for verification of pull requests.

  • Sphinx Styled Documentation (Maybe I'm thinking about it...)

  • Update benchmarks (They are old) can't believe I maintained this project for over a year now...

Videos

Contributing

I put my heart and soul into this library ever since it began and any help is apperciated and means a lot to me.

winloop's People

Contributors

finbird avatar jdeokkim avatar lschoe avatar vizonex avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

winloop's Issues

UV_EAGAIN (errno 4088) related to high/low watermarks.

This issue is about the second problem mentioned in issue #12.

The problem seems to be related to the current flow control implementation in Winloop 0.1.0. An UV_EAGAIN (errno 4088) occurs when handling larger volumes of data exchanges. The problem is not present with any of the other event loops (asyncio's proactor, selector, nor with uvloop).

You can reproduce the problem running, e.g., the np_lpsolver demo for the MPyC package. The following code is from the latest version MPyC v0.9.7 on GitHub, see mpyc/asyncoro.py. This is inside the connection_made(transport) method:

        if 'winloop' in str(self.runtime._loop):
            # Workaround to avoid problems with handling of high/low watermarks when
            # running MPyC demos with large communication complexity.
            # For example, "python np_lpsolver.py -i5 -M3 -E1"
            # gives "OSError: [Errno 4088] Unknown error"  (4088 stands for UV_EAGAIN).
            # Winloop 0.1.0 default setting, with FLOW_CONTROL_HIGH_WATER = 64:
            #   high = 65536 = FLOW_CONTROL_HIGH_WATER * 1024
            #   low  = 16    = FLOW_CONTROL_HIGH_WATER // 4
            # Workaround:
            self.transport.set_write_buffer_limits(high=2**18)
            # With high=2**18, problem still present for cases with even larger communication
            # complexity, like "python np_lpsolver.py -i7 -M3 -E1", and setting
            # high=2**22 resolves this case as well.
            # Alternative workaround: set high=0 to disable use of high/low watermarks.
            # NB: these workarounds do not work with SSL,
            # for example, "python np_lpsolver.py -i5 -M3 -E1 --ssl"
            # keeps giving "OSError: [Errno 4088] Unknown error" whatever we set for high and low.
            print(f'workaround for Winloop: {self.transport.get_write_buffer_limits()=}')

Using python np_lpsolver.py -i5 -M3 -E1 in mpyc/demos runs the demo between three parties on localhost using Winloop. If the default flow control settings are used, all parties will get a 4088 error. If the high watermark is increased from 2**16 to 2**18, the problem disappears. The problem also disappears by setting high=0. But, interestingly, these workarounds do not work with SSL.

Winloop is not work in uvicorn multiprocessing

In uvicorn, I have added a new file โ€œwinloop.pyโ€.
image
uvicorn/config.py:
image

Next:
from uvicorn import run
run("app_compat:create_app_fastapi", host="0.0.0.0",
workers=int(args["workers"]),
port=int(port),
loop="winloop",
factory=True)

Result:
image
Pid is 23052 and 4604.

Just,It is only running on PID 4604.

Inconsistent behavior with standard input

I have my simple console echoing script. (python3.12)
If I run this using pycharm's run configuration this works normally echoing the console input back to stdout. However any other running configuration fails. e.g) vscode, python3 my.py ... etc

However, if I use Path('CONIN$').open instead of os.dup any case fails with the same exception.

import asyncio
import sys
from io import TextIOWrapper, FileIO
from typing import TextIO

import winloop
from sys import stdin
import os
from pathlib import Path

async def main():
    loop = asyncio.get_running_loop()
    reader = asyncio.StreamReader(loop=loop)
    
    with FileIO(os.dup(sys.stdin.fileno())) as fileInput:
    # with Path("CONIN$").open() as fileInput:
        transport, protocol = await loop.connect_read_pipe(
            lambda : asyncio.StreamReaderProtocol(stream_reader=reader,loop=loop),
            pipe=fileInput
        )
        try:
            while not reader.at_eof():
                line = (await reader.readline()).decode().rstrip()
                print(line)
        finally:
            transport.close()
if __name__ == '__main__':    
    asyncio.run(main(), debug=True, loop_factory=winloop.new_event_loop)
(.venv) C:\Users\pbk\PycharmProjects\pythonProject>.\.venv\Scripts\python.exe foo.py
Traceback (most recent call last):
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.12_3.12.1008.0_x64__qbz5n2kfra8p0\Lib\asyncio\runners.py", line 194, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.12_3.12.1008.0_x64__qbz5n2kfra8p0\Lib\asyncio\runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "winloop\\loop.pyx", line 1556, in winloop.loop.Loop.run_until_complete
  File "C:\Users\pbk\PycharmProjects\pythonProject\foo.py", line 21, in main
    transport, protocol = await loop.connect_read_pipe(
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "winloop\\loop.pyx", line 2889, in connect_read_pipe
  File "winloop\\loop.pyx", line 2882, in winloop.loop.Loop.connect_read_pipe
  File "winloop\\handles/pipe.pyx", line 133, in winloop.loop.ReadUnixTransport._open
  File "winloop\\handles/pipe.pyx", line 35, in winloop.loop.__pipe_open
IsADirectoryError: [Errno 21] illegal operation on a directory

IsADirectoryError is not a correct error for this situation

proxy tls error

env_.venv\Lib\site-packages\aiohttp\connector.py:942: RuntimeWarning: An HTTPS request is being sent through an HTTPS proxy. This support for TLS in TLS is known to be disabled in the stdlib asyncio (Python <3.11). This is why you'll probably see an error in the log below.

It is possible to enable it via monkeypatching. For more details, see:

You can temporarily patch this as follows:

Connecting to an https site via an http proxy, how to fix this error?

Strange side-effect on help()

Hi, here's a thing I noticed a while ago when using the Python REPL in combination with winloop.

The problem is that certain calls to the built-in help() function don't work anymore, something to do with a redirection of stdout maybe.

import asyncio
from winloop import EventLoopPolicy
asyncio.set_event_loop_policy(EventLoopPolicy())  # 1st critical line for the problem to occur

print('1' * 80)    
help(pow)  # prints just fine
print('1' * 80)

asyncio.get_event_loop()  # 2nd critical line for the problem to occur

print('2' * 80)    
help(pow)  # only prints a blank line
print('2' * 80)

Running this code will produce:

11111111111111111111111111111111111111111111111111111111111111111111111111111111
Help on built-in function pow in module builtins:

pow(base, exp, mod=None)
    Equivalent to base**exp with 2 arguments or base**exp % mod with 3 arguments

    Some types, such as ints, are able to use a more efficient algorithm when
    invoked using the three argument form.

11111111111111111111111111111111111111111111111111111111111111111111111111111111
22222222222222222222222222222222222222222222222222222222222222222222222222222222

22222222222222222222222222222222222222222222222222222222222222222222222222222222

By omitting either (or both) critical lines, the problem disappears, and the help(pow) message will be printed in twice.

The actual use case for this problem is when I run the Python REPL using winloop (in combination with MPyC), which looks like this:

>python -m mpyc
asyncio REPL 3.11.8 (tags/v3.11.8:db85d51, Feb  6 2024, 22:03:32) [MSC v.1937 64 bit (AMD64)] on win32
Use "await" directly instead of "asyncio.run()".
Type "help", "copyright", "credits" or "license" for more information.
>>> import asyncio
>>> from mpyc.runtime import mpc
>>> secint = mpc.SecInt()
>>> secfxp = mpc.SecFxp()
>>> secflt = mpc.SecFlt()
>>> secfld127 = mpc.SecFld(127)
>>> secfld256 = mpc.SecFld(2**8)
>>> secsym = mpc.SecSymmetricGroup(5)
>>> secqr = mpc.SecQuadraticResidues(11)
>>> secsg = mpc.SecSchnorrGroup(l=1024)
>>> secec = mpc.SecEllipticCurve('Ed25519')
>>> seccl = mpc.SecClassGroup(-23)
>>> help(pow)

>>>

By disabling the use of winloop the problem disappears. Also, the problem does not occur on Linux using uvloop.

Do you have a clue about the cause? Something "bad" happens in the C(ython) code executed for the asyncio.get_event_loop() call.

import issue when freezing scripts

when freezing the script

import winloop
import asyncio

async def hello():
    print("Hello")

async def main():
    tasks = []
    for i in range(10):
        tasks.append(hello())
    await asyncio.gather(*tasks)

if __name__ == '__main__':
    winloop.install()
    asyncio.run(main())

with pyinstaller with the following option pyinstaller --onefile main.py and nuitka with nuitka --onefile --remove-output main.py
both the frozen pyinstaller exe and the compiled nuitka exe return errors along the lines of

Traceback (most recent call last):
  File "main.py", line 1, in <module>
    import winloop
  File "PyInstaller\loader\pyimod02_importers.py", line 391, in exec_module
  File "winloop\__init__.py", line 7, in <module>
  File "winloop\\loop.pyx", line 30, in init winloop.loop
ImportError: cannot import name _noop
[9352] Failed to execute script 'main' due to unhandled exception!
``` for pyinstaller and ```
Traceback (most recent call last):
  File "C:\Users\Divine\AppData\Local\Temp\ONEFIL~1\main.py", line 1, in <module>
    import winloop

  File "C:\Users\Divine\AppData\Local\Temp\ONEFIL~1\winloop\__init__.py", line 7, in <module winloop>
  File "winloop\\loop.pyx", line 30, in init winloop.loop
ImportError: cannot import name _noop``` for nuitka, the same commands work to freeze uvloop into executable files in linux.

Seemingly spurious UV_EOF (errno 4095) upon closing TCP connection.

Hi, I've been testing Winloop and I was happy to see similar performance speedups on Windows as for uvloop on Linux. Really nice!

To get full functionality for my application I had to use two simple workarounds though, to fix two problems with Winloop 0.1.0.

The first problem happens upon closing a TCP connection. An error UV_EOF occurs on one side of the connection. The workaround is to simply ignore this exception. This error does not happen with any of the other event loops (asyncio's proactor, selector, nor with uvloop).

You can reproduce the problem running the simplest demo for the MPyC package. The following code is from the latest version MPyC v0.9.7 on GitHub, see mpyc/asyncoro.py. This is inside the connection_lost(exc) method:

          if 'winloop' in str(self.runtime._loop):
              # Workaround to suppress seemingly spurious UV_EOF (4095) exception from winloop.
              # For example, "python helloworld.py -M2 --output-file -E1"
              # creates a file "party2_1.log" with the error present.
              # Does not happen over SSL, which makes sense as for SSL
              # self.transport.can_write_eof() == False.
              if exc.errno == 4095:  # NB: exc is an OSError in Winloop 0.1.0
                  print(f'suppressed UV_EOF error in connection_lost(): {type(exc)=} {exc=}')
              else:
                  raise exc

Using python helloworld.py -M2 --output-file -E1 in mpyc/demos runs the demo between two parties on localhost. Party 0 experiences no problems, but party 1 will get the 4095 error upon closing the TCP connection. The file party2_1.log created will show the error in its last line. (Note that party 1 used a server listening for incoming connections from party 0, so party 0 acts as client and party 1 as server.)

The problem does not happen when using SSL, which makes sense as an SSL transport has can_write_eof() == False.

Do you have any idea what causes this problem?

For the other problem I'll open a separate issue.

Workflow to upload wheels are still broken

Unfortunately I do not have the time that I used to fix such a problem and I will be looking for others to help with fixing the uploading portion. This is due to the fact that uploading the wheels and having proper tutorials for workflows is vague. If anyone wants to fix this give me a ping with @Vizonex and I'll be sure to chat with you about the problem... If we find such a tutorial on uploading the pypi wheels this will save a lot of windows computers the unwanted space of having to download the C/C++ stuff from Visual studio...

Can this be used on local apps?

By local apps, I mean asynchronous tasks where the I/O bottleneck is local (eg reading/saving from/to disk)? For example, I created a program that converts image formats, and the relevant part is shown below:

dir_ls = os.listdir(path_outer)
file_list = [path_outer + '\\' + e for e in dir_ls]

try:
    os.mkdir(path_outer + '\\' + 'converted')
except FileExistsError:
    pass
await asyncio.gather(*(asyncio.to_thread(file_convert, e, fmt, batch=True, count=i) for i, e in enumerate(file_list, start=1)))

Does Winloop has something akin to the .to_thread() method or is this exclusively meant to be used for web projects?

Conditional Variables will soon be deprecated soon any workarounds?

I have spoken to Scoder one of the Cython developers and It seems I have no response for solving the Macro issue Does anyone have any ideas or workarounds to this where we would be able to keep the keywords in the script because otherwise we will have more problems in the future with future updates and we don't want for that to happen. If anyone can fork this repo and come up with a solution please reply to me about it. I do have one idea but it would be a pain because we would have to replace all the numbers but then telling people what they are would be a pain to implement (which implies that we would need More Documentation in the long run...) with DEF gone we need a clear and ALL-Out solution to this issue because uvloop is in the same boat as us...

TypeError: no default __reduce__ due to non-trivial __cinit__

https://aiomultiprocess.omnilib.dev/en/latest/guide.html#using-uvloop

code:

async def fetch_detail(url: str, pool: aiomultiprocess.Pool):
    async with aiohttp.ClientSession() .get(url) as response:
        html = await response.text()
        return html

async def aiomultiprocess_main():
    main_url = "http://am.adianshi.com:6805/"
    async with aiomultiprocess.Pool(loop_initializer=winloop.new_event_loop()) as pool:
        task = pool.apply(fetch_detail, args=(main_url, pool))
        html=await task
        print(html)

if __name__ == "__main__":
    asyncio.run(aiomultiprocess_main())

It report error:

C:\ProgramData\anaconda3\envs\python311\python.exe C:\Users\Administrator\Personal_scripts\pythonProject\temp.py 
Traceback (most recent call last):
  File "C:\Users\Administrator\Personal_scripts\pythonProject\temp.py", line 60, in <module>
    asyncio.run(aiomultiprocess_main())
  File "C:\ProgramData\anaconda3\envs\python311\Lib\asyncio\runners.py", line 190, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "C:\ProgramData\anaconda3\envs\python311\Lib\asyncio\runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\ProgramData\anaconda3\envs\python311\Lib\asyncio\base_events.py", line 654, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "C:\Users\Administrator\Personal_scripts\pythonProject\temp.py", line 54, in aiomultiprocess_main
    async with aiomultiprocess.Pool(loop_initializer=winloop.new_event_loop()) as pool:
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\ProgramData\anaconda3\envs\python311\Lib\site-packages\aiomultiprocess\pool.py", line 186, in __init__
    self.init()
  File "C:\ProgramData\anaconda3\envs\python311\Lib\site-packages\aiomultiprocess\pool.py", line 214, in init
    self.processes[self.create_worker(qid)] = qid
                   ^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\ProgramData\anaconda3\envs\python311\Lib\site-packages\aiomultiprocess\pool.py", line 261, in create_worker
    process.start()
  File "C:\ProgramData\anaconda3\envs\python311\Lib\site-packages\aiomultiprocess\core.py", line 156, in start
    return self.aio_process.start()
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\ProgramData\anaconda3\envs\python311\Lib\multiprocessing\process.py", line 121, in start
    self._popen = self._Popen(self)
                  ^^^^^^^^^^^^^^^^^
  File "C:\ProgramData\anaconda3\envs\python311\Lib\multiprocessing\context.py", line 336, in _Popen
    return Popen(process_obj)
           ^^^^^^^^^^^^^^^^^^
  File "C:\ProgramData\anaconda3\envs\python311\Lib\multiprocessing\popen_spawn_win32.py", line 95, in __init__
    reduction.dump(process_obj, to_child)
  File "C:\ProgramData\anaconda3\envs\python311\Lib\multiprocessing\reduction.py", line 60, in dump
    ForkingPickler(file, protocol).dump(obj)
  File "<stringsource>", line 2, in winloop.loop.Loop.__reduce_cython__
TypeError: no default __reduce__ due to non-trivial __cinit__

[Request] Creating CI workflow file to build wheels to support different arch and py ver.

Hello Vizonex, I found this project very useful for me.
I request your help to creating a CI workflow file to automate the build process for wheels, including support for win32 and different py ver(py3.9-py3.12?). This would greatly benefit users who are running systems with 32-bit Windows architecture without building it by themselves. Thank you for your work!

unable to compile

I am trying to install winloop and fail:
winloop from sources 0.0.7.2
python 3.10
pip 23.2
conda
cython 3.0.0
Win 10.

When calling python setup.py build_ext --inplace I get error (trace below).
same error when installing by pip install winloop. just it gets einloop 0.0.6/

(py10) C:\petals\winloop>python setup.py build_ext --inplace
Compiling winloop\loop.pyx because it changed.
[1/1] Cythonizing winloop\loop.pyx
warning: winloop\includes/consts.pxi:1:0: The 'DEF' statement is deprecated and will be removed in a future Cython version. Consider using global variables, constants, and in-place literals instead. See cython/cython#4310
warning: winloop\includes/consts.pxi:3:0: The 'DEF' statement is deprecated and will be removed in a future Cython version. Consider using global variables, constants, and in-place literals instead. See cython/cython#4310
warning: winloop\includes/consts.pxi:4:0: The 'DEF' statement is deprecated and will be removed in a future Cython version. Consider using global variables, constants, and in-place literals instead. See cython/cython#4310
warning: winloop\includes/consts.pxi:5:0: The 'DEF' statement is deprecated and will be removed in a future Cython version. Consider using global variables, constants, and in-place literals instead. See cython/cython#4310
warning: winloop\includes/consts.pxi:7:0: The 'DEF' statement is deprecated and will be removed in a future Cython version. Consider using global variables, constants, and in-place literals instead. See cython/cython#4310
warning: winloop\includes/consts.pxi:8:0: The 'DEF' statement is deprecated and will be removed in a future Cython version. Consider using global variables, constants, and in-place literals instead. See cython/cython#4310
warning: winloop\includes/consts.pxi:10:0: The 'DEF' statement is deprecated and will be removed in a future Cython version. Consider using global variables, constants, and in-place literals instead. See cython/cython#4310
warning: winloop\includes/consts.pxi:13:0: The 'DEF' statement is deprecated and will be removed in a future Cython version. Consider using global variables, constants, and in-place literals instead. See cython/cython#4310
warning: winloop\includes/consts.pxi:16:0: The 'DEF' statement is deprecated and will be removed in a future Cython version. Consider using global variables, constants, and in-place literals instead. See cython/cython#4310
warning: winloop\includes/consts.pxi:21:0: The 'DEF' statement is deprecated and will be removed in a future Cython version. Consider using global variables, constants, and in-place literals instead. See cython/cython#4310
warning: winloop\includes/consts.pxi:24:0: The 'DEF' statement is deprecated and will be removed in a future Cython version. Consider using global variables, constants, and in-place literals instead. See cython/cython#4310
warning: winloop\includes/consts.pxi:25:0: The 'DEF' statement is deprecated and will be removed in a future Cython version. Consider using global variables, constants, and in-place literals instead. See cython/cython#4310
warning: winloop\includes/consts.pxi:1:0: The 'DEF' statement is deprecated and will be removed in a future Cython version. Consider using global variables, constants, and in-place literals instead. See cython/cython#4310
warning: winloop\includes/consts.pxi:3:0: The 'DEF' statement is deprecated and will be removed in a future Cython version. Consider using global variables, constants, and in-place literals instead. See cython/cython#4310
warning: winloop\includes/consts.pxi:4:0: The 'DEF' statement is deprecated and will be removed in a future Cython version. Consider using global variables, constants, and in-place literals instead. See cython/cython#4310
warning: winloop\includes/consts.pxi:5:0: The 'DEF' statement is deprecated and will be removed in a future Cython version. Consider using global variables, constants, and in-place literals instead. See cython/cython#4310
warning: winloop\includes/consts.pxi:7:0: The 'DEF' statement is deprecated and will be removed in a future Cython version. Consider using global variables, constants, and in-place literals instead. See cython/cython#4310
warning: winloop\includes/consts.pxi:8:0: The 'DEF' statement is deprecated and will be removed in a future Cython version. Consider using global variables, constants, and in-place literals instead. See cython/cython#4310
warning: winloop\includes/consts.pxi:10:0: The 'DEF' statement is deprecated and will be removed in a future Cython version. Consider using global variables, constants, and in-place literals instead. See cython/cython#4310
warning: winloop\includes/consts.pxi:13:0: The 'DEF' statement is deprecated and will be removed in a future Cython version. Consider using global variables, constants, and in-place literals instead. See cython/cython#4310
warning: winloop\includes/consts.pxi:16:0: The 'DEF' statement is deprecated and will be removed in a future Cython version. Consider using global variables, constants, and in-place literals instead. See cython/cython#4310
warning: winloop\includes/consts.pxi:21:0: The 'DEF' statement is deprecated and will be removed in a future Cython version. Consider using global variables, constants, and in-place literals instead. See cython/cython#4310
warning: winloop\includes/consts.pxi:24:0: The 'DEF' statement is deprecated and will be removed in a future Cython version. Consider using global variables, constants, and in-place literals instead. See cython/cython#4310
warning: winloop\includes/consts.pxi:25:0: The 'DEF' statement is deprecated and will be removed in a future Cython version. Consider using global variables, constants, and in-place literals instead. See cython/cython#4310
warning: winloop\handles/stream.pyx:3:0: The 'DEF' statement is deprecated and will be removed in a future Cython version. Consider using global variables, constants, and in-place literals instead. See cython/cython#4310
warning: winloop\handles/process.pyx:364:0: The 'DEF' statement is deprecated and will be removed in a future Cython version. Consider using global variables, constants, and in-place literals instead. See cython/cython#4310
warning: winloop\handles/process.pyx:365:0: The 'DEF' statement is deprecated and will be removed in a future Cython version. Consider using global variables, constants, and in-place literals instead. See cython/cython#4310
warning: winloop\handles/process.pyx:366:0: The 'DEF' statement is deprecated and will be removed in a future Cython version. Consider using global variables, constants, and in-place literals instead. See cython/cython#4310
warning: winloop\handles/process.pyx:367:0: The 'DEF' statement is deprecated and will be removed in a future Cython version. Consider using global variables, constants, and in-place literals instead. See cython/cython#4310
warning: winloop\handles/udp.pyx:351:8: The 'IF' statement is deprecated and will be removed in a future Cython version. Consider using runtime conditions or C macros instead. See cython/cython#4310

Error compiling Cython file:

...

cdef _call_later(self, uint64_t delay, object callback, object args,
                 object context):
    return TimerHandle(self, callback, args, delay, context)

cdef void _handle_exception(self, object ex):
     ^

winloop\loop.pyx:719:9: Signature not compatible with previous declaration

Error compiling Cython file:

...
cdef _call_soon_handle(self, Handle handle)

cdef _call_later(self, uint64_t delay, object callback, object args,
                 object context)

cdef void _handle_exception(self, object ex) noexcept
                           ^

winloop\loop.pxd:149:31: Previous declaration is here
warning: winloop\handles/basetransport.pyx:214:9: Compatible but non-identical C method '_is_reading' not redeclared in definition part of extension type 'UVBaseTransport'. This may cause incorrect vtables to be generated.
warning: winloop\handles/basetransport.pxd:54:25: Previous declaration is here
warning: winloop\handles/stream.pyx:284:9: Compatible but non-identical C method '_is_reading' not redeclared in definition part of extension type 'UVStream'. This may cause incorrect vtables to be generated.
warning: winloop\handles/basetransport.pxd:54:25: Previous declaration is here
warning: winloop\handles/udp.pyx:135:9: Compatible but non-identical C method '_is_reading' not redeclared in definition part of extension type 'UDPTransport'. This may cause incorrect vtables to be generated.
warning: winloop\handles/basetransport.pxd:54:25: Previous declaration is here

Error compiling Cython file:

...
# === overloads ===

cdef _new_socket(self)
cdef size_t _get_write_buffer_size(self) noexcept

cdef bint _is_reading(self)
                     ^

winloop\handles/basetransport.pxd:54:25: C method '_is_reading' is declared but not defined
Traceback (most recent call last):
File "C:\petals\winloop\setup.py", line 91, in
do_installation()
File "C:\petals\winloop\setup.py", line 57, in do_installation
ext_modules=cythonize(ext),
File "c:\conda\envs\py10\lib\site-packages\Cython\Build\Dependencies.py", line 1134, in cythonize
cythonize_one(*args)
File "c:\conda\envs\py10\lib\site-packages\Cython\Build\Dependencies.py", line 1301, in cythonize_one
raise CompileError(None, pyx_file)
Cython.Compiler.Errors.CompileError: winloop\loop.pyx

python3.12 fail to close asyncio.Runner

Traceback (most recent call last):
  File "C:\Users\pbk\PycharmProjects\pythonProject\foo.py", line 30, in <module>
    asyncio.run(main(), debug=True, loop_factory=winloop.new_event_loop)
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.12_3.12.1008.0_x64__qbz5n2kfra8p0\Lib\asyncio\runners.py", line 193, in run
    with Runner(debug=debug, loop_factory=loop_factory) as runner:
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.12_3.12.1008.0_x64__qbz5n2kfra8p0\Lib\asyncio\runners.py", line 62, in __exit__
    self.close()
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.12_3.12.1008.0_x64__qbz5n2kfra8p0\Lib\asyncio\runners.py", line 73, in close
    loop.shutdown_default_executor(constants.THREAD_JOIN_TIMEOUT))
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: shutdown_default_executor() takes exactly 0 positional arguments (1 given)

winloop.shutdown_default_executor takes 0 argument while asyncio.Runner.close expect to pass argument to the loop.shutdown_default_executor

support for TLS in TLS Warning

using aiohttp with an http proxy with an https request shows an
path\to\venv\Lib\site-packages\aiohttp\connector.py:899: RuntimeWarning: An HTTPS request is being sent through an HTTPS proxy. This support for TLS in TLS is known to be disabled in the stdlib asyncio. This is why you'll probably see an error in the log below.
this warning only shows when i install the winloop event policy

import winloop
import aiohttp
import asyncio


async def make_request():
    async with aiohttp.ClientSession() as session:
        async with session.get("https://www.google.com", proxy="http://ip:port") as response:
            print(response.status)


if __name__ == "__main__":
    winloop.install()
    asyncio.run(make_request())

if i comment out the winloop.install() then i don't get the error with the same code
image
image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.