News for hackers. Stuff that matters.
Re:CLI tools hidden in the Python standard library by BoppreH on Thursday June 29, 2023 @04:12AM (#36517749)
Speaking of hidden Python tools, I'm a big fan of re.Scanner[0]. It's a regex-based tokenizer[1] in the `re` module, that for reasons is completely missing from any official documentation.

You give it a pattern for each token type, and a function to be called on each match, and you get back a list of processed tokens.

Importantly, it processes the list in one pass and ensures the matches are contiguous, where a naive `re.findall` with capture groups will ignore unmatched characters. You also get a reference to the running scanner, so you can record the location of the match for reporting errors.

    import re
    scanner = re.Scanner([
      (r"[0-9]+",       lambda scanner, token:("INTEGER", int(token))),
      (r"[a-z_]+",      lambda scanner, token:("IDENTIFIER", token)),
      (r"[,.]+",        lambda scanner, token:("PUNCTUATION", token)),
      (r"\s+", None), # None == skip token.
    ])

    results, remainder = scanner.scan("45 pigeons, 23 cows, 11 spiders.")
    assert not remainder
    print(results)

    [('INTEGER', 45),
     ('IDENTIFIER', 'pigeons'),
     ('PUNCTUATION', ','),
     ('INTEGER', 23),
     ('IDENTIFIER', 'cows'),
     ('PUNCTUATION', ','),
     ('INTEGER', 11),
     ('IDENTIFIER', 'spiders'),
     ('PUNCTUATION', '.')]
[0]: https://stackoverflow.com/a/693818/252218

[1]: https://en.wikipedia.org/wiki/Lexical_analysis#Tokenization

Re:CLI tools hidden in the Python standard library by matsemann on Thursday June 29, 2023 @04:40AM (#36517923)
> completely missing from any official documentation

To be fair, most things are missing from the official documentation. When I learned kotlin, I read through their official docs, and knew about most language features in a day. When I learned python, I constantly got surprised by things I hadn't seen come up in the docs. For instance decorators was (still is?) not mentioned at all in the official tutorial.

Re:CLI tools hidden in the Python standard library by BoppreH on Thursday June 29, 2023 @04:43AM (#36517951)
Re:CLI tools hidden in the Python standard library by bragr on Thursday June 29, 2023 @10:33AM (#36520878)
These have always been documented. Hit the version selector: https://docs.python.org/2.7/glossary.html#term-decorator
Re:CLI tools hidden in the Python standard library by roelschroeven on Thursday June 29, 2023 @04:56AM (#36518027)
The tutorial is not supposed to cover all language features: "This tutorial does not attempt to be comprehensive and cover every single feature, or even every commonly used feature. Instead, it introduces many of Python’s most noteworthy features, and will give you a good idea of the language’s flavor and style."

But then I don't know how you're supposed to learn the features that are not in the tutorial. You can have a look at the table of contents of the standard library documentation for modules that might interest you, but that doesn't cover language features. Those are documented in The Python Language Reference, but that document is not really suited for learning from.

There are lots of websites and Youtube channels and so on, but you have to find them, and filter out the not-so-good ones which is not easy, especially for a beginner. I think there is room for some kind of official advanced tutorial to cover the gap.

Re:CLI tools hidden in the Python standard library by fastasucan on Thursday June 29, 2023 @04:36PM (#36526343)
I agree. Wish Python could been better with the documentation. Its a bit absurd that things feel more clear and simple reading Rust documentation than Python documentation for me, given that Python actually is a lot more simple and clear (for me).
Re:CLI tools hidden in the Python standard library by Timon3 on Thursday June 29, 2023 @04:20AM (#36517802)
It seems like the discussion of whether to document it died in April of 2003: https://mail.python.org/pipermail/python-dev/2003-April/0350...

Bummer, it's a cool feature, but I don't feel safe relying on undocumented features.

Re:CLI tools hidden in the Python standard library by bombolo on Thursday June 29, 2023 @05:24AM (#36518217)
Especially now that they are on a crusade against their own stdlib.

They regret including most modules… it seems they regret making python altogether instead of sticking with C? :D

Re:CLI tools hidden in the Python standard library by kzrdude on Thursday June 29, 2023 @05:34AM (#36518292)
This is a typical programmer, you'll regret code as soon as you turn your back on it. :)
Re:CLI tools hidden in the Python standard library by NegativeLatency on Thursday June 29, 2023 @11:13AM (#36521489)
Or before!
Re:CLI tools hidden in the Python standard library by Qem on Thursday June 29, 2023 @07:31AM (#36519035)
> They regret including most modules… it seems they regret making python altogether instead of sticking with C? :D

I also find it odd. Python would probably be a little known language without the huge batteries included by default. It's invaluable when you're working in a environment where you can't fully control what is installed, what is the case of most people at work. I believe this crusade endangers the language long-term.

Re:CLI tools hidden in the Python standard library by oefrha on Thursday June 29, 2023 @09:21AM (#36520003)
You're reading a ridiculous mischaracterization of reality (~20 deprecated modules [1] out of the ~300 PSL modules [2] is "most"?). Of course you find it odd.

[1] https://peps.python.org/pep-0594/

[2] https://docs.python.org/3/library/

Re:CLI tools hidden in the Python standard library by toyg on Thursday June 29, 2023 @11:24AM (#36521673)
It's the trend that is a bit worrying. It's definitely been floated more than once that the stdlib should be fundamentally gutted. It has not become a reality yet, but there are some loud voices advocating to just chuck most modules as a principle into pypi.
Re:CLI tools hidden in the Python standard library by eesmith on Thursday June 29, 2023 @11:39AM (#36521938)
"Trend"? Python has dropped quite a few modules over the decades.

"gl", "sgi", "fl", "sunaudiodev", "audioop", "stdwin", "rotor", "poly", "whatsound", "gopherlib" .. the list goes on.

Some of these were dropped with 1.6 (see "Obsolete Modules" at https://www.python.org/download/releases/1.6/ ). Some with 3.0 (see https://docs.python.org/3.10/whatsnew/2.6.html for then-upcoming removals.)

Re:CLI tools hidden in the Python standard library by dragonwriter on Thursday June 29, 2023 @01:32PM (#36523702)
There are two strong reasons for that:

(1) Not letting little used modules that pose maintenance problems drive up the cost of maintaining Python, and

(2) Not forcing actively used, actively developed modules to be limited to the core language upgrade cadence (and not forcing users to upgrade the language to get upgrades to the modules.)

Ruby I think has a decent approach to this (particularly, one that deals with #2 better than just evicting things entirely from the standard distribution) with “Gemification” of the standard library, where most things that are moved out of the standard library aren’t moved out of the standard distribution, but into a set of gems distributed with the standard distribution but which can be upgraded independently.

Re:CLI tools hidden in the Python standard library by oefrha on Thursday June 29, 2023 @02:30PM (#36524701)
Maybe I've been out of the loop for the past couple of years since I've been writing less Python and don't follow Twitter drama, but IIRC none of the "stdlib is where module goes to die" crowd has ever advocated a fundamental gutting of the existing stable and widely used modules in PSL.
Re:CLI tools hidden in the Python standard library by bombolo on Thursday June 29, 2023 @07:10PM (#36528096)
I was referring to this: https://pyfound.blogspot.com/2023/05/the-python-language-sum...

Of course nobody even knew so the default response is to hit that bottom arrow :D

Re:CLI tools hidden in the Python standard library by arp242 on Friday June 30, 2023 @12:50PM (#36538242)
"Had possibly been added before it was fully baked" is not the same as "we should never have added anything like it", and neither is "we have a much better solution but no one uses that because asyncio is in stdlib which we're now stuck with, for better or worse".

Your entire reading of that is just wrong.

Re:CLI tools hidden in the Python standard library by Znafon on Thursday June 29, 2023 @07:56AM (#36519249)
This is quite an oversimplification. Some modules have no active maintainers and take time from the small team that work on CPython. Some modules are deprecated and removed to make it possible to allocate time on other improvements, and they went back on some removals when users came forward showing that they were still needed.

There is some discussion about the rationale at https://peps.python.org/pep-0594/#rationale

Re:CLI tools hidden in the Python standard library by bombolo on Thursday June 29, 2023 @05:31PM (#36527017)
Did you read the latest news or not? They regret asyncio! (and many other core modules).

They won't remove them… but they regret having made them.

I think without, people would have just not used python.

Re:CLI tools hidden in the Python standard library by Redoubts on Friday June 30, 2023 @07:26AM (#36533050)
After using Trio, I would regret asyncio too
Re:CLI tools hidden in the Python standard library by vamega on Friday June 30, 2023 @11:09AM (#36536271)
Where was this news? I’d like to read this.
Re:CLI tools hidden in the Python standard library by emmelaich on Thursday June 29, 2023 @05:04AM (#36518078)
For a long time, MatchObject was missing too.

There now -- https://docs.python.org/3/library/re.html#match-objects

Re:CLI tools hidden in the Python standard library by anentropic on Thursday June 29, 2023 @05:41AM (#36518327)
FWIW there is an example of building a tokenizer/scanner using documented features of the re module here: https://docs.python.org/3.11/library/re.html#writing-a-token...

re.Scanner looks more succinct though...!

Re:CLI tools hidden in the Python standard library by czx4f4bd on Thursday June 29, 2023 @10:50AM (#36521155)
I find that even more bizarre tbh. Thst seems like the perfect place to document the Scanner class.
Re:CLI tools hidden in the Python standard library by carlossouza on Thursday June 29, 2023 @06:23AM (#36518598)
This is one of the best ChatGPT use cases: creating regex complex patterns
Re:CLI tools hidden in the Python standard library by nmstoker on Thursday June 29, 2023 @07:25AM (#36518985)
It's excellent at both producing them and explaining what it has generated.

And they're now just regurgitated things from the web, I've had novel ones generated fine (obviously you need to test them carefully still)

Re:CLI tools hidden in the Python standard library by extasia on Thursday June 29, 2023 @01:39PM (#36523828)
I agree. I made a little code formatter for aligning variable assignments on adjacent lines and used chatgpt for a lot of help with the regex
Re:CLI tools hidden in the Python standard library by tl_donson on Thursday June 29, 2023 @11:07PM (#36530070)
this one use case justified copilot as an expense for me.
Re:CLI tools hidden in the Python standard library by anitil on Thursday June 29, 2023 @08:10AM (#36519366)
Amazing! I had just written a regex tokenizer in python the other day, this would have been great!
Re:CLI tools hidden in the Python standard library by cricalix on Thursday June 29, 2023 @09:38AM (#36520213)
Curious cat - had you considered using Antlr4 and a Python visitor/listener? (Were you aware of antlr?). Depending what you're trying to do with a regex tokenizer, it might be suitable.
Re:CLI tools hidden in the Python standard library by anitil on Thursday June 29, 2023 @08:48PM (#36529031)
It was more just for fun than anything else. I was more interested in the recursive descent parser so the tokenizer was just a step along the way.

I've played with Antlr but never really vibed with it to be honest (and it was years ago)

Re:CLI tools hidden in the Python standard library by burntsushi on Thursday June 29, 2023 @09:40AM (#36520244)
You'll be able to do this soon with the Rust regex crate as well. Well, by using one of its dependencies. Once regex 1.9 is out, you'll be able to do this with regex-automata:

    use regex_automata::{
        meta::Regex,
        util::iter::Searcher,
        Anchored, Input,
    };
    
    #[derive(Clone, Copy, Debug)]
    enum Token {
        Integer,
        Identifier,
        Punctuation,
    }
    
    fn main() {
        let re = Regex::new_many(&[
            r"[0-9]+",
            r"[a-z_]+",
            r"[,.]+",
            r"\s+",
        ]).unwrap();
        let hay = "45 pigeons, 23 cows, 11 spiders";
        let input = Input::new(hay).anchored(Anchored::Yes);
        let mut it = Searcher::new(input).into_matches_iter(|input| {
            Ok(re.search(input))
        }).infallible();
        for m in &mut it {
            let token = match m.pattern().as_usize() {
                0 => Token::Integer,
                1 => Token::Identifier,
                2 => Token::Punctuation,
                3 => continue,
                pid => unreachable!("unrecognized pattern ID: {:?}", pid),
            };
            println!("{:?}: {:?}", token, &hay[m.range()]);
        }
        let remainder = &hay[it.input().get_span()];
        if !remainder.is_empty() {
            println!("did not consume entire haystack");
        }
    }
And its output:

    $ cargo run
       Compiling regex-scanner v0.1.0 (/home/andrew/tmp/scratch/regex-scanner)
        Finished dev [unoptimized + debuginfo] target(s) in 0.31s
         Running `target/debug/regex-scanner`
    Integer: "45"
    Identifier: "pigeons"
    Punctuation: ","
    Integer: "23"
    Identifier: "cows"
    Punctuation: ","
    Integer: "11"
    Identifier: "spiders"
A bit more verbose than the Python, but the library is exposing much lower level components. You have to do a little more stitching to get the `Scanner` behavior. But it does everything the Python does: a single scan (using finite automata and not backtracking like Python), skip certain token types and guarantees that the entirety of the haystack is consumed.
Re:CLI tools hidden in the Python standard library by fastasucan on Thursday June 29, 2023 @04:34PM (#36526321)
'A bit more verbose' = 2,5 times as many characters. Not saying its good or bad just saying its a bit more verbose ;)
Re:CLI tools hidden in the Python standard library by burntsushi on Thursday June 29, 2023 @08:06PM (#36528652)
Yes, as I said, the APIs exposed in regex-automata give a lot more power. It's an "expert" level crate. You could pretty easily build a scanner-like abstraction and get pretty close to the Python code.

I posted this because a lot of regex engines don't support this type of use case. Or don't support it well without having to give something up.

Re:CLI tools hidden in the Python standard library by n8henrie on Saturday July 01, 2023 @11:03AM (#36550871)
Interesting! Not often using either crate, this example looks like something for which I might usually look to nom. Is there a reason I should consider using regex for this use case instead (if neither is a pre-existing dependency)?
Re:CLI tools hidden in the Python standard library by burntsushi on Sunday July 02, 2023 @03:39PM (#36564885)
I don't use nom. I've tried using parser combinator libraries in the past but generally don't like them.

That said, I don't usually use regexes for this either. Instead, I just do things by hand.

So I'm probably not the right person to answer your question unfortunately. I just know that more than one person has asked for this style of use case to be supported in the regex crate. :-)

Re:CLI tools hidden in the Python standard library by sam2426679 on Thursday June 29, 2023 @12:31PM (#36522730)
I believe this is used internally by json.loads, which is not very surprising in hindsight.
Re:CLI tools hidden in the Python standard library by fastasucan on Thursday June 29, 2023 @04:25PM (#36526206)
Woah, thats a pretty cool feature! I allways feel a bit dirty trying to do anything like that manually (usually involving a string.split(",")[0][:2] etc, just asking to break).