frontpage.
newsnewestaskshowjobs

Made with ♥ by @iamnishanth

Open Source @Github

fp.

MS-DOS game copy protection and cracks

https://www.dosdays.co.uk/topics/game_cracks.php
1•TheCraiggers•22s ago•0 comments

Updates on GNU/Hurd progress [video]

https://fosdem.org/2026/schedule/event/7FZXHF-updates_on_gnuhurd_progress_rump_drivers_64bit_smp_...
1•birdculture•1m ago•0 comments

Epstein took a photo of his 2015 dinner with Zuckerberg and Musk

https://xcancel.com/search?f=tweets&q=davenewworld_2%2Fstatus%2F2020128223850316274
1•doener•1m ago•0 comments

MyFlames: Visualize MySQL query execution plans as interactive FlameGraphs

https://github.com/vgrippa/myflames
1•tanelpoder•2m ago•0 comments

Show HN: LLM of Babel

https://clairefro.github.io/llm-of-babel/
1•marjipan200•2m ago•0 comments

A modern iperf3 alternative with a live TUI, multi-client server, QUIC support

https://github.com/lance0/xfr
1•tanelpoder•4m ago•0 comments

Famfamfam Silk icons – also with CSS spritesheet

https://github.com/legacy-icons/famfamfam-silk
1•thunderbong•4m ago•0 comments

Apple is the only Big Tech company whose capex declined last quarter

https://sherwood.news/tech/apple-is-the-only-big-tech-company-whose-capex-declined-last-quarter/
1•elsewhen•8m ago•0 comments

Reverse-Engineering Raiders of the Lost Ark for the Atari 2600

https://github.com/joshuanwalker/Raiders2600
2•todsacerdoti•9m ago•0 comments

Show HN: Deterministic NDJSON audit logs – v1.2 update (structural gaps)

https://github.com/yupme-bot/kernel-ndjson-proofs
1•Slaine•12m ago•0 comments

The Greater Copenhagen Region could be your friend's next career move

https://www.greatercphregion.com/friend-recruiter-program
1•mooreds•13m ago•0 comments

Do Not Confirm – Fiction by OpenClaw

https://thedailymolt.substack.com/p/do-not-confirm
1•jamesjyu•13m ago•0 comments

The Analytical Profile of Peas

https://www.fossanalytics.com/en/news-articles/more-industries/the-analytical-profile-of-peas
1•mooreds•13m ago•0 comments

Hallucinations in GPT5 – Can models say "I don't know" (June 2025)

https://jobswithgpt.com/blog/llm-eval-hallucinations-t20-cricket/
1•sp1982•14m ago•0 comments

What AI is good for, according to developers

https://github.blog/ai-and-ml/generative-ai/what-ai-is-actually-good-for-according-to-developers/
1•mooreds•14m ago•0 comments

OpenAI might pivot to the "most addictive digital friend" or face extinction

https://twitter.com/lebed2045/status/2020184853271167186
1•lebed2045•15m ago•2 comments

Show HN: Know how your SaaS is doing in 30 seconds

https://anypanel.io
1•dasfelix•15m ago•0 comments

ClawdBot Ordered Me Lunch

https://nickalexander.org/drafts/auto-sandwich.html
3•nick007•16m ago•0 comments

What the News media thinks about your Indian stock investments

https://stocktrends.numerical.works/
1•mindaslab•17m ago•0 comments

Running Lua on a tiny console from 2001

https://ivie.codes/page/pokemon-mini-lua
1•Charmunk•18m ago•0 comments

Google and Microsoft Paying Creators $500K+ to Promote AI Tools

https://www.cnbc.com/2026/02/06/google-microsoft-pay-creators-500000-and-more-to-promote-ai.html
2•belter•20m ago•0 comments

New filtration technology could be game-changer in removal of PFAS

https://www.theguardian.com/environment/2026/jan/23/pfas-forever-chemicals-filtration
1•PaulHoule•21m ago•0 comments

Show HN: I saw this cool navigation reveal, so I made a simple HTML+CSS version

https://github.com/Momciloo/fun-with-clip-path
2•momciloo•22m ago•0 comments

Kinda Surprised by Seadance2's Moderation

https://seedanceai.me/
1•ri-vai•22m ago•2 comments

I Write Games in C (yes, C)

https://jonathanwhiting.com/writing/blog/games_in_c/
2•valyala•22m ago•0 comments

