[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
[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
[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
[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 : -- 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
[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
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
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
[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
[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
[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
[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
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 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
[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
[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
[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
[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
[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
[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
[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] 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
[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
[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
[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
[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
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
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
[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
[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
[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
[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
[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: 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
[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
[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: 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
[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
[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
[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
[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
[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
[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
[issue1152248] Add support for reading records with arbitrary separators to the standard IO stack
Change by Géry : -- nosy: +maggyero ___ Python tracker <https://bugs.python.org/issue1152248> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue17083] can't specify newline string for readline for binary files
Change by Géry : -- nosy: +maggyero ___ Python tracker <https://bugs.python.org/issue17083> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue37969] urllib.parse functions reporting false equivalent URIs
New submission from Géry : The Python library documentation of the `urllib.parse.urlunparse <https://docs.python.org/3/library/urllib.parse.html#urllib.parse.urlunparse>`_ and `urllib.parse.urlunsplit <https://docs.python.org/3/library/urllib.parse.html#urllib.parse.urlunsplit>`_ functions states: This may result in a slightly different, but equivalent URL, if the URL that was parsed originally had unnecessary delimiters (for example, a ? with an empty query; the RFC states that these are equivalent). So with the <http://example.com/?> URI:: >>> import urllib.parse >>> urllib.parse.urlunparse(urllib.parse.urlparse("http://example.com/?";)) 'http://example.com/' >>> urllib.parse.urlunsplit(urllib.parse.urlsplit("http://example.com/?";)) 'http://example.com/' But `RFC 3986 <https://tools.ietf.org/html/rfc3986?#section-6.2.3>`_ states the exact opposite: Normalization should not remove delimiters when their associated component is empty unless licensed to do so by the scheme specification. For example, the URI "http://example.com/?"; cannot be assumed to be equivalent to any of the examples above. Likewise, the presence or absence of delimiters within a userinfo subcomponent is usually significant to its interpretation. The fragment component is not subject to any scheme-based normalization; thus, two URIs that differ only by the suffix "#" are considered different regardless of the scheme. So maybe `urllib.parse.urlunparse` ∘ `urllib.parse.urlparse` and `urllib.parse.urlunsplit` ∘ `urllib.parse.urlsplit` are not supposed to be used for `syntax-based normalization <https://tools.ietf.org/html/rfc3986?#section-6>`_ of URIs. But still, both `urllib.parse.urlparse` or `urllib.parse.urlsplit` lose the "delimiter + empty component" information of the URI string, so they report false equivalent URIs:: >>> import urllib.parse >>> urllib.parse.urlparse("http://example.com/?";) == urllib.parse.urlparse("http://example.com/";) True >>> urllib.parse.urlsplit("http://example.com/?";) == urllib.parse.urlsplit("http://example.com/";) True P.-S. — Is there a syntax-based normalization function of URIs in the Python library? -- components: Library (Lib) messages: 350663 nosy: Jeremy.Hylton, maggyero, orsenthil priority: normal severity: normal status: open title: urllib.parse functions reporting false equivalent URIs type: behavior versions: Python 3.7 ___ Python tracker <https://bugs.python.org/issue37969> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue37969] urllib.parse functions reporting false equivalent URIs
Change by Géry : -- keywords: +patch pull_requests: +15308 stage: -> patch review pull_request: https://github.com/python/cpython/pull/15642 ___ Python tracker <https://bugs.python.org/issue37969> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue37969] urllib.parse functions reporting false equivalent URIs
Géry added the comment: @nicktimko Thanks for the historical track. Here is a patch that solves this issue by updating the `urlsplit` and `urlunsplit` functions of the `urllib.parse` module to keep the '?' and '#' delimiters in URIs if present, even if their associated component is empty, as required by RFC 3986: https://github.com/python/cpython/pull/15642 That way we get the correct behavior: >>> import urllib.parse >>> urllib.parse.urlunsplit(urllib.parse.urlsplit("http://example.com/?";)) 'http://example.com/?' >>> urllib.parse.urlunsplit(urllib.parse.urlsplit("http://example.com/#";)) 'http://example.com/#' Any feedback welcome. -- ___ Python tracker <https://bugs.python.org/issue37969> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue37969] Correct urllib.parse functions dropping the delimiters of empty URI components
Change by Géry : -- title: urllib.parse functions reporting false equivalent URIs -> Correct urllib.parse functions dropping the delimiters of empty URI components ___ Python tracker <https://bugs.python.org/issue37969> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue38255] Replace "method" with "attribute" in the description of super()
New submission from Géry : The description of `super()` uses the word "method" instead of the more general word "attribute". > super([type[, object-or-type]]) > Return a proxy object that delegates method calls to a parent or sibling > class of *type*. This is useful for accessing inherited methods that have > been overridden in a class. `super()` is not restricted to method access but can also do data attribute access: ``` >>> class A: ... x = True ... >>> class B(A): ... x = False ... >>> B().x False >>> super(B, B()).x True ``` I have just opened a PR to address this issue. -- assignee: docs@python components: Documentation messages: 352991 nosy: docs@python, maggyero, rhettinger priority: normal pull_requests: 15908 severity: normal status: open title: Replace "method" with "attribute" in the description of super() type: enhancement versions: Python 3.7 ___ Python tracker <https://bugs.python.org/issue38255> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue9334] argparse does not accept options taking arguments beginning with dash (regression from optparse)
Change by Géry : -- nosy: +maggyero ___ Python tracker <https://bugs.python.org/issue9334> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue38255] Replace "method" with "attribute" in the description of super()
Géry added the comment: Alright, I am fine with @rhettinger's alternative PR too. I am closing this. -- resolution: -> fixed stage: patch review -> resolved status: open -> closed ___ Python tracker <https://bugs.python.org/issue38255> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue38336] Remove the __set__ method restriction on data descriptors for attribute lookup precedence
Change by Géry : -- keywords: +patch pull_requests: +16112 stage: -> patch review pull_request: https://github.com/python/cpython/pull/16520 ___ Python tracker <https://bugs.python.org/issue38336> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue38336] Remove the __set__ method restriction on data descriptors for attribute lookup precedence
Géry added the comment: I have opened a PR here: https://github.com/python/cpython/pull/16520 -- ___ Python tracker <https://bugs.python.org/issue38336> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue38336] Remove the __set__ method restriction on data descriptors for attribute lookup precedence
New submission from Géry : The [language documentation](https://docs.python.org/3/reference/datamodel.html#invoking-descriptors) states: > Data descriptors with __set__() and __get__() defined always override a > redefinition in an instance dictionary. In contrast, non-data descriptors can > be overridden by instances. This override is not limited to data descriptors defining `__set__()` (and `__get__()`). It is also true for data descriptors defining `__delete__()` (and `__get__()`) and data descriptors defining both `__set__()` and `__delete__()` (and `__get__()`). In other words, _any_ data descriptors (objects defining either `__set__()` or `__delete__()` or both) defining `__get__()` override an attribute redefinition in an instance dictionary. -- assignee: docs@python components: Documentation messages: 353685 nosy: docs@python, maggyero priority: normal severity: normal status: open title: Remove the __set__ method restriction on data descriptors for attribute lookup precedence type: enhancement versions: Python 3.7 ___ Python tracker <https://bugs.python.org/issue38336> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue38336] Remove the __set__ method restriction on data descriptors for attribute lookup precedence
Change by Géry : -- nosy: +rhettinger ___ Python tracker <https://bugs.python.org/issue38336> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue38336] Remove the __set__ method restriction on data descriptors for attribute lookup precedence
Change by Géry : -- versions: +Python 3.8 -Python 3.7 ___ Python tracker <https://bugs.python.org/issue38336> ___ ___ 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
[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
[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
[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
[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
[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
[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
[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
[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
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
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
[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
[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] 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] 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
[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
[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
[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
[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
[issue38950] argparse uses "optional arguments" for "keyword arguments"
New submission from Géry : The argparse module incorrectly uses the terms "optional arguments" for keyword arguments. For instance this argument parser takes a required keyword argument and an optional positional argument, but classifies the former as an "optional argument" and the latter as a "positional argument": >>> import argparse >>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo', required=True) _StoreAction(option_strings=['--foo'], dest='foo', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None) >>> parser.add_argument('bar', nargs='?') _StoreAction(option_strings=[], dest='bar', nargs='?', const=None, default=None, type=None, choices=None, help=None, metavar=None) >>> parser.parse_args(['-h']) usage: [-h] --foo FOO [bar] positional arguments: bar optional arguments: -h, --help show this help message and exit --foo FOO Since the actual classification seems to distinguish positional from keyword arguments instead of required from optional arguments, I think that the "optional arguments:" section should be renamed to "keyword arguments:". -- components: Library (Lib) messages: 357681 nosy: bethard, maggyero, rhettinger priority: normal severity: normal status: open title: argparse uses "optional arguments" for "keyword arguments" type: enhancement versions: Python 2.7, Python 3.5, Python 3.6, Python 3.7, Python 3.8, Python 3.9 ___ Python tracker <https://bugs.python.org/issue38950> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue9694] argparse required arguments displayed under "optional arguments"
Géry added the comment: I have just run into the same issue here: https://bugs.python.org/issue38950 - I prefer Terry J. Reedy's "keyword arguments" as it is clear and consistent with "positional arguments". - But Steven Bethard 's "flag arguments" looks fine since it is well known to shell users. - Martin Panter's "options" looks okay since it is the standard name in GNU Coreutils (https://www.gnu.org/software/coreutils/manual/coreutils.html#Common-options). However I don't like it very much as it is still ambiguous: "options", like "optional arguments", still suggests something that is non required. And "options" is less consistent with "positional arguments" (nobody seems to have suggested "option arguments"). - Oliver Smith's "switches" does not look okay because it is not general enough since it is commonly restricted to Boolean arguments. Anyway, the first 3 solutions are better than the current "optional arguments". What is blocking the approval of Martin Panter's PR? -- nosy: +maggyero ___ Python tracker <https://bugs.python.org/issue9694> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue38950] argparse uses "optional arguments" for "keyword arguments"
Géry added the comment: Thanks paul j3 for the link. I am continuing the discussion there. -- ___ Python tracker <https://bugs.python.org/issue38950> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39037] Wrong trial order of __exit__ and __enter__ in the with statement
New submission from Géry : >>> class A: pass ... >>> with A(): pass ... Traceback (most recent call last): File "", line 1, in AttributeError: __enter__ I expected `AttributeError: __exit__`, since PEP 343 states (https://www.python.org/dev/peps/pep-0343/#specification-the-with-statement): > The details of the above translation are intended to prescribe the exact > semantics. If either of the relevant methods are not found as expected, the > interpreter will raise AttributeError, in the order that they are tried > (__exit__, __enter__). and the language documentation states (https://docs.python.org/3/reference/compound_stmts.html#the-with-statement): > The execution of the with statement with one “item” proceeds as follows: > 1. The context expression (the expression given in the with_item) is > evaluated to obtain a context manager. > 2. The context manager’s __exit__() is loaded for later use. > 3. The context manager’s __enter__() method is invoked. -- components: Interpreter Core messages: 358333 nosy: gvanrossum, maggyero, ncoghlan priority: normal severity: normal status: open title: Wrong trial order of __exit__ and __enter__ in the with statement type: behavior versions: Python 3.7 ___ 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] Wrong trial order of __exit__ and __enter__ in the with statement
Géry added the comment: Thanks @mark.dickinson for the link. Can I open a documentation PR for this? -- ___ 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
Change by Géry : -- nosy: +maggyero ___ 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
[issue39037] Wrong trial order of __exit__ and __enter__ in the with statement
Change by Géry : -- keywords: +patch pull_requests: +17078 stage: needs patch -> patch review pull_request: https://github.com/python/cpython/pull/17608 ___ 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] Wrong trial order of __exit__ and __enter__ in the with statement
Géry added the comment: Done @brett.cannon, would you like to review it? https://github.com/python/cpython/pull/17608 -- ___ 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
Change by Géry : -- title: Wrong trial order of __exit__ and __enter__ in the with statement -> Fix the trial order of the __exit__ and __enter__ methods 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
[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
[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
[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
[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: +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] 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
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
[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
[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
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
[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
[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
[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 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