winloop 0.1.4__tar.gz → 0.1.5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {winloop-0.1.4/winloop.egg-info → winloop-0.1.5}/PKG-INFO +26 -4
- winloop-0.1.5/pyproject.toml +79 -0
- winloop-0.1.5/setup.py +289 -0
- winloop-0.1.5/tests/test_fs_event.py +105 -0
- winloop-0.1.5/tests/test_pipes.py +304 -0
- winloop-0.1.5/tests/test_process.py +1047 -0
- winloop-0.1.5/tests/test_signals.py +470 -0
- winloop-0.1.5/tests/test_sockets.py +767 -0
- winloop-0.1.5/tests/test_tcp.py +3219 -0
- {winloop-0.1.4 → winloop-0.1.5}/winloop/__init__.py +1 -13
- {winloop-0.1.4 → winloop-0.1.5}/winloop/_testbase.py +4 -5
- {winloop-0.1.4 → winloop-0.1.5}/winloop/_version.py +1 -1
- {winloop-0.1.4 → winloop-0.1.5}/winloop/loop.c +14534 -12880
- {winloop-0.1.4 → winloop-0.1.5/winloop.egg-info}/PKG-INFO +26 -4
- winloop-0.1.5/winloop.egg-info/SOURCES.txt +41 -0
- winloop-0.1.5/winloop.egg-info/not-zip-safe +1 -0
- winloop-0.1.5/winloop.egg-info/requires.txt +19 -0
- {winloop-0.1.4 → winloop-0.1.5}/winloop.egg-info/top_level.txt +0 -1
- winloop-0.1.4/pyproject.toml +0 -9
- winloop-0.1.4/setup.py +0 -122
- winloop-0.1.4/tests/__main__.py +0 -16
- winloop-0.1.4/vendor/libuv/src/fs-poll.c +0 -287
- winloop-0.1.4/vendor/libuv/src/idna.c +0 -560
- winloop-0.1.4/vendor/libuv/src/inet.c +0 -298
- winloop-0.1.4/vendor/libuv/src/random.c +0 -123
- winloop-0.1.4/vendor/libuv/src/strscpy.c +0 -38
- winloop-0.1.4/vendor/libuv/src/strtok.c +0 -52
- winloop-0.1.4/vendor/libuv/src/thread-common.c +0 -175
- winloop-0.1.4/vendor/libuv/src/threadpool.c +0 -418
- winloop-0.1.4/vendor/libuv/src/timer.c +0 -200
- winloop-0.1.4/vendor/libuv/src/uv-common.c +0 -1029
- winloop-0.1.4/vendor/libuv/src/uv-data-getter-setters.c +0 -119
- winloop-0.1.4/vendor/libuv/src/version.c +0 -45
- winloop-0.1.4/vendor/libuv/src/win/async.c +0 -98
- winloop-0.1.4/vendor/libuv/src/win/core.c +0 -777
- winloop-0.1.4/vendor/libuv/src/win/detect-wakeup.c +0 -56
- winloop-0.1.4/vendor/libuv/src/win/dl.c +0 -135
- winloop-0.1.4/vendor/libuv/src/win/error.c +0 -173
- winloop-0.1.4/vendor/libuv/src/win/fs-event.c +0 -598
- winloop-0.1.4/vendor/libuv/src/win/fs.c +0 -3426
- winloop-0.1.4/vendor/libuv/src/win/getaddrinfo.c +0 -383
- winloop-0.1.4/vendor/libuv/src/win/getnameinfo.c +0 -146
- winloop-0.1.4/vendor/libuv/src/win/handle.c +0 -162
- winloop-0.1.4/vendor/libuv/src/win/loop-watcher.c +0 -122
- winloop-0.1.4/vendor/libuv/src/win/pipe.c +0 -2672
- winloop-0.1.4/vendor/libuv/src/win/poll.c +0 -586
- winloop-0.1.4/vendor/libuv/src/win/process-stdio.c +0 -416
- winloop-0.1.4/vendor/libuv/src/win/process.c +0 -1397
- winloop-0.1.4/vendor/libuv/src/win/signal.c +0 -282
- winloop-0.1.4/vendor/libuv/src/win/snprintf.c +0 -42
- winloop-0.1.4/vendor/libuv/src/win/stream.c +0 -252
- winloop-0.1.4/vendor/libuv/src/win/tcp.c +0 -1668
- winloop-0.1.4/vendor/libuv/src/win/thread.c +0 -470
- winloop-0.1.4/vendor/libuv/src/win/tty.c +0 -2422
- winloop-0.1.4/vendor/libuv/src/win/udp.c +0 -1137
- winloop-0.1.4/vendor/libuv/src/win/util.c +0 -1707
- winloop-0.1.4/vendor/libuv/src/win/winapi.c +0 -147
- winloop-0.1.4/vendor/libuv/src/win/winsock.c +0 -575
- winloop-0.1.4/winloop/includes/__init__.py +0 -23
- winloop-0.1.4/winloop.egg-info/SOURCES.txt +0 -72
- {winloop-0.1.4 → winloop-0.1.5}/LICENSE-APACHE +0 -0
- {winloop-0.1.4 → winloop-0.1.5}/LICENSE-MIT +0 -0
- {winloop-0.1.4 → winloop-0.1.5}/README.md +0 -0
- {winloop-0.1.4 → winloop-0.1.5}/setup.cfg +0 -0
- {winloop-0.1.4 → winloop-0.1.5}/tests/test_aiodns.py +0 -0
- {winloop-0.1.4 → winloop-0.1.5}/tests/test_aiohttp.py +0 -0
- {winloop-0.1.4 → winloop-0.1.5}/tests/test_aiomultiprocess.py +0 -0
- {winloop-0.1.4 → winloop-0.1.5}/tests/test_base.py +0 -0
- {winloop-0.1.4 → winloop-0.1.5}/tests/test_context.py +0 -0
- {winloop-0.1.4 → winloop-0.1.5}/tests/test_cython.py +0 -0
- {winloop-0.1.4 → winloop-0.1.5}/tests/test_dealloc.py +0 -0
- {winloop-0.1.4 → winloop-0.1.5}/tests/test_dns.py +0 -0
- {winloop-0.1.4 → winloop-0.1.5}/tests/test_executors.py +0 -0
- {winloop-0.1.4 → winloop-0.1.5}/tests/test_libuv_api.py +0 -0
- {winloop-0.1.4 → winloop-0.1.5}/tests/test_process_spawning.py +0 -0
- {winloop-0.1.4 → winloop-0.1.5}/tests/test_regr1.py +0 -0
- {winloop-0.1.4 → winloop-0.1.5}/tests/test_runner.py +0 -0
- {winloop-0.1.4 → winloop-0.1.5}/tests/test_sourcecode.py +0 -0
- {winloop-0.1.4 → winloop-0.1.5}/tests/test_testbase.py +0 -0
- {winloop-0.1.4 → winloop-0.1.5}/tests/test_udp.py +0 -0
- {winloop-0.1.4 → winloop-0.1.5}/tests/test_unix.py +0 -0
- {winloop-0.1.4 → winloop-0.1.5}/winloop/_noop.py +0 -0
- {winloop-0.1.4 → winloop-0.1.5}/winloop/loop.pyi +0 -0
- /winloop-0.1.4/tests/__init__.py → /winloop-0.1.5/winloop/py.typed +0 -0
- {winloop-0.1.4 → winloop-0.1.5}/winloop.egg-info/dependency_links.txt +0 -0
|
@@ -1,22 +1,44 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: winloop
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.5
|
|
4
4
|
Summary: Windows version of uvloop
|
|
5
5
|
Author: Vizonex
|
|
6
|
-
|
|
6
|
+
License: MIT License
|
|
7
|
+
Project-URL: github, https://github.com/Vizonex/Winloop
|
|
8
|
+
Keywords: asyncio,networking
|
|
9
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
10
|
+
Classifier: Framework :: AsyncIO
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
7
12
|
Classifier: License :: OSI Approved :: Apache Software License
|
|
8
13
|
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Operating System :: POSIX
|
|
15
|
+
Classifier: Operating System :: MacOS :: MacOS X
|
|
9
16
|
Classifier: Operating System :: Microsoft :: Windows
|
|
17
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
10
18
|
Classifier: Programming Language :: Python :: 3.8
|
|
11
19
|
Classifier: Programming Language :: Python :: 3.9
|
|
12
20
|
Classifier: Programming Language :: Python :: 3.10
|
|
13
21
|
Classifier: Programming Language :: Python :: 3.11
|
|
14
22
|
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
-
Classifier:
|
|
16
|
-
Classifier:
|
|
23
|
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
24
|
+
Classifier: Topic :: System :: Networking
|
|
25
|
+
Requires-Python: >=3.8.0
|
|
17
26
|
Description-Content-Type: text/markdown
|
|
18
27
|
License-File: LICENSE-APACHE
|
|
19
28
|
License-File: LICENSE-MIT
|
|
29
|
+
Provides-Extra: test
|
|
30
|
+
Requires-Dist: aiohttp>=3.8.1; python_version < "3.12" and extra == "test"
|
|
31
|
+
Requires-Dist: aiohttp==3.9.0b0; python_version >= "3.12" and extra == "test"
|
|
32
|
+
Requires-Dist: flake8~=5.0; extra == "test"
|
|
33
|
+
Requires-Dist: psutil; extra == "test"
|
|
34
|
+
Requires-Dist: pycodestyle~=2.9.0; extra == "test"
|
|
35
|
+
Requires-Dist: pyOpenSSL~=23.0.0; extra == "test"
|
|
36
|
+
Requires-Dist: mypy>=0.800; extra == "test"
|
|
37
|
+
Requires-Dist: Cython<0.30.0,>=0.29.36; extra == "test"
|
|
38
|
+
Provides-Extra: docs
|
|
39
|
+
Requires-Dist: Sphinx~=4.1.2; extra == "docs"
|
|
40
|
+
Requires-Dist: sphinxcontrib-asyncio~=0.3.0; extra == "docs"
|
|
41
|
+
Requires-Dist: sphinx_rtd_theme~=0.5.2; extra == "docs"
|
|
20
42
|
|
|
21
43
|
<img src="https://raw.githubusercontent.com/Vizonex/Winloop/main/winloop.png" width="200px"/>
|
|
22
44
|
<a href="https://github.com/psf/black"><img alt="Code style: black" src="https://img.shields.io/badge/code%20style-black-000000.svg"></a>
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "winloop"
|
|
3
|
+
description = "Windows version of uvloop"
|
|
4
|
+
authors = [{name = "Vizonex"}]
|
|
5
|
+
requires-python = '>=3.8.0'
|
|
6
|
+
readme = "README.md"
|
|
7
|
+
license = {text = "MIT License"}
|
|
8
|
+
dynamic = ["version"]
|
|
9
|
+
keywords = [
|
|
10
|
+
"asyncio",
|
|
11
|
+
"networking",
|
|
12
|
+
]
|
|
13
|
+
classifiers = [
|
|
14
|
+
"Development Status :: 5 - Production/Stable",
|
|
15
|
+
"Framework :: AsyncIO",
|
|
16
|
+
"Intended Audience :: Developers",
|
|
17
|
+
"License :: OSI Approved :: Apache Software License",
|
|
18
|
+
"License :: OSI Approved :: MIT License",
|
|
19
|
+
"Operating System :: POSIX",
|
|
20
|
+
"Operating System :: MacOS :: MacOS X",
|
|
21
|
+
"Operating System :: Microsoft :: Windows",
|
|
22
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
23
|
+
"Programming Language :: Python :: 3.8",
|
|
24
|
+
"Programming Language :: Python :: 3.9",
|
|
25
|
+
"Programming Language :: Python :: 3.10",
|
|
26
|
+
"Programming Language :: Python :: 3.11",
|
|
27
|
+
"Programming Language :: Python :: 3.12",
|
|
28
|
+
"Programming Language :: Python :: Implementation :: CPython",
|
|
29
|
+
"Topic :: System :: Networking",
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
[project.urls]
|
|
33
|
+
github = "https://github.com/Vizonex/Winloop"
|
|
34
|
+
|
|
35
|
+
[project.optional-dependencies]
|
|
36
|
+
test = [
|
|
37
|
+
# pycodestyle is a dependency of flake8, but it must be frozen because
|
|
38
|
+
# their combination breaks too often
|
|
39
|
+
# (example breakage: https://gitlab.com/pycqa/flake8/issues/427)
|
|
40
|
+
'aiohttp>=3.8.1; python_version < "3.12"',
|
|
41
|
+
'aiohttp==3.9.0b0; python_version >= "3.12"',
|
|
42
|
+
'flake8~=5.0',
|
|
43
|
+
'psutil',
|
|
44
|
+
'pycodestyle~=2.9.0',
|
|
45
|
+
'pyOpenSSL~=23.0.0',
|
|
46
|
+
'mypy>=0.800',
|
|
47
|
+
'Cython(>=0.29.36,<0.30.0)',
|
|
48
|
+
]
|
|
49
|
+
docs = [
|
|
50
|
+
'Sphinx~=4.1.2',
|
|
51
|
+
'sphinxcontrib-asyncio~=0.3.0',
|
|
52
|
+
'sphinx_rtd_theme~=0.5.2',
|
|
53
|
+
]
|
|
54
|
+
|
|
55
|
+
[build-system]
|
|
56
|
+
requires = [
|
|
57
|
+
"setuptools>=60",
|
|
58
|
+
"wheel",
|
|
59
|
+
"Cython(>=0.29.36,<0.30.0)",
|
|
60
|
+
]
|
|
61
|
+
build-backend = "setuptools.build_meta"
|
|
62
|
+
|
|
63
|
+
[tool.setuptools]
|
|
64
|
+
zip-safe = false
|
|
65
|
+
packages = ["winloop"]
|
|
66
|
+
|
|
67
|
+
[tool.setuptools.exclude-package-data]
|
|
68
|
+
"*" = ["*.c", "*.h"]
|
|
69
|
+
|
|
70
|
+
[tool.cibuildwheel]
|
|
71
|
+
build-frontend = "build"
|
|
72
|
+
# Winloop comment: skip tests for now ("ImportError: cannot import name 'includes' from ... " in GitHub action)
|
|
73
|
+
#test-extras = "test"
|
|
74
|
+
#test-command = "python -m unittest discover -v {project}/tests"
|
|
75
|
+
|
|
76
|
+
[tool.pytest.ini_options]
|
|
77
|
+
addopts = "--capture=no --assert=plain --strict-markers --tb=native --import-mode=importlib"
|
|
78
|
+
testpaths = "tests"
|
|
79
|
+
filterwarnings = "default"
|
winloop-0.1.5/setup.py
ADDED
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
|
|
3
|
+
vi = sys.version_info
|
|
4
|
+
if vi < (3, 8):
|
|
5
|
+
raise RuntimeError('winloop requires Python 3.8 or greater')
|
|
6
|
+
|
|
7
|
+
# Winloop comment: winloop now supports both Windows and non-Windows.
|
|
8
|
+
# Below uvloop's setup.py is merged with winloop's previous setup.py.
|
|
9
|
+
|
|
10
|
+
import os
|
|
11
|
+
import os.path
|
|
12
|
+
import pathlib
|
|
13
|
+
import platform
|
|
14
|
+
import re
|
|
15
|
+
import shutil
|
|
16
|
+
import subprocess
|
|
17
|
+
|
|
18
|
+
from setuptools import setup, Extension
|
|
19
|
+
from setuptools.command.build_ext import build_ext
|
|
20
|
+
from setuptools.command.sdist import sdist
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
CYTHON_DEPENDENCY = 'Cython(>=0.29.36,<0.30.0)'
|
|
24
|
+
MACHINE = platform.machine()
|
|
25
|
+
MODULES_CFLAGS = [os.getenv('UVLOOP_OPT_CFLAGS', '-O2')]
|
|
26
|
+
_ROOT = pathlib.Path(__file__).parent
|
|
27
|
+
LIBUV_DIR = str(_ROOT / 'vendor' / 'libuv')
|
|
28
|
+
LIBUV_BUILD_DIR = str(_ROOT / 'build' / 'libuv-{}'.format(MACHINE))
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def _libuv_build_env():
|
|
32
|
+
env = os.environ.copy()
|
|
33
|
+
|
|
34
|
+
cur_cflags = env.get('CFLAGS', '')
|
|
35
|
+
if not re.search(r'-O\d', cur_cflags):
|
|
36
|
+
cur_cflags += ' -O2'
|
|
37
|
+
|
|
38
|
+
env['CFLAGS'] = (cur_cflags + ' -fPIC ' + env.get('ARCHFLAGS', ''))
|
|
39
|
+
|
|
40
|
+
return env
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _libuv_autogen(env):
|
|
44
|
+
if os.path.exists(os.path.join(LIBUV_DIR, 'configure')):
|
|
45
|
+
# No need to use autogen, the configure script is there.
|
|
46
|
+
return
|
|
47
|
+
|
|
48
|
+
if not os.path.exists(os.path.join(LIBUV_DIR, 'autogen.sh')):
|
|
49
|
+
raise RuntimeError(
|
|
50
|
+
'the libuv submodule has not been checked out; '
|
|
51
|
+
'try running "git submodule init; git submodule update"')
|
|
52
|
+
|
|
53
|
+
subprocess.run(
|
|
54
|
+
['/bin/sh', 'autogen.sh'], cwd=LIBUV_DIR, env=env, check=True)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class uvloop_sdist(sdist):
|
|
58
|
+
def run(self):
|
|
59
|
+
if sys.platform != 'win32':
|
|
60
|
+
# Make sure sdist archive contains configure
|
|
61
|
+
# to avoid the dependency on autotools.
|
|
62
|
+
_libuv_autogen(_libuv_build_env())
|
|
63
|
+
super().run()
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class uvloop_build_ext(build_ext):
|
|
67
|
+
user_options = build_ext.user_options + [
|
|
68
|
+
('cython-always', None,
|
|
69
|
+
'run cythonize() even if .c files are present'),
|
|
70
|
+
('cython-annotate', None,
|
|
71
|
+
'Produce a colorized HTML version of the Cython source.'),
|
|
72
|
+
('cython-directives=', None,
|
|
73
|
+
'Cythion compiler directives'),
|
|
74
|
+
('use-system-libuv', None,
|
|
75
|
+
'Use the system provided libuv, instead of the bundled one'),
|
|
76
|
+
]
|
|
77
|
+
|
|
78
|
+
boolean_options = build_ext.boolean_options + [
|
|
79
|
+
'cython-always',
|
|
80
|
+
'cython-annotate',
|
|
81
|
+
'use-system-libuv',
|
|
82
|
+
]
|
|
83
|
+
|
|
84
|
+
def initialize_options(self):
|
|
85
|
+
super().initialize_options()
|
|
86
|
+
self.use_system_libuv = False
|
|
87
|
+
self.cython_always = False
|
|
88
|
+
self.cython_annotate = None
|
|
89
|
+
self.cython_directives = None
|
|
90
|
+
|
|
91
|
+
def finalize_options(self):
|
|
92
|
+
need_cythonize = self.cython_always
|
|
93
|
+
cfiles = {}
|
|
94
|
+
|
|
95
|
+
for extension in self.distribution.ext_modules:
|
|
96
|
+
for i, sfile in enumerate(extension.sources):
|
|
97
|
+
if sfile.endswith('.pyx'):
|
|
98
|
+
prefix, ext = os.path.splitext(sfile)
|
|
99
|
+
cfile = prefix + '.c'
|
|
100
|
+
|
|
101
|
+
if os.path.exists(cfile) and not self.cython_always:
|
|
102
|
+
extension.sources[i] = cfile
|
|
103
|
+
else:
|
|
104
|
+
if os.path.exists(cfile):
|
|
105
|
+
cfiles[cfile] = os.path.getmtime(cfile)
|
|
106
|
+
else:
|
|
107
|
+
cfiles[cfile] = 0
|
|
108
|
+
need_cythonize = True
|
|
109
|
+
|
|
110
|
+
if need_cythonize:
|
|
111
|
+
import pkg_resources
|
|
112
|
+
|
|
113
|
+
# Double check Cython presence in case setup_requires
|
|
114
|
+
# didn't go into effect (most likely because someone
|
|
115
|
+
# imported Cython before setup_requires injected the
|
|
116
|
+
# correct egg into sys.path.
|
|
117
|
+
try:
|
|
118
|
+
import Cython
|
|
119
|
+
except ImportError:
|
|
120
|
+
raise RuntimeError(
|
|
121
|
+
'please install {} to compile uvloop from source'.format(
|
|
122
|
+
CYTHON_DEPENDENCY))
|
|
123
|
+
|
|
124
|
+
cython_dep = pkg_resources.Requirement.parse(CYTHON_DEPENDENCY)
|
|
125
|
+
if Cython.__version__ not in cython_dep:
|
|
126
|
+
raise RuntimeError(
|
|
127
|
+
'uvloop requires {}, got Cython=={}'.format(
|
|
128
|
+
CYTHON_DEPENDENCY, Cython.__version__
|
|
129
|
+
))
|
|
130
|
+
|
|
131
|
+
from Cython.Build import cythonize
|
|
132
|
+
|
|
133
|
+
directives = {}
|
|
134
|
+
if self.cython_directives:
|
|
135
|
+
for directive in self.cython_directives.split(','):
|
|
136
|
+
k, _, v = directive.partition('=')
|
|
137
|
+
if v.lower() == 'false':
|
|
138
|
+
v = False
|
|
139
|
+
if v.lower() == 'true':
|
|
140
|
+
v = True
|
|
141
|
+
|
|
142
|
+
directives[k] = v
|
|
143
|
+
|
|
144
|
+
self.distribution.ext_modules[:] = cythonize(
|
|
145
|
+
self.distribution.ext_modules,
|
|
146
|
+
compiler_directives=directives,
|
|
147
|
+
annotate=self.cython_annotate)
|
|
148
|
+
|
|
149
|
+
super().finalize_options()
|
|
150
|
+
|
|
151
|
+
def build_libuv(self):
|
|
152
|
+
env = _libuv_build_env()
|
|
153
|
+
|
|
154
|
+
# Make sure configure and friends are present in case
|
|
155
|
+
# we are building from a git checkout.
|
|
156
|
+
_libuv_autogen(env)
|
|
157
|
+
|
|
158
|
+
# Copy the libuv tree to build/ so that its build
|
|
159
|
+
# products don't pollute sdist accidentally.
|
|
160
|
+
if os.path.exists(LIBUV_BUILD_DIR):
|
|
161
|
+
shutil.rmtree(LIBUV_BUILD_DIR)
|
|
162
|
+
shutil.copytree(LIBUV_DIR, LIBUV_BUILD_DIR)
|
|
163
|
+
|
|
164
|
+
# Sometimes pip fails to preserve the timestamps correctly,
|
|
165
|
+
# in which case, make will try to run autotools again.
|
|
166
|
+
subprocess.run(
|
|
167
|
+
['touch', 'configure.ac', 'aclocal.m4', 'configure',
|
|
168
|
+
'Makefile.am', 'Makefile.in'],
|
|
169
|
+
cwd=LIBUV_BUILD_DIR, env=env, check=True)
|
|
170
|
+
|
|
171
|
+
if 'LIBUV_CONFIGURE_HOST' in env:
|
|
172
|
+
cmd = ['./configure', '--host=' + env['LIBUV_CONFIGURE_HOST']]
|
|
173
|
+
else:
|
|
174
|
+
cmd = ['./configure']
|
|
175
|
+
subprocess.run(
|
|
176
|
+
cmd,
|
|
177
|
+
cwd=LIBUV_BUILD_DIR, env=env, check=True)
|
|
178
|
+
|
|
179
|
+
j_flag = '-j{}'.format(os.cpu_count() or 1)
|
|
180
|
+
c_flag = "CFLAGS={}".format(env['CFLAGS'])
|
|
181
|
+
subprocess.run(
|
|
182
|
+
['make', j_flag, c_flag],
|
|
183
|
+
cwd=LIBUV_BUILD_DIR, env=env, check=True)
|
|
184
|
+
|
|
185
|
+
def build_extensions(self):
|
|
186
|
+
if sys.platform == 'win32':
|
|
187
|
+
path = pathlib.Path("vendor", "libuv", "src")
|
|
188
|
+
c_files = [p.as_posix() for p in path.iterdir() if p.suffix == '.c']
|
|
189
|
+
c_files += [p.as_posix() for p in (path/'win').iterdir() if p.suffix == '.c']
|
|
190
|
+
self.extensions[-1].sources += c_files
|
|
191
|
+
super().build_extensions()
|
|
192
|
+
return
|
|
193
|
+
|
|
194
|
+
if self.use_system_libuv:
|
|
195
|
+
self.compiler.add_library('uv')
|
|
196
|
+
|
|
197
|
+
if sys.platform == 'darwin' and \
|
|
198
|
+
os.path.exists('/opt/local/include'):
|
|
199
|
+
# Support macports on Mac OS X.
|
|
200
|
+
self.compiler.add_include_dir('/opt/local/include')
|
|
201
|
+
else:
|
|
202
|
+
libuv_lib = os.path.join(LIBUV_BUILD_DIR, '.libs', 'libuv.a')
|
|
203
|
+
if not os.path.exists(libuv_lib):
|
|
204
|
+
self.build_libuv()
|
|
205
|
+
if not os.path.exists(libuv_lib):
|
|
206
|
+
raise RuntimeError('failed to build libuv')
|
|
207
|
+
|
|
208
|
+
self.extensions[-1].extra_objects.extend([libuv_lib])
|
|
209
|
+
self.compiler.add_include_dir(os.path.join(LIBUV_DIR, 'include'))
|
|
210
|
+
|
|
211
|
+
if sys.platform.startswith('linux'):
|
|
212
|
+
self.compiler.add_library('rt')
|
|
213
|
+
elif sys.platform.startswith(('freebsd', 'dragonfly')):
|
|
214
|
+
self.compiler.add_library('kvm')
|
|
215
|
+
elif sys.platform.startswith('sunos'):
|
|
216
|
+
self.compiler.add_library('kstat')
|
|
217
|
+
|
|
218
|
+
self.compiler.add_library('pthread')
|
|
219
|
+
|
|
220
|
+
super().build_extensions()
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
with open(str(_ROOT / 'winloop' / '_version.py')) as f:
|
|
224
|
+
for line in f:
|
|
225
|
+
if line.startswith('__version__ ='):
|
|
226
|
+
_, _, version = line.partition('=')
|
|
227
|
+
VERSION = version.strip(" \n'\"")
|
|
228
|
+
break
|
|
229
|
+
else:
|
|
230
|
+
raise RuntimeError(
|
|
231
|
+
'unable to read the version from winloop/_version.py')
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
if sys.platform == 'win32':
|
|
235
|
+
from Cython.Build import cythonize
|
|
236
|
+
ext = cythonize([
|
|
237
|
+
Extension(
|
|
238
|
+
"winloop.loop",
|
|
239
|
+
sources=[
|
|
240
|
+
"winloop/loop.pyx"
|
|
241
|
+
],
|
|
242
|
+
include_dirs=[
|
|
243
|
+
"vendor/libuv/src",
|
|
244
|
+
"vendor/libuv/src/win",
|
|
245
|
+
"vendor/libuv/include"
|
|
246
|
+
],
|
|
247
|
+
extra_link_args=[ # subset of libuv Windows libraries
|
|
248
|
+
"Shell32.lib",
|
|
249
|
+
"Ws2_32.lib",
|
|
250
|
+
"Advapi32.lib",
|
|
251
|
+
"iphlpapi.lib",
|
|
252
|
+
"Userenv.lib",
|
|
253
|
+
"User32.lib",
|
|
254
|
+
"Dbghelp.lib",
|
|
255
|
+
"Ole32.lib"
|
|
256
|
+
],
|
|
257
|
+
define_macros=[
|
|
258
|
+
("WIN32_LEAN_AND_MEAN", 1),
|
|
259
|
+
("_WIN32_WINNT", "0x0602")
|
|
260
|
+
]
|
|
261
|
+
)
|
|
262
|
+
])
|
|
263
|
+
else:
|
|
264
|
+
ext = [
|
|
265
|
+
Extension(
|
|
266
|
+
"winloop.loop",
|
|
267
|
+
sources=[
|
|
268
|
+
"winloop/loop.pyx",
|
|
269
|
+
],
|
|
270
|
+
extra_compile_args=MODULES_CFLAGS
|
|
271
|
+
),
|
|
272
|
+
]
|
|
273
|
+
|
|
274
|
+
setup_requires = []
|
|
275
|
+
|
|
276
|
+
if not (_ROOT / 'winloop' / 'loop.c').exists() or '--cython-always' in sys.argv:
|
|
277
|
+
# No Cython output, require Cython to build.
|
|
278
|
+
setup_requires.append(CYTHON_DEPENDENCY)
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
setup(
|
|
282
|
+
version=VERSION,
|
|
283
|
+
cmdclass={
|
|
284
|
+
'sdist': uvloop_sdist,
|
|
285
|
+
'build_ext': uvloop_build_ext
|
|
286
|
+
},
|
|
287
|
+
ext_modules=ext,
|
|
288
|
+
setup_requires=setup_requires
|
|
289
|
+
)
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import os.path
|
|
3
|
+
import tempfile
|
|
4
|
+
|
|
5
|
+
from winloop import _testbase as tb
|
|
6
|
+
from winloop.loop import FileSystemEvent
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Test_UV_FS_EVENT_CHANGE(tb.UVTestCase):
|
|
10
|
+
async def _file_writer(self):
|
|
11
|
+
f = await self.q.get()
|
|
12
|
+
while True:
|
|
13
|
+
f.write('hello uvloop\n')
|
|
14
|
+
f.flush()
|
|
15
|
+
# Winloop comment: insertion of os.fsync() call
|
|
16
|
+
# needed on Windows (Windows 10, Windows 11) to
|
|
17
|
+
# trigger change events; also works with Linux,
|
|
18
|
+
# but need to double check this.
|
|
19
|
+
os.fsync(f.fileno())
|
|
20
|
+
x = await self.q.get()
|
|
21
|
+
if x is None:
|
|
22
|
+
return
|
|
23
|
+
|
|
24
|
+
def fs_event_setup(self):
|
|
25
|
+
self.change_event_count = 0
|
|
26
|
+
self.fname = ''
|
|
27
|
+
self.q = asyncio.Queue()
|
|
28
|
+
|
|
29
|
+
def event_cb(self, ev_fname: bytes, evt: FileSystemEvent):
|
|
30
|
+
_d, fn = os.path.split(self.fname)
|
|
31
|
+
self.assertEqual(ev_fname, fn)
|
|
32
|
+
self.assertEqual(evt, FileSystemEvent.CHANGE)
|
|
33
|
+
self.change_event_count += 1
|
|
34
|
+
if self.change_event_count < 4:
|
|
35
|
+
self.q.put_nowait(0)
|
|
36
|
+
else:
|
|
37
|
+
self.q.put_nowait(None)
|
|
38
|
+
|
|
39
|
+
def test_fs_event_change(self):
|
|
40
|
+
self.fs_event_setup()
|
|
41
|
+
|
|
42
|
+
async def run(write_task):
|
|
43
|
+
self.q.put_nowait(tf)
|
|
44
|
+
try:
|
|
45
|
+
await asyncio.wait_for(write_task, 4)
|
|
46
|
+
except asyncio.TimeoutError:
|
|
47
|
+
write_task.cancel()
|
|
48
|
+
|
|
49
|
+
with tempfile.NamedTemporaryFile('wt') as tf:
|
|
50
|
+
self.fname = tf.name.encode()
|
|
51
|
+
h = self.loop._monitor_fs(tf.name, self.event_cb)
|
|
52
|
+
self.assertFalse(h.cancelled())
|
|
53
|
+
|
|
54
|
+
self.loop.run_until_complete(run(
|
|
55
|
+
self.loop.create_task(self._file_writer())))
|
|
56
|
+
h.cancel()
|
|
57
|
+
self.assertTrue(h.cancelled())
|
|
58
|
+
|
|
59
|
+
self.assertEqual(self.change_event_count, 4)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class Test_UV_FS_EVENT_RENAME(tb.UVTestCase):
|
|
63
|
+
async def _file_renamer(self):
|
|
64
|
+
await self.q.get()
|
|
65
|
+
os.rename(os.path.join(self.dname, self.changed_name),
|
|
66
|
+
os.path.join(self.dname, self.changed_name + "-new"))
|
|
67
|
+
await self.q.get()
|
|
68
|
+
|
|
69
|
+
def fs_event_setup(self):
|
|
70
|
+
self.dname = ''
|
|
71
|
+
self.changed_name = "hello_fs_event.txt"
|
|
72
|
+
self.changed_set = {self.changed_name, self.changed_name + '-new'}
|
|
73
|
+
self.q = asyncio.Queue()
|
|
74
|
+
|
|
75
|
+
def event_cb(self, ev_fname: bytes, evt: FileSystemEvent):
|
|
76
|
+
ev_fname = ev_fname.decode()
|
|
77
|
+
self.assertEqual(evt, FileSystemEvent.RENAME)
|
|
78
|
+
self.changed_set.remove(ev_fname)
|
|
79
|
+
if len(self.changed_set) == 0:
|
|
80
|
+
self.q.put_nowait(None)
|
|
81
|
+
|
|
82
|
+
def test_fs_event_rename(self):
|
|
83
|
+
self.fs_event_setup()
|
|
84
|
+
|
|
85
|
+
async def run(write_task):
|
|
86
|
+
self.q.put_nowait(0)
|
|
87
|
+
try:
|
|
88
|
+
await asyncio.wait_for(write_task, 4)
|
|
89
|
+
except asyncio.TimeoutError:
|
|
90
|
+
write_task.cancel()
|
|
91
|
+
|
|
92
|
+
with tempfile.TemporaryDirectory() as td_name:
|
|
93
|
+
self.dname = td_name
|
|
94
|
+
f = open(os.path.join(td_name, self.changed_name), 'wt')
|
|
95
|
+
f.write('hello!')
|
|
96
|
+
f.close()
|
|
97
|
+
h = self.loop._monitor_fs(td_name, self.event_cb)
|
|
98
|
+
self.assertFalse(h.cancelled())
|
|
99
|
+
|
|
100
|
+
self.loop.run_until_complete(run(
|
|
101
|
+
self.loop.create_task(self._file_renamer())))
|
|
102
|
+
h.cancel()
|
|
103
|
+
self.assertTrue(h.cancelled())
|
|
104
|
+
|
|
105
|
+
self.assertEqual(len(self.changed_set), 0)
|