1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
|
%global _empty_manifest_terminate_build 0
Name: python-xlocal
Version: 0.5
Release: 1
Summary: execution locals: killing global state (including thread locals)
License: UNKNOWN
URL: http://bitbucket.org/hpk42/xlocal/
Source0: https://mirrors.nju.edu.cn/pypi/web/packages/4f/3b/e7836d2a24926abff5d8bf2f485a0d6f90c2a931c3eaf67a2f45fc605d1f/xlocal-0.5.zip
BuildArch: noarch
%description
This module provides execution locals aka "xlocal" objects which implement
a more restricted variant of "thread locals". An execution local allows to
manage attributes on a per-execution basis in a manner similar to how real
locals work:
- Invoked functions cannot change the binding for the invoking function
- existence of a binding is local to a code block (and everything it calls)
Attribute bindings for an xlocal objects will not leak outside a
context-managed code block and they will not leak to other threads of
greenlets. By contrast, both process-globals and so called "thread
locals" do not implement the above properties.
Let's look at a basic example::
# content of example.py
from xlocal import xlocal
xcurrent = xlocal()
def output():
print "hello world", xcurrent.x
if __name__ == "__main__":
with xcurrent(x=1):
output()
If we execute this module, the ``output()`` function will see
a ``xcurrent.x==1`` binding::
$ python example.py
hello world 1
Here is what happens in detail: ``xcurrent(x=1)`` returns a context manager which
sets/resets the ``x`` attribute on the ``xcurrent`` object. While remaining
in the same thread/greenlet, all code triggered by the with-body (in this case
just the ``output()`` function) can access ``xcurrent.x``. Outside the with-
body ``xcurrent.x`` would raise an AttributeError. It is also not allowed
to directly set ``xcurrent`` attributes; you always have to explicitely mark their
life-cycle with a with-statement. This means that invoked code:
- cannot rebind xlocal state of its invoking functions (no side effects, yay!)
- xlocal state does not leak outside the with-context (lifecylcle control)
Another module may now reuse the example code::
# content of example_call.py
import example
with example.xcurrent(x=3):
example.output()
which when running ...::
$ python example_call.py
hello world 3
will cause the ``example.output()`` function to print the ``xcurrent.x`` binding
as defined at the invoking ``with xcurrent(x=3)`` statement.
Other threads or greenlets will never see this ``xcurrent.x`` binding; they may even
set and read their own distincit ``xcurrent.x`` object. This means that all
threads/greenlets can concurrently call into a function which will always
see the execution specific ``x`` attribute.
%package -n python3-xlocal
Summary: execution locals: killing global state (including thread locals)
Provides: python-xlocal
BuildRequires: python3-devel
BuildRequires: python3-setuptools
BuildRequires: python3-pip
%description -n python3-xlocal
This module provides execution locals aka "xlocal" objects which implement
a more restricted variant of "thread locals". An execution local allows to
manage attributes on a per-execution basis in a manner similar to how real
locals work:
- Invoked functions cannot change the binding for the invoking function
- existence of a binding is local to a code block (and everything it calls)
Attribute bindings for an xlocal objects will not leak outside a
context-managed code block and they will not leak to other threads of
greenlets. By contrast, both process-globals and so called "thread
locals" do not implement the above properties.
Let's look at a basic example::
# content of example.py
from xlocal import xlocal
xcurrent = xlocal()
def output():
print "hello world", xcurrent.x
if __name__ == "__main__":
with xcurrent(x=1):
output()
If we execute this module, the ``output()`` function will see
a ``xcurrent.x==1`` binding::
$ python example.py
hello world 1
Here is what happens in detail: ``xcurrent(x=1)`` returns a context manager which
sets/resets the ``x`` attribute on the ``xcurrent`` object. While remaining
in the same thread/greenlet, all code triggered by the with-body (in this case
just the ``output()`` function) can access ``xcurrent.x``. Outside the with-
body ``xcurrent.x`` would raise an AttributeError. It is also not allowed
to directly set ``xcurrent`` attributes; you always have to explicitely mark their
life-cycle with a with-statement. This means that invoked code:
- cannot rebind xlocal state of its invoking functions (no side effects, yay!)
- xlocal state does not leak outside the with-context (lifecylcle control)
Another module may now reuse the example code::
# content of example_call.py
import example
with example.xcurrent(x=3):
example.output()
which when running ...::
$ python example_call.py
hello world 3
will cause the ``example.output()`` function to print the ``xcurrent.x`` binding
as defined at the invoking ``with xcurrent(x=3)`` statement.
Other threads or greenlets will never see this ``xcurrent.x`` binding; they may even
set and read their own distincit ``xcurrent.x`` object. This means that all
threads/greenlets can concurrently call into a function which will always
see the execution specific ``x`` attribute.
%package help
Summary: Development documents and examples for xlocal
Provides: python3-xlocal-doc
%description help
This module provides execution locals aka "xlocal" objects which implement
a more restricted variant of "thread locals". An execution local allows to
manage attributes on a per-execution basis in a manner similar to how real
locals work:
- Invoked functions cannot change the binding for the invoking function
- existence of a binding is local to a code block (and everything it calls)
Attribute bindings for an xlocal objects will not leak outside a
context-managed code block and they will not leak to other threads of
greenlets. By contrast, both process-globals and so called "thread
locals" do not implement the above properties.
Let's look at a basic example::
# content of example.py
from xlocal import xlocal
xcurrent = xlocal()
def output():
print "hello world", xcurrent.x
if __name__ == "__main__":
with xcurrent(x=1):
output()
If we execute this module, the ``output()`` function will see
a ``xcurrent.x==1`` binding::
$ python example.py
hello world 1
Here is what happens in detail: ``xcurrent(x=1)`` returns a context manager which
sets/resets the ``x`` attribute on the ``xcurrent`` object. While remaining
in the same thread/greenlet, all code triggered by the with-body (in this case
just the ``output()`` function) can access ``xcurrent.x``. Outside the with-
body ``xcurrent.x`` would raise an AttributeError. It is also not allowed
to directly set ``xcurrent`` attributes; you always have to explicitely mark their
life-cycle with a with-statement. This means that invoked code:
- cannot rebind xlocal state of its invoking functions (no side effects, yay!)
- xlocal state does not leak outside the with-context (lifecylcle control)
Another module may now reuse the example code::
# content of example_call.py
import example
with example.xcurrent(x=3):
example.output()
which when running ...::
$ python example_call.py
hello world 3
will cause the ``example.output()`` function to print the ``xcurrent.x`` binding
as defined at the invoking ``with xcurrent(x=3)`` statement.
Other threads or greenlets will never see this ``xcurrent.x`` binding; they may even
set and read their own distincit ``xcurrent.x`` object. This means that all
threads/greenlets can concurrently call into a function which will always
see the execution specific ``x`` attribute.
%prep
%autosetup -n xlocal-0.5
%build
%py3_build
%install
%py3_install
install -d -m755 %{buildroot}/%{_pkgdocdir}
if [ -d doc ]; then cp -arf doc %{buildroot}/%{_pkgdocdir}; fi
if [ -d docs ]; then cp -arf docs %{buildroot}/%{_pkgdocdir}; fi
if [ -d example ]; then cp -arf example %{buildroot}/%{_pkgdocdir}; fi
if [ -d examples ]; then cp -arf examples %{buildroot}/%{_pkgdocdir}; fi
pushd %{buildroot}
if [ -d usr/lib ]; then
find usr/lib -type f -printf "/%h/%f\n" >> filelist.lst
fi
if [ -d usr/lib64 ]; then
find usr/lib64 -type f -printf "/%h/%f\n" >> filelist.lst
fi
if [ -d usr/bin ]; then
find usr/bin -type f -printf "/%h/%f\n" >> filelist.lst
fi
if [ -d usr/sbin ]; then
find usr/sbin -type f -printf "/%h/%f\n" >> filelist.lst
fi
touch doclist.lst
if [ -d usr/share/man ]; then
find usr/share/man -type f -printf "/%h/%f.gz\n" >> doclist.lst
fi
popd
mv %{buildroot}/filelist.lst .
mv %{buildroot}/doclist.lst .
%files -n python3-xlocal -f filelist.lst
%dir %{python3_sitelib}/*
%files help -f doclist.lst
%{_docdir}/*
%changelog
* Mon Apr 10 2023 Python_Bot <Python_Bot@openeuler.org> - 0.5-1
- Package Spec generated
|