Django scales. Stop blaming the framework (part 1 of 3)

https://medium.com/@tk512/django-scales-stop-blaming-the-framework-part-1-of-3-a2b5b0ff811f
1•sgt•22m ago•0 comments

Malwarebytes Is Now in ChatGPT

https://www.malwarebytes.com/blog/product/2026/02/scam-checking-just-got-easier-malwarebytes-is-n...
1•m-hodges•22m ago•0 comments

Thoughts on the job market in the age of LLMs

https://www.interconnects.ai/p/thoughts-on-the-hiring-market-in
1•gmays•23m ago•0 comments

Show HN: Stacky – certain block game clone

https://www.susmel.com/stacky/
3•Keyframe•26m ago•0 comments

AIII: A public benchmark for AI narrative and political independence

https://github.com/GRMPZQUIDOS/AIII
1•GRMPZ23•26m ago•0 comments
Open in hackernews

Dict Unpacking in Python

https://github.com/asottile/dict-unpacking-at-home
146•_ZeD_•7mo ago

Comments

zdimension•7mo ago
Did not know that such things could be accomplished by registering a new file coding format. Reminds me of https://pypi.org/project/goto-statement/
zahlman•7mo ago
This one is arguably even more of a hack; it's working at the source code level rather than the AST level.

The "coding" here is a bytes-to-text encoding. The Python lexer expects to see character data; you get to insert arbitrary code to convert the bytes to characters (or just use existing schemes the implement standards like UTF-8).

almostgotcaught•7mo ago
> it's working at the source code level rather than the AST level.

this (lexing) is the only use of the codec hack - if you want to manipulate the AST you do not need this and can just to `ast.parse` and then recompile the function.

zahlman•6mo ago
Indeed; the goto hack works that way (and uses a decorator to make it easier to invoke the AST-manipulation logic).
crabbone•7mo ago
I think there's a package to treat Jupyter notebooks as source code (so you can import them as modules).

While the OP package is obviously a joke, the one with notebooks is kind of useful. And, of course, obligatory quote about how languages that don't have meta-programming at the design level will reinvent it, but poorly.

Y_Y•7mo ago
You talking about this?

https://jupyter-notebook.readthedocs.io/en/stable/examples/N...

xg15•7mo ago
I'd argue "import from notebooks" is still only helpful in the "space bar heating" sense.

I think Notebooks are great for quick, "explorative" sketches of code. They are absolutely terrible for organizing "production" code.

I know it often happens that something starts in a notebook and then sort of morphs into a generic script or full-on application. But I think, this is usually the signal you should refactor, pull out the "grown" parts from the notebooks and organize them into proper Python modules.

If you have parts that are still experimental or explorative, consider importing your new modules into the notebook instead of the other way around.

Source: personal experience

nine_k•7mo ago
In short, it runs a text preprocessor as the source text decoder (like you would decode from Latin-1 or Shift-JIS to Unicode).
agumonkey•7mo ago
yeah that's the funny part here, would never have thought of this
tkcranny•6mo ago
Yeah I had totally forgotten about this. I remember seeing it around a bit in the python 2 days when UTF-8 wasn’t always assumed. The fact a ~macro system can be bolted on using this is impressive, hilarious, and shockingly terrible.
zelphirkalt•7mo ago
I found dictionary unpacking to be quite useful, when you don't want to mutate things. Code like:

    new_dict = {**old_dict, **update_keys_and_values_dict}
Or even complexer:

    new_dict = {
        **old_dict,
        **{
            key: val
            for key, val in update_keys_and_values_dict
            if key not in some_other_dict
        }
    }
It is quite flexible.
peter422•7mo ago
I love the union syntax in 3.9+:

  new_dict = old_dict | update_keys_and_values_dict
parpfish•7mo ago
Don’t forget the in place variant!

  the_dict |= update_keys_and_values_dict
masklinn•7mo ago
No no, do forget about it: like += for lists, |= mutates “the dict”, which often makes for awkward bugs.

And like += over list.extend, |= over dict.update is very little gain, and restricts legal locations (augmented assignments are statements, method calls are expressions even if they return "nothing")

IgorPartola•7mo ago
The |= does exactly what it says on the tin. How could it not mutate the left side of the assignment?
parpfish•7mo ago
In typed languages, I’m all about using nice safe immutable variables/values.

