[issue44090] Add class binding to unbound super objects for allowing autosuper with class methods
Géry added the comment: > Anthony Sottile provided this search to showing that at least a few popular > projects are using the one argument form of super(): Thanks for the link. But it gives lots of false positives. Only two popular projects (> 1k stars) use autosuper (urwid and evennia): https://sourcegraph.com/search?q=context:global+setattr%5C%28.*super%5C%28.*%5C%29%5C%29+file:%5C.py%24+-file:test.*%5C.py%24&patternType=regexp&case=yes The remaining projects use one-argument super incorrectly, as `super(cls).method()`, which looks up the method directly on class `super`: https://sourcegraph.com/search?q=context:global+content:%5B%5E_%5Dsuper%5C%28%5Cw%2B%5C%29%5B%5E:%5D+file:%5C.py%24+-file:test.*%5C.py%24&patternType=regexp&case=yes It is either a loud bug, which raises an `AttributeError`: ``` >>> class A: ... def f(self): pass ... >>> class B(A): ... def f(self): super(B).f() ... >>> B().f() Traceback (most recent call last): File "", line 1, in File "", line 2, in f AttributeError: 'super' object has no attribute 'f' ``` Or worse with `super(cls).__init__()` (99% of the cases), it is a SILENT bug, which call the constructor of class `super` instead of the parent constructor, leaving the object in an incompletely initialized state: ``` >>> class A: ... def __init__(self): print('hello') ... >>> class B(A): ... def __init__(self): super(B).__init__() ... >>> A() hello <__main__.A object at 0x10926e460> >>> B() <__main__.B object at 0x10926e520> ``` -- ___ Python tracker <https://bugs.python.org/issue44090> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue47220] Document the optional callback parameter of weakref.WeakMethod
New submission from Géry : - Document the optional *callback* parameter of `weakref.WeakMethod`. - Fix a few spelling mistakes. - Improve wording. -- components: Library (Lib) messages: 416697 nosy: maggyero priority: normal pull_requests: 30376 severity: normal status: open title: Document the optional callback parameter of weakref.WeakMethod type: enhancement versions: Python 3.10, Python 3.11, Python 3.9 ___ Python tracker <https://bugs.python.org/issue47220> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue47206] pickle docs are wrong about nested classes
Change by Géry : -- nosy: +maggyero ___ Python tracker <https://bugs.python.org/issue47206> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue47180] Remove unnecessary registration of weakref.WeakSet as a subtype of _collections_abc.Set
New submission from Géry : Registering `weakref.WeakSet` as a subtype of `_collections_abc.MutableSet` implies that it is also a subtype of `_collections_abc.Set` since `_collections_abc.MutableSet` is a subtype of `_collections_abc.Set` and the subtype relation is transitive. -- components: Library (Lib) messages: 416422 nosy: maggyero priority: normal pull_requests: 30287 severity: normal status: open title: Remove unnecessary registration of weakref.WeakSet as a subtype of _collections_abc.Set type: enhancement versions: Python 3.10, Python 3.11, Python 3.9 ___ Python tracker <https://bugs.python.org/issue47180> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue47178] Improve the implementations of Sequence.index and MutableSequence.extend in collections.abc
New submission from Géry : This P.R. will make the following changes to the `collections.abc` module: - simplify the implementation with slicing in function `Sequence.index`. - remove an unnecessary copy of `self` when a sequence extends itself in function `MutableSequence.extend`. -- components: Library (Lib) messages: 416415 nosy: maggyero priority: normal pull_requests: 30285 severity: normal status: open title: Improve the implementations of Sequence.index and MutableSequence.extend in collections.abc type: enhancement versions: Python 3.10, Python 3.11, Python 3.9 ___ Python tracker <https://bugs.python.org/issue47178> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue44090] Add class binding to unbound super objects for allowing autosuper with class methods
Géry added the comment: Alright, thanks. Raymond, any objections before I propose the removal of one-argument super? -- ___ Python tracker <https://bugs.python.org/issue44090> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue44090] Add class binding to unbound super objects for allowing autosuper with class methods
Géry added the comment: By the way: > I don't think we need two ways to do it. So do you think we could drop the support for single-argument super? Michele said in his article: > There is a single use case for the single argument syntax of super that I am > aware of, but I think it gives more troubles than advantages. The use case is > the implementation of autosuper made by Guido on his essay about new-style > classes. > If it was me, I would just remove the single argument syntax of super, making > it illegal. But this would probably break someone code, so I don't think it > will ever happen in Python 2.X. I did ask on the Python 3000 mailing list > about removing unbound super object (the title of the thread was let's get > rid of unbound super) and this was Guido's reply: >> Thanks for proposing this -- I've been scratching my head wondering what the >> use of unbound super() would be. :-) I'm fine with killing it -- perhaps >> someone can do a bit of research to try and find out if there are any >> real-life uses (apart from various auto-super clones)? --- Guido van Rossum > Unfortunaly as of now unbound super objects are still around in Python 3.0, > but you should consider them morally deprecated. -- ___ Python tracker <https://bugs.python.org/issue44090> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue47083] The __complex__ method is missing from the complex, float, and int built-in types
Géry added the comment: > I think this may fine as-is. In general, virtiual classes only promise that > an operation will work rather than promsing the presence of a particular > method. Okay, I just wanted to make sure that the absence of the `__complex__` method was intended and not an oversight, since the built-in numeric types define *all* the other methods of the numbers ABCs. -- ___ Python tracker <https://bugs.python.org/issue47083> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue44090] Add class binding to unbound super objects for allowing autosuper with class methods
Géry added the comment: > On StackOverflow, there has been some mild interest in the interactions > between super() and classmethod(): > > * https://stackoverflow.com/questions/64637174 > * https://stackoverflow.com/questions/1269217 > * https://stackoverflow.com/questions/1817183 Another one: https://stackoverflow.com/q/15291302/2326961 -- ___ Python tracker <https://bugs.python.org/issue44090> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue44090] Add class binding to unbound super objects for allowing autosuper with class methods
Géry added the comment: Thanks for the review. @rhettinger > And adding classmethod() support in super_descr_get() would create tight > coupling where there should be separate concerns (no other descriptor call is > classmethod specific). The descriptors `super`, `property`, and functions are already `classmethod` specific since their `__get__(instance, owner=None)` methods return `self` if `instance` is `None`, aren’t they? > The OP's proposed use case is mildly plausible though I've never seen it the > arise in practice. I agree that the parameterized factory method use case might be too rare to be compelling. @gvanrossum > That was perhaps a good idea 20 years ago, but nowadays you can use > argument-less super() Yes this proposal is likely too late. I found your autosuper solution quite elegant (no compiler magic) so I wanted to make it work with `classmethod` too after I realized it doesn’t, thanks to Michele’s article. -- ___ Python tracker <https://bugs.python.org/issue44090> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue47122] Fix the table of methods in the collections.abc documentation
New submission from Géry : This pull request makes the following changes to the table of methods in the [`collections.abc` documentation](https://docs.python.org/3/library/collections.abc.html): - `Reversible`: add `__iter__` abstract method; - `Generator`: replace `__iter__` with inherited mixin `Iterator` methods; - `MutableSequence`: add clear mixin method; - `Set`: remove `__ne__` mixin method (not defined here but in `object`), add `__rand__` mixin method, add `__ror__` mixin method, add `__rsub__` mixin method, add `__rxor__` mixin method; - `Mapping`: remove `__ne__` mixin method (not defined here but in `object`); - `ItemsView`: add inherited mixin `MappingView` method and inherited mixin `Set` methods; - `KeysView`: add inherited mixin `MappingView` method and inherited mixin `Set` methods; - `ValuesView`: add inherited mixin `MappingView` method; - `Coroutine`: add `__await__` abstract method; - `AsyncGenerator`: replace `__aiter__` with inherited mixin `AsyncIterator` methods; - footnotes: remove footnote 2 which is a duplicate of [the description of `collections.abc.Iterable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Iterable). -- assignee: docs@python components: Documentation messages: 416013 nosy: docs@python, maggyero priority: normal pull_requests: 30195 severity: normal status: open title: Fix the table of methods in the collections.abc documentation type: enhancement versions: Python 3.10, Python 3.11, Python 3.9 ___ Python tracker <https://bugs.python.org/issue47122> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue44090] Add class binding to unbound super objects for allowing autosuper with class methods
Géry added the comment: Apologies for the long delay. > Do we have any meaningful examples to show that this is desired and useful? A use case of `super()` in a `classmethod` that comes to mind is for parameterized factory methods. It is a variation of the classic factory method design pattern that lets the factory method of a creator creates *multiple* products according to a parameter identifying the product to create. Overriding the factory method lets you change or extend the products that are created, by mapping existing identifiers to different products or introducing new identifiers for new products (cf. GoF’s book *Design Patterns*, section ‘Factory Method’, subsection ‘Implementation’, paragraph 2): ``` >>> class MyCreator: ... @classmethod ... def make(cls, product_id): ... if product_id == 'mine': return MyProduct(creator=cls) ... if product_id == 'yours': return YourProduct(creator=cls) ... if product_id == 'theirs': return TheirProduct(creator=cls) ... raise ValueError('product_id {!r} not supported'.format(product_id)) ... >>> class YourCreator(MyCreator): ... @classmethod ... def make(cls, product_id): ... if product_id == 'mine': return YourProduct(creator=cls) ... if product_id == 'yours': return MyProduct(creator=cls) ... return super(YourCreator, cls).make(product_id) ... >>> class BaseProduct: ... def __init__(self, creator): self._creator = creator ... def __repr__(self): ... return '{}(creator={})'.format( ... type(self).__name__, self._creator.__name__) ... >>> class MyProduct(BaseProduct): pass ... >>> class YourProduct(BaseProduct): pass ... >>> class TheirProduct(BaseProduct): pass ... >>> MyCreator.make('mine') MyProduct(creator=MyCreator) >>> YourCreator.make('mine') YourProduct(creator=YourCreator) ``` -- ___ Python tracker <https://bugs.python.org/issue44090> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue672115] Assignment to __bases__ of direct object subclasses
Change by Géry : -- versions: +Python 3.11 -Python 3.6 ___ Python tracker <https://bugs.python.org/issue672115> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue672115] Assignment to __bases__ of direct object subclasses
Change by Géry : -- nosy: +maggyero ___ Python tracker <https://bugs.python.org/issue672115> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue47083] The __complex__ method is missing from the complex, float, and int built-in types
New submission from Géry : ## Expected outcome ``` >>> hasattr(complex(), '__complex__') True >>> hasattr(float(), '__complex__') True >>> hasattr(int(), '__complex__') True ``` ## Actual outcome ``` >>> hasattr(complex(), '__complex__') False >>> hasattr(float(), '__complex__') False >>> hasattr(int(), '__complex__') False ``` ## Rationale The `numbers.Complex` abstract base class has a `__complex__` abstract method and the `numbers.Real` and `numbers.Integral` abstract base classes inherit from `numbers.Complex` (https://github.com/python/cpython/blob/v3.10.3/Lib/numbers.py#L45-L47): ``` @abstractmethod def __complex__(self): """Return a builtin complex instance. Called for complex(self).""" ``` The `complex` built-in type is a virtual subclass (nominal subtype) of `numbers.Complex` (https://github.com/python/cpython/blob/v3.10.3/Lib/numbers.py#L144): ``` Complex.register(complex) ``` The `float` built-in type is a virtual subclass (nominal subtype) of `numbers.Real` (https://github.com/python/cpython/blob/v3.10.3/Lib/numbers.py#L264): ``` Real.register(float) ``` The `int` built-in type is a virtual subclass (nominal subtype) of `numbers.Integral` (https://github.com/python/cpython/blob/v3.10.3/Lib/numbers.py#L393): ``` Integral.register(int) ``` `__complex__` is the only method of the abstract base classes of `numbers` missing from `complex`, `float`, and `int`: ``` >>> import numbers >>> for attr in dir(numbers.Complex): ... if not hasattr(complex(), attr): print(attr) ... __abstractmethods__ __complex__ __module__ __slots__ _abc_impl >>> for attr in dir(numbers.Real): ... if not hasattr(float(), attr): print(attr) ... __abstractmethods__ __complex__ __module__ __slots__ _abc_impl >>> for attr in dir(numbers.Integral): ... if not hasattr(int(), attr): print(attr) ... __abstractmethods__ __complex__ __module__ __slots__ _abc_impl ``` -- components: Interpreter Core messages: 415689 nosy: maggyero priority: normal severity: normal status: open title: The __complex__ method is missing from the complex, float, and int built-in types type: behavior versions: Python 3.10, Python 3.11, Python 3.9 ___ Python tracker <https://bugs.python.org/issue47083> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue47029] Fix a BrokenPipeError when a multiprocessing.Queue is garbage collected
Géry added the comment: I forgot to include the output of the above program: ``` Traceback (most recent call last): File "/usr/local/Cellar/python@3.9/3.9.10/Frameworks/Python.framework/Versions/3.9/lib/python3.9/multiprocessing/queues.py", line 251, in _feed send_bytes(obj) File "/usr/local/Cellar/python@3.9/3.9.10/Frameworks/Python.framework/Versions/3.9/lib/python3.9/multiprocessing/connection.py", line 205, in send_bytes self._send_bytes(m[offset:offset + size]) File "/usr/local/Cellar/python@3.9/3.9.10/Frameworks/Python.framework/Versions/3.9/lib/python3.9/multiprocessing/connection.py", line 416, in _send_bytes self._send(header + buf) File "/usr/local/Cellar/python@3.9/3.9.10/Frameworks/Python.framework/Versions/3.9/lib/python3.9/multiprocessing/connection.py", line 373, in _send n = write(self._handle, buf) BrokenPipeError: [Errno 32] Broken pipe ``` -- ___ Python tracker <https://bugs.python.org/issue47029> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue47029] Fix a BrokenPipeError when a multiprocessing.Queue is garbage collected
Géry added the comment: I have attached the following patch: pass a reference to the reader end of the queue pipe to the queue thread so that the reader end is not garbage collected and closed before the queue thread has sent all the buffered data to the writer end. -- ___ Python tracker <https://bugs.python.org/issue47029> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue47029] Fix a BrokenPipeError when a multiprocessing.Queue is garbage collected
Change by Géry : -- keywords: +patch pull_requests: +30006 stage: -> patch review pull_request: https://github.com/python/cpython/pull/31913 ___ Python tracker <https://bugs.python.org/issue47029> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue47029] Fix a BrokenPipeError when a multiprocessing.Queue is garbage collected
New submission from Géry : A `BrokenPipeError` exception is raised when the queue thread of a `multiprocessing.Queue` still sends enqueued items to the write end of the queue pipe *after* the read end of the queue pipe has been [automatically closed during its garbage collection](https://docs.python.org/3/library/socket.html#socket.socket.close) following the garbage collection of the queue (the write end of the queue pipe is not garbage collected because it is also referenced by the queue thread): ``` import multiprocessing def main(): q = multiprocessing.Queue() q.put(0) if __name__ == '__main__': main() ``` -- components: Library (Lib) messages: 415272 nosy: maggyero priority: normal severity: normal status: open title: Fix a BrokenPipeError when a multiprocessing.Queue is garbage collected type: crash versions: Python 3.10, Python 3.11, Python 3.9 ___ Python tracker <https://bugs.python.org/issue47029> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue35844] Calling `Multiprocessing.Queue.close()` too quickly causes intermittent failure (BrokenPipeError)
Change by Géry : -- nosy: +maggyero ___ Python tracker <https://bugs.python.org/issue35844> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue23882] unittest discovery doesn't detect namespace packages when given no parameters
Change by Géry : -- nosy: +maggyero ___ Python tracker <https://bugs.python.org/issue23882> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue46934] Started multiprocessing.Process instances are unserialisable
Change by Géry : -- title: A started multiprocessing.Process instance cannot be serialised -> Started multiprocessing.Process instances are unserialisable ___ Python tracker <https://bugs.python.org/issue46934> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue46934] A started multiprocessing.Process instance cannot be serialised
Change by Géry : -- keywords: +patch pull_requests: +29821 stage: -> patch review pull_request: https://github.com/python/cpython/pull/31701 ___ Python tracker <https://bugs.python.org/issue46934> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue46934] A started multiprocessing.Process instance cannot be serialised
New submission from Géry : The Python program: ``` import multiprocessing import time class Application: def __init__(self): self._event = multiprocessing.Event() self._processes = [ multiprocessing.Process(target=self._worker) for _ in range(multiprocessing.cpu_count())] def _worker(self): while not self._event.is_set(): print(multiprocessing.current_process().name) time.sleep(1) def start(self): for process in self._processes: print('starting') process.start() def stop(self): self._event.set() for process in self._processes: process.join() if __name__ == '__main__': application = Application() application.start() time.sleep(3) application.stop() ``` Its output: ```none starting starting Traceback (most recent call last): File "/Users/maggyero/Desktop/application.py", line 31, in application.start() File "/Users/maggyero/Desktop/application.py", line 21, in start process.start() File "/usr/local/Cellar/python@3.9/3.9.10/Frameworks/Python.framework/Versions/3.9/lib/python3.9/multiprocessing/process.py", line 121, in start self._popen = self._Popen(self) File "/usr/local/Cellar/python@3.9/3.9.10/Frameworks/Python.framework/Versions/3.9/lib/python3.9/multiprocessing/context.py", line 224, in _Popen return _default_context.get_context().Process._Popen(process_obj) File "/usr/local/Cellar/python@3.9/3.9.10/Frameworks/Python.framework/Versions/3.9/lib/python3.9/multiprocessing/context.py", line 284, in _Popen return Popen(process_obj) File "/usr/local/Cellar/python@3.9/3.9.10/Frameworks/Python.framework/Versions/3.9/lib/python3.9/multiprocessing/popen_spawn_posix.py", line 32, in __init__ super().__init__(process_obj) File "/usr/local/Cellar/python@3.9/3.9.10/Frameworks/Python.framework/Versions/3.9/lib/python3.9/multiprocessing/popen_fork.py", line 19, in __init__ self._launch(process_obj) File "/usr/local/Cellar/python@3.9/3.9.10/Frameworks/Python.framework/Versions/3.9/lib/python3.9/multiprocessing/popen_spawn_posix.py", line 47, in _launch reduction.dump(process_obj, fp) File "/usr/local/Cellar/python@3.9/3.9.10/Frameworks/Python.framework/Versions/3.9/lib/python3.9/multiprocessing/reduction.py", line 60, in dump ForkingPickler(file, protocol).dump(obj) TypeError: cannot pickle 'weakref' object Traceback (most recent call last): File "", line 1, in File "/usr/local/Cellar/python@3.9/3.9.10/Frameworks/Python.framework/Versions/3.9/lib/python3.9/multiprocessing/spawn.py", line 116, in spawn_main exitcode = _main(fd, parent_sentinel) File "/usr/local/Cellar/python@3.9/3.9.10/Frameworks/Python.framework/Versions/3.9/lib/python3.9/multiprocessing/spawn.py", line 126, in _main self = reduction.pickle.load(from_parent) File "/usr/local/Cellar/python@3.9/3.9.10/Frameworks/Python.framework/Versions/3.9/lib/python3.9/multiprocessing/synchronize.py", line 110, in __setstate__ self._semlock = _multiprocessing.SemLock._rebuild(*state) FileNotFoundError: [Errno 2] No such file or directory ``` In the function `Application.__init__`, each call `multiprocessing.Process(target=self._worker)` initializes a `multiprocessing.Process` instance with the instance method `self._worker` as its `target` argument. `self._worker` is bound to `self` which has the instance attribute `self._processes`. In the function `Application.start`, each call `process.start()` serialises the `target` argument and therefore `self._processes`. `self._processes` is a list of `multiprocessing.Process` instances, initially not started yet. The first call `process.start()` starts the first `multiprocessing.Process` instance in that list without issue, but the second call `process.start()` fails. So a started `multiprocessing.Process` instance cannot be serialised. The root of the problem is that the `start` method of a `multiprocessing.Process` instance sets its `_popen` instance attribute to a `multiprocessing.popen_*.Popen` instance. The initialization of that instance performs these two steps (among others): 1. For a `multiprocessing.popen_spawn_posix.Popen` instance, a `multiprocessing.popen_spawn_win32.Popen` instance, or a `multiprocessing.popen_forkserver.Popen` instance but not a `multiprocessing.popen_fork.Popen` instance (i.e. for the start method `'spawn'` or the start method `'forkserver'` but not the start method `'fork'`), it [serialises](https://github.com/python/cpython/blob/v3.10.2/Lib/multiprocessing/popen_spawn_posix.py#L47) the `multiprocessing.Process` instance for writing it to the end of the pipe used by the parent process to communicate with the child
[issue38738] Fix formatting of True and False
Change by Géry : -- nosy: +maggyero nosy_count: 4.0 -> 5.0 pull_requests: +29809 pull_request: https://github.com/python/cpython/pull/31678 ___ Python tracker <https://bugs.python.org/issue38738> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue29971] threading.Lock.acquire() not interruptible on Windows
Change by Géry : -- nosy: +maggyero ___ Python tracker <https://bugs.python.org/issue29971> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue45274] Race condition in Thread._wait_for_tstate_lock()
Change by Géry : -- nosy: +maggyero ___ Python tracker <https://bugs.python.org/issue45274> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue46851] Document multiprocessing.set_forkserver_preload
Change by Géry : -- type: -> enhancement ___ Python tracker <https://bugs.python.org/issue46851> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue46851] Document multiprocessing.set_forkserver_preload
New submission from Géry : I have just notice that the multiprocessing.set_forkserver_preload (which originates from multiprocessing.forkserver.set_forkserver_preload) is not documented: https://github.com/python/cpython/blob/v3.10.2/Lib/multiprocessing/context.py#L180-L185 -- messages: 413934 nosy: docs@python, maggyero priority: normal severity: normal status: open title: Document multiprocessing.set_forkserver_preload versions: Python 3.10, Python 3.11, Python 3.7, Python 3.8, Python 3.9 ___ Python tracker <https://bugs.python.org/issue46851> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue46720] Add support for path-like objects to multiprocessing.set_executable for Windows to be on a par with Unix-like systems
Change by Géry : -- title: Add support of path-like objects to multiprocessing.set_executable for Windows to match Unix-like systems -> Add support for path-like objects to multiprocessing.set_executable for Windows to be on a par with Unix-like systems ___ Python tracker <https://bugs.python.org/issue46720> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue46720] Add support of path-like objects to multiprocessing.set_executable for Windows to match Unix-like systems
Change by Géry : -- type: -> enhancement ___ Python tracker <https://bugs.python.org/issue46720> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue46720] Add support of path-like objects to multiprocessing.set_executable for Windows to match Unix-like systems
Change by Géry : -- keywords: +patch pull_requests: +29439 stage: -> patch review pull_request: https://github.com/python/cpython/pull/31279 ___ Python tracker <https://bugs.python.org/issue46720> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue46720] Add support of path-like objects to multiprocessing.set_executable for Windows to match Unix-like systems
New submission from Géry : Any [path-like object](https://docs.python.org/3/glossary.html) can be passed to `multiprocessing.set_executable`, i.e. objects with `str`, `bytes`, or `os.PathLike` type. For instance these work (tested on MacOS with all start methods: ‘spawn’, ‘fork’, and ‘forkserver’): - `multiprocessing.set_executable(sys.executable)` (`str`); - `multiprocessing.set_executable(sys.executable.encode())` (`bytes`); - `multiprocessing.set_executable(pathlib.Path(sys.executable))` (`os.PathLike`). This is because the ‘fork’ start method does not exec any program in the subprocess, the ‘spawn’ start method converts its path argument to `bytes` with `os.fsencode` before passing to [`_posixsubprocess.fork_exec`](https://github.com/python/cpython/blob/v3.10.2/Lib/multiprocessing/util.py#L452-L455), and the ‘forkserver’ start method spawns a server process (like with the ‘spawn’ start method) which then forks itself at each request (like the ‘fork’ start method): ``` return _posixsubprocess.fork_exec( args, [os.fsencode(path)], True, passfds, None, None, -1, -1, -1, -1, -1, -1, errpipe_read, errpipe_write, False, False, None, None, None, -1, None) ``` Linux (and other Unix-like systems) uses the same code than MacOS for the three start methods so it should work for it too. However I have not tested this on Windows which uses the function [`_winapi.CreateProcess`](https://github.com/python/cpython/blob/v3.10.2/Lib/multiprocessing/popen_spawn_win32.py#L73-L75) for the ‘spawn’ start method (the only start method available on this OS) but I noticed that no conversion to `str` (not to `bytes` this time, since [the function expects `str`](https://github.com/python/cpython/blob/v3.10.2/Modules/_winapi.c#L1049)) of the path argument with `os.fsdecode` (not `os.fsencode` this time) is performed before passing it to the function: ``` hp, ht, pid, tid = _winapi.CreateProcess( python_exe, cmd, None, None, False, 0, env, None, None) ``` So on Windows only `str` path can be passed to `multiprocessing.set_executable`. This PR fixes this to be on a par with Unix-like systems which accept any path-like objects. -- components: Library (Lib) messages: 413073 nosy: maggyero priority: normal severity: normal status: open title: Add support of path-like objects to multiprocessing.set_executable for Windows to match Unix-like systems versions: Python 3.10, Python 3.11, Python 3.9 ___ Python tracker <https://bugs.python.org/issue46720> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue38119] resource tracker destroys shared memory segments when other processes should still have valid access
Change by Géry : -- nosy: +maggyero ___ Python tracker <https://bugs.python.org/issue38119> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue34486] "RuntimeError: release unlocked lock" when starting a thread
Change by Géry : -- nosy: +maggyero ___ Python tracker <https://bugs.python.org/issue34486> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue46285] protocol_version in http.server.test can be ignored
Change by Géry : -- keywords: +patch pull_requests: +29181 stage: needs patch -> patch review pull_request: https://github.com/python/cpython/pull/30999 ___ Python tracker <https://bugs.python.org/issue46285> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue46436] Pass the -d/--directory command-line option to http.server.CGIHTTPRequestHandler
Géry added the comment: Thanks for mentioning this issue @merwok. As you pointed out, function `test` in module [`http.server`](https://github.com/python/cpython/blob/main/Lib/http/server.py) expects a real request handler class argument (`SimpleHTTPRequestHandler` or `CGIHTTPRequestHandler`), not a partial object `partial(SimpleHTTPRequestHandler, directory=args.directory)` or `partial(CGIHTTPRequestHandler, directory=args.directory)`, so that the assignment of `protocol_version` class attribute in test is not ignored. The partial object in the `if __name__ == '__main__'` branch of module `http.server` was introduced in the first place to pass the directory argument to the request handler class’s `__init__` method called in method `BaseServer.finish_request` of module [`socketserver`](https://github.com/python/cpython/blob/main/Lib/socketserver.py): def finish_request(self, request, client_address): """Finish one request by instantiating RequestHandlerClass.""" self.RequestHandlerClass(request, client_address, self) But `BaseServer.finish_request` is a factory method of `BaseServer` (the abstract creator) so it is *designed* to be overridden in subclasses to customize the instantiation of the request handler class `BaseRequestHandler` (the abstract product). So the proper way to instantiate `SimpleHTTPRequestHandler` and `CGIHTTPRequestHandler` with the `directory` argument is to override `BaseServer.finish_request`. I have just updated my PR to implement this. It fixes both [#46285](https://bugs.python.org/issue46285) and [#46436](https://bugs.python.org/issue46436). -- ___ Python tracker <https://bugs.python.org/issue46436> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue46285] protocol_version in http.server.test can be ignored
Géry added the comment: Thanks Hugo for opening this issue and Éric for inviting me. As you guys pointed out, function test in module http.server expects a real handler class argument (SimpleHTTPRequestHandler or CGIHTTPRequestHandler), not a partial object partial(SimpleHTTPRequestHandler, directory=args.directory) or partial(CGIHTTPRequestHandler, directory=args.directory), so that the assignment of protocol_version class attribute in test is not ignored. The partial object in the if __name__ == '__main__' branch of module http.server was introduced in the first place to pass the directory argument to the handler class’s __init__ method called in method BaseServer.finish_request: def finish_request(self, request, client_address): """Finish one request by instantiating RequestHandlerClass.""" self.RequestHandlerClass(request, client_address, self) But finish_request is a factory method of BaseServer (the abstract creator) so it is DESIGNED to be overridden in subclasses to customize the instantiation of the handler class BaseRequestHandler (the abstract product). So the proper way to instantiate SimpleHTTPRequestHandler and CGIHTTPRequestHandler with the directory argument is to override BaseServer.finish_request. That is what I have just did by updating my PR here: https://github.com/python/cpython/pull/30701/commits/fc7f95f9d270a8a83cb2fd6d51eb0f904b85e0d9 It fixes both #46285 and #46436. -- ___ Python tracker <https://bugs.python.org/issue46285> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue46436] Pass the -d/--directory command-line option to http.server.CGIHTTPRequestHandler
Change by Géry : -- versions: +Python 3.9 ___ Python tracker <https://bugs.python.org/issue46436> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue43474] http.server.BaseHTTPRequestHandler end_header() fails
Géry added the comment: > http.server.BaseHTTPRequestHandler end_headers() can reference _header_buffer > array before it is assigned. @grumblor I was about to open the same bug after reading the implementation of http.server this morning and noticing that the attribute _headers_buffer of BaseHTTPRequestHandler is used in 4 methods: - send_response_only; - send_header; - end_headers; - flush_headers but its existence is not checked only in end_headers. > It seems like sending zero headers is not supported @andrei.avk It is actually supported by the syntax of HTTP/1.1 messages, cf. RFC 7230, § 3: HTTP-message = start-line *( header-field CRLF ) CRLF [ message-body ] For instance the method handle_expect_100 does not send any header: def handle_expect_100(self): self.send_response_only(HTTPStatus.CONTINUE) self.end_headers() return True It only writes a start line (which includes \r\n) followed by an empty line (\r\n) as a response: HTTP/1.1 100 Continue\r\n\r\n But self.end_headers() does not raise an AttributeError here like one might expect from its implementation: def end_headers(self): if self.request_version != 'HTTP/0.9': self._headers_buffer.append(b"\r\n") self.flush_headers() because, contrary to what its name suggests, self._headers_buffer does not only include the response headers but also the response start line, which is appended to the buffer before by self.send_response_only(HTTPStatus.CONTINUE): def send_response_only(self, code, message=None): """Send the response header only.""" if self.request_version != 'HTTP/0.9': if message is None: if code in self.responses: message = self.responses[code][0] else: message = '' if not hasattr(self, '_headers_buffer'): self._headers_buffer = [] self._headers_buffer.append(("%s %d %s\r\n" % (self.protocol_version, code, message)).encode( 'latin-1', 'strict')) So I am not sure it is a bug if we consider that send_response_only (which appends a start line to the buffer) is a precondition to end_headers (which appends an empty line to the buffer and flushes it). But then flush_headers should also have this precondition instead of preventing the AttributeError like this: def flush_headers(self): if hasattr(self, '_headers_buffer'): self.wfile.write(b"".join(self._headers_buffer)) self._headers_buffer = [] Let’s ask Andrew Schaaf (@endian) who introduced flush_headers in Python 3.3 (cf. https://bugs.python.org/issue3709) why he implemented end_headers by contract and flush_headers defensively. -- nosy: +endian, maggyero ___ Python tracker <https://bugs.python.org/issue43474> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue46436] Pass the -d/--directory command-line option to http.server.CGIHTTPRequestHandler
Change by Géry : -- nosy: -docs@python ___ Python tracker <https://bugs.python.org/issue46436> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue46436] Pass the -d/--directory command-line option to http.server.CGIHTTPRequestHandler
New submission from Géry : The API of [`http.server`](https://docs.python.org/3/library/http.server.html) supports the `directory` optional parameter for `CGIHTTPRequestHandler` (which is inherited from `SimpleHTTPRequestHandler`). The CLI of `http.server` supports the corresponding `-d/--directory` option. The `-d/--directory` option is passed to `SimpleHTTPRequestHandler` as the `directory` argument: > python -m http.server --directory /tmp/ But the `-d/--directory` option is not passed to `CGIHTTPRequestHandler` (which is enabled with the `--cgi` option): > python -m http.server --directory /tmp/ --cgi So the option is ignored in that case. -- components: Library (Lib) messages: 410973 nosy: docs@python, maggyero priority: normal pull_requests: 28899 severity: normal status: open title: Pass the -d/--directory command-line option to http.server.CGIHTTPRequestHandler type: behavior versions: Python 3.10, Python 3.11 ___ Python tracker <https://bugs.python.org/issue46436> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue44024] Improve the TypeError message for non-string second arguments passed to the built-in functions getattr and hasattr
Géry added the comment: Thanks for the review Serhiy. -- ___ Python tracker <https://bugs.python.org/issue44024> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39452] Improve the __main__ module documentation
Géry added the comment: No worries, it was almost twenty years ago. > But it's probably better to raise a dedicated exception in that case and > catch it in main(), rather than just calling sys.exit() deep inside the other > code. Yes I agree, and I think you explained very clearly why it is better in the blog post: > Another refinement is to define a Usage() exception, which we catch in an > except clause at the end of main(): > […] > This gives the main() function a single exit point, which is preferable over > multiple return 2 statements. So I think you made two independent points: - raising a dedicated exception instead of calling `sys.exit` inside nested functions and catching it inside `main` allows a single exit point; - calling `sys.exit` outside of `main` instead of inside prevents exiting the Python interpreter in an interactive session. -- ___ Python tracker <https://bugs.python.org/issue39452> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39452] Improve the __main__ module documentation
Géry added the comment: @jack__d Thanks for the rewrite! This is a great expansion. Unfortunately I didn’t have the time to review it before the merge. If I find something to be improved I will let you know. @gvanrossum > Your docs seem to promote the second, whereas I've usually preferred the > former. Are you sure? Yet in your 2003 blog post [*Python main() functions*](https://www.artima.com/weblogs/viewpost.jsp?thread=4829) you promoted the opposite idiom `if __name__ == "__main__": sys.exit(main())` over the idiom `if __name__ == "__main__": main()`: > Now the `sys.exit()` calls are annoying: when `main()` calls `sys.exit()`, > your interactive Python interpreter will exit! The remedy is to let > `main()`'s return value specify the exit status. I am interested in the rationale if you changed your mind. -- ___ Python tracker <https://bugs.python.org/issue39452> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue44090] Add class binding to unbound super objects for allowing autosuper with class methods
Change by Géry : -- keywords: +patch pull_requests: +24660 stage: -> patch review pull_request: https://github.com/python/cpython/pull/26009 ___ Python tracker <https://bugs.python.org/issue44090> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue44090] Add class binding to unbound super objects for allowing autosuper with class methods
New submission from Géry : A use case of one-argument `super` (aka unbound `super`) is Guido van Rossum’s autosuper described in his 2002 article [*Unifying types and classes in Python 2.2*](https://www.python.org/download/releases/2.2.3/descrintro/#cooperation). It works with functions, but not with `classmethod` as Michele Simionato noted in his 2008 article [*Things to Know About Python Super*](https://www.artima.com/weblogs/viewpost.jsp?thread=236278). I suggest fixing this by updating the method `super.__get__` to bind an unbound `super` object to the argument `owner` when there is no argument `instance` to bind to. Here is the patch applied to the C function [super_descr_get](https://github.com/python/cpython/blob/v3.9.5/Objects/typeobject.c#L8029-L8061) in Objects/typeobject.c, given in pure Python for better readability: ```python def __get__(self, instance, owner=None): if instance is None and owner is None: raise TypeError('__get__(None, None) is invalid') - if instance is None or self.__self__ is not None: + if self.__self__ is not None: return self + if instance is None: + return type(self)(self.__thisclass__, owner) return type(self)(self.__thisclass__, instance) ``` Demonstration: ```python >>> class A: ... def f(self): return 'A.f' ... @classmethod ... def g(cls): return 'A.g' ... >>> class B(A): ... def f(self): return 'B.f ' + self.__super.f() ... @classmethod ... def g(cls): return 'B.g ' + cls.__super.g() ... >>> B._B__super = super(B) # the CURRENT broken version of super >>> print(B().f()) # function succeeds (instance binding) B.f A.f >>> print(B.g())# classmethod fails (no binding) Traceback (most recent call last): File "", line 1, in File "", line 4, in g AttributeError: 'super' object has no attribute 'g' >>> B._B__super = super(B) # the PROPOSED fixed version of super >>> print(B().f()) # function succeeds (instance binding) B.f A.f >>> print(B.g())# classmethod succeeds (class binding) B.g A.g ``` -- components: Interpreter Core messages: 393326 nosy: maggyero priority: normal severity: normal status: open title: Add class binding to unbound super objects for allowing autosuper with class methods type: enhancement versions: Python 3.10, Python 3.11, Python 3.9 ___ Python tracker <https://bugs.python.org/issue44090> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue44024] Improve the TypeError message for non-string second arguments passed to the built-in functions getattr and hasattr
Change by Géry : -- title: Improve the error message for non-string second arguments passed to the built-in functions getattr and hasattr -> Improve the TypeError message for non-string second arguments passed to the built-in functions getattr and hasattr ___ Python tracker <https://bugs.python.org/issue44024> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue44024] Improve the error message for non-string second arguments passed to the built-in functions getattr and hasattr
Change by Géry : -- title: Use common TypeError message for built-in functions getattr and hasattr -> Improve the error message for non-string second arguments passed to the built-in functions getattr and hasattr ___ Python tracker <https://bugs.python.org/issue44024> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue44024] Use common TypeError message for built-in functions getattr and hasattr
Change by Géry : -- keywords: +patch pull_requests: +24544 stage: -> patch review pull_request: https://github.com/python/cpython/pull/25863 ___ Python tracker <https://bugs.python.org/issue44024> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue44024] Use common TypeError message for built-in functions getattr and hasattr
New submission from Géry : Problem --- Actual behaviour: ```python >>> getattr('foobar', 123) Traceback (most recent call last): File "", line 1, in TypeError: getattr(): attribute name must be string >>> hasattr('foobar', 123) Traceback (most recent call last): File "", line 1, in TypeError: hasattr(): attribute name must be string ``` Expected behaviour: ```python >>> getattr('foobar', 123) Traceback (most recent call last): File "", line 1, in TypeError: attribute name must be string, not 'int' >>> hasattr('foobar', 123) Traceback (most recent call last): File "", line 1, in TypeError: attribute name must be string, not 'int' ``` Motivation: ```python >>> setattr('foobar', 123, 'baz') Traceback (most recent call last): File "", line 1, in TypeError: attribute name must be string, not 'int' >>> delattr('foobar', 123) Traceback (most recent call last): File "", line 1, in TypeError: attribute name must be string, not 'int' ``` Solution In the function `builtin_getattr` defined in Python/bltinmodule.c, we remove the following lines: ```c if (!PyUnicode_Check(name)) { PyErr_SetString(PyExc_TypeError, "getattr(): attribute name must be string"); return NULL; } ``` because the expected `TypeError` message is already implemented in the subsequent call to the functions `_PyObject_LookupAttr` and `PyObject_GetAttr` defined in Objects/object.c: ```c PyObject * PyObject_GetAttr(PyObject *v, PyObject *name) { PyTypeObject *tp = Py_TYPE(v); if (!PyUnicode_Check(name)) { PyErr_Format(PyExc_TypeError, "attribute name must be string, not '%.200s'", Py_TYPE(name)->tp_name); return NULL; } […] int _PyObject_LookupAttr(PyObject *v, PyObject *name, PyObject **result) { PyTypeObject *tp = Py_TYPE(v); if (!PyUnicode_Check(name)) { PyErr_Format(PyExc_TypeError, "attribute name must be string, not '%.200s'", Py_TYPE(name)->tp_name); *result = NULL; return -1; } […] ``` Likewise, in the function `builtin_hasattr_impl` defined in Python/bltinmodule.c, we remove the following lines: ```c if (!PyUnicode_Check(name)) { PyErr_SetString(PyExc_TypeError, "hasattr(): attribute name must be string"); return NULL; } ``` because the expected `TypeError` message is already implemented in the subsequent call to the function `_PyObject_LookupAttr` defined in Objects/object.c. -- components: Interpreter Core messages: 392843 nosy: maggyero priority: normal severity: normal status: open title: Use common TypeError message for built-in functions getattr and hasattr type: behavior versions: Python 3.10, Python 3.11, Python 3.6, Python 3.7, Python 3.8, Python 3.9 ___ Python tracker <https://bugs.python.org/issue44024> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue43896] Update the Sphinx directive for super from function to class
Géry added the comment: > Elsewhere in the docs, all the links to this entry use the markup, > :func:`super` which looks nicer in the docs than the class reference. I was suggesting only to update the block Sphinx directive “.. function::” to “.. class::” for defining the signature (so that the “class” prefix appears before the signature, like for the other built-in types), not the inline Sphinx roles “:func:” to “:class:” (since for instance `int` use both in the page: :class:`int` and :func:`int`). Also the “class” prefix already appears in the interactive help when typing `help(super)`: Help on class super in module builtins: class super(object) | super() -> same as super(__class__, ) | super(type) -> unbound super object | super(type, obj) -> bound super object; requires isinstance(obj, type) | super(type, type2) -> bound super object; requires issubclass(type2, type) | Typical use to call a cooperative superclass method: | class C(B): | def meth(self, arg): | super().meth(arg) | This works for class methods too: | class C(B): | @classmethod | def cmeth(cls, arg): | super().cmeth(arg) -- ___ Python tracker <https://bugs.python.org/issue43896> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue43896] Update the Sphinx directive for super from function to class
Géry added the comment: > Looking again, it seems to someone has already started applying class markup > despite previous decisions not to do so. Yes, and he forgot super: class bool([x]) class bytearray([source[, encoding[, errors]]]) class bytes([source[, encoding[, errors]]]) class complex([real[, imag]]) class dict(**kwarg) class dict(mapping, **kwarg) class dict(iterable, **kwarg) class float([x]) class frozenset([iterable]) class int([x]) class int(x, base=10) class list([iterable]) class memoryview(obj) class object class property(fget=None, fset=None, fdel=None, doc=None) class range(stop) class range(start, stop[, step]) class set([iterable]) class slice(stop) class slice(start, stop[, step]) class str(object='') class str(object=b'', encoding='utf-8', errors='strict’) class tuple([iterable]) class type(object) class type(name, bases, dict, **kwds) -- ___ Python tracker <https://bugs.python.org/issue43896> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue43896] Update the Sphinx directive for super from function to class
Change by Géry : -- keywords: +patch pull_requests: +24212 stage: -> patch review pull_request: https://github.com/python/cpython/pull/25489 ___ Python tracker <https://bugs.python.org/issue43896> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue43896] Update the Sphinx directive for super from function to class
New submission from Géry : This PR updates the page [*Built-in Functions*](https://docs.python.org/3.9/library/functions.html#super) of the Python library documentation: `super` is not a `function` (`isinstance(super, type(lambda: None))` is `False`), it is a `type` (`isinstance(super, type)` is `True`), like `int`, `tuple`, `set`, etc. So it should get the same “class” prefix, i.e. > **super**([*type*[, *object-or-type*]]) should become > *class* **super**([*type*[, *object-or-type*]]) -- assignee: docs@python components: Documentation messages: 391458 nosy: docs@python, maggyero priority: normal severity: normal status: open title: Update the Sphinx directive for super from function to class type: enhancement versions: Python 3.10, Python 3.6, Python 3.7, Python 3.8, Python 3.9 ___ Python tracker <https://bugs.python.org/issue43896> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue43857] Fix the AttributeError message for deletion of a missing attribute
Change by Géry : -- keywords: +patch pull_requests: +24158 stage: -> patch review pull_request: https://github.com/python/cpython/pull/25424 ___ Python tracker <https://bugs.python.org/issue43857> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue43857] Fix the AttributeError message for deletion of a missing attribute
New submission from Géry : Compare the `AttributeError` messages in this interactive Python session: ```python >>> class A: ... y = 0 ... __slots__ = ('z',) ... >>> A().x […] AttributeError: 'A' object has no attribute 'x' >>> A().x = 1 […] AttributeError: 'A' object has no attribute 'x' >>> del A().x […] AttributeError: 'A' object has no attribute 'x' >>> A().y 0 >>> A().y = 2 […] AttributeError: 'A' object attribute 'y' is read-only >>> del A().y […] AttributeError: 'A' object attribute 'y' is read-only >>> A().z […] AttributeError: z >>> A().z = 3 >>> del A().z […] AttributeError: z ``` with the `AttributeError` messages in that one: ```python >>> class B: pass ... >>> B().x […] AttributeError: 'B' object has no attribute 'x' >>> B().x = 1 >>> del B().x […] AttributeError: x ``` The message `AttributeError: x` from `del B().x` does not feel right. I expect this message to be the same as the message `AttributeError: 'B' object has no attribute 'x'` from `B().x`, since in both cases the object `B()` has no attribute `'x'`. I have checked on PyPy 7.3.3 (Python 3.7.9) and it uses the expected message `AttributeError: 'B' object has no attribute 'x'` from `B().x` for `del B().x`. So this confirms my initial suspicion. In CPython, the `AttributeError` message for attribute retrieval is implemented [here](https://github.com/python/cpython/blob/v3.9.4/Objects/object.c#L1266-L1270) (except for [slot retrieval](https://github.com/python/cpython/blob/v3.9.4/Python/structmember.c#L70-L75)): ```c if (!suppress) { PyErr_Format(PyExc_AttributeError, "'%.50s' object has no attribute '%U'", tp->tp_name, name); } ``` And the `AttributeError` messages for attribute assignment and deletion are implemented [here](https://github.com/python/cpython/blob/v3.9.4/Objects/object.c#L1324-L1350) (except for [slot deletion](https://github.com/python/cpython/blob/v3.9.4/Python/structmember.c#L112-L118)): ```c if (dict == NULL) { dictptr = _PyObject_GetDictPtr(obj); if (dictptr == NULL) { if (descr == NULL) { PyErr_Format(PyExc_AttributeError, "'%.100s' object has no attribute '%U'", tp->tp_name, name); } else { PyErr_Format(PyExc_AttributeError, "'%.50s' object attribute '%U' is read-only", tp->tp_name, name); } goto done; } res = _PyObjectDict_SetItem(tp, dictptr, name, value); } else { Py_INCREF(dict); if (value == NULL) res = PyDict_DelItem(dict, name); else res = PyDict_SetItem(dict, name, value); Py_DECREF(dict); } if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError)) PyErr_SetObject(PyExc_AttributeError, name); ``` So it is the last line `PyErr_SetObject(PyExc_AttributeError, name);` that would be updated. Note that `_PyObjectDict_SetItem` delegates to `PyDict_DelItem` (if `value` is `NULL`) or `PyDict_SetItem` (if `value` is not `NULL`), and that only `PyDict_DelItem` can [set an exception](https://github.com/python/cpython/blob/v3.9.4/Objects/dictobject.c#L1655-L1657) `PyExc_KeyError`, which is then translated to an exception `PyExc_AttributeError` in the last line. -- components: Interpreter Core messages: 391140 nosy: maggyero priority: normal severity: normal status: open title: Fix the AttributeError message for deletion of a missing attribute type: enhancement versions: Python 3.10, Python 3.6, Python 3.7, Python 3.8, Python 3.9 ___ Python tracker <https://bugs.python.org/issue43857> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue43814] Fix the error message for disallowed __weakref__ slots
Change by Géry : -- keywords: +patch pull_requests: +24096 stage: -> patch review pull_request: https://github.com/python/cpython/pull/25362 ___ Python tracker <https://bugs.python.org/issue43814> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue43814] Fix the error message for disallowed __weakref__ slots
New submission from Géry : When ``` TypeError: __weakref__ slot disallowed: either we already got one, or __itemsize__ != 0 ``` is raised, the second condition `base->tp_itemsize != 0` (i.e. the base is a *variable-length* type, like `int`, `tuple` and `bytes`) in the error message is impossible since using a non-empty `__slots__` (e.g. `__slots__ = ('__weakref__',)`) for a subtype of a variable-length type raises a ``` TypeError: nonempty __slots__ not supported for subtype of '…' ``` earlier in the `type.__new__` implementation. -- components: Interpreter Core messages: 390851 nosy: maggyero priority: normal severity: normal status: open title: Fix the error message for disallowed __weakref__ slots type: enhancement versions: Python 3.10, Python 3.6, Python 3.7, Python 3.8, Python 3.9 ___ Python tracker <https://bugs.python.org/issue43814> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue43639] Do not raise AttributeError on instance attribute update/deletion if data descriptor with missing __set__/__delete__ method found on its type
Change by Géry : -- keywords: +patch pull_requests: +23781 stage: -> patch review pull_request: https://github.com/python/cpython/pull/25033 ___ Python tracker <https://bugs.python.org/issue43639> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue43639] Do not raise AttributeError on instance attribute update/deletion if data descriptor with missing __set__/__delete__ method found on its type
New submission from Géry : Currently, the `object.__setattr__` and `type.__setattr__` methods raise an `AttributeError` during attribute *update* on an instance if its type has an attribute which is a *data* descriptor without a `__set__` method. Likewise, the `object.__delattr__` and `type.__delattr__` methods raise an `AttributeError` during attribute *deletion* on an instance if its type has an attribute which is a *data* descriptor without a `__delete__` method. This should not be the case. When update/deletion is impossible through a data descriptor found on the type, update/deletion should carry its process on the instance, like when there is no data descriptor found on the type. And this is what the `object.__getattribute__` and `type.__getattribute__` methods already do: they do *not* raise an `AttributeError` during attribute *lookup* on an instance if its type has an attribute which is a *data* descriptor without a `__get__` method. See [the discussion on Python Discuss](https://discuss.python.org/t/why-do-setattr-and-delattr-raise-an-attributeerror-in-this-case/7836?u=maggyero). Here is a simple program illustrating the differences between attribute lookup by `object.__getattribute__` on the one hand (`AttributeError` is not raised), and attribute update by `object.__setattr__` and attribute deletion by `object.__delattr__` on the other hand (`AttributeError` is raised): ```python class DataDescriptor1: # missing __get__ def __set__(self, instance, value): pass def __delete__(self, instance): pass class DataDescriptor2: # missing __set__ def __get__(self, instance, owner=None): pass def __delete__(self, instance): pass class DataDescriptor3: # missing __delete__ def __get__(self, instance, owner=None): pass def __set__(self, instance, value): pass class A: x = DataDescriptor1() y = DataDescriptor2() z = DataDescriptor3() a = A() vars(a).update({'x': 'foo', 'y': 'bar', 'z': 'baz'}) a.x # actual: returns 'foo' # expected: returns 'foo' a.y = 'qux' # actual: raises AttributeError: __set__ # expected: vars(a)['y'] == 'qux' del a.z # actual: raises AttributeError: __delete__ # expected: 'z' not in vars(a) ``` Here is another simple program illustrating the differences between attribute lookup by `type.__getattribute__` on the one hand (`AttributeError` is not raised), and attribute update by `type.__setattr__` and attribute deletion by `type.__delattr__` on the other hand (`AttributeError` is raised): ```python class DataDescriptor1: # missing __get__ def __set__(self, instance, value): pass def __delete__(self, instance): pass class DataDescriptor2: # missing __set__ def __get__(self, instance, owner=None): pass def __delete__(self, instance): pass class DataDescriptor3: # missing __delete__ def __get__(self, instance, owner=None): pass def __set__(self, instance, value): pass class M(type): x = DataDescriptor1() y = DataDescriptor2() z = DataDescriptor3() class A(metaclass=M): x = 'foo' y = 'bar' z = 'baz' A.x # actual: returns 'foo' # expected: returns 'foo' A.y = 'qux' # actual: raises AttributeError: __set__ # expected: vars(A)['y'] == 'qux' del A.z # actual: raises AttributeError: __delete__ # expected: 'z' not in vars(A) ``` -- components: Interpreter Core messages: 389598 nosy: maggyero priority: normal severity: normal status: open title: Do not raise AttributeError on instance attribute update/deletion if data descriptor with missing __set__/__delete__ method found on its type type: behavior versions: Python 3.10, Python 3.6, Python 3.7, Python 3.8, Python 3.9 ___ Python tracker <https://bugs.python.org/issue43639> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue43479] Remove a duplicate comment and assignment in http.client
New submission from Géry : Remove a duplicate comment and assignment following the usage of a name already assigned in the http.client standard library. -- components: Library (Lib) messages: 388538 nosy: maggyero priority: normal pull_requests: 23597 severity: normal status: open title: Remove a duplicate comment and assignment in http.client type: enhancement versions: Python 3.10, Python 3.6, Python 3.7, Python 3.8, Python 3.9 ___ Python tracker <https://bugs.python.org/issue43479> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39457] Add an autocommit property to sqlite3.Connection with a PEP 249 compliant manual commit mode and migrate
Géry added the comment: @james.oldfield > What that answer doesn't mention is that, even with even with > isolation_mode=None, it's perfectly possible to start a transaction, which > takes the SQLite engine out of autocommit mode. Exactly, so since autocommit=True is equivalent to isolation_mode=None I do not see why you the name ‘autocommit’ would be a problem. As you said, when you issue BEGIN, you leave autocommit mode. > Under your proposal, the first line would be changed to say > "autocommit=True", even though not all the code below is in autocommit mode > (according to the SQLite engine's definition). What is the difference with isolation_mode=None which also means autocommit mode? > What's more, I could insert this line of code between statements 3 and 6: >print("Autocommit mode?", conn.autocommit) > And it would print True even though autocommit mode is off! No, because the autocommit property would be automatically updated to False at conn.execute("BEGIN"), which is the standard behaviour as @lemburg explained. @lemburg > I guess the SQLite driver does not start a new transaction for SELECTs, since > these are usually read-only Nor for DDL statements (CREATE, DROP). > For the same reason, removing the SELECT "optimization" may cause > a backwards incompatible change, which can be tricky to identify > and cause corruption of data (in this case, data not written to > the database, where it previously was written). Since DQL statements (SELECT) are read-only, maybe we could keep the optimization and start transactions implicitly only for DDL statements (CREATE, DROP)? -- ___ Python tracker <https://bugs.python.org/issue39457> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39457] Add an autocommit property to sqlite3.Connection with a PEP 249 compliant manual commit mode and migrate
Géry added the comment: > If this ever gets implemented, "autocommit" would be a terrible name for it. > That word has a very specific meaning in SQLite, which is essentially the > same as "not in a transaction started with BEGIN ...". Yes if you are talking about SQLite, the database ENGINE: the SQL statements inside BEGIN and COMMIT are said to be in manual commit mode, while SQL statements outside are said to be in autocommit mode. So the autocommit mode is the default mode for database ENGINES. But here I am talking about SQLite3, the Python database DRIVER. You do not issue BEGIN statements with database DRIVERS, they are issued implicitly, so that the manual mode is the default mode for database DRIVERS. Cf. this Stack Overflow answer for more details: https://stackoverflow.com/a/48391535/2326961 > At the moment, if you want to explicitly control when transactions start (a > good idea considering how confusing the current behaviour is) No, you do not want that at the database DRIVER level. Because like Mike Bayer explained in issue #9924, this is not what other database DRIVERS do, and this is not PEP 249 compliant (Python Database API Specification v2.0), as its author Marc-André Lemburg explained (cf. https://mail.python.org/pipermail/db-sig/2010-September/005645.html): > Randall Nortman wrote: > # PEP 249 says that transactions end on commit() or rollback(), but it > # doesn't explicitly state when transactions should begin, and there is > # no begin() method. > > Transactions start implicitly after you connect and after you call .commit() > or .rollback(). They are not started for each statement. -- ___ Python tracker <https://bugs.python.org/issue39457> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue37203] Correct classmethod emulation in Descriptor HowTo Guide
Change by Géry : -- versions: +Python 3.9 -Python 3.7 ___ Python tracker <https://bugs.python.org/issue37203> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue37203] Correct classmethod emulation in Descriptor HowTo Guide
Change by Géry : -- resolution: not a bug -> fixed ___ Python tracker <https://bugs.python.org/issue37203> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue37203] Correct classmethod emulation in Descriptor HowTo Guide
Change by Géry : -- pull_requests: +21866 pull_request: https://github.com/python/cpython/pull/22934 ___ Python tracker <https://bugs.python.org/issue37203> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue35181] Doc: Namespace Packages: Inconsistent documentation of __loader__ being None
Géry added the comment: Thanks @barry for reviewing and merging PR 15190 > I haven't merged PR 10016, but I left some additional comments. Are you > still interested in shepherding this PR? Also thanks for helping me with @ericsnowcurrently advancing this last PR. Yes I am still interested, I have reviewed all the comments and updated the whole thing, doing my best to keep the two descriptions of the module attributes and spec attributes consistent since this PEP updates both descriptions. -- ___ Python tracker <https://bugs.python.org/issue35181> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue35790] Correct the description of sys.exc_info() and add a code example
Change by Géry : -- nosy: +cheryl.sabella -eric.araujo, ezio.melotti, willingc title: Correct a statement about sys.exc_info() values restoration -> Correct the description of sys.exc_info() and add a code example type: -> enhancement versions: +Python 3.6, Python 3.8, Python 3.9 ___ Python tracker <https://bugs.python.org/issue35790> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39862] Why are the union relationships not implemented by default for ≤ and ≥?
Géry added the comment: Alright @rhettinger, here is the post: https://discuss.python.org/t/add-missing-default-implementations-of-le-and-ge/5327 -- ___ Python tracker <https://bugs.python.org/issue39862> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue41814] Mismatch between the manipulation of `sys.path` by `runpy` and by the Python command-line interface
New submission from Géry : Nicholas, I have noticed that `runpy.run_path` alters `sys.path` as expected for a file_path argument which is a valid `sys.path` entry (typically a directory or zip file). That is to say it adds the file_path argument to the beginning of `sys.path`, like `python `. However, I have also noticed that `runpy.run_path` does not alter `sys.path` as expected for a file_path argument which is a Python source or bytecode file path. That is to say it does not add the *parent path* of the file_path argument to the beginning of `sys.path`, contrary to `python `. Likewise, I have also noticed that `runpy.run_module` (with the alter_sys argument set to `True` of course) does not alter `sys.path` as expected. That is to say it does not add the path of the *current directory* to the beginning of `sys.path`, contrary to `python -m `. Only the first of the three previous `sys.path` manipulations is documented in https://docs.python.org/3/library/runpy.html though, so the `runpy` implementation is at least compliant with its specification. So is the mismatch between the manipulation of `sys.path` by `runpy` and by the Python command-line interface a specification bug or is it the intended behaviour? -- components: Library (Lib) messages: 377171 nosy: maggyero, ncoghlan priority: normal severity: normal status: open title: Mismatch between the manipulation of `sys.path` by `runpy` and by the Python command-line interface type: behavior versions: Python 3.8 ___ Python tracker <https://bugs.python.org/issue41814> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39452] Improve the __main__ module documentation
Géry added the comment: I agree with you Terry. Another thing that bothers me: in the current document, the __main__ module is reduced to its environment (aka context or dictionary), whereas a module object has other important attributes such as its code. So how about adding the following changes? - :mod:`__main__` --- Top-level code environment - == + :mod:`__main__` --- Startup module + == -:synopsis: The environment where top-level code is run. +:synopsis: The first module from which the code is executed at startup. - ``'__main__'`` is the name of the environment where top-level code is run. + ``'__main__'`` is the name of the startup module. - A module can discover whether or not it is running in the main environment + A module can discover whether or not it is initialized as the :mod:`__main__` module -- ___ Python tracker <https://bugs.python.org/issue39452> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39452] Improve the __main__ module documentation
Géry added the comment: Thanks for your extended review Steven. > You state that these two phrases are from the runpy documentation: > > * "run from the module namespace" > * "run from the file system" > > but neither of those phrases appear in the runpy documentation here: > > https://docs.python.org/3/library/runpy.html I agree. Actually the first paragraph of the page uses the phrases: - "located using the module namespace"; - "located using the file system", so instead of saying: - "run a module located using the module namespace" to mean "python - "run a module located using the file system" to mean "python -m ", I simplified to: - "run from the module namespace" - "run from the file system" But since the terminology is misleading I have used these phrases instead: - `python`: "module initialized from an interactive prompt"; - `python < `: "module initialized from standard input"; - `python `: "module initialized from a file argument"; - `python -c `: "module initialized from a `-c` argument"; - `python -m `: "module initialized from a `-m` argument"; - `import `: "module initialized from an import statement". What the documentation tries to explain is that in all of these cases except the last one, code is executed in the __main__ module. I have updated the PR. > The PR changes the term "scope" to "environment", but I think that is wrong. > An environment is potentially greater than a scope. `__main__` is a module > namespace, hence a scope. The environment includes things outside of that > scope, such as the builtins, environment variables, the current working > directory, the python path, etc. We don't talk about modules being an > environment, but as making up a scope. I disagree. According to Wikipedia (https://en.wikipedia.org/wiki/Scope_(computer_science)), the term "scope" is the part of a program where a name binding is valid, while the term "environment" (synonym of "context") is the set of name bindings that are valid within a part of a program. Therefore "scope" is a property of a name binding (a name binding has a scope), and "environment" is a property of a part of a program (a part of a program has an environment). And the term "environment" is actually already used in the original title and synopsis of the document (and it is correct): > :mod:`__main__` --- Top-level script environment > .. module:: __main__ > :synopsis: The environment where the top-level script is run. So my change to the body fixes the inconsistent and incorrect usage of "scope": - ``'__main__'`` is the name of the scope in which top-level code executes. + ``'__main__'`` is the name of the environment where top-level code is run. - A module can discover whether or not it is running in the main scope + A module can discover whether or not it is running in the main environment > Placing the comment above the `if`, where it will apply to the entire `if` > statement, is incorrect. I agree. Sometimes you see comments before if statements but they usually don't start with "execute". I have updated the PR. > The second problem is that when running a module with -m it *is* imported. > PEP 338 is clear about this: I agree. I should have said "when the module is not initialized from an import statement". But note that even before my change the original document already used the phrase "not imported": - executing code in a module when it is run as a script or with ``python - -m`` but not when it is imported:: + executing code in a module when it is not imported:: - # execute only if run as a script + # Execute only if the module is not imported. I have updated the PR. -- ___ Python tracker <https://bugs.python.org/issue39452> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39862] Why are the union relationships not implemented by default for ≤ and ≥?
Géry added the comment: More precisely: The following relationships are always valid and therefore implemented by default in Python (_except for the union relationships, which seems arbitrary and is the reason of this Python issue_): - 2 [complementary](https://en.wikipedia.org/wiki/Binary_relation#Complement) relationships: "= and ≠ are each other’s complement"; - 6 [converse](https://en.wikipedia.org/wiki/Binary_relation#Converse) relationships*: "= is the converse of itself", "≠ is the converse of itself", "< and > are each other’s converse", and "≤ and ≥ are each other’s converse"; - 2 [union](https://en.wikipedia.org/wiki/Binary_relation#Union) relationships: "≤ is the union < and =" and "≥ is the union of > and ≤". The following relationships are only valid for [total orders](https://en.wikipedia.org/wiki/Binary_relation#Properties) and therefore not implemented by default in Python (but users can conveniently implement them when they are valid with the [`functools.total_ordering`](https://docs.python.org/3/library/functools.html#functools.total_ordering) class decorator provided by the Python standard library): - 4 [complementary](https://en.wikipedia.org/wiki/Binary_relation#Complement) relationships: "< and ≥ are each other’s complement" and "> and ≤ are each other’s complement". \* Converse relationships are implemented in Python through the [`NotImplemented` protocol](https://docs.python.org/3/reference/datamodel.html#the-standard-type-hierarchy). -- ___ Python tracker <https://bugs.python.org/issue39862> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39862] Why are the union relationships not implemented by default for ≤ and ≥?
Géry added the comment: Note that other relationships are always valid _and already implemented by default in the interpreter (through the `NotImplemented` return value protocol)_: = is the [converse](https://en.wikipedia.org/wiki/Binary_relation#Converse) of itself, ≠ is the converse of itself, < and > are each other’s converse, ≤ and ≥ as each other’s converse. ("converse" is loosely called "reflected" in the Python documentation.) Which also makes me think that the last sentence of this documentation paragraph is incorrect: > By default, `__ne__()` delegates to `__eq__()` and inverts the result > unless it is `NotImplemented`. There are no other implied > relationships among the comparison operators, for example, the truth > of `(x are each other’s converse, and ≤ and ≥ are each other’s converse. -- ___ Python tracker <https://bugs.python.org/issue39862> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39862] Why are the union relationships not implemented by default for ≤ and ≥?
Géry added the comment: Thanks for the reference @Raymond. I could not find any mention of the union relationships for ≤ and ≥ though. Since they are always valid for Boolean values, in the same way that ≠ is always the complement of = for Boolean values and default implemented as such in the interpreter, what do you think of default implementing these union relationships in the interpreter? -- ___ Python tracker <https://bugs.python.org/issue39862> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39862] Why are the union relationships not implemented by default for ≤ and ≥?
New submission from Géry : Mathematically, the [binary relation](https://en.wikipedia.org/wiki/Binary_relation) ≤ is the [union](https://en.wikipedia.org/wiki/Binary_relation#Union) of the binary relations < and =, while the binary relation ≥ is the union of the binary relations > and =. So is there a reason why Python does not implement `__le__` in terms of `__lt__` and `__eq__` by default, and `__ge__` in terms of `__gt__` and `__eq__` by default? The default implementation would be like this (but probably in C for performance, like `__ne__`): ```python def __le__(self, other): result_1 = self.__lt__(other) result_2 = self.__eq__(other) if result_1 is not NotImplemented and result_2 is not NotImplemented: return result_1 or result_2 return NotImplemented def __ge__(self, other): result_1 = self.__gt__(other) result_2 = self.__eq__(other) if result_1 is not NotImplemented and result_2 is not NotImplemented: return result_1 or result_2 return NotImplemented ``` This would save users from implementing these two methods all the time. Here is the relevant paragraph in the [Python documentation](https://docs.python.org/3/reference/datamodel.html#object.__lt__) (emphasis mine): > By default, `__ne__()` delegates to `__eq__()` and inverts the result > unless it is `NotImplemented`. There are no other implied > relationships among the comparison operators, **for example, the truth > of `(xhttps://en.wikipedia.org/wiki/Binary_relation#Properties) (also called connex orders) and therefore not implemented by default: < is the [complement](https://en.wikipedia.org/wiki/Binary_relation#Complement) of ≥, and > is the complement of ≤. These complementary relationships can be easily implemented by users when they are valid with the [`functools.total_ordering`](https://docs.python.org/3/library/functools.html#functools.total_ordering) class decorator provided by the Python standard library. -- components: Interpreter Core messages: 363426 nosy: maggyero priority: normal severity: normal status: open title: Why are the union relationships not implemented by default for ≤ and ≥? type: enhancement versions: Python 3.9 ___ Python tracker <https://bugs.python.org/issue39862> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39457] Add an autocommit property to sqlite3.Connection with a PEP 249 compliant manual commit mode and migrate
Géry added the comment: > - Remove the value None of the autocommit property and its deprecation > warning. Correction: - Remove the value None of the autocommit property and its deprecation warning, so that the old manual commit mode disappears. -- ___ Python tracker <https://bugs.python.org/issue39457> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39457] Add an autocommit property to sqlite3.Connection with a PEP 249 compliant manual commit mode and migrate
Géry added the comment: > - Remove the value None of the isolation_level property, so that the old > manual commit mode disappears. Correction: - Remove the value None of the isolation_level property. -- ___ Python tracker <https://bugs.python.org/issue39457> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue10740] sqlite3 module breaks transactions and potentially corrupts data
Géry added the comment: @R. David Murray > Please open a new issue for this request. Done here: https://bugs.python.org/issue39457 -- ___ Python tracker <https://bugs.python.org/issue10740> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39457] Add an autocommit property to sqlite3.Connection with a PEP 249 compliant manual commit mode and migrate
Change by Géry : -- title: Add an autocommit property to sqlite3.Connection with truly PEP 249 compliant manual commit mode and migrate -> Add an autocommit property to sqlite3.Connection with a PEP 249 compliant manual commit mode and migrate ___ Python tracker <https://bugs.python.org/issue39457> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39457] Add an autocommit property to sqlite3.Connection with truly PEP 249 compliant manual commit mode and migrate
New submission from Géry : In non-autocommit mode (manual commit mode), the sqlite3 database driver implicitly issues a BEGIN statement before each DML statement (INSERT, UPDATE, DELETE, REPLACE) not already in a database transaction, BUT NOT before DDL statements (CREATE, DROP) nor before DQL statements (SELECT) (cf. https://github.com/python/cpython/blob/master/Modules/_sqlite/cursor.c#L480): ``` /* We start a transaction implicitly before a DML statement. SELECT is the only exception. See #9924. */ if (self->connection->begin_statement && self->statement->is_dml) { if (sqlite3_get_autocommit(self->connection->db)) { result = _pysqlite_connection_begin(self->connection); if (!result) { goto error; } Py_DECREF(result); } } ``` Like Mike Bayer explained in issue #9924, this is not what other database drivers do, and this is not PEP 249 compliant (Python Database API Specification v2.0), as its author Marc-André Lemburg explained (cf. https://mail.python.org/pipermail/db-sig/2010-September/005645.html): > Randall Nortman wrote: > # PEP 249 says that transactions end on commit() or rollback(), but it > # doesn't explicitly state when transactions should begin, and there is > # no begin() method. > > Transactions start implicitly after you connect and after you call .commit() or .rollback(). They are not started for each statement. > > # I think the implication is that transactions begin > # on the first execute(), but that's not explicitly stated. At least > # one driver, pysqlite2/sqlite3, does not start a transaction for a > # SELECT statement. It waits for a DML statement (INSERT, UPDATE, > # DELETE) before opening a transaction. Other drivers open transactions > # on any statement, including SELECT. > # > # My question for the DB-SIG is: Can I call it a bug in pysqlite2 that > # it does not open transactions on SELECT? Should the spec be amended > # to make this explicit? Or are both behaviors acceptable, in which > # case perhaps a begin() method needs to be added for when the user > # wants control over opening transactions? > > I should probably add a note to PEP 249 about this. Aymeric Augustin said in issue #10740: > While you're there, it would be cool to provide "connection.autocommit = > True" as an API to enable autocommit, because "connection.isolation_level = > None" isn't a good API at all -- it's very obscure and has nothing to do with > isolation level whatsoever. So I suggest that we introduce a new autocommit property and use it to enable a truly PEP 249 compliant manual commit mode (that is to say with transactions starting implicitly after connect(), commit() and rollback() calls, allowing transactional DDL and DQL): ``` autocommit = True # enable the autocommit mode autocommit = False # disable the autocommit mode (enable the new PEP 249 manual commit mode) autocommit = None # fallback to the commit mode set by isolation_level ``` I also suggest that we use this new PEP 249 manual commit mode (with transactional DDL and DQL) by default and drop the old manual commit mode (without transactional DDL and DQL). We could use the following migration strategy: 1. During the deprecation period: - Add the new autocommit property with the value None by default, so that the old manual commit mode is still the default. - Add a deprecation warning for the value None of the autocommit property, in favor of the other values True and False. It will prompt users who enabled the autocommit mode with isolation_level = None to use autocommit = True instead, and users who disabled the autocommit mode (that is to say users who enabled the old manual commit mode) with isolation_level = DEFERRED/IMMEDIATE/EXCLUSIVE to use autocommit = False instead AND add to their code the potentially missing commit() calls required by the new PEP 249 manual commit mode. 2. After the deprecation period: - Set the value of the autocommit property to False by default, so that the new PEP 249 manual commit mode becomes the new default. - Remove the value None of the autocommit property and its deprecation warning. - Remove the value None of the isolation_level property, so that the old manual commit mode disappears. -- components: Library (Lib) messages: 360732 nosy: ghaering, lemburg, maggyero, r.david.murray, zzzeek priority: normal severity: normal status: open title: Add an autocommit property to sqlite3.Connection with truly PEP 249 compliant manual commit mode and migrate type: enhancement versions: Python 3.8 ___ Python tracker <https://bugs.python.org/issue39457> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue10740] sqlite3 module breaks transactions and potentially corrupts data
Géry added the comment: @Aymeric Augustin > While you're there, it would be cool to provide "connection.autocommit = > True" as an API to enable autocommit, because "connection.isolation_level = > None" isn't a good API at all -- it's very obscure and has nothing to do with > isolation level whatsoever. +1. We could use this new autocommit property to enable the new full transactional mode (that is to say with transactional DDL): ``` connection.autocommit = True # enable the autocommit mode connection.autocommit = False # disable the autocommit mode (enable the full transactional mode) connection.autocommit = None # fallback to connection.isolation_level ``` To transition from the old partial transactional mode (without transactional DDL) by default to the new full transactional mode (with transactional DDL) by default, we could use the following migration strategy: 1. During the deprecation period: - Add the new autocommit property with the value None by default, so that the old partial transactional mode is still the default. - Add a deprecation warning for the value None of the autocommit property, in favor of the other values True and False. It will prompt users who enabled the autocommit mode with connection.isolation_level = None to use connection.autocommit = True instead, and users who disabled the autocommit mode (that is to say users who enabled the old partial transactional mode) with connection.isolation_level = DEFERRED/IMMEDIATE/EXCLUSIVE to use connection.autocommit = False instead AND add to their code the potentially missing connection.commit() calls required by the new full transactional mode for committing DDL statements. 2. After the deprecation period: - Set the value of the autocommit property to False by default, so that the new full transactional mode becomes the new default. - Remove the value None of the autocommit property and its deprecation warning. - Remove the value None of the isolation_level property, so that the old partial transactional mode disappears. -- ___ Python tracker <https://bugs.python.org/issue10740> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39452] Improve the __main__ module documentation
New submission from Géry : This PR will apply the following changes on the [`__main__` module documentation](https://docs.python.org/3.7/library/__main__.html): - correct the phrase "run as script" by "run from the file system" (as used in the [`runpy`](https://docs.python.org/3/library/runpy.html) documentation) since "run as script" does not mean the intended `python foo.py` but `python -m foo` (cf. [PEP 338](https://www.python.org/dev/peps/pep-0338/)); - replace the phrase "run with `-m`" by "run from the module namespace" (as used in the [`runpy`](https://docs.python.org/3/library/runpy.html) documentation) since the module can be equivalently run with `runpy.run_module('foo')` instead of `python -m foo`; - make the block comment [PEP 8](https://www.python.org/dev/peps/pep-0008/#comments)-compliant (located before the `if` block, capital initialised, period ended); - add a missing case for which a package's \_\_main\_\_.py is executed (when the package is run from the file system: `python foo/`). -- assignee: docs@python components: Documentation messages: 360682 nosy: docs@python, maggyero priority: normal pull_requests: 17565 severity: normal status: open title: Improve the __main__ module documentation type: enhancement versions: Python 3.8 ___ Python tracker <https://bugs.python.org/issue39452> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue10740] sqlite3 module breaks transactions and potentially corrupts data
Géry added the comment: With Berker Peksag's patch merged in 2016, in the default non auto-commit mode, sqlite3 implicitly issues a BEGIN statement before any non SELECT statement not already in a transaction, EXCEPT DDL statements, for backwards compatibility reasons: +/* For backwards compatibility reasons, do not start a transaction if a + DDL statement is encountered. If anybody wants transactional DDL, + they can issue a BEGIN statement manually. */ +if (self->connection->begin_statement && !sqlite3_stmt_readonly(self->statement->st) && !self->statement->is_ddl) { +if (sqlite3_get_autocommit(self->connection->db)) { +result = _pysqlite_connection_begin(self->connection); +if (!result) { +goto error; +} +Py_DECREF(result); } } Is there any plan to cover DDL statements as well in a future Python version and deprecate the old behaviour? That would avoid having to insert BEGIN statements manually for getting transactional DDL statements, like in psycopg2 for PostgreSQL databases. -- nosy: +maggyero ___ Python tracker <https://bugs.python.org/issue10740> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39048] Look up __aenter__ before __aexit__ in the async with statement
Change by Géry : -- title: Look up __aenter__ before __aexit__ in async with -> Look up __aenter__ before __aexit__ in the async with statement ___ Python tracker <https://bugs.python.org/issue39048> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39037] Look up __enter__ before __exit__ in the with statement documentation
Change by Géry : -- title: Fix the trial order of the __exit__ and __enter__ methods in the with statement documentation -> Look up __enter__ before __exit__ in the with statement documentation ___ Python tracker <https://bugs.python.org/issue39037> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39048] Look up __aenter__ before __aexit__ in async with
Change by Géry : -- title: Change the lookup order of __aenter__ and __aexit__ for async with -> Look up __aenter__ before __aexit__ in async with ___ Python tracker <https://bugs.python.org/issue39048> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39048] Change the lookup order of __aenter__ and __aexit__ for async with
Change by Géry : -- title: Reorder __aenter__ & __aexit__ checks for async with statement -> Change the lookup order of __aenter__ and __aexit__ for async with ___ Python tracker <https://bugs.python.org/issue39048> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39037] Fix the trial order of the __exit__ and __enter__ methods in the with statement documentation
Change by Géry : -- resolution: -> fixed stage: patch review -> resolved status: open -> closed ___ Python tracker <https://bugs.python.org/issue39037> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39037] Fix the trial order of the __exit__ and __enter__ methods in the with statement documentation
Géry added the comment: Thanks @ncoghlan, it perfectly answered my question on Stack Overflow: https://stackoverflow.com/questions/59322585/what-is-the-exact-try-statement-equivalent-of-the-with-statement-in-python -- ___ Python tracker <https://bugs.python.org/issue39037> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39037] Fix the trial order of the __exit__ and __enter__ methods in the with statement documentation
Géry added the comment: @gvanrossum By the way, is there any particular reason why the ``try`` statement implementation equivalent to the ``with`` statement given in PEP 343 puts the finally clause in an outer ``try`` statement instead of in the inner ``try`` statement? (cf. https://www.python.org/dev/peps/pep-0343/#specification-the-with-statement) In other words, couldn't we simplify this: ``` mgr = (EXPR) exit = type(mgr).__exit__ # Not calling it yet value = type(mgr).__enter__(mgr) exc = True try: try: VAR = value # Only if "as VAR" is present BLOCK except: # The exceptional case is handled here exc = False if not exit(mgr, *sys.exc_info()): raise # The exception is swallowed if exit() returns true finally: # The normal and non-local-goto cases are handled here if exc: exit(mgr, None, None, None) ``` into that? ``` mgr = (EXPR) exit = type(mgr).__exit__ # Not calling it yet value = type(mgr).__enter__(mgr) exc = True try: VAR = value # Only if "as VAR" is present BLOCK except: # The exceptional case is handled here exc = False if not exit(mgr, *sys.exc_info()): raise # The exception is swallowed if exit() returns true finally: # The normal and non-local-goto cases are handled here if exc: exit(mgr, None, None, None) ``` -- ___ Python tracker <https://bugs.python.org/issue39037> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue27100] Attempting to use class with both __enter__ & __exit__ undefined yields __exit__ attribute error
Géry added the comment: @ncoghlan > Reviewing the discussion, I assume this was left open to cover reordering the > __aenter__ and __aexit__ checks for async with, but that can just as easily > be handled as a separate issue (which would also be clearer at the NEWS > level). Here it is: https://bugs.python.org/issue39048 -- ___ Python tracker <https://bugs.python.org/issue27100> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39048] bpo-39048: Reorder the __aenter__ and __aexit__ method checks for the async with statement
Change by Géry : -- title: Reorder the __aenter__ and __aexit__ checks for async with -> bpo-39048: Reorder the __aenter__ and __aexit__ method checks for the async with statement ___ Python tracker <https://bugs.python.org/issue39048> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39048] Reorder the __aenter__ and __aexit__ method checks for the async with statement
Change by Géry : -- title: bpo-39048: Reorder the __aenter__ and __aexit__ method checks for the async with statement -> Reorder the __aenter__ and __aexit__ method checks for the async with statement ___ Python tracker <https://bugs.python.org/issue39048> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue27100] Attempting to use class with both __enter__ & __exit__ undefined yields __exit__ attribute error
Change by Géry : -- pull_requests: +17081 pull_request: https://github.com/python/cpython/pull/17609 ___ Python tracker <https://bugs.python.org/issue27100> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39048] Reorder the __aenter__ and __aexit__ checks for async with
New submission from Géry : Following https://bugs.python.org/issue27100 which did it for the with statement, what was left to do was to reorder the __aenter__ and __aexit__ method checks for the async with statement. I have opened a PR for this here: https://github.com/python/cpython/pull/17609 -- components: Interpreter Core messages: 358403 nosy: brett.cannon, maggyero, rhettinger priority: normal pull_requests: 17080 severity: normal status: open title: Reorder the __aenter__ and __aexit__ checks for async with type: behavior versions: Python 3.8 ___ Python tracker <https://bugs.python.org/issue39048> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue27100] Attempting to use class with both __enter__ & __exit__ undefined yields __exit__ attribute error
Change by Géry : -- pull_requests: -17079 ___ Python tracker <https://bugs.python.org/issue27100> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue27100] Attempting to use class with both __enter__ & __exit__ undefined yields __exit__ attribute error
Change by Géry : -- pull_requests: +17079 pull_request: https://github.com/python/cpython/pull/17609 ___ Python tracker <https://bugs.python.org/issue27100> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue38295] test_relative_path of test_py_compile fails on macOS 10.15 Catalina
Change by Géry : -- nosy: +maggyero ___ Python tracker <https://bugs.python.org/issue38295> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com