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.
Files changed (85) hide show
  1. {winloop-0.1.4/winloop.egg-info → winloop-0.1.5}/PKG-INFO +26 -4
  2. winloop-0.1.5/pyproject.toml +79 -0
  3. winloop-0.1.5/setup.py +289 -0
  4. winloop-0.1.5/tests/test_fs_event.py +105 -0
  5. winloop-0.1.5/tests/test_pipes.py +304 -0
  6. winloop-0.1.5/tests/test_process.py +1047 -0
  7. winloop-0.1.5/tests/test_signals.py +470 -0
  8. winloop-0.1.5/tests/test_sockets.py +767 -0
  9. winloop-0.1.5/tests/test_tcp.py +3219 -0
  10. {winloop-0.1.4 → winloop-0.1.5}/winloop/__init__.py +1 -13
  11. {winloop-0.1.4 → winloop-0.1.5}/winloop/_testbase.py +4 -5
  12. {winloop-0.1.4 → winloop-0.1.5}/winloop/_version.py +1 -1
  13. {winloop-0.1.4 → winloop-0.1.5}/winloop/loop.c +14534 -12880
  14. {winloop-0.1.4 → winloop-0.1.5/winloop.egg-info}/PKG-INFO +26 -4
  15. winloop-0.1.5/winloop.egg-info/SOURCES.txt +41 -0
  16. winloop-0.1.5/winloop.egg-info/not-zip-safe +1 -0
  17. winloop-0.1.5/winloop.egg-info/requires.txt +19 -0
  18. {winloop-0.1.4 → winloop-0.1.5}/winloop.egg-info/top_level.txt +0 -1
  19. winloop-0.1.4/pyproject.toml +0 -9
  20. winloop-0.1.4/setup.py +0 -122
  21. winloop-0.1.4/tests/__main__.py +0 -16
  22. winloop-0.1.4/vendor/libuv/src/fs-poll.c +0 -287
  23. winloop-0.1.4/vendor/libuv/src/idna.c +0 -560
  24. winloop-0.1.4/vendor/libuv/src/inet.c +0 -298
  25. winloop-0.1.4/vendor/libuv/src/random.c +0 -123
  26. winloop-0.1.4/vendor/libuv/src/strscpy.c +0 -38
  27. winloop-0.1.4/vendor/libuv/src/strtok.c +0 -52
  28. winloop-0.1.4/vendor/libuv/src/thread-common.c +0 -175
  29. winloop-0.1.4/vendor/libuv/src/threadpool.c +0 -418
  30. winloop-0.1.4/vendor/libuv/src/timer.c +0 -200
  31. winloop-0.1.4/vendor/libuv/src/uv-common.c +0 -1029
  32. winloop-0.1.4/vendor/libuv/src/uv-data-getter-setters.c +0 -119
  33. winloop-0.1.4/vendor/libuv/src/version.c +0 -45
  34. winloop-0.1.4/vendor/libuv/src/win/async.c +0 -98
  35. winloop-0.1.4/vendor/libuv/src/win/core.c +0 -777
  36. winloop-0.1.4/vendor/libuv/src/win/detect-wakeup.c +0 -56
  37. winloop-0.1.4/vendor/libuv/src/win/dl.c +0 -135
  38. winloop-0.1.4/vendor/libuv/src/win/error.c +0 -173
  39. winloop-0.1.4/vendor/libuv/src/win/fs-event.c +0 -598
  40. winloop-0.1.4/vendor/libuv/src/win/fs.c +0 -3426
  41. winloop-0.1.4/vendor/libuv/src/win/getaddrinfo.c +0 -383
  42. winloop-0.1.4/vendor/libuv/src/win/getnameinfo.c +0 -146
  43. winloop-0.1.4/vendor/libuv/src/win/handle.c +0 -162
  44. winloop-0.1.4/vendor/libuv/src/win/loop-watcher.c +0 -122
  45. winloop-0.1.4/vendor/libuv/src/win/pipe.c +0 -2672
  46. winloop-0.1.4/vendor/libuv/src/win/poll.c +0 -586
  47. winloop-0.1.4/vendor/libuv/src/win/process-stdio.c +0 -416
  48. winloop-0.1.4/vendor/libuv/src/win/process.c +0 -1397
  49. winloop-0.1.4/vendor/libuv/src/win/signal.c +0 -282
  50. winloop-0.1.4/vendor/libuv/src/win/snprintf.c +0 -42
  51. winloop-0.1.4/vendor/libuv/src/win/stream.c +0 -252
  52. winloop-0.1.4/vendor/libuv/src/win/tcp.c +0 -1668
  53. winloop-0.1.4/vendor/libuv/src/win/thread.c +0 -470
  54. winloop-0.1.4/vendor/libuv/src/win/tty.c +0 -2422
  55. winloop-0.1.4/vendor/libuv/src/win/udp.c +0 -1137
  56. winloop-0.1.4/vendor/libuv/src/win/util.c +0 -1707
  57. winloop-0.1.4/vendor/libuv/src/win/winapi.c +0 -147
  58. winloop-0.1.4/vendor/libuv/src/win/winsock.c +0 -575
  59. winloop-0.1.4/winloop/includes/__init__.py +0 -23
  60. winloop-0.1.4/winloop.egg-info/SOURCES.txt +0 -72
  61. {winloop-0.1.4 → winloop-0.1.5}/LICENSE-APACHE +0 -0
  62. {winloop-0.1.4 → winloop-0.1.5}/LICENSE-MIT +0 -0
  63. {winloop-0.1.4 → winloop-0.1.5}/README.md +0 -0
  64. {winloop-0.1.4 → winloop-0.1.5}/setup.cfg +0 -0
  65. {winloop-0.1.4 → winloop-0.1.5}/tests/test_aiodns.py +0 -0
  66. {winloop-0.1.4 → winloop-0.1.5}/tests/test_aiohttp.py +0 -0
  67. {winloop-0.1.4 → winloop-0.1.5}/tests/test_aiomultiprocess.py +0 -0
  68. {winloop-0.1.4 → winloop-0.1.5}/tests/test_base.py +0 -0
  69. {winloop-0.1.4 → winloop-0.1.5}/tests/test_context.py +0 -0
  70. {winloop-0.1.4 → winloop-0.1.5}/tests/test_cython.py +0 -0
  71. {winloop-0.1.4 → winloop-0.1.5}/tests/test_dealloc.py +0 -0
  72. {winloop-0.1.4 → winloop-0.1.5}/tests/test_dns.py +0 -0
  73. {winloop-0.1.4 → winloop-0.1.5}/tests/test_executors.py +0 -0
  74. {winloop-0.1.4 → winloop-0.1.5}/tests/test_libuv_api.py +0 -0
  75. {winloop-0.1.4 → winloop-0.1.5}/tests/test_process_spawning.py +0 -0
  76. {winloop-0.1.4 → winloop-0.1.5}/tests/test_regr1.py +0 -0
  77. {winloop-0.1.4 → winloop-0.1.5}/tests/test_runner.py +0 -0
  78. {winloop-0.1.4 → winloop-0.1.5}/tests/test_sourcecode.py +0 -0
  79. {winloop-0.1.4 → winloop-0.1.5}/tests/test_testbase.py +0 -0
  80. {winloop-0.1.4 → winloop-0.1.5}/tests/test_udp.py +0 -0
  81. {winloop-0.1.4 → winloop-0.1.5}/tests/test_unix.py +0 -0
  82. {winloop-0.1.4 → winloop-0.1.5}/winloop/_noop.py +0 -0
  83. {winloop-0.1.4 → winloop-0.1.5}/winloop/loop.pyi +0 -0
  84. /winloop-0.1.4/tests/__init__.py → /winloop-0.1.5/winloop/py.typed +0 -0
  85. {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.4
3
+ Version: 0.1.5
4
4
  Summary: Windows version of uvloop
5
5
  Author: Vizonex
6
- Keywords: winloop,libuv,windows,fast-asyncio,uvloop-alternative
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: Intended Audience :: Developers
16
- Classifier: Framework :: AsyncIO
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)