But in python, everything is mutable so there’s only so much safety you can wring out of adhering the an immutable style. Any other function can hop in and start mutating things (even your “private” attributes). Plan for mutations occurring everywhere.

graemep•7mo ago
I find the fewer mutations the easier code is to understand, at the level of an individual function.

Of course you do not have the safety you would have in a language that enforces immutability, but there is still a cost (in terms of maintenance and the likelihood of bugs) to mutation.

masklinn•7mo ago
> The |= does exactly what it says on the tin. How could it not mutate the left side of the assignment?

The normal way? If the LHS is an integer. |= updates the binding but does not mutate the object.

Nothing requires that |= mutate the LHS let alone do so unconditionally (e.g. it could update the LHS in place as an optimisation iff the refcount indicated that was the only reference, which would optimise the case where you create a local then update it in multiple steps, but would avoid unwittingly updating a parameter in-place).

edit: you might not be understanding what dict.__ior__ is doing:

  >>> a = b = {}
  >>> c = {1: 2}
  >>> b |= c
  >>> a
  {1: 2}
That is, `a |= b` does not merely desugar to `a = a | b`, dict.__ior__ does a `self.update(other)` internally before updating the binding to its existing value. Which also leads to this fun bit of trivial (most known from list.__iadd__ but "working" just as well here):

  >>> t = ({},)
  >>> t[0] |= {1: 2}
  Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
  TypeError: 'tuple' object does not support item assignment
  >>> t
  ({1: 2},)
dumah•6mo ago
That’s not “the normal way”, it’s just the case when the LHS is immutable.

This behavior is congruent to C++ and it’s documented and idiomatic.

It’d be weird if the in-place operator deeply copied the LHS, and problematic for a garbage-collected language in high throughput applications.

masklinn•6mo ago
> That’s not “the normal way”, it’s just the case when the LHS is immutable.

It’s the default behaviour of |= if you override |, you need to specifically override |= to do otherwise.

> This behavior is congruent to C++

An excellent reason to do something else in and of itself.

> it’s documented and idiomatic.

Documenting a trap does not make it less of a trap. Innocently replacing | by |= induces a massive behavioural change which the user has little reason to expect, and which can easily lead to bugs due to mutating shared data.

> It’d be weird if the in-place operator deeply copied the LHS

I see you understand neither Python nor the behaviour of the | operator.

> problematic for a garbage-collected language in high throughput applications.

dict.update exists, if you specifically need to update the LHS in place it works just fine.

sco1•7mo ago
The author also has an accompanying video: https://youtu.be/eqiM0xRmFJg
andy99•7mo ago

  def u(**kwargs):
    return tuple(kwargs.values())
Am I missing something, is this effectively the same?

*I realize the tuple can be omitted here

Grikbdl•7mo ago
Yours relies on ordering, OP's presumably does not.
Izkata•7mo ago
You have to pull them out by key name, and not just get everything. Here's a working version, though with a totally different syntax (to avoid having to list the keys twice, once as keys and once as resulting variable names):

  >>> def u(locals, dct, keys):
  ...     for k in keys:
  ...         locals[k] = dct[k]
  ... 
  >>> dct = {'greeting': 'hello', 'thing': 'world', 'farewell': 'bye'}
  >>> u(locals(), dct, ['greeting', 'thing'])
  >>> greeting
  'hello'
  >>> thing
  'world'
  >>> farewell
  Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
  NameError: name 'farewell' is not defined

Modifying locals() is generally frowned upon, as there's no guarantee it'll work. But it does for this example.
sischoel•7mo ago
Or use itemgetter:

  >>> from operator import itemgetter
  >>> dct = {'greeting': 'hello', 'thing': 'world', 'farewell': 'bye'}
  >>> thing, greeting = itemgetter("thing", "greeting")(dct)
  >>> thing
  'world'
  >>> greeting
  'hello'
notpushkin•7mo ago
Ohhh, nice. Also, attrgetter (which also supports dotted notation to get nested attrs! Sadly, no dotted notation for itemgetter.)

https://docs.python.org/3/library/operator.html#operator.att...

