Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

'codecs' module docs improvements #63747

Closed
zuo mannequin opened this issue Nov 11, 2013 · 23 comments
Closed

'codecs' module docs improvements #63747

zuo mannequin opened this issue Nov 11, 2013 · 23 comments
Assignees
Labels
docs Documentation in the Doc dir type-feature A feature request or enhancement

Comments

@zuo
Copy link
Mannequin

zuo mannequin commented Nov 11, 2013

BPO 19548
Nosy @malemburg, @doerwalter, @ncoghlan, @vstinner, @ezio-melotti, @berkerpeksag, @vadmium
Files
  • codecs-doc.patch
  • codecs-doc.v2.patch
  • codecs-doc.v3.patch
  • issue19548-codecs-doc.py34.patch: Updated version of patch for Python 3.4 branch
  • issue19548-codecs-doc.v5.py3.4.patch
  • default-branch-followup.patch
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = 'https://github.com/ncoghlan'
    closed_at = <Date 2015-01-06.14:42:05.079>
    created_at = <Date 2013-11-11.01:29:13.621>
    labels = ['type-feature', 'docs']
    title = "'codecs' module docs improvements"
    updated_at = <Date 2015-01-07.04:59:02.472>
    user = 'https://bugs.python.org/zuo'

    bugs.python.org fields:

    activity = <Date 2015-01-07.04:59:02.472>
    actor = 'ncoghlan'
    assignee = 'ncoghlan'
    closed = True
    closed_date = <Date 2015-01-06.14:42:05.079>
    closer = 'ncoghlan'
    components = ['Documentation']
    creation = <Date 2013-11-11.01:29:13.621>
    creator = 'zuo'
    dependencies = []
    files = ['37485', '37525', '37530', '37553', '37610', '37618']
    hgrepos = []
    issue_num = 19548
    keywords = ['patch']
    message_count = 23.0
    messages = ['202593', '202594', '202595', '202598', '202604', '203038', '203040', '203043', '203044', '203049', '207375', '219830', '232849', '233017', '233020', '233035', '233167', '233505', '233543', '233544', '233552', '233560', '233562']
    nosy_count = 11.0
    nosy_names = ['lemburg', 'doerwalter', 'ncoghlan', 'vstinner', 'ezio.melotti', 'zuo', 'docs@python', 'python-dev', 'berker.peksag', 'martin.panter', 'Zoinkity..']
    pr_nums = []
    priority = 'normal'
    resolution = 'fixed'
    stage = 'resolved'
    status = 'closed'
    superseder = None
    type = 'enhancement'
    url = 'https://bugs.python.org/issue19548'
    versions = ['Python 3.4', 'Python 3.5']

    @zuo
    Copy link
    Mannequin Author

    zuo mannequin commented Nov 11, 2013

    When learning about the 'codecs' module I encountered several places in the docs of the module that, I believe, could be improved to be clearer and easier for codecs-begginers:

    1. Ad codecs.encode and codecs.decode descriptions: I believe it would be worth to mention that, unlike str.encode()/bytes.decode(), these functions (and all their counterparts in the classes the module contains) support not only "traditional str/bytes encodings", but also bytes-to-bytes as well as str-to-str encodings.

    2. Ad 'codecs.register': in two places there is such a text: These have to be factory functions providing the following interface: factory([...] errors='strict') -- errors='strict' may be confusing (at the first sight it may suggest that the only valid value is 'strict'; maybe factory(errors=<error handler label>) with an appropriate description below would be better?).

    3. Ad codecs.open: I believe there should be a reference to the built-in open() as an alternative that is better is most cases.

    4. Ad codecs.BOM*: These constants define various encodings of the Unicode byte order mark (BOM). -- the world encodings seems to be confusing here; maybe These constants define various byte sequences being Unicode byte order marks (BOMs) for several encodings. They are used... would be better?

    5. Ad 7.2.1. Codec Base Classes + codecs.IncrementalEncoder/codecs/IncrementalDecoder:

    • Each codec has to define four interfaces to make it usable as codec in Python: stateless encoder, stateless decoder, stream reader and stream writer -- only four? Not six? What about incremental encoder/decoder???
    • Comparing the fragments (and tables) about error halding methods (Codecs Base Classes, IncrementalEncoder, IncrementalDecoder) with similar fragment in the codecs.register description and with the codecs.register_error description I was confused: is it the matter of a particular codec implementation or of a registered error handler to implement a particular way of error handling? I believe it would be worth to describe clearly relations between these elements of the API. Also more detailed description of differences beetween error handling for encoding and decoding, and translation would be a good thing.
    1. Ad 7.2.1.6. StreamReaderWriter Objects and 7.2.1.7. StreamRecoder Objects: It would be worth to say explicitly that, contrary to previously described abstract classes (IncrementalEncoder/Decoder, StreamReader/Writer), these classes are concrete ones (if I understand it correctly).

    2. Ad 7.2.4. Python Specific Encodings:

    • raw_unicode_encoding -- see: ticket bpo-19539.
    • unicode_encoding -- Produce a string that is suitable as Unicode literal in Python source code but it is not a string; it's a bytes object (which could be used in source code using an ascii-compatibile encoding).
    • bytes-to-bytes and str-to-str encodings -- maybe it would be nice to mention that these encodings cannot be used with str.encode()/bytes.decode() methods (and to mention again they can be used with the functions/method provided by the codecs module).

    @zuo zuo mannequin assigned docspython Nov 11, 2013
    @zuo zuo mannequin added the docs Documentation in the Doc dir label Nov 11, 2013
    @zuo
    Copy link
    Mannequin Author

    zuo mannequin commented Nov 11, 2013

    s/world/word
    s/begginers/beginners

    (sorry, it's late night here)

    @zuo
    Copy link
    Mannequin Author

    zuo mannequin commented Nov 11, 2013

    1. Again ad codecs.open: the default file mode is actually 'rb', not 'r'.

    2. Several places in the docs -- ad: codecs.register_error, codecs.open, codecs.EncodedFile, Codec.encode/decode, codecs.StreamWriter/StreamReader -- do not cover cases of using bytes-to-bytes and/or str-to-str encodings (especially when using string/bytes and text/binary terms).

    3. codecs.replace_errors -- bytestring should be replaced with bytes-like object (as in other places).

    @zuo
    Copy link
    Mannequin Author

    zuo mannequin commented Nov 11, 2013

    1. Ad encoding 'undefined': The sentence Can be used as the system encoding if no automatic coercion between byte and Unicode strings is desired. was suitable for Python 2.x, but not for Python 3.x'. I believe, this sentence should be removed.

    @ncoghlan
    Copy link
    Contributor

    A few more:

    • codec name normalisation (lower case, space to hyphen) is not mentioned
      in the codecs.register description

    • search function registration is not reversible, which doesn't play well
      with module reloading

    • codecs.CodecInfo init signature is not covered

    @ncoghlan
    Copy link
    Contributor

    Another big one: the encodings module API is not documented in the prose docs, and nor is the interface between the default search function and the individual encoding definitions. There's some decent info in help(encoding) though.

    The interaction with the import system could also be documented better - you can actually blacklist codecs by manipulating sys.modules and the encodings namespace, and you can search additional locations for codec modules by manipulating encodings.__path__ (even without it being declared as a namespace package)

    @malemburg
    Copy link
    Member

    On 16.11.2013 14:25, Nick Coghlan wrote:

    Nick Coghlan added the comment:

    Another big one: the encodings module API is not documented in the prose docs, and nor is the interface between the default search function and the individual encoding definitions. There's some decent info in help(encoding) though.

    The interaction with the import system could also be documented better - you can actually blacklist codecs by manipulating sys.modules and the encodings namespace, and you can search additional locations for codec modules by manipulating encodings.__path__ (even without it being declared as a namespace package)

    Those were not documented on purpose, since they are an implementation
    detail of the encodings package search function.

    If you document them now, you'll set the implementation in stone,
    making future changes to the logic difficult. I'd advise against
    this to stay flexible, unless you want to open up the encodings
    package as namespace package - then you'd have to add documentation
    for the import interface.

    @BreamoreBoy
    Copy link
    Mannequin

    BreamoreBoy mannequin commented Nov 16, 2013

    Could they be documented with a massive warning in red "Cpython implementation detail - subject to change without notice"? Or documented in a place that is only accessible to developers and not users? Or...???

    @malemburg
    Copy link
    Member

    On 16.11.2013 15:03, Mark Lawrence wrote:

    Mark Lawrence added the comment:

    Could they be documented with a massive warning in red "Cpython implementation detail - subject to change without notice"? Or documented in a place that is only accessible to developers and not users? Or...???

    The API is documented in encodings/init.py for developers.

    @ncoghlan
    Copy link
    Contributor

    On 16 November 2013 23:33, Marc-Andre Lemburg <report@bugs.python.org> wrote:

    On 16.11.2013 14:25, Nick Coghlan wrote:
    Those were not documented on purpose, since they are an implementation
    detail of the encodings package search function.

    If you document them now, you'll set the implementation in stone,
    making future changes to the logic difficult. I'd advise against
    this to stay flexible, unless you want to open up the encodings
    package as namespace package - then you'd have to add documentation
    for the import interface.

    Yes, that was what got me thinking along those lines, but to make that
    possible, the contents of encodings/init.py would need to be moved
    somewhere else. So this probably isn't on the table for 3.4.

    @vadmium
    Copy link
    Member

    vadmium commented Jan 5, 2014

    Addition to the list of improvements:

    • Under codecs.IncrementalEncoder.reset() it mentions calling encode('', final=True). This call does not work as written for the byte encoders in my experience, because they do not accept empty text strings. Perhaps it should just say to use the final=True flag with no data.

    @Zoinkity
    Copy link
    Mannequin

    Zoinkity mannequin commented Jun 5, 2014

    One glaring omission is any information about multibyte codecs--the class, its methods, and how to even define one.

    Also, the primary use for codecs.register would be to append a single codec to the lookup registry. Simple usage of the method only provides lookup for the provided codecs and will not include regularly-accessible ones such as "utf-8". It would be enormously helpful to provide an example of proper, safe usage.

    @serhiy-storchaka serhiy-storchaka added the type-feature A feature request or enhancement label Dec 17, 2014
    @vadmium
    Copy link
    Member

    vadmium commented Dec 18, 2014

    Here is a patch addressing many of the points raised. Please have a look and give any feedback. Beware I am not very familiar with the Restructured Text markup and haven’t tried compiling it.

    1. Mentioned bytes-to-bytes and text-to-text in general right at the top. Any APIs (e.g. see bpo-20132) that don't support them should be pointed out as exceptions to the rule.

    2. The underlying mode is forced to binary, so 'r' is the same as 'rb'. I removed the 'b' from the signature for clarity.

    ## Jan’s points not yet addressed: ##

    1. I expect the built-in open() function would already be much more obvious and advertised, so I didn't add any cross-reference from codecs.open().

    2. Both points still need addressing:

    • Lack of requirement for implementing incremental codecs
    • Responsibility of implementing error handlers
    1. First point left unaddressed:
    • register_error() error_handler replacement data type (unsure of details)

    ## Numbering Nick’s points: ##

    1. Codec name normalization: Not addressed; what should be written?

    [13. Registration not reversible: Added in patch]

    [14. Added CodecInfo class, pulling out some existing details from register().]

    1. “encodings” module: not done

    2. Import system: not done

    ## My (Martin’s) point: ##

    [17. IncrementalEncoder.reset(): done]

    ## Zoinkity’s points, not addressed: ##

    1. Multibyte codecs

    2. register() usage example

    ## Some new points of my own that need fixing: ##

    1. The doc string for register() says the search function is also allowed to return a tuple of functions, but the reference manual does not mention this. Which is more accurate? (I notice CodecInfo is a subclass of “tuple”.)

    2. EncodedFile() seems to return StreamRecoder instances. Perhaps move them closer together? Should probably warn that EncodedFile's data_encoding is handled by a stateless codec.

    3. The Codec.encode() and decode() methods return a length consumed, but I suspect they have to consume everything they are supplied because the code I have seen ignores this return value.

    @vadmium
    Copy link
    Member

    vadmium commented Dec 22, 2014

    Adding patch v2 after learning how to compile the docs and fixing my errors. I also simplified the descriptions of the CodecInfo attributes by defering the constructor signatures to where they are fully defined under “Codec base classes”, and merged the list of error handlers there as well.

    A side effect of merging error handler lists is that “surrogatepass” is now defined for codecs in general, not just Codec.encode() and decode().

    Also I noticed that “unicode_escape” actually does Latin-1 decoding.

    @ncoghlan
    Copy link
    Contributor

    Thanks for those drafts, Martin - they look like a strong improvement to me. While I still had plenty of comments/questions on v2, I think that's more a reflection on how long it has been since we gave these docs a thorough overall review, moreso than a reflection on the proposed changes.

    Victor - I added you to the nosy list for this one, as I'd specifically like your comments on the StreamReader/Writer docs updates. I'd like to make it clear that these are distinct from the "text encoding only" APIs in the io module, while still accurately describing the behaviour of the standard codecs.

    @vadmium
    Copy link
    Member

    vadmium commented Dec 23, 2014

    New patch version addressing many of the comments; thanks for reviewing! Also adds and extends some unit tests to confirm some of the corner cases I am documenting.

    @ncoghlan
    Copy link
    Contributor

    I started making a few edits based on Zuo and Walter's comments while getting this patch ready for merging, and decided the end result could benefit from an additional round of feedback before committing it.

    This particular patch is also aimed at the Python 3.4 maintenance branch rather than at trunk - the introduction of the new namereplace error handler in 3.5 means that the previous patch didn't apply cleanly to the maintenance branch.

    While Zoinkity's feedback is also valid (i.e. multibyte codecs aren't documented properly, custom codec registration is both harder than it really should be and not well documented), I think those are better filed and handled as separate issues, rather than trying to handle them here as part of the general "bring the current content of the codec module documentation up to date with the current state of Python 3".

    @ncoghlan ncoghlan assigned ncoghlan and unassigned docspython Dec 29, 2014
    @vadmium
    Copy link
    Member

    vadmium commented Jan 6, 2015

    Adding patch v5, for the 3.4 branch. There is at least one reference that still needs fixing in the default branch that is not applicable to the 3.4 branch. Main changes from Nick’s patch:

    • Removed sentence now redundant with introduction to open() and EncodedFile()
    • Fixed wording to allow for missing surrogateescape_errors() etc
    • Changed heading to clarify Codec objects are stateless
    • Restored relaxation for StreamWriter writing to text stream
    • New wording under “Encodings and Unicode”
    • Update cross references to new “Error Handlers” section

    @python-dev
    Copy link
    Mannequin

    python-dev mannequin commented Jan 6, 2015

    New changeset 0646eee8296a by Nick Coghlan in branch '3.4':
    bpo-19548: update codecs module documentation
    https://hg.python.org/cpython/rev/0646eee8296a

    New changeset 4d00d0109147 by Nick Coghlan in branch 'default':
    Merge bpo-19548 changes from 3.4
    https://hg.python.org/cpython/rev/4d00d0109147

    @ncoghlan
    Copy link
    Contributor

    ncoghlan commented Jan 6, 2015

    Thanks for the work on this folks, both Jan for the feedback, Martin for the writing, and everyone else for their comments.

    I don't believe we addressed all of Jan's comments, but I'd like to request that any further comments be filed as separate issues, now that the larger restructure of the content is out of the way.

    @ncoghlan ncoghlan closed this as completed Jan 6, 2015
    @vadmium
    Copy link
    Member

    vadmium commented Jan 6, 2015

    Thanks Nick. Here is a small followup patch for the default (3.5) branch to keep things consistent.

    @python-dev
    Copy link
    Mannequin

    python-dev mannequin commented Jan 7, 2015

    New changeset 20a5a56ce090 by Nick Coghlan in branch 'default':
    Issue bpo-19548: clean up merge issues in codecs docs
    https://hg.python.org/cpython/rev/20a5a56ce090

    @ncoghlan
    Copy link
    Contributor

    ncoghlan commented Jan 7, 2015

    Thanks for the follow-up patch Martin - I missed those when I did the merge forward from 3.4.

    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    docs Documentation in the Doc dir type-feature A feature request or enhancement
    Projects
    None yet
    Development

    No branches or pull requests

    4 participants