Rocksolid Light

Welcome to novaBBS (click a section below)

mail  files  register  newsreader  groups  login

Message-ID:  

6 May, 2024: The networking issue during the past two days has been identified and fixed.


devel / comp.lang.python / Re: imaplib: is this really so unwieldy?

SubjectAuthor
o Re: imaplib: is this really so unwieldy?Dennis Lee Bieber

1
Re: imaplib: is this really so unwieldy?

<mailman.347.1621981552.3087.python-list@python.org>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=13334&group=comp.lang.python#13334

  copy link   Newsgroups: comp.lang.python
Path: i2pn2.org!i2pn.org!news.swapon.de!fu-berlin.de!uni-berlin.de!not-for-mail
From: wlfr...@ix.netcom.com (Dennis Lee Bieber)
Newsgroups: comp.lang.python
Subject: Re: imaplib: is this really so unwieldy?
Date: Tue, 25 May 2021 15:53:03 -0400
Organization: IISS Elusive Unicorn
Lines: 234
Message-ID: <mailman.347.1621981552.3087.python-list@python.org>
References: <21fb6c5f-97a4-654b-887f-2c31a549bcbe@adminart.net>
<YKzFm7gR+5eKzov7@cskk.homeip.net>
<d4d433ff-5de6-31df-4234-e93feea454fc@adminart.net>
<14hqag1k3ujs43uij6rig68vckqo97j386@4ax.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
X-Trace: news.uni-berlin.de ORfQa6urjCYR6J/xQ7469gfWv5AHr0jR0+drWMtdo6lg==
Return-Path: <python-python-list@m.gmane-mx.org>
X-Original-To: python-list@python.org
Delivered-To: python-list@mail.python.org
Authentication-Results: mail.python.org; dkim=none reason="no signature";
dkim-adsp=none (unprotected policy); dkim-atps=neutral
X-Spam-Status: OK 0.000
X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'argument': 0.04; 'def':
0.04; 'containing': 0.05; 'error:': 0.05; 'indicate': 0.05;
'string': 0.05; 'okay': 0.07; 'used.': 0.07; '"""': 0.09; 'byte':
0.09; 'convert': 0.09; 'data)': 0.09; 'else:': 0.09; 'example:':
0.09; 'flags': 0.09; 'infinite': 0.09; 'ok,': 0.09; 'other.':
0.09; 'prints': 0.09; 'received:ciao.gmane.io': 0.09;
'received:gmane.io': 0.09; 'received:list': 0.09; 'rfc': 0.09;
"shouldn't": 0.09; "can't": 0.14; 'import': 0.14; '%s"': 0.16;
'(name,': 0.16; '+0200,': 0.16; '3.8.2': 0.16; 'append': 0.16;
'args:': 0.16; 'arguments': 0.16; 'command.': 0.16; 'defaults':
0.16; 'everywhere,': 0.16; 'fetch': 0.16; 'ideal.': 0.16;
'literal': 0.16; 'marks': 0.16; 'message-id:@4ax.com': 0.16;
'none:': 0.16; 'received:116.202': 0.16; 'received:116.202.254':
0.16; 'received:116.202.254.214': 0.16; 'specify': 0.16;
'strings,': 0.16; 'turns': 0.16; 'uid': 0.16; 'unicode': 0.16;
'that.': 0.16; 'python': 0.16; 'tue,': 0.18; "aren't": 0.20;
"i've": 0.22; 'install': 0.22; 'object': 0.23; 'returns': 0.23;
'skip:_ 10': 0.23; 'to:addr:python-list': 0.23; 'actual': 0.24;
'command': 0.24; 'header': 0.24; 'lines': 0.24; '>>>': 0.26;
'seems': 0.26; 'space': 0.26; 'library': 0.27; 'single': 0.28;
'module': 0.28; 'text': 0.29; '(and': 0.30; 'header:User-Agent:1':
0.31; 'header:Organization:1': 0.31; 'there': 0.31; 'code,': 0.31;
'but': 0.31; 'expect': 0.31; 'item': 0.31; 'raise': 0.31; "i'm":
0.32; 'fine.': 0.32; 'guess': 0.32; 'needed.': 0.32; 'objects':
0.32; 'program': 0.33; 'server': 0.33; 'functions': 0.34;
'contains': 0.35; 'appears': 0.35; 'request': 0.35; 'way': 0.37;
"it's": 0.38; 'something': 0.38; 'use': 0.38; 'url-
ip:151.101.36.223/32': 0.38; 'url-ip:151.101.36/24': 0.38; 'does':
0.38; 'list': 0.39; 'least': 0.40; 'messages': 0.40; 'simple':
0.40; 'comes': 0.40; 'directory': 0.40; "skip:' 10": 0.40; "skip:'
20": 0.40; 'valid': 0.40; 'reference': 0.61; 'send': 0.61;
'search': 0.61; 'skip:b 10': 0.62; 'identified': 0.63; 'numbers':
0.63; 'subject:this': 0.63; 'types': 0.63; 'skip:m 20': 0.64;
'range': 0.64; 'once': 0.64; 'back': 0.65; 'above': 0.65; 'right':
0.66; 'skip:t 20': 0.67; 'skip:4 10': 0.68; 'acted': 0.69;
'number.': 0.69; 'del': 0.71; 'received:116': 0.71; 'below': 0.71;
'skip:\xe2 10': 0.72; 'name,': 0.75; 'states': 0.80; '2021': 0.84;
'converted': 0.84; 'illegal': 0.84; 'mandated': 0.84; 'strings':
0.84; 'subject:really': 0.84; 'url-ip:76/8': 0.84; 'return,': 0.91
X-Injected-Via-Gmane: http://gmane.org/
User-Agent: ForteAgent/8.00.32.1272
X-No-Archive: YES
X-Mailman-Approved-At: Tue, 25 May 2021 18:25:50 -0400
X-BeenThere: python-list@python.org
X-Mailman-Version: 2.1.34
Precedence: list
List-Id: General discussion list for the Python programming language
<python-list.python.org>
List-Unsubscribe: <https://mail.python.org/mailman/options/python-list>,
<mailto:python-list-request@python.org?subject=unsubscribe>
List-Archive: <https://mail.python.org/pipermail/python-list/>
List-Post: <mailto:python-list@python.org>
List-Help: <mailto:python-list-request@python.org?subject=help>
List-Subscribe: <https://mail.python.org/mailman/listinfo/python-list>,
<mailto:python-list-request@python.org?subject=subscribe>
X-Mailman-Original-Message-ID: <14hqag1k3ujs43uij6rig68vckqo97j386@4ax.com>
X-Mailman-Original-References: <21fb6c5f-97a4-654b-887f-2c31a549bcbe@adminart.net>
<YKzFm7gR+5eKzov7@cskk.homeip.net>
<d4d433ff-5de6-31df-4234-e93feea454fc@adminart.net>
 by: Dennis Lee Bieber - Tue, 25 May 2021 19:53 UTC