sischoel•6mo ago
Dotted notation would not work because the keys in a dict can also contain dots. I am not terrible familiar with them but there is something called `lenses` that comes from functional programming that should allow you to access nested structures. And I am pretty sure there must be at least one python library that implements that.
masklinn•7mo ago
TFA looks things up by key, and allows pulling a subset of the dict.
kristjansson•7mo ago
While not nearly as fun as the OP, I’d note that this sort of unpacking is very pleasant in the newish PEP636 match case statements:

https://peps.python.org/pep-0636/#matching-builtin-classes

xg15•7mo ago
Looks really cool!

Will this allow combinations of bound and unbound variables?

E.g.:

  def is_on_horizontal_line(point, line_y):
    match point:
      case (x, line_y):
        return f"Yes, with x={x}"
      case _:
        return "No"
Seems both useful and potentially confusing.
thayne•7mo ago
It allows you to use bound variables/constants as long as the expression includes a dot so you can distinguish it from a capture variable.

Scala allows matching against bound variables but requires it either start with an uppercase letter or be surrounded in backtics in the pattern. I don't know that that would make sense for python, but there could potentially be some special syntax to spicify you want to compare against an existing variable instead of capturing a new variable.

xg15•7mo ago
Ah, that makes sense. Maybe the "exceptions" (dots, uppercase letters, etc) are needed to permit bound variables that we usually don't think of as variables at all, like class or package identifiers?
nikisweeting•7mo ago
I would donate $500 to the PSF tomorrow if they added this, the lack of it is daily pain
almostgotcaught•7mo ago
you can't do this consistently across all cases without compiler assistance (see https://doc.rust-lang.org/book/ch19-03-pattern-syntax.html or https://peps.python.org/pep-0636/#matching-builtin-classes linked below).
nikisweeting•7mo ago
perfect is enemy of good imo, dict destructuring is so valuable that I'm willing to bend some rules / add some rules to make it possible. can't we just copy whatever JS does?
skeledrew•7mo ago
If it's that valuable to you personally you can use that project to remove your "daily pain". No need to inflict the pain caused by such a thing being present in official Python. Some of us like for the language to remain highly readable.
notpushkin•7mo ago
> you can use that project

It’s not meant for production use. Quite clearly so: https://github.com/asottile/dict-unpacking-at-home#please-do...

almostgotcaught•7mo ago
> perfect is enemy of good imo

You can't land a language feature that only sometimes works - that's absolutely horrid UX.

> can't we just copy whatever JS does?

I wasn't aware that js does this and I don't know it's implemented. So maybe I should retract my claim about compiler assistance.

nikisweeting•6mo ago
It's been one of the headline features keeping me happy in JS for 9+ years.
IshKebab•7mo ago
You shouldn't be using dicts for data that you know the name of anyway - use dataclasses or named tuples. Dicts are best for things with keys that are not known at compile time.
IgorPartola•7mo ago
Since when can you use data classes for kwargs? There are plenty of times when you should use a dict even if you know the keys.
IshKebab•7mo ago
You shouldn't be using kwargs! That is also well known to be bad practice (or it should be anyway).

https://medium.com/codex/stop-using-kwargs-as-method-argumen...

http://ivory.idyll.org/blog/on-kwargs.html

Give me another one.

almostgotcaught•7mo ago
lol i think you didn't read/understand this - the article is about **kwargs (which is sometimes sloppy) while the person you're responding to is talking about "exploding" a dict when calling a function (this does not require **kwargs at all).
IshKebab•6mo ago
So when they said "kwargs" they didn't actually mean **kwargs they meant something else which doesn't even require kwargs? How did you magically infer that?
ahupp•7mo ago
I’d agree with this, unless the kwargs is typed with the new-ish PEP-692: https://peps.python.org/pep-0692/
porridgeraisin•6mo ago
Sure, but destructuring makes sense for both. Just assign the variables without corresponding keys a value of None.
crabbone•7mo ago
Now come on... for code golf? Why on Earth would anyone want extra syntax in a language with already tons of bloat in the syntax that contribute nothing to language's capabilities? It's, in Bill Gates words, like paying to make airplanes heavier...

This package is a funny gimmick, to illustrate, probably, unintended consequences of some of the aspects of Python's parser. Using this for anything other than another joke is harmful...

porridgeraisin•6mo ago
Destructuring/unpacking and packing add more to the language than whatever crap they stuff into every new python release these days. Let's never forget they _removed_ in its entirety a standard library package, that is the level we are dealing with here...

