root / NEWS

Revision 838c8524618c6cac976cbd530e7edc271e291c46, 9.6 kB (checked in by Sebastien Martini <ookoi@…>, 10 months ago)

COPYING and NEWS files added.

  • Property mode set to 100644
Line 
1Changes in version 0.8.0:
2------------------------
3
4* Incompatible changes with version 0.7.x
5
6  - Dropped support for python 2.3 (supports only CPython >= 2.4)
7  - Changed attribute names of class Event:
8    * 'is_dir' becomes 'dir'
9    * 'event_name' becomes 'maskname'
10  - Altered namespace:
11    * Everything previously accessible under inotify.* is now accessible
12      under pyinotify.
13  - When meaningful, an event (instance of Event) brings a new
14    attribute 'pathname'
15  - Modified debugging messages:
16    * The VERBOSE variable is removed, and is replaced by the logging module
17    * Set the reporting level like this: log.setLevel(level)
18    * print_err(msg) replaced by log.error(msg)
19  - EventsCodes:
20    * _get_event_name(mask) replaced by get_masks(mask)
21    * EventsCodes.IN_* replaced by IN_* (avalaible at the pyinotify's scope)
22  - Notifier:
23    * Avoid use of ThreadedNotifier, everything can be done with Notifier
24      and it provides more functionalities
25    * Use Notifier.loop() method instead of using an infinite while loop
26
27
28
29Changes in version 0.6.2:
30------------------------
31
32* New features
33
34  - Pathname pattern expansion:
35    Something like  python -m pyinotify /tmp/[0-9]*.gif  now works.
36    See http://www.python.org/doc/lib/module-glob.html for more details.
37
38
39
40Changes in version 0.6.0:
41------------------------
42
43* Incompatible changes
44
45  List of incompatible changes in pyinotify.py:
46
47 -------------------------------------------------------------------
48|                v0.5                |               Now            |
49|-------------------------------------------------------------------|
50| i1 = SimpleINotify()               | wm = WatchManager()          |
51| i2 = ThreadedINotify()             | n1 = Notifier(wm)            |
52|                                    | n2 = ThreadedNotifier(wm)    |
53|-------------------------------------------------------------------|
54| i2.start()                         | n2.start()                   |
55|-------------------------------------------------------------------|
56| i1.add_watch(...)                  | wm.add_watch(...)            |
57| i2.rm_watch(...)                   | wm.rm_watch(...)             |
58|-------------------------------------------------------------------|
59| i1.close()                         | n1.stop()                    |
60|-------------------------------------------------------------------|
61| DEBUG = True                       | VERBOSE = True               |
62|-------------------------------------------------------------------|
63| event.isdir                        | event.is_dir                 |
64|-------------------------------------------------------------------|
65| i1.event_check()                   | n1.check_events()            |
66|-------------------------------------------------------------------|
67| raise ProcessEventException(err)   | raise ProcessEventError(err) |
68| raise INotifyException(err)        | raise NotifierError(err)     |
69|------------------------------------|------------------------------|
70| def process_default(s,a,b):        | def process_default(s,event):|
71|     pass                           |     pass                     |
72 -------------------------------------------------------------------
73
74
75* New features
76
77  - supported flags: IN_ONLYDIR, IN_DONT_FOLLOW, IN_MASK_ADD,
78    IN_MOVE_SELF
79
80  - auto_add: if a watch is added with this flag set to true, every
81              new subdirectory will be automatically watched too.
82
83  - possibility to pass one instance of your processing class to Notifier
84    or ThreadedNotifier and this object will be called by default for each
85    watch. Note, you always can give an instance to add_watch(),
86    update_watch().
87
88
89* Fixed
90
91  - The pathname is appropriately updated in this case:
92     wm.add_watch('/a/')
93     wm.add_watch('/a/b/')
94     echo "bar" > /a/foo.txt
95     mv /a/foo.txt /a/b/foo.txt
96    The necessary condition is to have watches both on the source dir and
97    on the dst dir.
98
99  - Ignored (deleted) watches are removed from watch manager.
100
101
102* Pending bug
103
104  - Consider this case:
105
106    wm.add_watch('/a/foo.txt') # where neither /a nor /a/b are watched
107    mv /a/foo.txt /a/b/foo.txt
108
109    In this case we have received IN_MOVE_SELF but we are unable to
110    infer the new pathname. The event IN_MOVE_SELF doesn't provide this
111    indication.
112
113    Actually, the safest way to use pyinotify is to watch a top directory
114    (say /tmp) one we don't expect be moved, and the watched items located
115    in this directory should only be moved inside this directory or inside
116    another watched top directory (in the same device).
117
118    Example:
119       wm.add_watch('/tmp', rec=True)
120       mv /tmp/foo/  /tmp/bar/         [safe]
121       mv /tmp/bar/  ~/tmp/            [unsafe]
122       mv /tmp /tmp-new                [unsafe]
123
124
125
126Changes in version 0.5.0:
127------------------------
128
129* Few namespace modifications (incompatible changes)
130
131  - pyinotfiy.inotify.* becomes inotify.*  this namespace is a simple
132    wrap of inotify's features (3 systems calls, and 3 variables).
133  - pyinotify.* unchanged. This namespace handle higher developments
134    made on top of inotify.
135  - python -m pyinotify  now works (no need to wait python 2.4.5 :) )
136
137
138* New features
139
140  - You can read and update the followings variables (accessible through
141    the namespace inotify):
142      - max_queued_events
143      - max_user_instances
144      - max_user_watches
145
146
147
148Changes in version 0.4.0:
149------------------------
150
151Few things have been modified (again) to add more consistence and
152reliability. Reliability: it is now easy to immediately and precisely
153know if an operation failed or not, and on which path or wd. That,
154without interrupting (without raising exceptions) the monitoring.
155It is more consistent because once you have added a watch on a path
156you keep the returned wd and use it to further update or remove this
157watch, this is the natural way. Howewer, in case where you have lost
158the wd and only have the path you still might retrieve the wd with
159the method get_wd(path).
160
161
162* Incompatible changes
163
164  - add_watch returns a dictionary {path: watch_descriptor, ...}
165    where:
166      - path is the path given as argument or a subdirectory (if
167        rec is set to True)
168      - watch_descriptor is the corresponding wd, which is a
169        positive integer if the watch has been successfully added
170        or is a negative integer if it failed.
171
172  - update_watch only accepts a wd or a list of wd. Moreover, it now
173    returns a dictionary {wd: success, ...}
174    where:
175      - wd is the watch directory being updated (given as argument
176        or retrieved by rec=True).
177      - success is boolean value. success is set to True is the
178        update succeed, False otherwise.
179
180  - rm_watch only accepts a wd or a list of wd. Moreover, it now
181    returns a dictionary {wd: success, ...} see 'update_watch'
182    just above.
183
184
185
186Changes in version 0.3.3:
187------------------------
188
189* bug fix and cosmetic changes.
190
191
192
193Changes in version 0.3.1:
194------------------------
195
196* Incompatible changes
197
198  - Event.length removed.
199
200
201
202Changes in version 0.3.0:
203------------------------
204
205This is a development version, there are many changes from 0.2.x
206releases, this release must be considered as unstable.
207
208Most of the changes affects the SimpleINotify class.
209
210
211* Incompatible changes
212
213  - No more raise an INotify Exception in case where an error occurred
214    in the methods add_watch, update_watch, rm_watch.
215
216  - Ignore update to an nonexistent watch.
217
218  - Different behavior for the recursive treatment of the update_watch
219    method. Recursively update only existing and valid watches, doesn't
220    follow symlinks.
221
222  - The method rm_watch returns a list of watch descriptor (those who
223    were removed).
224
225
226* New features
227
228  - two new methods: get_wd and get_path. The former takes a path and
229    returns the associated watch descriptor, the latter takes a wd and
230    returns a path. (returning None if the request couldn't be
231    satisfied)
232
233  - add_watch accepts a list of path as well as a single path.
234
235  - update_watch and remove_watch accept both string path and int wd
236    as argument. Note: that the preferred argument for update_watch
237    is the path whereas the preferred one for rm_watch is the wd.
238
239  - The methods rm_watch and update_watch can recursively be applied on
240    theirs arguments. The symlinks aren't followed. Read also the next
241    section.
242
243  - rm_watch returns the list of watch descriptors of watches
244    successfully removed.
245
246
247* Performances
248
249  - Always prefer string path for update_watch, and int wd for rm_watch.
250
251  - Always prefer to save the result of one operation e.g. add_watch
252    for further update or remove watches with this list instead the use
253    of the 'rec' option which is very expansive.
254
255
256* Exceptions vs errors vs nothing
257
258  The previous versions raised exceptions on explicit errors, the
259  drawback was to drop important informations. For example, given
260  the list ['a-valid-path', 'non-valid-path', 'a-valid-path2'], the
261  first item was successfully added whereas an exception was raised on
262  the second, thus the first wd hadn't been returned to the caller,
263  and the last item hadn't been processed.
264
265  The new approach is to quietly ignore errors, process all items and
266  to return all successfully executed operations. The benefit is to never
267  hang up the execution of one operation, the called method will never
268  unexpectedly fail, if all operations failed, the result is an empty
269  list. The drawback is to not directly and explicitly report errors.
270  This task is left to the caller, which is able to compare the input
271  parameters to the received list.
272
273  Obviously this is a subjective choice but i think this is the least
274  worst. Anyway, feel free to send me a comment to say if in your use
275  case this choice works or if it is really really annoying.
276
Note: See TracBrowser for help on using the browser.