[issue26792] docstrings of runpy.run_{module,path} are rather sparse
Change by Antony Lee : -- nosy: -Antony.Lee ___ Python tracker <https://bugs.python.org/issue26792> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue46785] On Windows, os.stat() can fail if called while another process is creating or deleting the file
Change by Antony Lee : -- nosy: -Antony.Lee ___ Python tracker <https://bugs.python.org/issue46785> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue46785] On Windows, os.stat() can fail if called while another process is creating or deleting the file
New submission from Antony Lee : In a first Python process, repeatedly create and delete a file: from pathlib import Path while True: Path("foo").touch(); Path("foo").unlink() In another process, repeatedly check for the path's existence: from pathlib import Path while True: print(Path("foo").exists()) On Linux, the second process prints a random series of True and False. On Windows, it quickly fails after a few dozen iterations (likely machine-dependent) with PermissionError: [WinError 5] Access is denied: 'foo' which is actually raised by the stat() call. I would suggest that this is not really desirable behavior? -- components: Windows messages: 413468 nosy: Antony.Lee, paul.moore, steve.dower, tim.golden, zach.ware priority: normal severity: normal status: open title: On Windows, os.stat() can fail if called while another process is creating or deleting the file versions: Python 3.10 ___ Python tracker <https://bugs.python.org/issue46785> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue43721] Documentation of property.{getter, setter, deleter} fails to mention that a *new* property is returned
Change by Antony Lee : -- nosy: -Antony.Lee ___ Python tracker <https://bugs.python.org/issue43721> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue26120] pydoc: move __future__ imports out of the DATA block
Change by Antony Lee : -- nosy: -Antony.Lee ___ Python tracker <https://bugs.python.org/issue26120> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue24253] pydoc for namespace packages indicates FILE as built-in
Change by Antony Lee : -- nosy: -Antony.Lee ___ Python tracker <https://bugs.python.org/issue24253> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue45962] Clarify that PyModule_AddString{Constant, Macro} use utf-8
New submission from Antony Lee : The documentation for PyModule_AddString{Constant,Macro} does not specify the encoding used. Checking the source shows that these simply call PyUnicode_FromString and thus use utf8, but perhaps this could be made explicit. -- assignee: docs@python components: C API, Documentation messages: 407518 nosy: Antony.Lee, docs@python priority: normal severity: normal status: open title: Clarify that PyModule_AddString{Constant,Macro} use utf-8 versions: Python 3.11 ___ Python tracker <https://bugs.python.org/issue45962> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue43286] [doc] Clarify that Popen.returncode does not get auto-set when the process terminates
Change by Antony Lee : -- nosy: -Antony.Lee ___ Python tracker <https://bugs.python.org/issue43286> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue33581] Document "optional components that are commonly included in Python distributions."
Change by Antony Lee : -- nosy: -Antony.Lee ___ Python tracker <https://bugs.python.org/issue33581> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue27161] Confusing exception in Path().with_name
Change by Antony Lee : -- nosy: -Antony.Lee ___ Python tracker <https://bugs.python.org/issue27161> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue23991] ZipFile sanity checks
Change by Antony Lee : -- nosy: -Antony.Lee ___ Python tracker <https://bugs.python.org/issue23991> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue25477] text mode for pkgutil.get_data
Change by Antony Lee : -- nosy: -Antony.Lee ___ Python tracker <https://bugs.python.org/issue25477> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue44019] operator.call/operator.__call__
Change by Antony Lee : -- nosy: -Antony.Lee ___ Python tracker <https://bugs.python.org/issue44019> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue44019] operator.call/operator.__call__
Antony Lee added the comment: Python2's apply has different semantics: it takes non-unpacked arguments, i.e. def apply(f, args, kwargs={}): return f(*args, **kwargs) rather than def call(f, *args, **kwargs): return f(*args, **kwargs) I agree that both functions can be written in two (or one) line, but the same can be said of most functions in the operator module (def add(x, y): return x + y); from the module's doc ("efficient functions corresponding to the intrinsic operators"), I would argue that the criteria for inclusion are efficiency (operator.call is indeed fast, see the linked PR) and intrinsicness (I don't know if there's a hard definition, but function calling certainly seems intrinsic). -- ___ Python tracker <https://bugs.python.org/issue44019> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue27175] Unpickling Path objects
Antony Lee added the comment: I guess I could instead add some OS-dependent entries for Path classes into _compat_pickle (to do the remapping at load time) if you prefer? I don't have a strong preference either-way. -- ___ Python tracker <https://bugs.python.org/issue27175> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue27175] Unpickling Path objects
Antony Lee added the comment: Despite the now well-known security limitations of pickle, it is still used as a simple way (from the user PoV) to exchange arbitrary Python objects (see e.g. https://joblib.readthedocs.io/en/latest/persistence.html). Such objects can sometimes include Paths as attributes, and it seems unfortunate that the presence of a Path makes the entire object (which may include many more things than just the Path) impossible to unpickle on a different OS (especially if unpickling into a PurePath keeps all the functionality that makes sense on that other OS). -- ___ Python tracker <https://bugs.python.org/issue27175> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue27175] Unpickling Path objects
Antony Lee added the comment: You are correct as to the meaning of "convert". The alternative approach you suggest would also work, but that seems to go much more against the design of pathlib to me. OTOH I guess it is up to Antoine to rule on that. -- ___ Python tracker <https://bugs.python.org/issue27175> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue27175] Unpickling Path objects
Antony Lee added the comment: It means the Path/PurePath that would be constructed with the same single str parameter, or equivalently that has the same os.fspath(). -- ___ Python tracker <https://bugs.python.org/issue27175> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue27175] Unpickling Path objects
Change by Antony Lee : -- keywords: +patch pull_requests: +26526 stage: -> patch review pull_request: https://github.com/python/cpython/pull/28083 ___ Python tracker <https://bugs.python.org/issue27175> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue44019] operator.call/operator.__call__
Antony Lee added the comment: > I'm not convinced that operator.caller() would be useful to me. To be clear, as noted above, I have realized that the semantics I initially proposed (now known as "caller") are not particularly useful; the semantics I am proposing (and implementing in the linked PR) are `call(f, *args, **kwargs) == f(*args, **kwargs)`. > I don't see how operator.caller() implements an existing "intrinsic operators > of Python". Agreed; on the other hand function calling is much more intrinsic(?!) > Can't you use functools.partial() for that? How do you propose to do that? Perhaps I am missing an easy solution... -- ___ Python tracker <https://bugs.python.org/issue44019> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue44019] operator.call/operator.__call__
Change by Antony Lee : -- keywords: +patch pull_requests: +26342 stage: -> patch review pull_request: https://github.com/python/cpython/pull/27888 ___ Python tracker <https://bugs.python.org/issue44019> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue38956] argparse.BooleanOptionalAction should not add the default value to the help string by default
Change by Antony Lee : -- nosy: -Antony.Lee ___ Python tracker <https://bugs.python.org/issue38956> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue44850] Could operator.methodcaller be optimized using LOAD_METHOD?
Change by Antony Lee : -- keywords: +patch pull_requests: +26252 stage: -> patch review pull_request: https://github.com/python/cpython/pull/27782 ___ Python tracker <https://bugs.python.org/issue44850> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue44850] Could operator.methodcaller be optimized using LOAD_METHOD?
New submission from Antony Lee : Currently, methodcaller is not faster than a plain lambda: ``` In [1]: class T: ...: a = 1 ...: def f(self): pass ...: In [2]: from operator import * In [3]: %%timeit t = T(); mc = methodcaller("f") ...: mc(t) ...: ...: 83.1 ns ± 0.862 ns per loop (mean ± std. dev. of 7 runs, 1000 loops each) In [4]: %%timeit t = T(); mc = lambda x: x.f() ...: mc(t) ...: ...: 81.4 ns ± 0.0508 ns per loop (mean ± std. dev. of 7 runs, 1000 loops each) ``` (on some machines, I find that it is even slower). Compare with attrgetter, which *is* faster: ``` In [5]: %%timeit t = T(); ag = attrgetter("a") ...: ag(t) ...: ...: 33.7 ns ± 0.0407 ns per loop (mean ± std. dev. of 7 runs, 1000 loops each) In [6]: %%timeit t = T(); ag = lambda x: x.a ...: ag(t) ...: ...: 50.1 ns ± 0.057 ns per loop (mean ± std. dev. of 7 runs, 1000 loops each) ``` Given that the operator module explicitly advertises itself as being "efficient"/"fast", it seems reasonable to try to optimize methodcaller. Looking at its C implementation, methodcaller currently uses PyObject_GetAttr followed by PyObject_Call; I wonder whether this can be optimized using a LOAD_METHOD-style approach to avoid the construction of the bound method (when applicable)? -- components: Library (Lib) messages: 399066 nosy: Antony.Lee priority: normal severity: normal status: open title: Could operator.methodcaller be optimized using LOAD_METHOD? ___ Python tracker <https://bugs.python.org/issue44850> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue44019] operator.call/operator.__call__
Antony Lee added the comment: Actually, upon further thought, the semantics I suggested above should go into `operator.caller` (cf. `operator.methodcaller`), and `operator.call`/`operator.__call__` should instead be defined as `operator.call(f, *args, **kwargs) == f(*args, **kwargs)`, so that the general rule `operator.opname(a, b) == a.__opname__(b)` (modulo dunder lookup rules) remains applicable. -- ___ Python tracker <https://bugs.python.org/issue44019> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue20012] Re: Allow Path.relative_to() to accept non-ancestor paths
Change by Antony Lee : -- nosy: -Antony.Lee ___ Python tracker <https://bugs.python.org/issue20012> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue34389] CPython may fail to build in the presence of a ~/.pydistutils.cfg
Change by Antony Lee : -- nosy: -Antony.Lee ___ Python tracker <https://bugs.python.org/issue34389> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue44189] multiprocessing AF_PIPE name format is slightly confusing in the docs
New submission from Antony Lee : https://docs.python.org/3/library/multiprocessing.html#address-formats currently states > An 'AF_PIPE' address is a string of the form r'\.\pipe{PipeName}'. To use > Client() to connect to a named pipe on a remote computer called ServerName > one should use an address of the form r'\ServerName\pipe{PipeName}' instead. which suggests that if the pipe is named "foo", the string should be r'\.\pipe{foo}' (especially given that the other substituted string, ServerName, is given in italics... but actually the correct format is r'\.\pipe\foo'. Hence I would suggest fixing the markup to give name formats as r'\.pipe\PipeName' where PipeName, is in italics, like ServerName. -- assignee: docs@python components: Documentation messages: 394020 nosy: Antony.Lee, docs@python priority: normal severity: normal status: open title: multiprocessing AF_PIPE name format is slightly confusing in the docs ___ Python tracker <https://bugs.python.org/issue44189> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue44019] operator.call/operator.__call__
New submission from Antony Lee : Adding a call/__call__ function to the operator module (where `operator.call(*args, **kwargs)(func) == func(*args, **kwargs)`, similarly to operator.methodcaller) seems consistent with the design with the rest of the operator module. An actual use case I had for such an operator was collecting a bunch of callables in a list and wanting to dispatch them to concurrent.futures.Executor.map, i.e. something like `executor.map(operator.call, funcs)` (to get the parallelized version of `[func() for func in funcs]`). -- components: Library (Lib) messages: 392809 nosy: Antony.Lee priority: normal severity: normal status: open title: operator.call/operator.__call__ versions: Python 3.11 ___ Python tracker <https://bugs.python.org/issue44019> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue43721] Documentation of property.{getter, setter, deleter} fails to mention that a *new* property is returned
New submission from Antony Lee : property.{getter,setter,deleter} returns a new property with a new {fget,fset,fdel}. This is documented at https://docs.python.org/3/library/functions.html#property, and intended behavior (see e.g. https://bugs.python.org/issue1620). However the corresponding docstrings, e.g. `pydoc property.getter`, are "Descriptor to change the getter (setter, deleter) on a property." This wording suggests that no copy is being made and that the property is mutated in-place. -- assignee: docs@python components: Documentation messages: 390149 nosy: Antony.Lee, docs@python priority: normal severity: normal status: open title: Documentation of property.{getter,setter,deleter} fails to mention that a *new* property is returned ___ Python tracker <https://bugs.python.org/issue43721> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue43286] Clarify that Popen.returncode does not get auto-set when the process terminates
New submission from Antony Lee : Currently, the documentation for Popen.returncode states The child return code, set by poll() and wait() (and indirectly by communicate()). A None value indicates that the process hasn’t terminated yet. A negative value -N indicates that the child was terminated by signal N (POSIX only). As far back as https://bugs.python.org/issue1727024 it had been suggested that this fails to emphasize an important piece of information, namely that this attribute can be outdated (it is *only* set if poll() or wait() are called; this is not obvious, e.g. returncode could have beeen implemented as a property that auto-calls poll()). I do realize that a strict reading of the docs does suggest the actual behavior, but a bit of explicitness won't hurt... The wording suggested in https://bugs.python.org/issue1727024 seems clearer to me ("Note: The value stored in returncode may be out-of-date. Use poll() to reliably find the current return code."). -- assignee: docs@python components: Documentation messages: 387463 nosy: Antony.Lee, docs@python priority: normal severity: normal status: open title: Clarify that Popen.returncode does not get auto-set when the process terminates versions: Python 3.10 ___ Python tracker <https://bugs.python.org/issue43286> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue42976] __text_signature__ parser silently drops arguments with certain unsupported default forms
New submission from Antony Lee : Starting from the keyword-arguments example at https://docs.python.org/3/extending/extending.html#keyword-parameters-for-extension-functions, change the docstring of `parrot` to "parrot(voltage, state, action, type=1<<5)\n--\n\n" (yes, the documented default value for type does not correspond to the actual implementation, but that's irrelevant here). Compiling the extension module and running pydoc on it yields the following parsed signature for `parrot`: `parrot(voltage, state, action)` i.e. the `type` parameter got silently dropped. (Note that `1<<5` can legitimately occur, e.g. as a bitmask flag, especially given that one currently cannot refer to globals in __text_signature__ (https://bugs.python.org/issue37881).) -- components: Extension Modules messages: 385335 nosy: Antony.Lee priority: normal severity: normal status: open title: __text_signature__ parser silently drops arguments with certain unsupported default forms ___ Python tracker <https://bugs.python.org/issue42976> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue42684] Improvements to documentation for PyUnicode_FS{Converter, Decoder}
New submission from Antony Lee : The docs for PyUnicode_FSConverter and PyUnicode_FSDecoder could be improved on two points: - The functions also reject str/bytes that contain null bytes (one can easily verify that there's a specific check for them in the C implementations). Currently the docs only say that the converters use PyUnicode_EncodeFSDefault/PyUnicode_DecodeFSDefaultAndSize, but those don't check for null bytes. - The functions only ever return 1 or 0 (indicating success or failures), which means that one can just use e.g. `if (!PyUnicode_FSConverter(foo, &bar)) { goto error; } ...` (this pattern occurs repeatedly in the CPython codebase). In theory, given that the functions are only documented as being "O&"-converters, they could also be returning Py_CLEANUP_SUPPORTED in which case they'd need to be called a second time on failure to release allocated memory. -- assignee: docs@python components: C API, Documentation messages: 383378 nosy: Antony.Lee, docs@python priority: normal severity: normal status: open title: Improvements to documentation for PyUnicode_FS{Converter,Decoder} ___ Python tracker <https://bugs.python.org/issue42684> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue42385] adjust enum.auto's behavior for StrEnum to return the enum name
Change by Antony Lee : -- nosy: -Antony.Lee ___ Python tracker <https://bugs.python.org/issue42385> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue42385] adjust enum.auto's behavior for StrEnum to return the enum name
Antony Lee added the comment: Thanks for implementing! -- ___ Python tracker <https://bugs.python.org/issue42385> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue34750] locals().update doesn't work in Enum body, even though direct assignment to locals() does
Change by Antony Lee : -- nosy: -Antony.Lee ___ Python tracker <https://bugs.python.org/issue34750> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue34750] locals().update doesn't work in Enum body, even though direct assignment to locals() does
Antony Lee added the comment: Thanks! -- ___ Python tracker <https://bugs.python.org/issue34750> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue42520] add_dll_directory only accepts absolute paths
New submission from Antony Lee : os.add_dll_directory appears to only accept absolute paths, inheriting this restriction from AddDllDirectory. That's absolutely fine, but could perhaps be mentioned in the docs (https://docs.python.org/3/library/os.html#os.add_dll_directory), especially considering that the docs do mention the parallel with `sys.path`, which *does* support relative paths. -- assignee: docs@python components: Documentation messages: 382228 nosy: Antony.Lee, docs@python priority: normal severity: normal status: open title: add_dll_directory only accepts absolute paths versions: Python 3.9 ___ Python tracker <https://bugs.python.org/issue42520> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue42451] Indicate in the docs that PyTuple_GetItem does not support negative indices
Change by Antony Lee : -- nosy: -Antony.Lee ___ Python tracker <https://bugs.python.org/issue42451> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue42451] Indicate in the docs that PyTuple_GetItem does not support negative indices
New submission from Antony Lee : Unlike `PySequence_GetItem`, `PyTuple_GetItem` does not support negative indices ("indexing from the end"). That is fine, but warrants a notice in the docs (as that behavior is certainly not obvious). The same wording as for `PyList_GetItem` (changing "list" to "tuple") should be good enough (`PyList_GetItem` currently states: "The position must be non-negative; indexing from the end of the list is not supported. If index is out of bounds (<0 or >=len(list)), return NULL and set an IndexError exception.") -- assignee: docs@python components: C API, Documentation messages: 381716 nosy: Antony.Lee, docs@python priority: normal severity: normal status: open title: Indicate in the docs that PyTuple_GetItem does not support negative indices versions: Python 3.10 ___ Python tracker <https://bugs.python.org/issue42451> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue42385] Should enum.auto's behavior be adjusted for StrEnum to return the enum name?
New submission from Antony Lee : Currently, enum.auto doesn't work with the new (Py3.10) StrEnum: `class E(enum.StrEnum): a = enum.auto()` results in `TypeError: 1 is not a string`. I would guess that the most reasonable behavior for auto() in a StrEnum would be to return the name itself, as implemented in the AutoName example at https://docs.python.org/3.10/library/enum.html#using-automatic-values. I believe that this may just be a matter of copying the corresponding `_generate_next_value_` implementation into the definition of StrEnum? -- components: Library (Lib) messages: 381220 nosy: Antony.Lee priority: normal severity: normal status: open title: Should enum.auto's behavior be adjusted for StrEnum to return the enum name? versions: Python 3.10 ___ Python tracker <https://bugs.python.org/issue42385> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue40624] add support for != (not-equals) in ElementTree XPath
Change by Antony Lee : -- nosy: -Antony.Lee ___ Python tracker <https://bugs.python.org/issue40624> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue27320] ./setup.py --help-commands should sort extra commands
Change by Antony Lee : -- nosy: -Antony.Lee ___ Python tracker <https://bugs.python.org/issue27320> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue24970] Make distutils.Command an ABC
Change by Antony Lee : -- nosy: -Antony.Lee ___ Python tracker <https://bugs.python.org/issue24970> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue34750] locals().update doesn't work in Enum body, even though direct assignment to locals() does
Antony Lee added the comment: To be honest, I don't really remember what exact use case I had in my mind 2 years ago (as I probably worked around it in one way or another). However, one example that I can think of (and that I have actually implemented before) is auto-conversion of C #defines from a C header file to a Python-level enum (e.g. for semi-automatic generation of a ctypes wrapper): # A general header parser (untested, just an example) def parse_defines(header_file): d = {} for line in header_file: if line.startswith("#define"): _, k, v = line.split() d[k] = int(v) return d # Now wrapping a specific C library foo_defines = parse_defines("foo.h") class Foo(Enum): locals().update({k: v for k, v in foo_defines.items() if k.startswith("FOO_")}) def some_method(self): ... # e.g. call a C function that takes a FOO_* as parameter. Obviously I could always just replace the method by a free function, but that's true for (nearly) all methods. In other words, it seems a bit "unfair" that it is easy to define methods on enums where all options are explicitly listed, but very hard(?) to do so on enums with programatically defined options. -- ___ Python tracker <https://bugs.python.org/issue34750> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39783] Optimize construction of Path from other Paths by just returning the same object?
Change by Antony Lee : -- nosy: -Antony.Lee ___ Python tracker <https://bugs.python.org/issue39783> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue31254] WeakKeyDictionary/Mapping doesn't call __missing__
Change by Antony Lee : -- nosy: -Antony.Lee ___ Python tracker <https://bugs.python.org/issue31254> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue38045] enum.Flag instance creation is slow
Antony Lee added the comment: Now fixed, I believe. -- resolution: -> fixed stage: patch review -> resolved status: open -> closed ___ Python tracker <https://bugs.python.org/issue38045> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue40625] Autogenerate signature for METH_NOARGS and perhaps METH_O extension functions
New submission from Antony Lee : It would be nice if METH_NOARGS extension methods had an autogenerated signature (or rather, autogenerated __text_signature__ that gets picked up by inspect.signature). After all, the signature is trivially known at compile time. The same *could* possibly be done for METH_O methods, for which the effective signature is known too. The *name* of the sole parameter is not known, but given that the parameter is (I believe?) positional only, that name "shouldn't" really matter (in the sense, e.g., that whether `signature.bind()` succeeds or not doesn't depend on the parameter name). -- components: C API messages: 368830 nosy: Antony.Lee priority: normal severity: normal status: open title: Autogenerate signature for METH_NOARGS and perhaps METH_O extension functions versions: Python 3.9 ___ Python tracker <https://bugs.python.org/issue40625> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue40624] add support for != (not-equals) in ElementTree XPath
New submission from Antony Lee : It would be a small usability improvement if ElementTree's XPath support also supported the != (not-equals) operator. I am specifically mentioning only != and not >/ <https://bugs.python.org/issue40624> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue40470] Make inspect.signature able to parse format strings.
New submission from Antony Lee : It would be nice if inspect.signature was able to understand bound str.format methods, e.g. `inspect.signature("{a} {b}".format) == inspect.signature(lambda *args, a, b, **kwargs: None)` (`*args, **kwargs` are there because str.format ignores additional arguments). Right now I believe the only way to parse format strings is string.Formatter, which is slightly less discoverable and harder to use (although it certainly also provides more info, e.g. inspect.signature wouldn't be able to tell about format specifiers, but that's fine). -- messages: 367852 nosy: Antony.Lee priority: normal severity: normal status: open title: Make inspect.signature able to parse format strings. versions: Python 3.9 ___ Python tracker <https://bugs.python.org/issue40470> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue40313] bytes.hex(sep, bytes_per_sep) is many times slower than manually inserting the separators
New submission from Antony Lee : Consider the following example, linewrapping 10^4 bytes in hex form to 128 characters per line, on Py 3.8.2 (Arch Linux repo package): In [1]: import numpy as np, math In [2]: data = np.random.randint(0, 256, (100, 100), dtype=np.uint8).tobytes() In [3]: %timeit data.hex("\n", -64) 123 µs ± 5.8 µs per loop (mean ± std. dev. of 7 runs, 1 loops each) In [4]: %timeit h = data.hex(); "\n".join([h[n * 128 : (n+1) * 128] for n in range(math.ceil(len(h) / 128))]) 45.4 µs ± 746 ns per loop (mean ± std. dev. of 7 runs, 1 loops each) In [5]: h = data.hex(); "\n".join([h[n * 128 : (n+1) * 128] for n in range(math.ceil(len(h) / 128))]) == data.hex("\n", -64) Out[5]: True (the last line checks the validity of the code.) It appears that a naive manual wrap is nearly 3x faster than the builtin functionality. -- components: Library (Lib) messages: 366678 nosy: Antony.Lee priority: normal severity: normal status: open title: bytes.hex(sep, bytes_per_sep) is many times slower than manually inserting the separators versions: Python 3.8 ___ Python tracker <https://bugs.python.org/issue40313> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39682] pathlib.Path objects can be used as context managers
Change by Antony Lee : -- nosy: -Antony.Lee ___ Python tracker <https://bugs.python.org/issue39682> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue25024] Allow passing "delete=False" to TemporaryDirectory
Change by Antony Lee : -- nosy: -Antony.Lee ___ Python tracker <https://bugs.python.org/issue25024> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39682] pathlib.Path objects can be used as context managers
Antony Lee added the comment: Immutability and hashability are listed first among "general properties" of paths (https://docs.python.org/3/library/pathlib.html#general-properties), and in the PEP proposing pathlib (https://www.python.org/dev/peps/pep-0428/#immutability). Looking at it again I *guess* the docs version could be read as only guaranteeing this for PurePaths (because that's in the PurePath section) rather than Path, but the PEP version clearly implies that this is true for both PurePaths and concrete Paths. It may be tricky to check usage in third-party packages, given that one would need to look for `with : ...` rather than, say, a method name which can be grepped. Do you have any suggestions here? -- ___ Python tracker <https://bugs.python.org/issue39682> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39775] inspect.Signature.parameters should be an OrderedDict, not a plain dict
Change by Antony Lee : -- nosy: -Antony.Lee ___ Python tracker <https://bugs.python.org/issue39775> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue23080] BoundArguments.arguments should be unordered
Change by Antony Lee : -- nosy: -Antony.Lee ___ Python tracker <https://bugs.python.org/issue23080> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39682] pathlib.Path objects can be used as context managers
Antony Lee added the comment: A problem of having this bit of state in paths is that it violates assumptions based on immutability/hashability, e.g. with from pathlib import Path p = Path("foo") q = Path("foo") with p: pass unique_paths = {p, q} print(len(unique_paths)) # == 1, as p == q for path in unique_paths: print(path.resolve()) # Fails if the path is closed. The last line fails with `unique_paths = {p, q}` as p has been closed (and apparently sets keep the first element when multiple "equal" elements are passed in), but not with `unique_paths = {q, p}`. It would also prevent optimizations based on immutability as proposed in https://bugs.python.org/issue39783. -- nosy: +Antony.Lee ___ Python tracker <https://bugs.python.org/issue39682> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39783] Optimize construction of Path from other Paths by just returning the same object?
Antony Lee added the comment: Decorating __new__ with lru_cache would likely run into memory leakage problems? (one would need a "weak lru_cache", I guess). I didn't know about the _closed attribute. From a quick look it appears to only be settable by using the path (not the actual file) as a context manager, and only serves to block further filesystem methods, but I'm not even sure why? (for example, it doesn't block fspath, so it won't prevent operations via os.path functions anyways...) -- ___ Python tracker <https://bugs.python.org/issue39783> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39783] Optimize construction of Path from other Paths by just returning the same object?
New submission from Antony Lee : Many functions which take a path-like object typically also accept strings (sorry, no hard numbers here). This means that if the function plans to call Path methods on the object, it needs to first call Path() on the arguments to convert them, well, to Paths. This adds an unnecessary cost in the case where the argument is *already* a Path object (which should become more and more common as the use of pathlib spreads), as Path instantiation is not exactly cheap (it's on the order of microseconds). Instead, given that Paths are immutable, `Path(path)` could just return the exact same path instance, completely bypassing instance creation (after checking that the argument's type exactly matches whatever we need and is not, say, PureWindowsPath when we want to instantiate a PosixPath, etc.). Note that there is prior art for doing so in CPython: creating a frozenset from another frozenset just returns the same instance: ``` In [1]: s = frozenset({1}); id(s) == id(frozenset(s)) == id(s.copy()) Out[1]: True ``` -- components: Library (Lib) messages: 362874 nosy: Antony.Lee priority: normal severity: normal status: open title: Optimize construction of Path from other Paths by just returning the same object? versions: Python 3.9 ___ Python tracker <https://bugs.python.org/issue39783> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39775] inspect.Signature.parameters should be an OrderedDict, not a plain dict
Antony Lee added the comment: It looks good to me, thanks. -- ___ Python tracker <https://bugs.python.org/issue39775> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39775] inspect.Signature.parameters should be an OrderedDict, not a plain dict
New submission from Antony Lee : https://bugs.python.org/issue36350 / https://github.com/python/cpython/pull/12412 changed Signature.parameters and BoundArguments.arguments to be plain dicts, not OrderedDicts (for Py3.9a4). Even though I agree for BoundArguments.arguments (in fact I argued for this behavior in https://bugs.python.org/issue23080), I think Signature.parameters should remain OrderedDicts. Otherwise, one would get >>> inspect.signature(lambda x, y: None).parameters == inspect.signature(lambda y, x: None).parameters True which seems plain wrong (comparing the signature objects themselves still correctly return False because __eq__ explicitly considers parameter order, but one may e.g. want to compare parameters for equality while ignoring the return annotation). -- components: Library (Lib) messages: 362800 nosy: Antony.Lee priority: normal severity: normal status: open title: inspect.Signature.parameters should be an OrderedDict, not a plain dict versions: Python 3.9 ___ Python tracker <https://bugs.python.org/issue39775> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue23080] BoundArguments.arguments should be unordered
Antony Lee added the comment: Done in bugs.python.org/issue36350 / https://github.com/python/cpython/pull/12412. -- resolution: -> fixed stage: needs patch -> resolved status: open -> closed ___ Python tracker <https://bugs.python.org/issue23080> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39716] argparse.ArgumentParser does not raise on duplicated subparsers, even though it does on duplicated flags
Antony Lee added the comment: Sure, https://github.com/python/cpython/pull/18605 it is. -- ___ Python tracker <https://bugs.python.org/issue39716> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39716] argparse.ArgumentParser does not raise on duplicated subparsers, even though it does on duplicated flags
Change by Antony Lee : -- keywords: +patch pull_requests: +17971 stage: -> patch review pull_request: https://github.com/python/cpython/pull/18605 ___ Python tracker <https://bugs.python.org/issue39716> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39716] argparse.ArgumentParser does not raise on duplicated subparsers, even though it does on duplicated flags
New submission from Antony Lee : If one tries to add twice the same flag to an ArgumentParser, one gets a helpful exception: from argparse import ArgumentParser p = ArgumentParser() p.add_argument("--foo") p.add_argument("--foo") results in argparse.ArgumentError: argument --foo: conflicting option string: --foo However, adding twice the same subparser raises no exception: from argparse import ArgumentParser p = ArgumentParser() sp = p.add_subparsers() sp.add_parser("foo") sp.add_parser("foo") even though the two subparsers shadow one another in the same way as two identical flags. -- components: Library (Lib) messages: 362421 nosy: Antony.Lee priority: normal severity: normal status: open title: argparse.ArgumentParser does not raise on duplicated subparsers, even though it does on duplicated flags versions: Python 3.9 ___ Python tracker <https://bugs.python.org/issue39716> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39461] [RFE] os.environ should support Path-like values, like subprocess(..., env=...)
Antony Lee added the comment: FWIW, I'm actually fine with not supporting Path objects in os.environ, as long as the behavior is *consistent* with the env kwarg to subprocess.run() -- note that the original title of the thread only pointed out to the inconsistency, and did not strongly request that os.environ support Paths. -- ___ Python tracker <https://bugs.python.org/issue39461> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39461] os.environ does not support Path-like values, but subprocess(..., env=...) does
New submission from Antony Lee : As of Py3.8/Linux: In [1]: os.environ["foo"] = Path("bar") --- TypeError Traceback (most recent call last) in > 1 os.environ["foo"] = Path("bar") ~/miniconda3/envs/default/lib/python3.8/os.py in __setitem__(self, key, value) 676 def __setitem__(self, key, value): 677 key = self.encodekey(key) --> 678 value = self.encodevalue(value) 679 self.putenv(key, value) 680 self._data[key] = value ~/miniconda3/envs/default/lib/python3.8/os.py in encode(value) 746 def encode(value): 747 if not isinstance(value, str): --> 748 raise TypeError("str expected, not %s" % type(value).__name__) 749 return value.encode(encoding, 'surrogateescape') 750 def decode(value): TypeError: str expected, not PosixPath In [2]: subprocess.run('echo "$foo"', env={**os.environ, "foo": Path("bar")}, shell=True) bar Out[2]: CompletedProcess(args='echo "$foo"', returncode=0) I guess it would be nice if it was possible to set os.environ entries to Path-like values, but most importantly, it seems a bit inconsistent that doing so is not possible on os.environ, but works when setting the `env` of a subprocess call. -- components: Library (Lib) messages: 360750 nosy: Antony.Lee priority: normal severity: normal status: open title: os.environ does not support Path-like values, but subprocess(..., env=...) does versions: Python 3.9 ___ Python tracker <https://bugs.python.org/issue39461> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue38956] argparse.BooleanOptionalAction should not add the default value to the help string by default
New submission from Antony Lee : https://bugs.python.org/issue8538 recently added to Py3.9 a much welcome addition to argparse, namely the capability to generate --foo/--no-foo flag pairs. A small issue with the implementation is that it *always* appends the default value to the help string (if any): if help is not None and default is not None: help += f" (default: {default})" This is inconsistent with other action classes, and results in the defaults being printed twice if using ArgumentsDefaultHelpFormatter (which is the documented way to include the defaults in the help text): from argparse import * parser = ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter) parser.add_argument("--foo", action=BooleanOptionalAction, help="Whether to foo it", default=True) parser.add_argument("--quux", help="Set the quux", default=42) print(parser.parse_args()) yields usage: foo.py [-h] [--foo | --no-foo] [--quux QUUX] optional arguments: -h, --help show this help message and exit --foo, --no-foo Whether to foo it (default: True) (default: True) # <--- HERE --quux QUUX Set the quux (default: 42) I think the fix is just a matter of not adding the default value to the help string. -- components: Library (Lib) messages: 357733 nosy: Antony.Lee priority: normal severity: normal status: open title: argparse.BooleanOptionalAction should not add the default value to the help string by default versions: Python 3.9 ___ Python tracker <https://bugs.python.org/issue38956> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue38603] inspect.getdoc could examine the __class__ cell for dynamically generated subclasses
Change by Antony Lee : -- keywords: +patch pull_requests: +16485 stage: -> patch review pull_request: https://github.com/python/cpython/pull/16957 ___ Python tracker <https://bugs.python.org/issue38603> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue38603] inspect.getdoc could examine the __class__ cell for dynamically generated subclasses
New submission from Antony Lee : Currently, `inspect.getdoc()` fails to inherit docstrings in dynamically generated subclasses, such as ``` class Base: def method(self): "some docstring" def make_subclass(): class subclass(Base): def method(self): return super().method() return subclass subclass = make_subclass() inspect.getdoc(subclass.method) # => returns None ``` because `inspect._findclass()` tries to find the base class by parsing `subclass.method.__qualname__` which is `"make_subclass..subclass.method"` and chokes over `..`. In the case where the method does rely on `super()`, there is another way we can go back to the "owning" class of the method: by looking up the contents of the `__class__` cell (which is set up to make 0-arg super()). Perhaps a `__class__` cell could even be set up for *all* methods defined in dynamically created subclasses (i.e. whose `__qualname__` includes `..`), to help with introspection? -- components: Library (Lib) messages: 355472 nosy: Antony.Lee priority: normal severity: normal status: open title: inspect.getdoc could examine the __class__ cell for dynamically generated subclasses versions: Python 3.9 ___ Python tracker <https://bugs.python.org/issue38603> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue38045] enum.Flag instance creation is slow
Antony Lee added the comment: Actually, microoptimizing _power_of_two is a red herring and the problem is the quadratic complexity of _decompose (_value2member_map_ becomes bigger and bigger at each iteration). Replacing the implementation of _decompose by the following fixes the performance issue (the original snippet executes in ~150ms, which may be even more optimizable but already a 30x improvement :)), and still passes test_enum.py (from cpython 3.7.4): def _decompose(flag, value): """Extract all members from the value.""" # _decompose is only called if the value is not named not_covered = value members = [] for member in flag: member_value = member.value if member_value and member_value & value == member_value: members.append(member) not_covered &= ~member_value if issubclass(flag, IntFlag) and value > 0: while not_covered: new_value = 2 ** _high_bit(not_covered) if new_value not in flag._value2member_map_: # construct singleton pseudo-members pseudo_member = int.__new__(flag, value) pseudo_member._name_ = None pseudo_member._value_ = value flag._value2member_map_.setdefault(value, pseudo_member) members.append(flag(new_value)) not_covered &= ~new_value if not members and value in flag._value2member_map_: members.append(flag._value2member_map_[value]) members.sort(key=lambda m: m._value_, reverse=True) if len(members) > 1 and members[0].value == value: # we have the breakdown, don't need the value member itself members.pop(0) return members, not_covered Checking for issubclass(flag, IntFlag) is a bit ugly but that's because Flag and IntFlag really need two separate implementations of _decompose -- the former wants to error out on uncovered values, the latter should create them on-the-fly. -- ___ Python tracker <https://bugs.python.org/issue38045> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue38045] Flag instance creation is slow
New submission from Antony Lee : Consider the following example from enum import Flag F = Flag("F", list("abcdefghijklm")) for idx in range(2**len(F) - 1): F(idx) creating all possible combos of 13 flags, so 8192 instances (yes, I know the instances are cached later, but the initial cost is still significant). Locally, this takes over 4.5s to execute; profiling shows that ~30% of that time is spent executing enum._is_power_of_two(!): def _power_of_two(value): if value < 1: return False return value == 2 ** _high_bit(value) Indeed, replacing the implementation of _power_of_two by import math _powers_of_two = { 2 ** i for i in range(math.ceil(math.log2(sys.maxsize)) + 1)} def _power_of_two(value): return (value in _powers_of_two if value <= sys.maxsize else value == 2 ** _high_bit(value)) shaves off ~30% of the runtime (obviously this won't help for huge (>sys.maxsize) flag values, but these are rarer I would think). An even better fix, I think, would be for Flag to cache `flags_to_check` (updating it at the same time as `_value2member_map_`) instead of recomputing it each time in _decompose flags_to_check = [ (m, v) for v, m in list(flag._value2member_map_.items()) if m.name is not None or _power_of_two(v) ] as this actually needlessly introduces quadratic complexity when iterating over all possible combos (because the size of _value2member_map_ is growing). (Also, it's not actually clear to me how one can end up with unnamed power-of-two instances in _value2member_map?) -- messages: 351244 nosy: Antony.Lee priority: normal severity: normal status: open title: Flag instance creation is slow versions: Python 3.8 ___ Python tracker <https://bugs.python.org/issue38045> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue37743] How should contextmanager/ContextDecorator work with generators?
Change by Antony Lee : -- nosy: -Antony.Lee ___ Python tracker <https://bugs.python.org/issue37743> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue37881] __text_signature__ parser doesn't handle globals in extension module
New submission from Antony Lee : Starting from the custom2 example at https://docs.python.org/3/extending/newtypes_tutorial.html#adding-data-and-methods-to-the-basic-example, change the methods table to static PyMethodDef Custom_methods[] = { {"foo", (PyCFunction) Custom_foo, METH_VARARGS, "foo(x=ONE)\n--\n\nFoos this." }, {NULL} /* Sentinel */ }; and add a global ONE to the module dict: PyModule_AddObject(m, "ONE", PyLong_FromLong(1)); Building and running e.g. pydoc on this module results in Traceback (most recent call last): File ".../lib/python3.7/inspect.py", line 2003, in wrap_value value = eval(s, module_dict) File "", line 1, in NameError: name 'ONE' is not defined During handling of the above exception, another exception occurred: Traceback (most recent call last): File ".../lib/python3.7/inspect.py", line 2006, in wrap_value value = eval(s, sys_module_dict) File "", line 1, in NameError: name 'ONE' is not defined During handling of the above exception, another exception occurred: Traceback (most recent call last): File ".../lib/python3.7/runpy.py", line 193, in _run_module_as_main "__main__", mod_spec) File ".../lib/python3.7/inspect.py", line 2008, in wrap_value raise RuntimeError() RuntimeError I think the fix is fairly simple; one needs to replace module_name = getattr(obj, '__module__', None) in inspect.py::_signature_fromstr by module_name = (getattr(obj, '__module__', None) or getattr(getattr(obj, '__objclass__'), '__module__', None)) (This is a less general but simpler solution than https://bugs.python.org/issue23967.) -- components: Extension Modules messages: 349919 nosy: Antony.Lee priority: normal severity: normal status: open title: __text_signature__ parser doesn't handle globals in extension module ___ Python tracker <https://bugs.python.org/issue37881> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue37743] How should contextmanager/ContextDecorator work with generators?
New submission from Antony Lee : The docs for ContextDecorator (of which contextmanager is a case) describe its semantics as: ... for any construct of the following form: def f(): with cm(): # Do stuff ContextDecorator lets you instead write: @cm() def f(): # Do stuff However, when decorating a generator, the equivalence is broken: from contextlib import contextmanager @contextmanager def cm(): print("start") yield print("stop") def gen_using_with(): with cm(): yield from map(print, range(2)) @cm() def gen_using_decorator(): yield from map(print, range(2)) print("using with") list(gen_using_with()) print("==") print("using decorator") list(gen_using_decorator()) results in using with start 0 1 stop == using decorator start stop 0 1 i.e., when used as a decorator, the entire contextmanager is executed first before iterating over the generator (which is unsurprising given the implementation of ContextDecorator: ContextDecorator returns a function that executes the context manager and returns the generator, which is only iterated over later). Should this be considered as a bug in ContextDecorator, and should ContextDecorator instead detect when it is used to decorate a generator (e.g. with inspect.isgeneratorfunction), and switch its implementation accordingly in that case? -- components: Library (Lib) messages: 348878 nosy: Antony.Lee priority: normal severity: normal status: open title: How should contextmanager/ContextDecorator work with generators? versions: Python 3.8 ___ Python tracker <https://bugs.python.org/issue37743> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue31006] typing.NamedTuple should add annotations to its constructor (__new__) parameters.
Change by Antony Lee : -- nosy: -Antony.Lee ___ Python tracker <https://bugs.python.org/issue31006> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue37109] Inacurrate documentation regarding return type of math.factorial
Change by Antony Lee : -- nosy: -Antony.Lee ___ Python tracker <https://bugs.python.org/issue37109> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue37109] Inacurrate documentation regarding return type of math.factorial
Antony Lee added the comment: oops, missed that, thanks for pointing that out. -- stage: -> resolved status: open -> closed ___ Python tracker <https://bugs.python.org/issue37109> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue37109] Inacurrate documentation regarding return type of math.factorial
New submission from Antony Lee : https://docs.python.org/3/library/math.html says The following functions are provided by this module. Except when explicitly noted otherwise, all return values are floats. and math.factorial(x) Return x factorial. Raises ValueError if x is not integral or is negative. but math.factorial returns an int (which is perfectly reasonable and just needs to be documented): In [3]: math.factorial(5) Out[3]: 120 -- assignee: docs@python components: Documentation messages: 344039 nosy: Antony.Lee, docs@python priority: normal severity: normal status: open title: Inacurrate documentation regarding return type of math.factorial versions: Python 3.8 ___ Python tracker <https://bugs.python.org/issue37109> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue22964] dbm.open(..., "x")
Change by Antony Lee : -- nosy: -Antony.Lee ___ Python tracker <https://bugs.python.org/issue22964> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue19895] Cryptic error when subclassing multiprocessing classes
Change by Antony Lee : -- nosy: -Antony.Lee ___ Python tracker <https://bugs.python.org/issue19895> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue36277] pdb's recursive debug command is not listed in the docs
Change by Antony Lee : -- nosy: -Antony.Lee ___ Python tracker <https://bugs.python.org/issue36277> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue35232] Add `module`/`qualname` arguments to make_dataclass for picklability
Change by Antony Lee : -- nosy: -Antony.Lee ___ Python tracker <https://bugs.python.org/issue35232> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue36277] pdb's recursive debug command is not listed in the docs
Antony Lee added the comment: I'll pass on that for now. -- ___ Python tracker <https://bugs.python.org/issue36277> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue36277] pdb's recursive debug command is not listed in the docs
New submission from Antony Lee : pdb's recursive debug command (mentioned e.g. in https://bugs.python.org/issue35931) is not listed in https://docs.python.org/3/library/pdb.html#debugger-commands. (I haven't checked whether any other command is missing.) -- assignee: docs@python components: Documentation messages: 337828 nosy: Antony.Lee, docs@python priority: normal severity: normal status: open title: pdb's recursive debug command is not listed in the docs ___ Python tracker <https://bugs.python.org/issue36277> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue35874] Clarify that the (...) convertor to PyArg_ParseTuple... accepts any sequence.
New submission from Antony Lee : The documentation for the accepted types for each format unit in PyArg_ParseTuple (and its variants) is usually quite detailed; compare for example y* (bytes-like object) [Py_buffer] This variant on s* doesn’t accept Unicode objects, only bytes-like objects. This is the recommended way to accept binary data. and S (bytes) [PyBytesObject *] Requires that the Python object is a bytes object, without attempting any conversion. Raises TypeError if the object is not a bytes object. The C variable may also be declared as PyObject*. There, the type in parenthesis (which is explained as "the entry in (round) parentheses is the Python object type that matches the format unit") differentiates between "bytes-like object" and "bytes". However, the documentation for "(...)" is a bit more confusing: (items) (tuple) [matching-items] The object must be a Python sequence whose length is the number of format units in items. The C arguments must correspond to the individual format units in items. Format units for sequences may be nested. The type in parenthesis is "tuple" (exactly), but the paragraph says "sequence". The actual behavior appears indeed to be that any sequence (e.g., list, numpy array) is accepted, so I'd suggest changing the type in the parenthesis to "sequence". -- assignee: docs@python components: Documentation messages: 334660 nosy: Antony.Lee, docs@python priority: normal severity: normal status: open title: Clarify that the (...) convertor to PyArg_ParseTuple... accepts any sequence. ___ Python tracker <https://bugs.python.org/issue35874> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue33944] Deprecate and remove pth files
Change by Antony Lee : -- nosy: -Antony.Lee ___ Python tracker <https://bugs.python.org/issue33944> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue35232] Add `module`/`qualname` arguments to make_dataclass for picklability
New submission from Antony Lee : Currently, dataclasses created by make_dataclass are not picklable, because their __module__ is set to "types". It seems that this would be easily fixed by letting make_dataclass gain a `module` and a `qualname` kwarg, similarly to the Enum functional form (https://docs.python.org/3/library/enum.html#functional-api). -- components: Library (Lib) messages: 329847 nosy: Antony.Lee priority: normal severity: normal status: open title: Add `module`/`qualname` arguments to make_dataclass for picklability versions: Python 3.7 ___ Python tracker <https://bugs.python.org/issue35232> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue33944] Deprecate and remove pth files
Antony Lee added the comment: There are a number of packages that can "self-import" into any Python process depending on the presence of an environment variable, by installing a pth file that contains something like `import os; __import__("thepkg") if os.environ.get("THEENVVAR") else None`. Examples include colorization of logging output (https://coloredlogs.readthedocs.io/en/latest/api.html#environment-variables) or installation of a trace function (https://pypi.org/project/hunter/#environment-variable-activation). If the pth mechanism goes away, a preload system should definitely be present to provide a replacement; it should again support multiple packages each installing their own hook. -- nosy: +Antony.Lee ___ Python tracker <https://bugs.python.org/issue33944> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue35063] Checking for abstractmethod implementation fails to consider MRO for builtins
New submission from Antony Lee : When checking whether a class implements all abstractmethods (to know whether the class can be instantiated), one should only consider methods that come *before* the abstractmethod in the MRO -- methods that come after cannot be said to override the abstractmethod. Indeed, this is currently the case: from abc import ABC, abstractmethod class NeedsFoo(ABC): foo = abstractmethod(lambda self: None) class HasFoo(ABC): foo = lambda self: None class FooImplFirst(HasFoo, NeedsFoo): pass class FooImplSecond(NeedsFoo, HasFoo): pass FooImplFirst() try: FooImplSecond() except TypeError: pass else: raise Exception("Expected error") Here FooImplFirst correctly overrides the foo method (using the HasFoo mixin first), so can be instantiated; FooImplSecond doesn't (by the MRO, FooImplSecond().foo would resolve to the abstract implementation), and we get a TypeError on instantiation. However, this is not the case when considering builtins: from abc import ABC, abstractmethod class NeedsKeys(ABC): keys = abstractmethod(lambda self: None) HasKeys = dict # dict has a keys method. class KeysImplFirst(HasKeys, NeedsKeys): pass class KeysImplSecond(NeedsKeys, HasKeys): pass KeysImplFirst() try: KeysImplSecond() except TypeError: pass else: raise Exception("Expected error") This example differs from the first only by having dict be the mixin that provides the keys method. However, running this example shows that KeysImplSecond() will incorrectly succeed: the ABC machinery does not realize that the keys method has not been overridden. (Alternatively, one could say that "providing the method later in the MRO" is also sufficient; I think that goes against the expectations about ABCs but at least consistency between the non-builtin and builtin cases would be better.) -- components: Library (Lib) messages: 328419 nosy: Antony.Lee priority: normal severity: normal status: open title: Checking for abstractmethod implementation fails to consider MRO for builtins versions: Python 3.7 ___ Python tracker <https://bugs.python.org/issue35063> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue23596] gzip argparse interface
Change by Antony Lee : -- nosy: -Antony.Lee ___ Python tracker <https://bugs.python.org/issue23596> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue34807] pathlib.[r]glob fails when the toplevel directory is not readable, whereas glob.glob "succeeds"
New submission from Antony Lee : After $ mkdir -p foo/bar && chmod 000 foo one gets In [1]: glob.glob("foo/bar") Out[1]: [] but In [2]: list(Path("foo/bar").glob("*")) gives a PermissionError. I'm not arguing that pathlib should reproduce glob's behavior (in fact I think raising an exception is better in this case), but this could be better documented (os.walk does indicate that "By default, errors from the scandir() call are ignored." whereas I don't think either glob or pathlib docs mention this point at all). Compare with https://bugs.python.org/issue24120, which relates to unreadable directories found *inside* the toplevel directory. -- components: Library (Lib) messages: 326432 nosy: Antony.Lee priority: normal severity: normal status: open title: pathlib.[r]glob fails when the toplevel directory is not readable, whereas glob.glob "succeeds" versions: Python 3.7 ___ Python tracker <https://bugs.python.org/issue34807> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue34750] locals().update doesn't work in Enum body, even though direct assignment to locals() does
Antony Lee added the comment: > I agree though that adding an update method would be nice though and can be > done in just a few lines of code. Again, this can be done just be inheriting the methods from MutableMapping. In fact even now one can just write class E(Enum): MutableMapping.update(locals(), {"a": 1}) and this will do the "right" thing but that's hardly an obvious way to do it... -- ___ Python tracker <https://bugs.python.org/issue34750> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue34750] locals().update doesn't work in Enum body, even though direct assignment to locals() does
Antony Lee added the comment: > encourage the common assumption that locals() returns a dict where mutating > it actually works, since it usually doesn't. It does at global and class scope, not at function scope. FWIW, PEP558 (admittedly not accepted yet) proposes to modify the documentation for the semantics of locals() at class-scope to match the actual behavior (https://www.python.org/dev/peps/pep-0558/#class-scope): At class scope [...] changes to the returned mapping must change the values bound to local variable names in the execution environment. > I'm worried that making _EnumDict inherit from collections.abc.MutableMapping > in general would slow down Enums (at the very least creation, I'm not clear > on whether _EnumDict remains, hidden behind the mappingproxy, for future > lookups on the class), since MutableMapping would introduce a Python layer of > overhead to most calls. "Normal" calls won't: __setitem__ / __getitem__ stays what they are, they were implemented in Python and stay implemented in Python. Whoever calls update() will go through an extra Python layer, but there's not much you can do about that. Alternatively, if you *really* don't want to support the MutableMapping API, at least it should be disabled (e.g. by adding stub implementations of update(), etc. that throw NotImplementedError). Again performance-wise this would only affect those who try to call these methods. As a side note, I would be curious to see any realistic code where the performance of enum creation turns out to be critical. I don't think(?) the _EnumDict stays afterwards, at least PEP558 (which supposedly corresponds to the actual current behavior) also states "The mapping returned by locals() will not be used as the actual class namespace underlying the defined class (the class creation process will copy the contents to a fresh dictionary that is only accessible by going through the class machinery)." -- ___ Python tracker <https://bugs.python.org/issue34750> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue34750] locals().update doesn't work in Enum body, even though direct assignment to locals() does
Antony Lee added the comment: I have a personal helper function for writing (Qt) GUIs that generates ComboBoxes from Enums; essentially something like class Choices(Enum): choice1 = "text for choice 1" choice2 = "text for choice 2" def callback(choice: Choices): # do stuff based on choice pass create_combobox(Choices, callback=callback) I'm not including the actual code for create_combobox because it's not particularly relevant here. So far, if I wanted to add methods to the Choice enum (e.g. for simplifying the code in `callback`), I could do it directly; if I wanted to dynamically generate the list of choices, I could also do it (by using the functional API). But to do both, it would have been nice to use the locals().update approach in the bug report above. Instead, I need to do something like class MethodsMixin(Enum): def method(self): ... ChoicesWithMethods = MethodsMixin("ChoicesWithMethods", []) (As a side note, I originally thought I could do the inheritance in the opposite direction Choices = Enum("Choices", [...]) class ChoicesWithMethods(Choices): def method(self): ... but that fails because Choices is a final class. It would be nice if it was still possible to inherit from Choices *as long as only methods are added, rather than new members* (I understand why adding new members is problematic). But this is really a side point.) Making _EnumDict actually support update() and every other relevant method is actually not particularly difficult: I think you just need to make it inherit from (collections.abc.MutableMapping, dict) (in that order); this is exactly the approach used (since a while ago) by matplotlib's RcParams class (https://github.com/matplotlib/matplotlib/blob/v3.0.0/lib/matplotlib/__init__.py#L783). -- ___ Python tracker <https://bugs.python.org/issue34750> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue34750] locals().update doesn't work in Enum body, even though direct assignment to locals() does
New submission from Antony Lee : A quick check suggests that enum entries can be programmatically created by assigning to locals() in the Enum body: class E(Enum): locals()["a"] = 1 E.a # -> However, using locals().update(...) doesn't, and silently does the wrong thing: class E(Enum): locals().update({"a": "a"}) E.a # -> 'a' (Yes, in this simple case, I could just use the functional API (`E = Enum("E", [("a", "a")])`), but the above is simpler if I also want e.g. to define methods for the Enum. -- components: Library (Lib) messages: 325864 nosy: Antony.Lee priority: normal severity: normal status: open title: locals().update doesn't work in Enum body, even though direct assignment to locals() does versions: Python 3.7 ___ Python tracker <https://bugs.python.org/issue34750> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue34526] Path.relative_to() taking multiple arguments could be better documented
New submission from Antony Lee : Currently, the docs for Path.relative_to read PurePath.relative_to(*other) Compute a version of this path relative to the path represented by other. If it’s impossible, ValueError is raised: (examples follow) It's a bit confusing why other is a star-args, especially as no example actually passes more than one argument to relative_to. The docstring is a tiny bit clearer: Return the relative path to another path identified by the passed arguments. If the operation is not possible (because this is not a subpath of the other path), raise ValueError. Effectively, a Path is constructed from all *other args and used as base for the computation of the relative path. It looks a bit like a misfeature to me, but at least it could be better documented (e.g. by adding `Path("/tmp/foo/bar").relative_to("/tmp", "foo") == Path("bar")` as example in the docs). -- assignee: docs@python components: Documentation messages: 324224 nosy: Antony.Lee, docs@python priority: normal severity: normal status: open title: Path.relative_to() taking multiple arguments could be better documented versions: Python 3.7 ___ Python tracker <https://bugs.python.org/issue34526> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue34389] CPython may fail to build in the presence of a ~/.pydistutils.cfg
New submission from Antony Lee : I have a ~/.pydistutils.cfg with the following contents: [build_ext] force = true inplace = true (--force is useful because sometimes just comparing timestamps is insufficient to know whether a package needs to be rebuilt, e.g. in the presence of external dependencies -- and I use ccache anyways to avoid paying for excessive rebuilds; --inplace is useful as I have quite a few packages with extension modules that are editably-installed). With this ~/.pydistutils.cfg, cpython fails to build. For example, having checked out v3.7.0 from a git clone (otherwise clean git repo, per `git clean -xfd`), mkdir build && cd build && ../configure && make ultimately results in gcc -pthread -shared build/temp.linux-x86_64-3.7/home/antony/src/extern/cpython/Modules/_ctypes/_ctypes.o build/temp.linux-x86_64-3.7/home/antony/src/extern/cpython/Modules/_ctypes/callbacks.o build/temp.linux-x86_64-3.7/home/antony/src/extern/cpython/Modules/_ctypes/callproc.o build/temp.linux-x86_64-3.7/home/antony/src/extern/cpython/Modules/_ctypes/stgdict.o build/temp.linux-x86_64-3.7/home/antony/src/extern/cpython/Modules/_ctypes/cfield.o -L/usr/local/lib -lffi -ldl -o /home/antony/src/extern/cpython/build/_ctypes.cpython-37m-x86_64-linux-gnu.so *** WARNING: renaming "_struct" since importing it failed: build/lib.linux-x86_64-3.7/_struct.cpython-37m-x86_64-linux-gnu.so: cannot open shared object file: No such file or directory Traceback (most recent call last): File "../setup.py", line 442, in check_extension_import importlib._bootstrap._load(spec) File "", line 696, in _load File "", line 670, in _load_unlocked File "", line 583, in module_from_spec File "", line 1043, in create_module File "", line 219, in _call_with_frames_removed ImportError: build/lib.linux-x86_64-3.7/_struct.cpython-37m-x86_64-linux-gnu.so: cannot open shared object file: No such file or directory During handling of the above exception, another exception occurred: Traceback (most recent call last): File "../setup.py", line 2363, in main() File "../setup.py", line 2358, in main "Tools/scripts/2to3", "Tools/scripts/pyvenv"] File "/home/antony/src/extern/cpython/Lib/distutils/core.py", line 148, in setup dist.run_commands() File "/home/antony/src/extern/cpython/Lib/distutils/dist.py", line 966, in run_commands self.run_command(cmd) File "/home/antony/src/extern/cpython/Lib/distutils/dist.py", line 985, in run_command cmd_obj.run() File "/home/antony/src/extern/cpython/Lib/distutils/command/build.py", line 135, in run self.run_command(cmd_name) File "/home/antony/src/extern/cpython/Lib/distutils/cmd.py", line 313, in run_command self.distribution.run_command(command) File "/home/antony/src/extern/cpython/Lib/distutils/dist.py", line 985, in run_command cmd_obj.run() File "/home/antony/src/extern/cpython/Lib/distutils/command/build_ext.py", line 339, in run self.build_extensions() File "../setup.py", line 308, in build_extensions self.check_extension_import(ext) File "../setup.py", line 447, in check_extension_import assert not self.inplace AssertionError make: *** [Makefile:618: sharedmods] Error 1 Removing the ~/.pydistutils.cfg fixes the issue and leads to a successful build. I think(?) CPython's build system should essentially make sure that distutils behaves as if `--no-user-cfg` was in effect. Or at least the limitation should be documented, but it's not very practical to have to temporarily rename an existing ~/.pydistutils.cfg whenever building CPython. See also https://bugs.python.org/issue9309, perhaps. -- components: Build messages: 323452 nosy: Antony.Lee priority: normal severity: normal status: open title: CPython may fail to build in the presence of a ~/.pydistutils.cfg versions: Python 3.7 ___ Python tracker <https://bugs.python.org/issue34389> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue33581] Document "optional components that are commonly included in Python distributions."
New submission from Antony Lee : The stdlib docs intro include the following sentences: It also describes some of the optional components that are commonly included in Python distributions. For Unix-like operating systems Python is normally provided as a collection of packages, so it may be necessary to use the packaging tools provided with the operating system to obtain some or all of the optional components. However, as far as I can tell, there is no easy way to actually know what parts of the stdlib are "optional". The _thread module's doc does state "The module is optional.", and the threading module's doc also implies that it is optional ("The dummy_threading module is provided for situations where threading cannot be used because _thread is missing.") (yes, I know support for threadless builds is going away in 3.7; that's irrelevant here.), but even ensurepip's docs don't state that it may be missing (even though I believe(?) that it is indeed removed (and intended to be so) from some linux distribution's Pythons). A master list of "optional" features would thus be welcome. Its usefulness is to know what parts of the stdlib we can actually rely on; e.g. in https://github.com/matplotlib/matplotlib/issues/10866 a Matplotlib user noted that bz2 is not present in all Python installs. -- assignee: docs@python components: Documentation messages: 317140 nosy: Antony.Lee, docs@python priority: normal severity: normal status: open title: Document "optional components that are commonly included in Python distributions." ___ Python tracker <https://bugs.python.org/issue33581> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com