Not saying it needs to be done with the decoder hack, it should have proper compiler support, but it's basically necessary. It's the best feature in JS hands down.

  >> a, b = 2, 3 # say

  >> d = dict_of(a, b)
  >> d
  {"a": 2, "b": 3}

  >> # somewhere else...
  >> { a, b } = d
  >> a + b
  5
The dict_of() function is already possible at runtime with python `ast` magic, see [1]. That package also has unpack_keys() again made possible with `ast`, but we'd of course want proper language support.

[1] https://github.com/alexmojaki/sorcery

agumonkey•7mo ago
Coming from lisp/haskell I always wanted destructuring but after using it quite a lot in ES6/Typescript, I found it's not always as ergonomic and readable as I thought.
qwertox•7mo ago
This confuses me a bit

  dct = {'a': [1, 2, 3]}
  {'a': [1, *rest]} = dct
  print(rest)  # [2, 3]
Does this mean that i can use?

  dct = {'a': [1, 2, 3]}
  {'b': [4, *rest]} = dct
  print(rest)  # [2, 3]
and more explicit

  dct = {'a': [1, 2, 3]}
  {'_': [_, *rest]} = dct
  print(rest)  # [2, 3]
qexat•7mo ago
None of the last two LHSes will match `dct`, so you'll get a runtime error.
masklinn•7mo ago
> Does this mean that i can use?

They'll both trigger a runtime error, since the key you're using in the pattern (LHS) does not match any key in the dict.

Note that `'_'` is an actual string, and thus key, it's not any sort of wildcard. Using a bare `_` as key yields a syntax error, I assume because it's too ambiguous for the author to want to support it.

odyssey7•7mo ago
Python needs a better dictionary. Also, Python needs better names for things than dict.
nikisweeting•6mo ago
In the meantime I find myself resorting to these:

- https://pypi.org/project/python-benedict/ - https://docs.pydantic.dev/ - https://github.com/alexmojaki/sorcery

yde_java•7mo ago
I use the Python package 'sorcery' [0] in all my production services.

It gives dict unpacking but also a shorthand dict creation like this:

    from sorcery import dict_of, unpack_keys
    a, b = unpack_keys({'a': 1, 'b': 42})
    assert a == 1
    assert b == 42
    assert dict_of(a, b) == {'a': 1, 'b': 42}
[0] https://github.com/alexmojaki/sorcery
john-radio•7mo ago
That seems a bit crazy and like it would lead to unpredictable and hard-to-mantain code. (pardon my candor).
rrishi•7mo ago
im curios why you think so ?
notpushkin•7mo ago
So I see asottile has gone from backporting released features [1] to backporting unreleased ones!

[1]: https://pypi.org/p/future-fstrings, mentioned in https://github.com/asottile/dict-unpacking-at-home#please-do...

xg15•7mo ago
Lame: Submit a PEP, campaign for community support, write a patch, go back and forth with the maintainers, endure weeks and months of bikeshedding, then maybe, eventually have your feature included in the next Python release.

Game: Use the codec hack, immediately publish your feature for all Python versions, then write "please do not use" to be safe.

sametmax•7mo ago
Anthony is also the maintainer of the deadsnake ppa, if you were searching for reasons to love him more.
mixmastamyk•7mo ago
Believe he’s the same person who won’t allow pyflakes to support # noqa, because it’s “opinionated.”

As if dropping that word is some sort of justification. I don’t know what the opinion is! Worse is better?

ziofill•7mo ago
The confusing bit to me is that the LHS of this

{greeting, thing} = dct

is a set, which is not ordered, so why would greeting and thing be assigned in the order in which they appear?

xg15•7mo ago
I don't think they are. They are matched by variable names, so this:

  {thing, greeting} = dct
Should have the exact same result.
frollogaston•6mo ago
After using JS, Python dicts and objects feel so cumbersome. I don't see why they need to be separate things, and why you can't access a dict like `dict.key`. Destructuring is the icing on the cake. In JS, it even handles the named args use case like

   const foo = ({name, age, email}) => { }
I'm guessing all of this has been proposed in Python before, and rejected in part because at this point it'd create way more confusion than it's worth.
tkcranny•6mo ago
I don’t mind the distinction of it as a map container keeping dot properties/methods separate from the keyed values. But yeah the endless string quoting is painful coming back from JS, bare key literals in constructors like JS would be a welcome addition for sure, as would named key unpacking like this whole post is about.