On Tue, 25 May 2021 19:21:39 +0200, hw <hw@adminart.net> declaimed the
following:

>
>Oh ok, it seemed to be fine. Would it be the right way to do it with
>sys.exit()? Having to import another library just to end a program
>might not be ideal.

I've never had to use sys. for exit...

C:\Users\Wulfraed>python
Python ActivePython 3.8.2 (ActiveState Software Inc.) based on
on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> exit()

C:\Users\Wulfraed>python
Python ActivePython 3.8.2 (ActiveState Software Inc.) based on
on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> exit(123)

C:\Users\Wulfraed>echo %errorlevel%
123

C:\Users\Wulfraed>

>Yes, and I don't understand it. 'print(msgnums)' prints:
>
>[b'']
>
>when there are no messages and
>
>[b'1 2 3 4 5']
>

Okay -- a bytes object with the equivalent of ASCI 1-5 with a space
separator...

>So I was guessing that it might be an array containing a single a string
>and that refering to the first element of the array turns into a string
>with which split() can used. But 'print(msgnums[0].split())' prints
>
>[b'1', b'2', b'3', b'4', b'5']

So you now have a list of individual bytes objects have the ASCII
digits 1-5

>[1]: https://docs.python.org/3/library/imaplib.html
>

>
>That's not what the documentation says.

What part?

"""
The message_set options to commands below is a string specifying one or
more messages to be acted upon. It may be a simple message number ('1'), a
range of message numbers ('2:4'), or a group of non-contiguous ranges
separated by commas ('1:3,6:9'). A range can contain an asterisk to
indicate an infinite upper bound ('3:*').
"""
>>> mnums = [b'1 2 3 4 5']
>>> mnums2 = mnums[0].decode("UTF-8")
>>> mnums2
'1 2 3 4 5'
>>> msg_set = ",".join("%s" % mn for mn in mnums2.split())
>>> msg_set
'1,2,3,4,5'
>>>

