[issue28876] bool of large range raises OverflowError
Changes by Akira Li <4kir4...@gmail.com>: -- pull_requests: +572 ___ Python tracker <http://bugs.python.org/issue28876> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue28876] bool of large range raises OverflowError
Akira Li added the comment: > Akira, could you open a pull request on GitHub? Done. PR 699 -- ___ Python tracker <http://bugs.python.org/issue28876> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue29352] provide the authorative source for s[i:j] negative slice indices (<-len(s)) behavior for standard sequences
Akira Li added the comment: I prefer the wording in the current patch. Though I don't have strong feelings one way or the other as long as the behavior is specified explicitly. -- ___ Python tracker <http://bugs.python.org/issue29352> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue29352] provide the authorative source for s[i:j] negative slice indices (<-len(s)) behavior for standard sequences
Changes by Akira Li <4kir4...@gmail.com>: -- pull_requests: +576 ___ Python tracker <http://bugs.python.org/issue29352> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22069] TextIOWrapper(newline="\n", line_buffering=True) mistakenly treat \r as a newline
New submission from Akira Li: TextIOWrapper(b, newline="\n", line_buffering=True) object calls flush() while writing "\r". See test_line_buffering() method in Lib/test/test_io.py:2114 The documentation says [1]: > If line_buffering is True, flush() is implied when a call to write contains > a newline character. i.e., writing \r shouldn't force flush() if newline="\n" [1] https://docs.python.org/3.4/library/io.html#io.TextIOWrapper -- components: IO messages: 223965 nosy: akira priority: normal severity: normal status: open title: TextIOWrapper(newline="\n", line_buffering=True) mistakenly treat \r as a newline type: behavior versions: Python 2.7, Python 3.4, Python 3.5 ___ Python tracker <http://bugs.python.org/issue22069> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue563491] Add separator argument to readline()
Akira Li added the comment: Reincarnation: issue #1152248: Add support for reading records with arbitrary separators to the standard IO stack -- nosy: +akira ___ Python tracker <http://bugs.python.org/issue563491> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue17083] can't specify newline string for readline for binary files
Akira Li added the comment: Related issue #1152248: Add support for reading records with arbitrary separators to the standard IO stack It suggests to extend the newline support for both text and binary files. -- nosy: +akira ___ Python tracker <http://bugs.python.org/issue17083> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue1152248] Add support for reading records with arbitrary separators to the standard IO stack
Akira Li added the comment: To make the discussion more specific, here's a patch that adds support for alternative newlines in _pyio.TextIOWrapper. It aslo updates the documentation and adds more io tests. It does not provide C implementation or the extended newline support for binary files. As a side-effect it also fixes the bug in line_buffering=True behavior, see issue22069O. Note: The implementation does no newline translations unless in legacy special cases i.e., newline='\0' behaves like newline='\n'. This is a key distinction from the behavior described in http://bugs.python.org/file36008/pep-newline.txt The initial specification is from https://mail.python.org/pipermail/python-ideas/2014-July/028381.html -- keywords: +patch nosy: +akira Added file: http://bugs.python.org/file36098/io-newline-issue1152248.patch ___ Python tracker <http://bugs.python.org/issue1152248> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue1152248] Add support for reading records with arbitrary separators to the standard IO stack
Akira Li added the comment: > As a side-effect it also fixes the bug in line_buffering=True > behavior, see issue22069O. It should be issue22069 "TextIOWrapper(newline="\n", line_buffering=True) mistakenly treat \r as a newline" Reuploaded the patch so that it applies cleanly on the current tip. -- Added file: http://bugs.python.org/file36114/io-newline-issue1152248-2.patch ___ Python tracker <http://bugs.python.org/issue1152248> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue19829] _pyio.BufferedReader and _pyio.TextIOWrapper destructor don't emit ResourceWarning if the file is not closed
Akira Li added the comment: Related issue21859 "Add Python implementation of FileIO" -- nosy: +akira ___ Python tracker <http://bugs.python.org/issue19829> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue1152248] Add support for reading records with arbitrary separators to the standard IO stack
Akira Li added the comment: > Akira, your patch does this: > > -self._writetranslate = newline != '' > -self._writenl = newline or os.linesep > +self._writetranslate = newline in (None, '\r', '\r\n') > +self._writenl = newline if newline is not None else os.linesep > > Any reason you made the second change? Why change the value assigned > to _writenl for newline='\n' when you don't want to actually change > the behavior for those cases? Just so you can double-check at write > time that _writetranslate is never set unless _writenl is '\r', > \r\n', or os.linesep? If newline='\n' then writenl is '\n' with and without the patch. If newline='\n' then write('\n\r') writes '\n\r' with and without the patch. If newline='\n' then writetranslate=False (with the patch). It does not change the result for newline='\n' as it is documented now [1]: [newline] can be None, '', '\n', '\r', and '\r\n'. ... If newline is any of the other legal values [namely '\r', '\n', '\r\n'], any '\n' characters written are translated to the given string. [...] are added by me for clarity. [1] https://docs.python.org/3.4/library/io.html#io.TextIOWrapper writetranslate=False so that if newline='\0' then write('\0\n') would write '\0\n' i.e., embed '\n' are not corrupted if newline='\0'. That is why it is the "no translation" patch: +When writing output to the stream: + +- if newline is None, any '\n' characters written are translated to + the system default line separator, os.linesep +- if newline is '\r' or '\r\n', any '\n' characters written are + translated to the given string +- no translation takes place for any other newline value [any string]. -- ___ Python tracker <http://bugs.python.org/issue1152248> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22094] test_ossaudiodev fails unnecessarily
New submission from Akira Li: $ ./python -mtest -uaudio test_ossaudiodev [1/1] test_ossaudiodev test test_ossaudiodev failed -- Traceback (most recent call last): File "./Lib/test/test_ossaudiodev.py", line 148, in test_playback self.play_sound_file(*sound_info) File "./Lib/test/test_ossaudiodev.py", line 89, in play_sound_file (elapsed_time, expected_time)) AssertionError: False is not true : elapsed time (0.0590214729309082) > 10% off of expected time (3.5127309036445333) 1 test failed: test_ossaudiodev The failure is caused by dsp.write(data) that doesn't write all data on my machine. If it is replaced with dsp.writeall(data) then the test passes. The docs [1] say that dsp.write() should write all data by default: oss_audio_device.write(data) Write the Python string data to the audio device and return the number of bytes written. If the audio device is in blocking mode (the default), the entire string is always written [1] https://docs.python.org/3.4/library/ossaudiodev.html The comments in Modules/ossaudiodev.c suggest that dsp.write(data) should write *all* data unless dsp.nonblock() is called: /* Open with O_NONBLOCK to avoid hanging on devices that only allow one open at a time. This does *not* affect later I/O; OSS provides a special ioctl() for non-blocking read/write, which is exposed via oss_nonblock() below. */ fd = _Py_open(devicename, imode|O_NONBLOCK); ... /* And (try to) put it back in blocking mode so we get the expected write() semantics. */ if (fcntl(fd, F_SETFL, 0) == -1) { close(fd); PyErr_SetFromErrnoWithFilename(PyExc_IOError, devicename); return NULL; } -- components: Tests messages: 224159 nosy: akira priority: normal severity: normal status: open title: test_ossaudiodev fails unnecessarily type: behavior versions: Python 3.4 ___ Python tracker <http://bugs.python.org/issue22094> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22094] oss_audio_device.write(data) produces short writes
Changes by Akira Li <4kir4...@gmail.com>: -- title: test_ossaudiodev fails unnecessarily -> oss_audio_device.write(data) produces short writes ___ Python tracker <http://bugs.python.org/issue22094> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22094] oss_audio_device.write(data) produces short writes
Akira Li added the comment: >From Modules/ossaudiodev.c: /* NB. writeall() is only useful in non-blocking mode: according to Guenter Geiger on the linux-audio-dev list (http://eca.cx/lad/2002/11/0380.html), OSS guarantees that write() in blocking mode consumes the whole buffer. In blocking mode, the behaviour of write() and writeall() from Python is indistinguishable. */ -- ___ Python tracker <http://bugs.python.org/issue22094> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22094] oss_audio_device.write(data) produces short writes
Changes by Akira Li <4kir4...@gmail.com>: -- components: +Library (Lib) -Tests ___ Python tracker <http://bugs.python.org/issue22094> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22054] Add os.get_blocking() and os.set_blocking() functions
Akira Li added the comment: Maybe is_something() is a better name than get_something() if something is a boolean? -- nosy: +akira ___ Python tracker <http://bugs.python.org/issue22054> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue12970] os.walk() consider some symlinks as dirs instead of non-dirs
Akira Li added the comment: I've updated os.walk() documentation to mention that *dirnames* list includes symlinks to directories. To imitate the other two cases: - treat the symlinks as files: for dirpath, dirnames, files in os.walk(top): dirs = [] for name in dirnames: (files if islink(join(dirpath, name)) else dirs).append(name) dirnames = dirs - don't include in either of the lists: for dirpath, dirnames, files in os.walk(top): dirnames[:] = [name for name in dirnames if not islink(join(dirpath, name))] where islink = os.path.islink and join = os.path.join. I've uploaded the documentation patch. Please, review. -- nosy: +akira Added file: http://bugs.python.org/file36138/docs-walk-issue12970.patch ___ Python tracker <http://bugs.python.org/issue12970> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22054] Add os.get_blocking() and os.set_blocking() functions
Akira Li added the comment: > os and socket modules already use getxxx() / setxxx() names: > > - os.get_inheritable() / os.set_inheritable() > - os.getuid() / os.setuid() > - os.getgroups() / os.setgroups() > - os.getxattr() os.setxattr() > - socket.gettimeout() / socket.settimeout() > - socket.get_inheritable() / socket.set_inheritable() > - etc. egid, euid, gid, groups, pgid, pgrp, priority, resgid, sid, uid, xatrr, hostname, timeout, sockopt are not boolean. Though get_inheritable() spoils the pot. Compare: if os.get_blocking(fd): # is it a bug? Does it return some mode bits? # Do I need stat.IS_BLK(os.get_blocking(fd)) here instead? And: if os.is_blocking(fd): # it is clear that fd is blocking There could be an argument that get_inheritable should be renamed to is_inheritable instead. -- ___ Python tracker <http://bugs.python.org/issue22054> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22089] collections.MutableSet does not provide update method
Akira Li added the comment: Set has no __ior__ method but MutableSet has: class MySet(MutableSet): update = MutableSet.__ior__ Unlike set.__ior__; MutableSet.__ior__ accepts an arbitrary iterable and therefore MutableSet.update is redundant. set.__ior__ doesn't accept an arbitrary iterable: >>> s = set() >>> s.update('ab') >>> s |= 'ab' Traceback (most recent call last): File "", line 1, in TypeError: unsupported operand type(s) for |=: 'set' and 'str' >>> s |= set('ab') >>> s {'a', 'b'} MutableSet.__ior__ does accept an arbitrary iterable: from collections.abc import MutableSet class UpperSet(MutableSet): """Like set() but stores items in upper case.""" def __init__(self, iterable=()): self._set = set() self |= iterable def _key(self, item): return item.upper() update = MutableSet.__ior__ # implement MutableSet abstract methods def __contains__(self, item): return self._key(item) in self._set def __iter__(self): return iter(self._set) def __len__(self): return len(self._set) def add(self, item): self._set.add(self._key(item)) def discard(self, item): self._set.discard(self._key(item)) Example: s = UpperSet('σs') assert 'σ' in s and 'Σ' in s and 'S' in s and 'ς' in s and 'ſ' in s s.update('dzẞ') # or s |= 'dzẞ' assert 'Dz' in s and 'DZ' in s and 'ß' not in s and 'SS' not in s s |= 'ß' # or s.update('ß') assert s == {'Σ', 'S', 'DZ', 'ẞ', 'SS'} -- nosy: +akira ___ Python tracker <http://bugs.python.org/issue22089> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22089] collections.MutableSet does not provide update method
Akira Li added the comment: On the other hand update() method may accept multiple iterables at once: def update(self, *iterables): for it in iterables: self |= it and therefore it is not equivalent to __ior__ method. In this case: 'difference', 'intersection', 'union' set methods could also be added to Set and 'difference_update', 'intersection_update', 'update' to MutableSet. Negative consequences: - no use-case? - there are more than one way to spell an operation e.g., &= and intersection_update for a single iterable case - documentation, tests, methods implementation have to be maintained in sync with frozenset/set Positive: - Set/MutableSet can be a drop in replacement for frozenset/set without manually reimplementing the named methods even if multiple iterables are not used - documentation, tests, methods implementation are maintained only in stdlib and therefore bugs are fixed in a single place and the same behavior everywhere I've uploaded a prototype patch that implements the named methods, mentions them in Set/MutableSet documentation, and adds sanity tests. If somebody provides a compelling use-case for adding the named methods then further work on the patch could be done. -- keywords: +patch Added file: http://bugs.python.org/file36152/set-update.patch ___ Python tracker <http://bugs.python.org/issue22089> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22101] collections.abc.Set doesn't provide copy() method
New submission from Akira Li: The documentation for standard types says [1]: clear() and copy() are included for consistency with the interfaces of mutable containers that don’t support slicing operations (such as dict and set) New in version 3.3: clear() and copy() methods. [1] https://docs.python.org/3.4/library/stdtypes.html#immutable-sequence-types but collections.abc documentation mentions only clear() method. I've uploaded a patch that implements Set.copy() method, mentions it in Set's documentation, and adds a sanity test. -- components: Library (Lib) files: set-copy.patch keywords: patch messages: 224255 nosy: akira priority: normal severity: normal status: open title: collections.abc.Set doesn't provide copy() method type: behavior versions: Python 3.4, Python 3.5 Added file: http://bugs.python.org/file36153/set-copy.patch ___ Python tracker <http://bugs.python.org/issue22101> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22101] collections.abc.Set doesn't provide copy() method
Akira Li added the comment: > I don't think this is needed nor do I think that it is a good idea to > have a copy() method in the ABCs because they know so little about > their concrete underlying class (perhaps the backing store in the > filesystem or a database). Besides, a user already has workable > alternatives such as creating a new instance and applying |= to > populate it. "because they know so little about their concrete underlying class" FYI, the patch demonstrates how to implement copy() for *any* MutableSet: def copy(self): return self._from_iterable(self) _from_iterable() default implementation is cls(self) i.e., the copy() method may be also efficient by default e.g., it may return the object itself for immutable types. --- The issue is closed so the rest can be ignored. > In general, we don't do API expansions without motivating use cases to > guide the design. The reason to add Set.copy() is the same one as for set.copy() i.e., add the equivalent of L[:] to mutable containers that don't support slicing as the documentation excerpt in msg224255 explicitly says (copy() doesn't modify its object so it can be added to immutable type). General purpose language should provide an ability to copy a container. In practice, people spell this operation as CustomSet(s) thus hardcoding the type and ruining the flexibility provided by s.copy() duck-typing (or copy.copy()). The same could be said about MutableMapping (separate issue) e.g., merge a, b dictionaries assuming no .copy() method: d = dict(a) d.update(b) vs. the same with .copy(): d = a.copy() d.update(b) The latter may also work for a custom dict. The former is hardcoded to produce a dict e.g., you have to reimplement it (and all the surrounding code) for OrderedDict, SortedDict, Splay tree -based dict, etc. Luckily projects such as blist, banyan that implement custom container types do provide copy() method. I don't see why we should make it harder to correctly implement/use custom set/dict types. -- ___ Python tracker <http://bugs.python.org/issue22101> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue16353] add function to os module for getting path to default shell
Akira Li added the comment: > Should it be function? Why not use just a variable initialized at > import time? The path to the default shell shouldn't change during > the time of program execution. > if sys.platform == 'win32': > default_shell = 'cmd.exe' > else: >default_shell = '/bin/sh' Andriod uses /system/bin/sh (and /sbin/sh if we believe some adb source on the internet). See issue16255: "subrocess.Popen needs /bin/sh but Android only has /system/bin/sh" POSIX recommends [1] `getconf PATH` (os.confstr('CS_PATH')): Applications should note that the standard PATH to the shell cannot be assumed to be either /bin/sh or /usr/bin/sh, and should be determined by interrogation of the PATH returned by getconf PATH, ensuring that the returned pathname is an absolute pathname and not a shell built-in. For example, to determine the location of the standard sh utility: $ command -v sh i.e. shell executable is shutil.which('sh', os.defpath) on POSIX. os.defpath could be tweaked on Android. To avoid dependency on shutil something like msg174628 could be adopted: if sys.platform == "win32": # use sys.platform to accommodate java def get_shell_executable(): """Return path to the command processor specified by %ComSpec%. Default: %SystemRoot%\system32\cmd.exe """ return (environ.get('ComSpec') or path.join(environ.get('SystemRoot', r'C:\Windows'), r'system32\cmd.exe')) else: # POSIX def get_shell_executable(): """Return path to the standard system shell executable. Default: '/bin/sh' """ for dirpath in defpath.split(pathsep): sh = dirpath + sep + 'sh' #NOTE: interpret '' as '/' if access(sh, F_OK | X_OK) and path.isfile(sh): #NOTE: allow symlinks e.g., /bin/sh on Ubuntu may be dash return sh return '/bin/sh' #XXX either OS or python are broken if we got here Windows part is based on msg224512. If r'C:\Windows' or '/bin/sh' code is reached then it means that either OS or python are broken/misconfigured. system(), popen() are described on POSIX as [2]: # fork() execl(shell path, "sh", "-c", command, (char *)0); subprocess module that replaces system, popen, spawn*p* calls may use os.get_shell_executable() to implement shell=True. os.defpath is [3]: The default search path used by exec*p* and spawn*p* if the environment doesn’t have a 'PATH' key. Also available via os.path. In the absense of os.confstr('CS_PATH') on Android (msg175006), os.defpath seems appropriate than os.environ['PATH'] to expand 'sh' basename to the full path to be used by subprocess later. os.get_shell() name might imply that a shell object is returned that can run commands like for example os.popen() returns a file-like object that is not true (the intent is to return a path -- a simple string). os.get_shell_executable() is similar to sys.executable that returns path to python executable. os.get_shell_executable() is not necessary for every python run therefore it is better to keep it a function to avoid unnecessary stat calls on startup. Though the result should not change during the program run. > On Windows the ComSpec environment variable could change during > program execution. Does it? The docs for os.environ say [4]: This mapping is captured the first time the os module is imported, typically during Python startup as part of processing site.py. Changes to the environment made after this time are not reflected in os.environ, except for changes made by modifying os.environ directly. I've uploaded a patch with the described implementation (plus docs, tests). [1] http://pubs.opengroup.org/onlinepubs/9699919799/utilities/sh.html [2] http://pubs.opengroup.org/onlinepubs/9699919799/functions/popen.html [3] https://docs.python.org/3.4/library/os.html#os.defpath [4] https://docs.python.org/3.4/library/os.html#os.environ -- nosy: +akira Added file: http://bugs.python.org/file36195/os.get_shell_executable.patch ___ Python tracker <http://bugs.python.org/issue16353> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue16353] add function to os module for getting path to default shell
Changes by Akira Li <4kir4...@gmail.com>: -- versions: +Python 3.5 -Python 3.4 ___ Python tracker <http://bugs.python.org/issue16353> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue16353] add function to os module for getting path to default shell
Changes by Akira Li <4kir4...@gmail.com>: Removed file: http://bugs.python.org/file36195/os.get_shell_executable.patch ___ Python tracker <http://bugs.python.org/issue16353> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue16353] add function to os module for getting path to default shell
Changes by Akira Li <4kir4...@gmail.com>: Added file: http://bugs.python.org/file36196/os.get_shell_executable.patch ___ Python tracker <http://bugs.python.org/issue16353> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue14534] Add method to mark unittest.TestCases as "do not run".
Akira Li added the comment: About the name: abstract_tests could be used e.g.: @abstract_tests class AbcSetTests(TestCase): # test abc.Set Set = abstract_property() def setUp(self): self.set = self.Set('abc') def test_difference(self): self.assert... def test_union(self): self.assert... It is clear that AbcSetTests do not run because the class is abstract (can't create an instance). It is clear that to create a concrete test, you need to subclass the abstract class (serve as a base class): class BuiltinSetTests(AbcSetTests): # test builtins.set Set = set class FrozenSetTests(AbcSetTests): # test frozenset Set = frozenset It might not be necessary to enforce all abstract constraints in the implementation initially. The only thing that needs to be implemented is that tests from @abstract_tests decorated class should not be run. -- nosy: +akira ___ Python tracker <http://bugs.python.org/issue14534> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue19055] Clarify docs for re module: why * does not match as many repetitions as possible.
Akira Li added the comment: tl;dr: added patch that clarifies Python re behavior. Please, review. --- The documented behavior is not clear: why (a|ab)* is not equivalent to (a|ab)(a|ab) for aba if the docs say "as many repetitions as are possible"? And it is not obvious (it is not the only possible behavior) e.g., POSIX [1] expects the longest match, PCRE [2] group may be atomic (/possesive quantifiers), or there is ungreedy repetition: $ echo abac | grep -o '\(a\|ab\)* # Basic Regular Expression aba $ echo abac | grep -Eo '(a|ab)*' # Extended Regular Expression aba $ echo abac | grep -Po '(a|ab)*' # PCRE (like Python regexes) a a $ echo abac | grep -Po '(a|ab)(a|ab)' # PCRE (two repeats) aba $ echo abac | grep -Po '(a|ab)*c' # PCRE (re-eval to match the rest) abac $ echo abAc | grep -iPo '(a|ab)*+c' # PCRE (possessive quantifiers) Ac $ echo abac | grep -Po '(a|ab)*?' # PCRE (ungreedy, zero repeats) # matches nothing where BREs, EREs are defined in [1] that says: If the pattern permits a variable number of matching characters and thus there is more than one such sequence starting at that point, *the longest such sequence is matched*. and: Consistent with the whole match being the longest of the leftmost matches, each subpattern, from left to right, *shall match the longest possible string.* Python regexes work like PCRE [2] that says: The matching process tries each alternative in turn, from left to right, and *the first one that succeeds is used*. If the alternatives are within a subpattern (defined below), "succeeds" means matching the rest of the main pattern as well as the alternative in the subpattern. It explains why (a|ab)* matches only a in aba ("the first one that succeeds") and why at the same time (a|ab)*c matches abac: (a|ab) may match ab in the latter case because the main pattern would fail otherwise i.e., the advanced definition of "succeeds" is used: ""succeeds" means matching the rest of the main pattern ...". Python docs [3] are similar but do not contain the "advanced" "succeeds" definition: REs separated by ``'|'`` are tried from left to right. When one pattern completely matches, that branch is accepted. This means that once ``A`` matches, ``B`` will not be tested further, even if it would produce a longer overall match. In other words, the ``'|'`` operator is never greedy. It explains why (a|ab) matches a in aba. '*' behavior [2]: By default, the quantifiers are "greedy", that is, they match as much as possible (up to the maximum number of permitted times), without causing the rest of the pattern to fail. and again Python docs [3] are similar: ``'*'`` Causes the resulting RE to match 0 or more repetitions of the preceding RE, as many repetitions as are possible. It implies that (a|ab)* should be equivalent to (a|ab)(a|ab) to match aba -- TWO REPETITIONS ARE MORE THAN ONE: "as many repetitions as are possible". But it matches only 'a' i.e., it works as (a|ab) -- only one repetition instead of two. In reality, (a|ab)* along works like a*. I've uploaded a documentation patch that makes Python documentation for '|' more similar to PCRE and clarifies '*' definition as R. David Murray suggested in msg198126. Please, review. [1] http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html [2] http://man7.org/linux/man-pages/man3/pcrepattern.3.html [3] http://hg.python.org/cpython/file/18a311479e8b/Doc/library/re.rst -- components: -Regular Expressions keywords: +patch nosy: +akira title: Regular expressions: * does not match as many repetitions as possible. -> Clarify docs for re module: why * does not match as many repetitions as possible. versions: +Python 3.5 -Python 2.7, Python 3.3 Added file: http://bugs.python.org/file36340/re-docs-repetitions.patch ___ Python tracker <http://bugs.python.org/issue19055> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue19055] Clarify docs for re module: why * does not match as many repetitions as possible.
Changes by Akira Li <4kir4...@gmail.com>: Removed file: http://bugs.python.org/file36340/re-docs-repetitions.patch ___ Python tracker <http://bugs.python.org/issue19055> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue19055] Clarify docs for re module: why * does not match as many repetitions as possible.
Changes by Akira Li <4kir4...@gmail.com>: Added file: http://bugs.python.org/file36341/re-docs-repetitions.patch ___ Python tracker <http://bugs.python.org/issue19055> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue5411] Add xz support to shutil
Akira Li added the comment: sphinx generates warning for the current docs introduced by this issue: WARNING: Explicit markup ends without a blank line; unexpected unindent. I've uploaded a documentation patch that fixes it. -- nosy: +akira Added file: http://bugs.python.org/file36342/docs-fix-sphinx-warning.patch ___ Python tracker <http://bugs.python.org/issue5411> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue21041] pathlib.PurePath.parents rejects negative indexes
Akira Li added the comment: > #7951 has an interesting debate on negative indexes that is possibly > applicable here. Mark could you point to a message that explains why p.parents[-2] is worse than p.parents[len(p.parents)-2]? -- ___ Python tracker <http://bugs.python.org/issue21041> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22241] strftime/strptime round trip fails even for UTC datetime object
New submission from Akira Li: >>> from datetime import datetime, timezone >>> dt = datetime.now(timezone.utc) >>> fmt = '%Y-%m-%d %H:%M:%S.%f %Z%z' >>> datetime.strptime(dt.strftime(fmt), fmt) Traceback (most recent call last): File "", line 1, in File "/cpython/Lib/_strptime.py", line 500, in _strptime_datetime tt, fraction = _strptime(data_string, format) File "/cpython/Lib/_strptime.py", line 337, in _strptime (data_string, format)) ValueError: time data '2014-08-21 11:29:13.537251 UTC+00:00+' does not match format '%Y-%m-%d %H:%M:%S.%f %Z%z' The issue is that dt.strftime('%Z') produces 'UTC+00:00' (due to timezone.utc.tzname(dt) returning 'UTC+00:00') instead of 'UTC' that strptime() accepts and %Z examples [1] in the docs demonstrate. [1] https://docs.python.org/3.4/library/datetime.html#strftime-and-strptime-behavior -- components: Library (Lib) messages: 225606 nosy: akira priority: normal severity: normal status: open title: strftime/strptime round trip fails even for UTC datetime object type: behavior versions: Python 3.4, Python 3.5 ___ Python tracker <http://bugs.python.org/issue22241> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22241] strftime/strptime round trip fails even for UTC datetime object
Akira Li added the comment: I don't see, how it is a duplicate. Everything works if pytz.utc (.tzname() == 'UTC') is used instead of timezone.utc (.tzname() == 'UTC+00:00'). Everything works if UTC class from the example [1] in the tzinfo docs is used. It only breaks due to the weird timezone.utc.tzname() return value. [1] https://docs.python.org/3.4/library/datetime.html#datetime.tzinfo.fromutc Why does datetime.now(timezone.utc).strftime('%Z') (via timezone.utc.tzname(dt)) produce 'UTC+00:00'? How is it motivated? Is it documented somewhere? Can datetime.now(timezone.utc).strftime('%Z') be changed to return 'UTC'? -- ___ Python tracker <http://bugs.python.org/issue22241> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22246] add strptime(s, '%s')
New submission from Akira Li: issue12750 makes strftime('%s') portable. For symmetry, datetime.strptime(s, '%s') could be enabled to return local time as an aware (to avoid loosing info) datetime object for a given integer (seconds since the Epoch) timestamp string. I've uploaded a prototype patch with a draft implementation, docs, and tests. -- components: Library (Lib) files: draft-strptime-%s.diff keywords: patch messages: 225624 nosy: akira priority: normal severity: normal status: open title: add strptime(s, '%s') type: enhancement versions: Python 3.5 Added file: http://bugs.python.org/file36430/draft-strptime-%s.diff ___ Python tracker <http://bugs.python.org/issue22246> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22246] add strptime(s, '%s')
Changes by Akira Li <4kir4...@gmail.com>: Removed file: http://bugs.python.org/file36430/draft-strptime-%s.diff ___ Python tracker <http://bugs.python.org/issue22246> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22246] add strptime(s, '%s')
Changes by Akira Li <4kir4...@gmail.com>: Added file: http://bugs.python.org/file36431/draft-strptime-%s.diff ___ Python tracker <http://bugs.python.org/issue22246> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue12750] datetime.strftime('%s') should respect tzinfo
Akira Li added the comment: issue22246 discusses the reverse: strptime('12345', '%s') -- ___ Python tracker <http://bugs.python.org/issue12750> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22241] strftime/strptime round trip fails even for UTC datetime object
Akira Li added the comment: > I see that you participated in the original discussion (msg107608). > We settled on str(timezone.utc) == 'UTC+00:00' and this was clearly a > deliberate choice. I don't think we can revisit this now, but we can > probably make strptime smart enough to parse UTC±hh:mm with %Z format > code. I see it advocates either 'UTC' or '+00:00' ('-00:00' is semantically different) i.e., mutually exclusive options: UTC is special enough (it is a real timezone that is widely used) to warrant 'UTC' name. On the other hand '+HH:MM' (%:z) (note: *without* 'UTC' prefix) is easily extendable for a fixed-offset tzinfo family and it allows to use %Z to generate/parse date/time strings with rfc3339-like utc offset and the "numeric" tzname() would stress that a fixed-offset datetime.timezone doesn't represent "real" zoneinfo timezone. UTC+HH:MM is neither here nor there: it is easily confusable with deprecated :GMT+H, Etc/GMT-H zoneinfo timezones (I'm not sure about the signs) and it doesn't help generate/parse isoformat() strings e.g., it confuses dateutil.parser therefore *strftime('... %Z') with datetime.timezone should be avoided.* pytz is *the* module that exposes zoneinfo (*the* timezone database) to Python. Its tzname() methods (and therefore strftime('%Z')) produce timezone abbreviations such as 'UTC', 'EST', 'CST' (all %Z examples in datetime docs) that may be ambiguous (the same abbreviation can be used by several timezones) and in reverse -- a single timezone can use several abbreviations for the same purpose (non-DST related). I find '%Z%z' to be easier to read at a glance compared to %z along (imagine you look at dozens timestamps at once e.g., in a log collected from several machines). -- ___ Python tracker <http://bugs.python.org/issue22241> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22274] subprocess.Popen(stderr=STDOUT) fails to redirect subprocess stderr to stdout
New submission from Akira Li: The following command should not produce any output but it does: $ ./python >/dev/null -c 'import subprocess as S, sys; S.call([sys.executable, "-c", "import sys; print(42, file=sys.stderr)"], stderr=S.STDOUT)' Its stdout is redirected to /dev/null. It starts a subprocess with its stderr redirected to stdout. See "Redirect subprocess stderr to stdout" [1] on Stackoverflow. [1] http://stackoverflow.com/questions/11495783/redirect-subprocess-stderr-to-stdout I've uploaded a patch that fixes the issue on POSIX. Please, run the provided test (in the patch), to see whether the code should be fixed on Windows too (it might work as is there). No documentation changes are required. Please, review. -- components: Library (Lib) files: subprocess-stderr_redirect_with_no_stdout_redirect.diff keywords: patch messages: 225898 nosy: akira priority: normal severity: normal status: open title: subprocess.Popen(stderr=STDOUT) fails to redirect subprocess stderr to stdout type: behavior versions: Python 3.4 Added file: http://bugs.python.org/file36472/subprocess-stderr_redirect_with_no_stdout_redirect.diff ___ Python tracker <http://bugs.python.org/issue22274> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22274] subprocess.Popen(stderr=STDOUT) fails to redirect subprocess stderr to stdout
Akira Li added the comment: Josh, on Windows, if at least one standard stream is replaced; all three hStdInput, hStdOutput, hStdError handles are provided (all-or-nothing). On POSIX, standard streams stdin (0), stdout (1), stderr (2) are always inherited from the parent. Each stream can be manipulated independently. c2pwrite=-1 is different from providing c2pwrite=1 (STDOUT_FILENO) explicitly e.g., set_inheritable() call is made after the fork() in the latter case. My patch leads to dup2(fileno(stdout), STDERR_FILENO) when stdout is None and stderr=STDOUT on POSIX i.e., it redirects stderr to the inherited stdout (like 2>&1 in the shell). It has no effect otherwise. sys.__stdout__ is used so that the call fails sooner without fork() if fileno(stdout) is not a valid file descriptor when python initializes (daemon, GUI). __stdout__-based solution doesn't support a case when fileno(stdout) is changed later in the program e.g., using freopen() on some systems. -- ___ Python tracker <http://bugs.python.org/issue22274> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22277] webbrowser.py add parameters to suppress output on stdout and stderr
Akira Li added the comment: open(url, stdout=DEVNULL) won't work on Windows (os.startfile()) and OS X (AppleScript) by default. UnixBrowser already suppresses the output when it is safe, if self.redirect_stdout=True and self.background=True are set. Also, open(url, stdout=DEVNULL) would probably break text-browsers such as elinks (e.g., they are run when $DISPLAY environment variable is not set). What left: Unix browsers for which webbrowser doesn't think that it is safe to suppress the output. If webbrowser allows the output when it shouldn't then it could be fixed on case by case basis and/or maybe some mechanism could be provided to override the webbrowser choice e.g., BaseBrowser.suppress_output attribute that defaults to None (let webbrowser decide). webbrowser is a high-level interface; stdout/stderr from subprocess are too low-level for open() function (inventing your own stdout/stderr values is even worse). -- nosy: +akira ___ Python tracker <http://bugs.python.org/issue22277> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22296] cookielib uses time.time(), making incorrect checks of expiration times in cookies
Akira Li added the comment: time.time() returns the current time in seconds since Epoch it is neither local nor UTC time. It can be converted to both. You can get local time using datetime.fromtimestamp(ts). You can get UTC time using datetime.utcfromtimestamp(ts) or to get an aware datetime object: datetime.fromtimestamp(ts, timezone.utc), where ts is the timestamp in seconds since Epoch. I don't know whether there is an issue with cookie.is_expired() but it is incorrect to use time.mktime() with UTC time tuple unless the local time is UTC. To get the timestamp from a datetime object, you could use .timestamp() method instead: from datetime import datetime, timezone now = datetime.now(timezone.utc) # the current time seconds_since_epoch = now.timestamp() seconds_since_epoch = time.time() # might be less precise -- nosy: +akira ___ Python tracker <http://bugs.python.org/issue22296> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22296] cookielib uses time.time(), making incorrect checks of expiration times in cookies
Akira Li added the comment: timestamp() method works correctly for an aware datetime objects as in my example (notice: timezone.utc in the code). The issue is not that it is a manual computation, the issue is that it is incorrect: #XXX WRONG, DO NOT DO IT time.mktime(datetime.datetime.utcnow().timetuple()) On older Python versions, given a utc time as a naive datetime object, POSIX timestamp is: ts = (utc_dt - datetime(1970, 1, 1)).total_seconds() utc_dt = datetime(1970, 1, 1) + timedelta(seconds=ts) # in reverse -- ___ Python tracker <http://bugs.python.org/issue22296> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22296] cookielib uses time.time(), making incorrect checks of expiration times in cookies
Akira Li added the comment: The last example assumes that time.gmtime(0) is 1970-01-01 00:00:00Z (otherwise time.time() may return different timestamp) -- ___ Python tracker <http://bugs.python.org/issue22296> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22356] mention explicitly that stdlib assumes gmtime(0) epoch is 1970
New submission from Akira Li: See discussion on Python-ideas https://mail.python.org/pipermail/python-ideas/2014-September/029228.html -- assignee: docs@python components: Documentation files: docs-time-epoch_is_1970.diff keywords: patch messages: 226539 nosy: akira, docs@python priority: normal severity: normal status: open title: mention explicitly that stdlib assumes gmtime(0) epoch is 1970 type: behavior versions: Python 2.7, Python 3.4, Python 3.5 Added file: http://bugs.python.org/file36567/docs-time-epoch_is_1970.diff ___ Python tracker <http://bugs.python.org/issue22356> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22377] %Z in strptime doesn't match EST and others
Akira Li added the comment: if PEP 431 is implemented (or anything that gives access to zoneinfo) then strptime could extend the list of timezones it accepts (utc + local timezone names) to include names from the tz database: import pytz # $ pip install pytz {tzname for tz in map(pytz.timezone, pytz.all_timezones) for _, _, tzname in getattr(tz, '_transition_info', [])} It includes EST. -- nosy: +akira ___ Python tracker <http://bugs.python.org/issue22377> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22377] %Z in strptime doesn't match EST and others
Akira Li added the comment: Without %z (utc offset) strptime returns a naive datetime object that is interpreted as utc or local time usually. It might explain why %Z tries to match only utc and the local timezone names. -- ___ Python tracker <http://bugs.python.org/issue22377> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22426] strptime accepts the wrong '2010-06-01 MSK' string but rejects the right '2010-06-01 MSD'
New submission from Akira Li: >>> import os >>> import time >>> os.environ['TZ'] = 'Europe/Moscow' >>> time.tzset() >>> time.strptime('2010-06-01 MSK', '%Y-%m-%d %Z') time.struct_time(tm_year=2010, tm_mon=6, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=1, tm_yday=152, tm_isdst=0) >>> time.strptime('2010-06-01 MSD', '%Y-%m-%d %Z') Traceback (most recent call last): File "", line 1, in File "/usr/lib/python2.7/_strptime.py", line 467, in _strptime_time return _strptime(data_string, format)[0] File "/usr/lib/python2.7/_strptime.py", line 325, in _strptime (data_string, format)) ValueError: time data '2010-06-01 MSD' does not match format '%Y-%m-%d %Z' datetime.strptime() and Python 3 behavior is exactly the same. The correct name is MSD: >>> from datetime import datetime, timezone >>> dt = datetime(2010, 5, 31, 21, tzinfo=timezone.utc).astimezone() >>> dt.strftime('%Y-%m-%d %Z') '2010-06-01 MSD' strptime() uses the current (wrong for the past date) time.tzname names despite the correct name being known to the system (as the example above demonstrates). In general, it is impossible to validate a time zone abbreviation even if the time zone database is available: - tzname may be ambiguous -- multiple zoneinfo matches (around one third of tznames the tz database correspond to multiple UTC offsets (at the same or different times) -- it is not unusual) i.e., any scheme that assumes that tzname is enough to get UTC offset such as Lib/email/_parsedate.py is wrong. - and even if zoneinfo is known, it may be misleading e.g., e.g., HAST (Hawaii-Aleutian Standard Time) might be rejected because Pacific/Honolulu zoneinfo uses HST. HAST corresponds to America/Adak (US/Aleutian) in tzdata (UTC offset may be the same). It might be too rare to care. Related: issue22377 -- components: Library (Lib) messages: 226966 nosy: akira priority: normal severity: normal status: open title: strptime accepts the wrong '2010-06-01 MSK' string but rejects the right '2010-06-01 MSD' type: behavior versions: Python 2.7, Python 3.4, Python 3.5 ___ Python tracker <http://bugs.python.org/issue22426> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22426] strptime accepts the wrong '2010-06-01 MSK' string but rejects the right '2010-06-01 MSD'
Akira Li added the comment: Correction: The correct offset is +0400: >>> dt = datetime(2010, 5, 31, 20, tzinfo=timezone.utc).astimezone() And _timezones dict is defined in Lib/email/_parseaddr.py -- ___ Python tracker <http://bugs.python.org/issue22426> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22377] %Z in strptime doesn't match EST and others
Akira Li added the comment: If the current implementation is considered correct (%Z not recognizing EST) then indeed extending the list of recognized timezones is another issue. And the docs should be changed to match the implementation. The current behavior is broken, see also issue22426 If we assume that the docs are correct (%Z should match EST) even if it is not implemented yet then it is this issue's responsibility to extend the list of recognized timezones (even an incomplete hard-coded list generated by the code from msg226857 would be fine). Lib/email/_parseaddr.py approach (tzname corresponds to a fixed utc offset) is wrong: tzname may correspond to multiple utc offsets at the same time (different timezones) and at different times (even within the same timezone). Having the tz database won't fix it: *tzname along is not enough to determine UTC offset in _many_ cases.* CST is ambiguous if %z is not given therefore even if strptime() had the access to a larger list of recognized timezones; it is not clear what the return value would be: - aware datetime: which timezone to use? - naive datetime: it might be misleading if the input timezone name doesn't correspond to utc or the local timezone email._parseaddr._timezones is misleading if used globally: CST is also used in Australia, China with different utc offsets. One of possible solutions is to return aware datetime objects if a new truthy *timezones* keyword-only argument is provided. It may contain a mapping to disambiguate timezone abbreviations: {'EST': timedelta|tzinfo}. If *timezones* is False then strptime() returns a naive datetime object. The only difference from the current behavior is that a larger list of timezones is supported to match the docs. With bool(timezones) == True, strptime() could return an aware datetime object in utc, local timezones, or any timezone in *timezones* if it is a mapping. Default *timezones* is None that means timezone=False for backward compatibility. DeprecationWarning is added that timezone=True will be default in the next release 3.6 if no objections are received until then e.g., if tzname and timezones is None: # %Z matches non-empty string warn("Default *timezones* parameter for " "%s.strptime() will be True in Python 3.6. " "Pass timezones=False to preserve the old behaviour" % ( cls.__qualname__,), category=DeprecationWarning, stacklevel=2) I've uploaded the patch draft-strptime-%Z-timezones.diff that implements this solution. It also contains tests and docs updates. -- keywords: +patch Added file: http://bugs.python.org/file36634/draft-strptime-%Z-timezones.diff ___ Python tracker <http://bugs.python.org/issue22377> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22426] strptime accepts the wrong '2010-06-01 MSK' string but rejects the right '2010-06-01 MSD'
Akira Li added the comment: My patch for issue22377 also fixes this bug. With the patch applied. Both MSK and MSD are accepted if the new timezones parameter is false (default for Python 3.5, will be changed to True in Python 3.6 If timezones is True then MSD return a correct aware datetime object, MSK is rejected. -- ___ Python tracker <http://bugs.python.org/issue22426> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22426] strptime accepts the wrong '2010-06-01 MSK' string but rejects the right '2010-06-01 MSD'
Akira Li added the comment: MSD variant works on my machine because C library uses the historical timezone database there. I'm not sure whether it works on old Windows versions. -- ___ Python tracker <http://bugs.python.org/issue22426> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22442] subprocess.check_call hangs on large PIPEd data.
Akira Li added the comment: > This is a documented failure on the python subprocess page, > but why not just fix it up directly in python itself? If you want to discard the output; you could use: check_call(args, stdin=DEVNULL, stdout=DEVNULL, stderr=STDOUT) check_call() passes its parameters to Popen() as is. The only parameter it knows about is args that is used to raise an exception. Do you want check_call() to inspect the parameters and to do something about stdout=PIPE, stderr=PIPE? Where "something" could be: - nothing -- the current behavior: everything works until the child process produces enough output to fill any of OS pipe buffers as documented - call proc.communicate() -- store (unlimited) output in memory instead of just hanging: everything works slowly until the system runs out of memory - replace with DEVNULL -- "do what I mean" behavior: inconsistent with the direct Popen() call - raise ValueError with informative error message (about DEVNULL option) after issueing a DeprecationWarning for a release: it fixes this particular misuse of check_call(). Are there other common "wrong in every case" check_call() parameters? -- nosy: +akira ___ Python tracker <http://bugs.python.org/issue22442> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22377] %Z in strptime doesn't match EST and others
Akira Li added the comment: > I don't think we are going to support a timezone list like that without PEP > 431. PEP 431 won't fix this issue. See below. > You should attach your patch to a new issue. When I said this should > the doc issue, that is because only a doc fix is acceptable for 3.4. > Adding more timezones to recognize would be an enhancement, given the > complexity of the proposed solution. The docs are correct (they imply that %Z should accept EST). It is the implementation that is deficient. The patch introduces a new parameter therefore I agree: it should be applied only in 3.5+ > On the other hand, if timezone names are ambiguous, I'm not sure there > *is* a fix other than using the "defacto standard" names and offsets > used by the email library. Actually, isn't there a written standard > that addresses this issue? I seem to remember reading a discussion of > the problem somewhere... Multi-timezone programming email._parseaddr._timezones with CST=-600 is like US-ASCII (the standard). Code that uses local timezone is bilingual (locale-based): CST=-600 in Chicago but it is CST=+800 in China and it may be something else in other parts of the world. The *timezones* parameter in my patch allows to specify the encoding different from the current locale. Code that uses the tz database is multilingual (Unicode): knowing the encoding (zoneinfo name and the time) it is possible to decode almost all encoded characters (to find out whether the timezone abbreviation is valid with a given time and to find the correct UTC offset). If you don't know the encoding then the support for Unicode (the presence of the tz database (PEP 431)) along won't allow you to decode a byte sequence (time string). You need an encoding (timezone name, time) to interpret the input correctly. Given that the list is used to accept a string as a timezone abbreviation, I don't think it should depend on PEP 431 e.g., old date strings/people may use WST even if the new pytz timezones do not use it. The initial list could be seeded from using pytz as in my patch and then expanded as necessary by hand (there is no official entity that tracks timezone abbreviations). -- ___ Python tracker <http://bugs.python.org/issue22377> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22443] read(1) blocks on unflushed output
Akira Li added the comment: Related: http://stackoverflow.com/questions/25923901/last-unbuffered-line-cant-be-read Make sure you follow the links in the comments. -- nosy: +akira ___ Python tracker <http://bugs.python.org/issue22443> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22442] subprocess.check_call hangs on large PIPEd data.
Akira Li added the comment: > What do you think? I would prefer to deprecate PIPE argument for subprocess.call(): issue DeprecationWarning in 3.5 and raise ValueError in 3.6+ I've uploaded a patch that issues the warning. -- keywords: +patch type: -> enhancement versions: +Python 3.5 -Python 2.7 Added file: http://bugs.python.org/file36675/subprocess.call-deprecate-PIPE.diff ___ Python tracker <http://bugs.python.org/issue22442> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue21332] subprocess bufsize=1 docs are misleading
Changes by Akira Li <4kir4...@gmail.com>: Added file: http://bugs.python.org/file36679/subprocess-line-buffering-issue21332-ps5.patch ___ Python tracker <http://bugs.python.org/issue21332> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22442] subprocess.check_call hangs on large PIPEd data.
Akira Li added the comment: @juj: DeprecationWarning is generated if PIPE is passed to call() as any positional or keyword argument in particular stdin, stdout, stderr. It also applies to check_call() that uses call() internally. -- ___ Python tracker <http://bugs.python.org/issue22442> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22442] subprocess.check_call hangs on large PIPEd data.
Akira Li added the comment: Victor, the message in my patch is copied almost verbatim from the current subprocess' documentation [1] [1] https://hg.python.org/cpython/file/850a62354402/Doc/library/subprocess.rst#l57 People use `call(cmd, stdout=PIPE)` as a *broken* way to suppress output i.e., when they actually want `call(cmd, stdout=DEVNULL)` The issue with `call(cmd, stdout=PIPE)` that it *appears* to work if cmd doesn't produce much output i.e., it might work in tests but may hang in production. It is unrelated to check_output(), getstatusouptut() or getoutput(). -- ___ Python tracker <http://bugs.python.org/issue22442> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22477] GCD in Fractions
Akira Li added the comment: Whether or not gcd(a, b) == gcd(|a|, |b|) depends on the definition if we believe to Stepanov of C++ STL fame who mentions in his lecture [1] [1] http://www.stepanovpapers.com/gcd.pdf that the current implementation that uses two operation __bool__ and __mod__: def gcd(a, b): while b: a, b = b, a%b return a can be applied to Euclidean ring elements (not just positive or negative integers). Despite Knuth’s objection to gcd(1, -1) = -1, adding `if a < 0: a = -a` at the end changes the requirements for the type. Here's the definition from the lecture [1]: Greatest common divisor is a common divisor that is divisible by any other common divisor. I have no opinion on whether or not fractions.gcd() should be changed. I thought that I should mention that different definitions exist. -- nosy: +akira ___ Python tracker <http://bugs.python.org/issue22477> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22477] GCD in Fractions
Changes by Akira Li <4kir4...@gmail.com>: -- nosy: -akira ___ Python tracker <http://bugs.python.org/issue22477> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22472] OSErrors should use str and not repr on paths
Akira Li added the comment: OSError has *filename* attribute. Could it be passed to the UI instead? -- nosy: +akira ___ Python tracker <http://bugs.python.org/issue22472> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22472] OSErrors should use str and not repr on paths
Akira Li added the comment: I meant, in general, repr() is better for an error message because it should be unambigous unlike str() but in your particular case you could use filename attribute to format the way you like it for your UI. -- ___ Python tracker <http://bugs.python.org/issue22472> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22524] PEP 471 implementation: os.scandir() directory scanning function
Changes by Akira Li <4kir4...@gmail.com>: -- nosy: +akira ___ Python tracker <http://bugs.python.org/issue22524> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue28876] bool of large range raises OverflowError
Akira Li added the comment: Here's a patch with range_bool() implementation, tests and the docs update. I'm not sure how it should be documented. I've specified it as versionchanged:: 3.6 -- keywords: +patch nosy: +akira Added file: http://bugs.python.org/file45765/range_bool.patch ___ Python tracker <http://bugs.python.org/issue28876> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue28876] bool of large range raises OverflowError
Akira Li added the comment: I've removed the documentation changes from the patch. -- Added file: http://bugs.python.org/file45773/range_bool-no_docs.patch ___ Python tracker <http://bugs.python.org/issue28876> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue28180] sys.getfilesystemencoding() should default to utf-8
Changes by Akira Li <4kir4...@gmail.com>: -- nosy: +akira ___ Python tracker <http://bugs.python.org/issue28180> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue28876] bool of large range raises OverflowError
Akira Li added the comment: Following the python-dev discussion [1] I've added a variant of the patch that uses c99 designated initializers [2] [1] https://mail.python.org/pipermail/python-dev/2017-January/147175.html [2] https://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html -- Added file: http://bugs.python.org/file46378/range_bool-c99-designated-initializers.patch ___ Python tracker <http://bugs.python.org/issue28876> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue28876] bool of large range raises OverflowError
Akira Li added the comment: I've updated the patch to use 4-space indent (pep-7). I've added space around "=" (pep-7); unlike the usual "dict(designator=value)" -- no space around "=" for keyword argument (pep-8). -- Added file: http://bugs.python.org/file46391/range_bool-c99-designated-initializers-indent.patch ___ Python tracker <http://bugs.python.org/issue28876> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue29352] provide the authorative source for s[i:j] negative slice indices (<-len(s)) behavior for standard sequences
New submission from Akira Li: I've failed to find where the behavior for negative indices in s[i:j] expression (i, j < -len(s)) for standard sequences (str, list, etc) is formally defined. The observed behavior implemented in PySlice_GetIndicesEx(): If "len(s) + i" or "len(s) + j" is negative, use 0. [1] I don't see it in the docs. if (*start < 0) *start += length; if (*start < 0) *start = (*step < 0) ? -1 : 0; ... if (*stop < 0) *stop += length; if (*stop < 0) *stop = (*step < 0) ? -1 : 0; The tutorial mentions [2]: > out of range slice indexes are handled gracefully when used for > slicing" slice.indices() documentation says [3]: > Missing or out-of-bounds indices are handled in a manner consistent > with regular slices. Neither define it explicitly. The behavior for the upper boundary is defined explicitly [4]: > If *i* or *j* is greater than ``len(s)``, use ``len(s)`` I've added the documentation patch that defines the behavior for the lower boundary too. [1] Objects/sliceobject.c [2] Doc/tutorial/introduction.rst [3] Doc/reference/datamodel.rst [4] Doc/library/stdtypes.rst -- assignee: docs@python components: Documentation files: docs-negative-slice-indices.patch keywords: patch messages: 286098 nosy: akira, docs@python priority: normal severity: normal status: open title: provide the authorative source for s[i:j] negative slice indices (<-len(s)) behavior for standard sequences versions: Python 3.5, Python 3.6, Python 3.7 Added file: http://bugs.python.org/file46393/docs-negative-slice-indices.patch ___ Python tracker <http://bugs.python.org/issue29352> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue27050] Demote run() below the high level APIs in subprocess docs
Akira Li added the comment: > setting "universal_newlines=True" switches to UTF-8 encoded text pipes It uses locale.getpreferredencoding(False) encoding -- something like cp1252,cp1251,etc on Windows, and UTF-8 on *nix with proper locale settings. It is ASCII (C/POSIX locale default) if the locale is not set in cron, ssh, init.d scripts, etc. If you need a different character encoding, you could use (instead of universal_newlines=True): pipe = io.TextIOWrapper(process.stdout, encoding=character_encoding) A better spelling for universal_newlines=True would be text_mode=True. A summary table (like in itertools' module) would be nice. check_output() name is unfortunate but it does the right thing and it is not hard to use for a beginner -- once somebody discovers it e.g., via "Running shell command from Python and capturing the output" Stack Overflow question http://stackoverflow.com/questions/4760215/running-shell-command-from-python-and-capturing-the-output Compare: output = check_output([sys.executable, '-c', 'print("abc")']) and output = run([sys.executable, '-c', 'print("abc)'], stdout=PIPE).stdout The latter command doesn't raise exception if the child process fails. A beginner has to know about check=True to do the right thing: output = run([sys.executable, '-c', 'print("abc")'], stdout=PIPE, check=True).stdout It is easier to refer to check_output() if someone asks "How do I get command's output in Python?" I wish call() did what check_call() does and the current call() behavior would be achieved by the opposite parameter e.g. no_raise_on_status=False being the default: rc = call(command, no_raise_on_status=True) If we can't change the interface then check_call() is the answer to "Calling an external command in Python" question http://stackoverflow.com/questions/89228/calling-an-external-command-in-python - check_call(command) -- run command, raise if it fails - output = check_output(command) -- get command's output, raise if it fails. To pass *data* to the command via its standard input, pass input=data. To get/pass text (Unicode) instead of bytes, pass universal_newlines=True - check_call("a -- *.jpg | b 2>&1 >output | c", shell=True) -- run a shell command as is It is a pity that a list argument such as ["ls", "-l"] is allowed with shell=True These cover the most common operations with a subprocess. Henceforth, run() is more convenient if we don't need to interact with the child process while it is running. For example, if we introduce the word PIPE (a magic object in the kernel that connects processes) then to capture both standard and error streams of the command: cp = run(command, stdout=PIPE, stderr=PIPE) output, errors = cp.stdout, cp.stderr run() allows to get the output and to get the exit status easily: cp.returncode. Explicit cp.stdout_text, cp.stdout_bytes regardless the text mode would be nice. To interact with a child process while it is running, Popen() have to be used directly. There could be buffering and other issues (tty vs. pipe), see "Q: Why not just use a pipe (popen())?" http://pexpect.readthedocs.io/en/latest/FAQ.html#whynotpipe Working with both stdout/stderr or a non-blocking read require threads or asyncio, fcntl, etc. A couple of words should be said about killing a command started with shell=True. (to kill a process tree: set start_new_session=True parameter and call os.killpg()). timeout option doesn't work in this case (it uses Popen.kill()). check_output() unlike check_call() may wait for grandchildren if they inherit the pipe. Mention Job object on Windows e.g., http://stackoverflow.com/questions/23434842/python-how-to-kill-child-processes-when-parent-dies -- nosy: +akira ___ Python tracker <http://bugs.python.org/issue27050> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue27273] subprocess.run(cmd, input='text') should pass universal_newlines=True to Popen
New submission from Akira Li: At the moment, subprocess.run(cmd, input='text') raises TypeError. It would be nice if universal_newlines=isinstance(input, str) if *input* is set. I've attached a corresponding patch with the necessary changes to the docs, tests and the subprocess.run() code. -- components: Library (Lib) files: text_input.diff keywords: patch messages: 267936 nosy: akira priority: normal severity: normal status: open title: subprocess.run(cmd, input='text') should pass universal_newlines=True to Popen type: enhancement versions: Python 3.6 Added file: http://bugs.python.org/file43314/text_input.diff ___ Python tracker <http://bugs.python.org/issue27273> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue27079] Bugs in curses.ascii predicates
Akira Li added the comment: There is an overlapping issue from 2010: "curses.ascii.isblank() function is broken. It confuses backspace (BS 0x08) with tab (0x09)" http://bugs.python.org/issue9770 Your patch fixes it too (it should be closed). Note: the patch does not pass tests from Lib/test/test_curses_ascii.py attached to issue9770 (even if the code: `if char_class_name in ('cntrl', 'punct') test = unittest.expectedFailure(test)` is removed) e.g., iscntrl(-1) should be False but it returns True: $ ./python >>> import curses.ascii >>> curses.ascii.iscntrl(-1) #XXX expected False True If we ignore negative ints then isblank, ispunct, iscntrl provided in the curses_ascii.patch are ok. -- nosy: +akira ___ Python tracker <http://bugs.python.org/issue27079> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue27079] Bugs in curses.ascii predicates
Akira Li added the comment: I'm not sure anything should be done (e.g., it is "undefined behavior" to pass a negative value such as CHAR_MIN (if *char* type is signed) to a character classification function in C. Though EOF value (-1 traditionally) should be handled). If you want to explore it further; I've enumerated open questions in 2014 (inconsistent TypeError, ord(c) > 0x100, negative ints handling, etc) http://bugs.python.org/issue9770#msg221008 -- ___ Python tracker <http://bugs.python.org/issue27079> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22627] Calling timestamp() on a datetime object modifies the timestamp of a different datetime object.
Akira Li added the comment: Christopher, About your script http://paste.ubuntu.com/8562027/ dateutil may break if the local timezone had different UTC offset in the past. You could use tzlocal module to get pytz timezone that can handle such timezones. To get the correct time for 1414274400 timezone in Europe/Moscow timezone, you need the latest tz database e.g., `pytz` works but fromtimestamp, dateutil that use the local tz database fail (2:00 instead of 1:00): >>> import time >>> import os >>> os.environ['TZ'] = 'Europe/Moscow' >>> time.tzset() >>> from datetime import datetime, timezone >>> from tzlocal import get_localzone >>> datetime.fromtimestamp(1414274400, get_localzone()) datetime.datetime(2014, 10, 26, 1, 0, tzinfo=) >>> datetime.utcfromtimestamp(1414274400).replace(tzinfo=timezone.utc).astimezone(get_localzone()) datetime.datetime(2014, 10, 26, 1, 0, tzinfo=) >>> datetime.fromtimestamp(1414274400) # wrong datetime.datetime(2014, 10, 26, 2, 0) >>> datetime.fromtimestamp(1414274400, timezone.utc).astimezone() # wrong datetime.datetime(2014, 10, 26, 2, 0, tzinfo=datetime.timezone(datetime.timedelta(0, 14400), 'MSK')) >>> datetime.utcfromtimestamp(1414274400).replace(tzinfo=timezone.utc).astimezone() # wrong datetime.datetime(2014, 10, 26, 2, 0, tzinfo=datetime.timezone(datetime.timedelta(0, 14400), 'MSK')) >>> from dateutil.tz import gettz, tzutc >>> datetime.fromtimestamp(1414274400, gettz()) # wrong datetime.datetime(2014, 10, 26, 2, 0, tzinfo=tzfile('/usr/share/zoneinfo/Europe/Moscow')) >>> datetime.fromtimestamp(1414274400, tzutc()).astimezone(gettz()) # wrong datetime.datetime(2014, 10, 26, 2, 0, tzinfo=tzfile('/usr/share/zoneinfo/Europe/Moscow')) >>> datetime.utcfromtimestamp(1414274400).replace(tzinfo=tzutc()).astimezone(gettz()) # wrong datetime.datetime(2014, 10, 26, 2, 0, tzinfo=tzfile('/usr/share/zoneinfo/Europe/Moscow')) To avoid surprises, always use UTC time to perform date arithmetics: EPOCH = datetime(1970, 1,1, tzinfo=pytz.utc) utc_dt = EPOCH + timedelta(seconds=timestamp) should work for dates after 2038 too. To convert it to the local timezone: from tzlocal import get_localzone local_dt = utc_dt.astimezone(get_localzone()) ts = (local_dt - EPOCH) // timedelta(seconds=1) assert ts == timestamp # if timestamp is an integer Python stdlib assumes POSIX encoding for time.time() value (issue22356) therefore the formulae work on all platforms where Python works. -- nosy: +akira ___ Python tracker <http://bugs.python.org/issue22627> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue11820] idle3 shell os.system swallows shell command output
Akira Li added the comment: It looks like the issue can be reduced to whether or not to show this output: >>> import os >>> os.write(1, b'should we see this in idle?\n') should we see this in idle? 28 assuming sys.__stdout__.fileno() == fileno(stdout) == 1. If "should we see this in idle?" is shown in idle then the output that writes to the inherited C stdout such as os.system('ls'), subprocess.call('ls') will also be shown automatically. And in reverse If "should we see this in idle?" should not be shown then other C stdout output such as produced by os.system('ls') should not be redirected too. The output written to the same file should be shown/not shown consistently. os.write(2, b'the same goes for stderr\n') -- nosy: +akira ___ Python tracker <http://bugs.python.org/issue11820> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22709] restore accepting detached stdin in fileinput binary mode
New submission from Akira Li: The patch for Issue #21075: "fileinput.FileInput now reads bytes from standard stream if binary mode is specified" broke code that used sys.stdin = sys.stdin.detach() with FileInput(mode='rb') in Python 3.3 I've attached the patch that makes FileInput to accept detached sys.stdin (without 'buffer' attribute) in binary mode. -- components: Library (Lib) files: fileinput-detached-stdin.diff keywords: patch messages: 229859 nosy: akira priority: normal severity: normal status: open title: restore accepting detached stdin in fileinput binary mode type: behavior versions: Python 3.4, Python 3.5, Python 3.6 Added file: http://bugs.python.org/file36997/fileinput-detached-stdin.diff ___ Python tracker <http://bugs.python.org/issue22709> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22709] restore accepting detached stdin in fileinput binary mode
Akira Li added the comment: It is incorrect that sys.stdin is *always* a text stream. It often is, but not always. There are cases when it is not e.g., $ tar zcf - stuff | gpg -e | ssh user@server 'cat - > stuff.tar.gz.gpg' tar's stdout is *not* a text stream. gpg's stdin/stdout are *not* text streams. ssh's stdin is *not* a text stream. etc. If any of the steps are implemented in Python then it is useful to consider sys.stdin as a binary stream. Any script written before Python 3.4.1 (#21075) that used FileInput binary mode *had to* use sys.stdin = sys.stdin.detach() A bugfix release should not break working code. -- ___ Python tracker <http://bugs.python.org/issue22709> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22709] restore accepting detached stdin in fileinput binary mode
Akira Li added the comment: > This is not related to Python. Terms "character", "string", "text", "file" > can have different meaning in different domains. In Python we use Python > terminology. There is no such thing as sys.stdin in Posix-compatible shell, > because Posix-compatible shell has no the sys module and doesn't use a dot to > access attributes. I use Python terminology (text - Unicode string, binary data - bytes). Though text vs. binary data distinction is language independent ( it doesn't matter how Unicode type is called in a particular language). Python can be used to implement `tar`, `gpg`, `ssh`, `7z`, etc. I don't see what POSIX has anything to do with that fact. It is very simple actually: text -> encode -> bytes bytes -> decode -> text In most cases text should be human readable. It doesn't make sense to encode/decode input/output of gpg-like utilities using a character encoding. *Therefore* the notion of sys.stdin being a bytes stream (io.BufferedReader) can be useful in this case. The lines produced by FileInput are often (after optional processing) written to sys.stdout. If binary mode is used then FileInput(mode='rb') yields bytes therefore it is also useful to consider sys.stdout a binary stream (io.BufferedWriter) in this case. It introduces a nice symmetry: text FileInput mode -> text streams binary FileInput mode -> binary streams By design, FileInput treats stdin as any other file. It even supports a special name for it: '-'. A file may be in binary mode; stdin should be able too. sys.stdout is used outside of FileInput therefore no changes in FileInput itself are necessary but sys.stdin is used inside FileInput that is why the change is needed. > Correct solution in this case would be to use the workaround "sys.stdin = sys.stdin.detach()" conditionally, only in Python versions which have a bug. Do you mean every Python 3 version before Python 3.4.1? Correct solution is to avoid blaming users (your fault -> you change your programs) for our mistakes and fix the bug in Python itself. The patch is attached. -- ___ Python tracker <http://bugs.python.org/issue22709> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22749] remove obsolete remark in time.clock() docs
New submission from Akira Li: time.clock() documentation [1] says: this is the function to use for benchmarking Python or timing algorithms. and Deprecated since version 3.3: The behaviour of this function depends on the platform: use perf_counter() or process_time() instead, depending on your requirements, to have a well defined behaviour. [1]: https://hg.python.org/cpython/file/a22ef88143b9/Doc/library/time.rst#l127 The first remark is incorrect since 3.3. I've attached a documentation patch that removes it. -- assignee: docs@python components: Documentation files: docs-time-clock-remove-stale-remark.diff keywords: patch messages: 230124 nosy: akira, docs@python priority: normal severity: normal status: open title: remove obsolete remark in time.clock() docs type: behavior versions: Python 3.3, Python 3.4, Python 3.5, Python 3.6 Added file: http://bugs.python.org/file37048/docs-time-clock-remove-stale-remark.diff ___ Python tracker <http://bugs.python.org/issue22749> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22798] time.mktime doesn't update time.tzname
New submission from Akira Li: time.tzname is initialized from C tzname variable or tm_zone around Jan, Jul of the current year. If time.mktime() is called with a time tuple from the past/future then after the call time.tzname might be out-of-sync with the corresponding C tzname and tm_zone values. Because C mktime may change tzname, tm_zone values on some systems and time.mktime calls C mktime. I've attached test_mktime_changes_tzname.c file that demonstrates that mktime() may change tzname. -- components: Library (Lib) files: test_mktime_changes_tzname.c messages: 230674 nosy: akira priority: normal severity: normal status: open title: time.mktime doesn't update time.tzname type: behavior versions: Python 3.4, Python 3.5, Python 3.6 Added file: http://bugs.python.org/file37132/test_mktime_changes_tzname.c ___ Python tracker <http://bugs.python.org/issue22798> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22798] time.mktime doesn't update time.tzname
Akira Li added the comment: I've attached test-timezone-info-is-updated.diff file -- a patch for Lib/test/test_time.py that demonstrates that time functions fail to update the timezone info. The test uses Europe/Moscow timezone but most timezones around the world had/will have different tzname/utc offset (unrelated to DST changes) in the past/future. -- keywords: +patch Added file: http://bugs.python.org/file37133/test-timezone-info-is-updated.diff ___ Python tracker <http://bugs.python.org/issue22798> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22798] time.mktime doesn't update time.tzname
Changes by Akira Li <4kir4...@gmail.com>: Added file: http://bugs.python.org/file37134/test_mktime_changes_tzname.c ___ Python tracker <http://bugs.python.org/issue22798> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22799] wrong time.timezone
New submission from Akira Li: $ TZ=:Europe/Moscow ./python -mtest -v test_time == FAIL: test_localtime_timezone (test.test_time.TestPytime) -- Traceback (most recent call last): File ".../Lib/test/test_time.py", line 721, in test_localtime_timezone self.assertEqual(lt.tm_gmtoff, -[time.timezone, time.altzone][lt.tm_isdst]) AssertionError: 10800 != 14400 -- Ran 45 tests in 1.832s FAILED (failures=1, skipped=3) test test_time failed 1 test failed: test_time UTC offset had changed on 2014-10-26 in Europe/Moscow timezone from MSK+0400 to MSK+0300. Python time.timezone returns -14400 (old utc offset) despite C timezone variable having the correct value (Python uses tm_gmtoff from Jan here). Similar case where timezone, altzone may be wrong http://bugs.python.org/msg31138 The issue again http://bugs.python.org/issue22798 is that time timezone attribute is out-of-sync with the corresponding C variable i.e., C library provides correct values but time module doesn't use them. -- components: Library (Lib) messages: 230684 nosy: akira priority: normal severity: normal status: open title: wrong time.timezone type: behavior versions: Python 3.4, Python 3.5, Python 3.6 ___ Python tracker <http://bugs.python.org/issue22799> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue16353] add function to os module for getting path to default shell
Akira Li added the comment: > Matt Frank added the comment: > > Unfortunately os.defpath seems to be hardcoded. And hardcoded to the > wrong value on every system I have looked at, including Linux. os.defpath is supposed to be ':'+CS_PATH, e.g., look at glibc (C library used on Linux) sysdeps/posix/spawni.c I don't know whether it is possible to change CS_PATH without recompiling every statically linked executable on a system, sysdeps/unix/confstr.h: #define CS_PATH "/bin:/usr/bin" Though this issue is about the path to the standard shell sh/cmd.exe. It is not about os.defpath. The patch [1] has tests. Have you tried to run them? The tests *pass* at least on one system ;) [1] http://bugs.python.org/review/16353/#ps12569 To run the tests, download the patch into your python checkout: $ curl -O \ http://bugs.python.org/file36196/os.get_shell_executable.patch and apply it: $ patch -p1< os.get_shell_executable.patch to run only test_os.py: $ ./python -mtest test_os > Lib/posixpath.py sets defpath=':/bin:/usr/bin' which is _not_ what > getconf CS_PATH` returns on my Linux (the extra ':' at the beginning > means "include the cwd" which is almost certainly not what anyone > wants.) os.get_shell_executable() does not use cwd. Neither the documentation nor the code in the patch suggest that. > The hardcoded value '/bin:/usr/bin' would also be wrong for > Solaris and AIX installations that are trying to be POSIX (I think > they use /usr/xpg4/bin/sh). os.defpath is the default search path used by exec*p* and spawn*p* i.e., if os.defpath is incorrect for these system then os.exec*p* and os.spawn*p* functions could also be broken. I expect that Windows, OS X, Linux work as is. If the tests fail on Solaris, AIX then os.defpath should be tweaked on these systems if it hasn't been already. Note: os.defpath is a very conservative value: it should be set at python's installation time at the very latest. Henceforth it should remain the same. > And Lib/ntpath.py sets defpath='.;C:\\bin', which doesn't resemble a > path that even works (as pointed out in now closed > http://bugs.python.org/issue5717). (The correct value may be > %SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\'.) Please, look at the patch. Neither the documentation nor the code suggest that os.defpath is used on Windows. > So I don't know where to go next. I'm happy to cook up a different > patch, but I have no idea what it should be. Here are some > possibilities: > > 1. Kick the can down the road: file a new bug against os.defpath and > (somehow) fix Lib/*path.py so they do something more reasonable in > more cases. One of which might be to have posixpath.py try to call > os.confstr() (and then, perhaps, special-code something in > Modules/posixmodule.c in the case that HAVE_CONFSTR is not defined.) > > 2. Modify @akira's patch to call os.confstr('CS_PATH') instead of > os.defpath, and then deal with the fact that very few systems actually > implement confstr() (perhaps by special-coding something in > Modules/posixmodule.c as described above.) Note I'm the author of http://bugs.python.org/issue16353#msg224514 message that references the POSIX recommendation about `getconf PATH` and *explicitly* mentions os.confstr('CS_PATH'). I don't remember exactly the motivation to use os.defpath instead of os.confstr('CS_PATH'). A guess: the result is the same (a lone `:` is ignored in the patch) but os.defpath is easier to modify for uncommon systems where os.confstr might not be available. I expect that the tests in the patch will pass on all stable buildbots [2] successfully without any modifications (with os.defpath as is). [2] http://buildbot.python.org/all/waterfall?category=3.x.stable Other systems should probably configure os.defpath appropriately (it should include the path to the standard shell). > 3. Modify this patch to fall back to `PATH` if `sh` can't be found on > os.defpath (or os.confstr('CS_PATH') fails). The standard shell should not depend on PATH envvar. The tests show that os.get_shell_executable() works even with an empty environment. The motivation is the same as why `getconf PATH` exists in the first place. The documentation for os.get_shell_executable() (from the patch): Return a path to the standard system shell executable -- ``sh`` program on POSIX (default: ``'/bin/sh'``) or ``%ComSpec%`` command processor on Windows (default: ``%SystemRoot%\system32\cmd.exe``). Availability: Unix, Windows The intent is that os.get_shell_executable() returns the same *shell path* as used by system(3) on POSIX i.e., (ignoring signals, etc) os.system(command) could be impl
[issue16353] add function to os module for getting path to default shell
Akira Li added the comment: > Matt Frank added the comment: > > In msg230720 Akira Li (akira) wrote: >> os.defpath is supposed to be ':'+CS_PATH, e.g., look at glibc (C library >> used on Linux) sysdeps/posix/spawni.c I don't know whether it is >> possible to change CS_PATH without recompiling every statically linked >> executable on a system, sysdeps/unix/confstr.h: >> >> #define CS_PATH "/bin:/usr/bin" >> >> Though this issue is about the path to the standard shell sh/cmd.exe. >> It is not about os.defpath. > > I understand this issue is about the path to the standard shell. > My argument is that os.defpath is the wrong tool for finding that > path, and os.confstr('CS_PATH') is the correct tool, as you originally > suggested in msg224514. > I'll repeat os.defpath definition that I've cited in the same message msg224514: The default search path used by exec*p* and spawn*p* if the environment doesn’t have a 'PATH' key. Also available via os.path. 1. os.defpath should work (contain the path to the standard shell) everywhere where os.confstr("CS_PATH") works. 2. And it might be easier to customize e.g., on systems where there is no os.confstr or where changing CS_PATH involves recompiling crucial system processes. If these two statements are not true then os.defpath could be dropped. >> The patch [1] has tests. Have you tried to run them? >> The tests *pass* at least on one system ;) >> >> [...] >> >> os.get_shell_executable() does not use cwd. Neither the documentation >> nor the code in the patch suggest that. > > I ran the tests (and the entire Python test suite) before I wrote my > first message. But you didn't test what happens when there is a bogus > 'sh' somewhere along the path. You also have a bug in your path > searching loop that interprets an empty element on the path as "/". > Here's the current failure mode: > > Go to root on your Posix system. With "su" or "sudo" create an > executable file named sh. (for example "cd /; sudo touch sh; sudo > chmod +x sh"). Then go back to your python interpreter (with the > patch applied) and run "os.get_shell_executable()". The returned > result will be '/sh'. > But if you fix the loop to iterate over the path correctly (including > 'cwd') then you will find that putting an executable named 'sh' in the > current working directory will make os.get_shell_executable() return > the "sh" in the current working directory (because os.defpath says it > should). > Comment in the patch explicitly says that '' is interpreted as '/'. The intent is to exclude the current working directory, thinking that /sh executable can create only root. And root can do anything to the machine anyway. I agree. It is a misfeature. I've uploaded a new patch that excludes '' completely. The previous code tried to be too cute. > The loop _should_ be treating empty path elements as current working > directory. (In the glibc sysdeps/posix/spawni.c file you pointed to > look around line 281, by the comment that says "/* Two adjacent > colons, or a colon at the beginning or the end of 'PATH' means to > search the current directory.*/") yes. Empty path element stands for the current working directory e.g., $ PATH= python $ PATH=: python $ PATH=:/ python $ PATH=/: python run ./python on my system. The current working directory is intentionally excluded (in the original and in the current patches) otherwise os.get_exec_path(env={}) would be used. > Note also, that glibc's spawni() uses two different "default paths". > One is for if the user didn't specify their PATH variable (that's the > one where they use ":/bin:/usr/bin") and a completely different (built > in path is used in the spawn*p* version) if it turns out that the file > is a script that needs to run under the system sh. (On line 290 they > call maybe_script_execute(), which calls script_execute(), which uses > _PATH_BSHELL.) glibc hardcodes the path (like subprocess module does currently): #define _PATH_BSHELL"/bin/sh" os.get_shell_executable() is an enhancement that allows (Unix) systems to configure the path via os.defpath. > But os.defpath doesn't work on Android either (because it is hardcoded > to ':/bin:/usr/bin'). As I've mentioned in msg224514 before posting my original patch: - "Andriod uses /system/bin/sh" - "os.defpath could be tweaked on Android" i.e., yes. Default os.defpath doesn't work there and it should be configured on Android to include the path to the standard shell. -- ___ Python tracker <http://bugs.python.org/issue16353> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue16353] add function to os module for getting path to default shell
Changes by Akira Li <4kir4...@gmail.com>: Added file: http://bugs.python.org/file37140/os.get_shell_executable-3.patch ___ Python tracker <http://bugs.python.org/issue16353> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22791] datetime.utcfromtimestamp() shoud have option for create tz aware datetime
Akira Li added the comment: >>> from datetime import datetime, timezone >>> datetime.fromtimestamp(0, timezone.utc) datetime.datetime(1970, 1, 1, 0, 0, tzinfo=datetime.timezone.utc) already works and it is documented [1] [1] https://docs.python.org/3/library/datetime.html#datetime.datetime.fromtimestamp Or it can be written as: >>> epoch = datetime(1970, 1, 1, tzinfo=timezone.utc) >>> aware_utc = epoch + timedelta(seconds=posix_timestamp) -- nosy: +akira ___ Python tracker <http://bugs.python.org/issue22791> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22791] datetime.utcfromtimestamp() shoud have option for create tz aware datetime
Akira Li added the comment: I agree the documentation should nudge towards aware datetime objects. I've attached a documentation patch as an example. -- keywords: +patch Added file: http://bugs.python.org/file37162/issue22791-utcfromtimestamp-aware.diff ___ Python tracker <http://bugs.python.org/issue22791> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22536] subprocess should include filename in FileNotFoundError exception
Akira Li added the comment: I can confirm that without the patch the filename attribute is None despite being mentioned in strerror. Travis, you should use `orig_executable` instead of `args[0]` to cover: subprocess.call("exit 0", shell=True, executable='/nonexistent bash') case. And use `cwd` if `child_exec_never_called`, to be consistent with the error message (see if/else statements above the raise statement). It seems appropriate to set filename even if errno is not ENOENT but to be conservative, you could provide filename iff `err_msg` is also changed i.e., iff errno is ENOENT. -- nosy: +akira ___ Python tracker <http://bugs.python.org/issue22536> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22536] subprocess should include filename in FileNotFoundError exception
Akira Li added the comment: If the_oserror.filename is not None then str(the_oserror) appends the filename twice: [Errno 2] No such file or directory: 'nonexistent': 'nonexistent' You could remove `err_msg += ':' ...` statements to avoid the repeatition. It may break the code that uses strerror attribute. But exception error messages are explicitly excluded from backward compatibility considirations therefore it might be ok to break it here. I can't find the reference so it should probably be resolved as a new issue (independent from providing the filename attribute value). -- ___ Python tracker <http://bugs.python.org/issue22536> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22536] subprocess should include filename in FileNotFoundError exception
Akira Li added the comment: It would be inconsitent to provide filename only if exec is called e.g.: >>> import subprocess subprocess.call("not used", cwd="nonexistent") FileNotFoundError: [Errno 2] No such file or directory: 'nonexistent' The error message shows the filename (cwd) despite exec not being called therefore it would be logical to provide non-None `filename` attribute here too. If we ignore the backward compatibility issue I've mentioned in msg231297 then the current code: if errno_num == errno.ENOENT: if child_exec_never_called: # The error must be from chdir(cwd). err_msg += ': ' + repr(cwd) else: err_msg += ': ' + repr(orig_executable) raise child_exception_type(errno_num, err_msg) could be replaced with: if errno_num == errno.ENOENT: if child_exec_never_called: # The error must be from chdir(cwd). filename = cwd else: filename = orig_executable raise child_exception_type(errno_num, err_msg, filename) raise child_exception_type(errno_num, err_msg) [1] https://hg.python.org/cpython/file/23ab1197df0b/Lib/subprocess.py#l1443 -- ___ Python tracker <http://bugs.python.org/issue22536> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue21872] LZMA library sometimes fails to decompress a file
Akira Li added the comment: @Esa changing the buffer size helps with some "bad" files but lzma module still fails on some files. I've uploaded decompress-example-files.py script that demonstrates it. -- nosy: +akira Added file: http://bugs.python.org/file37239/decompress-example-files.py ___ Python tracker <http://bugs.python.org/issue21872> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue21872] LZMA library sometimes fails to decompress a file
Changes by Akira Li <4kir4...@gmail.com>: Added file: http://bugs.python.org/file37240/decompress-example-files.py ___ Python tracker <http://bugs.python.org/issue21872> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue21872] LZMA library sometimes fails to decompress a file
Changes by Akira Li <4kir4...@gmail.com>: Removed file: http://bugs.python.org/file37239/decompress-example-files.py ___ Python tracker <http://bugs.python.org/issue21872> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue21872] LZMA library sometimes fails to decompress a file
Akira Li added the comment: If lzma._BUFFER_SIZE is less than 2048 then all example files are decompressed successfully (at least lzma module produces the same results as xz utility) -- Added file: http://bugs.python.org/file37241/decompress-example-files.py ___ Python tracker <http://bugs.python.org/issue21872> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue21872] LZMA library sometimes fails to decompress a file
Changes by Akira Li <4kir4...@gmail.com>: Removed file: http://bugs.python.org/file37240/decompress-example-files.py ___ Python tracker <http://bugs.python.org/issue21872> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22752] incorrect time.timezone value
Akira Li added the comment: C standard delegates to implementations: The local time zone and Daylight Saving Time are implementation-defined. gcc (one of the implementations) says [1]: [timezone] contains the difference between UTC and the latest local standard time, in seconds west of UTC. Notice the word "latest". To be fair, gcc (the actual implementation) uses a weird logic to assign timezone, daylight values in Europe/Moscow timezone in 2011-2015. Python own tests assume that time.timezone reflects the *current* (most recent) time http://bugs.python.org/issue22799 C tzname, timezone, daylight are not constants. They may change e.g., see http://bugs.python.org/issue22798 (the C code demonstrates that tzname changes even for the same local timezone). POSIX specifies a profile (additional restrictions but no conflict) of C standard for the time functions e.g., tzset(), mktime() [2], ctime(), localtime() may change tzname, timezone, daylight (but *not* gmtime() or asctime()). To summarize: - timezone is implementation-defined in C - gcc (one of implementations) says that timezone corresponds to the latest time (the actual behavior is complicated) - POSIX says that time functions shall set timezone info i.e., timezone is not a constant (it is obvious due to tzset() existence) - Python tests assume that timezone corresponds to the current time (not january or july) I'm not sure what time.timezone behaviour should be: - leave it as is (unsynchronized with C values and it may be different from the current correct value) -- it makes time module unusable in some timezones (60% all time, 11% since 2001), some of the time - use "latest" correct (gmtoff where available) value during importing the time module -- it would fix this issue22752 - synchronize with C values -- it improves some things e.g., it may fix http://bugs.python.org/issue22426 but it might make the behavior more platform dependent (tests needed) and it make things worse in some timezones e.g., where dst() != 1 hour (13% all time, 0.9% since 2000) [1] http://www.gnu.org/software/libc/manual/html_node/Time-Zone-Functions.html [2] http://pubs.opengroup.org/onlinepubs/9699919799/functions/mktime.html -- nosy: +akira ___ Python tracker <http://bugs.python.org/issue22752> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22798] time.mktime doesn't update time.tzname
Akira Li added the comment: One of the ways to fix this issue is to synchronize time.tzname attribute with the corresponding C tzname variable. I've uploaded sync-time-timezone-attr-with-c.diff patch that synchronizes tzname, timezone, altzone, daylight attributes. The patch also includes tests. No docs changes are necessary. The code follows C, POSIX standards and the time module documentation. Any differences are unintetional. The patch also fixes "wrong time.timezone" issue http://bugs.python.org/issue22799 The patch doesn't use tm_gmtoff, tm_zone C values from jan, jul to set timezone, tzname time module attributes therefore it may break software that relies on that behaviour. I would be interested to hear about such instances. I've removed the cygwin branch in the code (I haven't found cygwin buildbot). It could be added back as is if necessary. -- Added file: http://bugs.python.org/file37273/sync-time-timezone-attr-with-c.diff ___ Python tracker <http://bugs.python.org/issue22798> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com