>Well, ok, but it's not helpful that b is being inserted like everywhere,
>and I have to keep asking myself what I'm looking at because bytes are
>bytes.
>
That b'' is how Python prefixes a sequence of bytes to differentiate
from a UNICODE string. In Python 2, all strings were byte-strings, and
UNICODE had a u'' indicator.

Python 3 defaults to unicode for strings and marks non-unicode byte
sequences with the b''

>Then its documentation should at least specify what the library does.
>And perhaps it shouldn't specify that some of its functions expect their
>parameters to be strings rather than what other functions return,
>requiring guesswork and conversations of the data because the functions
>kinda aren't compatabile with each other.

"""
All arguments to commands are converted to strings, except for
AUTHENTICATE, and the last argument to APPEND which is passed as an IMAP4
literal.
"""

seems to imply that the arguments can be passed as other types (byte
sequence, actual integers), and the library will internally convert them as
needed.

"""
Each command returns a tuple: (type, [data, ...]) where type is usually
'OK' or 'NO', and data is either the text from the command response, or
mandated results from the command. Each data is either a bytes, or a tuple.
If a tuple, then the first part is the header of the response, and the
second part contains the data (ie: ‘literal’ value).
"""

Note that imaplib is a Python module in the install lib directory --
you can readily open it in an editor to see what it does internally.

Looking at the code, it appears to convert arguments (and command name)
to bytes if the item comes in as a string. See lines with <<<<<

"""
def _command(self, name, *args):

if self.state not in Commands[name]:
self.literal = None
raise self.error("command %s illegal in state %s, "
"only allowed in states %s" %
(name, self.state,
', '.join(Commands[name])))

for typ in ('OK', 'NO', 'BAD'):
if typ in self.untagged_responses:
del self.untagged_responses[typ]

if 'READ-ONLY' in self.untagged_responses \
and not self.is_readonly:
raise self.readonly('mailbox status changed to READ-ONLY')

tag = self._new_tag()
name = bytes(name, self._encoding) <<<<<
data = tag + b' ' + name <<<<<
for arg in args:
if arg is None: continue
if isinstance(arg, str):
arg = bytes(arg, self._encoding) <<<<<
data = data + b' ' + arg <<<<<

literal = self.literal
if literal is not None:
self.literal = None
if type(literal) is type(self._command):
literator = literal
else:
literator = None
data = data + bytes(' {%s}' % len(literal),
self._encoding)<<<<

if __debug__:
if self.debug >= 4:
self._mesg('> %r' % data)
else:
self._log('> %r' % data)

try:
self.send(data + CRLF)
except OSError as val:
raise self.abort('socket error: %s' % val)

if literal is None:
return tag

while 1:
# Wait for continuation response

while self._get_response():
if self.tagged_commands[tag]: # BAD/NO?
return tag

# Send literal

if literator:
literal = literator(self.continuation_response)

if __debug__:
if self.debug >= 4:
self._mesg('write literal size %s' % len(literal))

try:
self.send(literal)
self.send(CRLF)
except OSError as val:
raise self.abort('socket error: %s' % val)

if not literator:
break

return tag
"""

>First I have to guess what the response might be ... And once I manged
>that, there's still no way to do something with a message by its uid.
>

It will be whatever the IMAP server returns for that request -- back to
the RFC to determine that.

UID is a server command, just as SEARCH and FETCH are server commands
-- reference the RFC to find out what the UID command does...

"""
def uid(self, command, *args):
"""Execute "command arg ..." with messages identified by UID,
rather than message number.

(typ, [data]) = <instance>.uid(command, arg1, arg2, ...)

Returns response appropriate to 'command'.
"""
"""
FETCH is one of the valid commands so... something like

imap_instance.uid("fetch", aUID, [ "body[text]"])

(I can't tell how the UID is passed from the documentation, above is
guessed from RFC -- which is also a tad unclear)

Example: C: A999 UID FETCH 4827313:4828442 FLAGS
S: * 23 FETCH (FLAGS (\Seen) UID 4827313)
S: * 24 FETCH (FLAGS (\Seen) UID 4827943)
S: * 25 FETCH (FLAGS (\Seen) UID 4828442)
S: A999 OK UID FETCH completed

--
Wulfraed Dennis Lee Bieber AF6VN
wlfraed@ix.netcom.com http://wlfraed.microdiversity.freeddns.org/

1
server_pubkey.txt

rocksolid light 0.9.81
clearnet tor