schmonz.com is a Fediverse instance that uses the ActivityPub protocol. In other words, users at this host can communicate with people that use software like Mastodon, Pleroma, Friendica, etc. all around the world.

This server runs the snac software and there is no automatic sign-up process.

Search results for tag #python

[?]Trey Hunner 🐍 » 🌐
@treyhunner@mastodon.social

“If you find subprocess.run to be a little too verbose, you might consider writing a custom wrapper function or two for your own use cases.”

Read more 👉 pym.dev/running-subprocesses-i

    [?]Leanpub » 🌐
    @leanpub@mastodon.social

    Build Your First LLM: A Hands-On Guide to Language Models by Hasan Degismez 📖 on Leanpub!

    Learn how large language models work by building one from scratch. This hands-on guide walks you from first principles to a working Transformer you understand inside out.

    Link: leanpub.com/FirstLLM

      #refactoring boosted

      [?]Hack a Day (unofficial) » 🤖 🌐
      @hackaday@www.urbanmind.net

      Mixed None-and-raise APIs fail under model rewrites. The error taxonomy is the real product surface. Pin that taxonomy with characterization tests first, always.

      Change one except clause only after the pin stays green. Happy-path unit tests will not save this refactor. Callers already branch on None, dict keys, and types.

      Collapse any one of those shapes and production breaks. The defect is an unrecorded taxonomy, not missing types.

      Why model rewrites miss the contract


      AI coding threads keep offering full-file cleanups. Those cleanups prefer one error type. They also prefer raising over returning None.

      That preference is style, not evidence. A messy dispatcher often has three outcomes. Some inputs raise ValueError for bad payloads.

      Some inputs return None after a send failure. Some inputs return {"ok": False, "status": 429}. Downstream code already checks all three shapes.

      Loop-style agent edits make the same cut. They unify handlers because duplication looks sloppy. Duplication here is the published contract.

      Four observables to freeze


      Record these four fields for every fixture. Skip prose messages on the first pass. Message strings drift across harmless edits.

      1. Escaping exception type, or a sentinel if none.
      2. Return shape: None, mapping keys, or other.
      3. Integer status when a mapping returns.
      4. Count of WARNING-or-higher log records.

      Types and keys usually stay stable. Status integers also stay stable. Log counts need a named logger, not the root.

      Decision table for one dispatcher


      The table below is the spec. It is a labeled example. It is not a production trace.

      Fixture

      Escapes

      Return

      Status

      WARN+

      empty body

      RuntimeError

      n/a

      n/a

      0

      invalid JSON

      ValueError

      n/a

      n/a

      0

      JSON list

      ValueError

      n/a

      n/a

      0

      missing id

      none

      None

      n/a

      1

      send TypeError

      none

      None

      n/a

      1

      send TimeoutError

      none

      None

      n/a

      1

      downstream 429

      none

      dict

      429

      1

      downstream 200

      none

      dict

      200

      0


      Keep the send TypeError row. That row is the trap. A cleaner except often drops it.

      Artifact: characterization harness


      The code is a worked example. Run it locally before any extract. Do not treat it as measured field data.

      # events.py — labeled example, not a live service
      from __future__ import annotations

      import json
      import logging
      from typing import Any, Callable

      log = logging.getLogger("events")

      SendFn = Callable[[dict], tuple[int, Any]]

      def dispatch_event(raw: str | None, send: SendFn):
      """Messy contract: None, dict, or raise."""
      if raw is None or raw == "":
      raise RuntimeError("empty body")
      try:
      payload = json.loads(raw)
      except Exception:
      raise ValueError("bad json")
      if not isinstance(payload, dict):
      raise ValueError("bad json")
      if "id" not in payload:
      log.warning("missing id")
      return None
      try:
      status, body = send(payload)
      except Exception:
      log.warning("send failed")
      return None
      if status >= 400:
      log.warning("downstream %s", status)
      return {"ok": False, "status": status, "body": body}
      return {"ok": True, "status": status, "body": body}

      # test_events_contract.py — worked example
      import json
      import logging

      import pytest

      from events import dispatch_event

      def _records(caplog):
      return [r for r in caplog.records if r.name == "events" and r.levelno >= logging.WARNING]

      def _run(raw, send, caplog):
      caplog.set_level(logging.WARNING, logger="events")
      try:
      value = dispatch_event(raw, send)
      return None, value, _records(caplog)
      except Exception as exc:
      return type(exc), None, _records(caplog)

      def test_empty_body_raises_runtime_error(caplog):
      exc, value, recs = _run("", lambda p: (200, "ok"), caplog)
      assert exc is RuntimeError
      assert value is None
      assert len(recs) == 0

      @pytest.mark.parametrize("raw", ["{", "[]", "null"])
      def test_bad_json_raises_value_error(raw, caplog):
      exc, value, recs = _run(raw, lambda p: (200, "ok"), caplog)
      assert exc is ValueError
      assert value is None
      assert len(recs) == 0

      def test_missing_id_returns_none(caplog):
      exc, value, recs = _run('{"name": "x"}', lambda p: (200, "ok"), caplog)
      assert exc is None
      assert value is None
      assert len(recs) == 1

      def test_send_type_error_returns_none(caplog):
      def send(_payload):
      raise TypeError("broken client")

      exc, value, recs = _run('{"id": 1}', send, caplog)
      assert exc is None
      assert value is None
      assert len(recs) == 1

      def test_send_timeout_returns_none(caplog):
      def send(_payload):
      raise TimeoutError("late")

      exc, value, recs = _run('{"id": 1}', send, caplog)
      assert exc is None
      assert value is None
      assert len(recs) == 1

      def test_downstream_429_is_dict(caplog):
      exc, value, recs = _run('{"id": 1}', lambda p: (429, "slow"), caplog)
      assert exc is None
      assert value == {"ok": False, "status": 429, "body": "slow"}
      assert len(recs) == 1

      def test_downstream_200_is_dict(caplog):
      exc, value, recs = _run('{"id": 1}', lambda p: (200, {"n": 1}), caplog)
      assert exc is None
      assert value == {"ok": True, "status": 200, "body": {"n": 1}}
      assert len(recs) == 0

      Run the file before editing handlers. Use a short traceback during the first pin.

      python -m pytest test_events_contract.py -q --tb=short

      Prove the suite catches a collapsed taxonomy


      A green suite with no mutation check is weak. You must see a failed unified-error fork. Keep that fork out of the merge.

      # test_events_mutation.py — must fail against a unified raise rewrite
      import events

      def test_unified_raise_would_break_send_type_error(monkeypatch, caplog):
      def rewritten(raw, send):
      payload = __import__("json").loads(raw)
      status, body = send(payload) # TypeError now escapes
      return {"ok": status < 400, "status": status, "body": body}

      monkeypatch.setattr(events, "dispatch_event", rewritten)
      with pytest.raises(TypeError):
      events.dispatch_event('{"id": 1}', lambda p: (_ for _ in ()).throw(TypeError("x")))

      Expect this mutation test to fail on the rewrite. Restore the messy handler after that check. The failure is the evidence, not a vibe.

      Numbered workflow


      1. Copy the messy module into a branch. Do not edit handlers yet.
      2. Inventory callers that check is None or catch types.
      3. Fill the four-column table from those callers.
      4. Encode each row as one test function.
      5. Add one mutation test that unifies errors.
      6. Confirm the mutation test fails on purpose.
      7. Restore the original handler body.
      8. Apply one extract or one except edit.
      9. Re-run the same characterization file.
      10. Revert if any row changes shape.

      Step two is not optional. Tests invented from the callee miss caller branches. Caller branches are the contract.

      rg -n "dispatch_event\(" -g "*.py"
      rg -n "is None|except ValueError|except RuntimeError" -g "*.py"

      Record each hit as a fixture name. Missing hits become missing rows. Missing rows make unsafe extracts look safe.

      The smallest safe change


      Do not narrow except Exception on send first. The table says TypeError becomes None. Narrowing that clause raises TypeError instead.

      That raise is a contract break. Extract the block without narrowing. Keep the same log line and None return.

      def _send_or_none(payload, send):
      try:
      return send(payload)
      except Exception:
      log.warning("send failed")
      return None

      def dispatch_event(raw, send):
      if raw is None or raw == "":
      raise RuntimeError("empty body")
      payload = _parse_object(raw)
      if "id" not in payload:
      log.warning("missing id")
      return None
      result = _send_or_none(payload, send)
      if result is None:
      return None
      status, body = result
      if status >= 400:
      log.warning("downstream %s", status)
      return {"ok": False, "status": status, "body": body}
      return {"ok": True, "status": status, "body": body}

      That extract is boring. Boring is the point. The taxonomy stays in the table.

      A later change can narrow exceptions. Do that only with a version note. Add a row that expects TypeError to escape. Tell callers before you merge.

      Parse-side except narrowing


      The JSON branch is different. json.loads should raise json.JSONDecodeError. Re-raising ValueError is the published type.

      Narrowing except Exception to except json.JSONDecodeError can be safe. Prove it with the invalid JSON row. Prove it with the JSON list row too.

      def _parse_object(raw):
      try:
      payload = json.loads(raw)
      except json.JSONDecodeError:
      raise ValueError("bad json") from None
      if not isinstance(payload, dict):
      raise ValueError("bad json")
      return payload

      Both bad-JSON fixtures must still raise ValueError. A leaked JSONDecodeError is a taxonomy change. Do not ship that leak without a caller audit.

      from None also drops __cause__. Add a cause fixture if any caller reads it. Skip that fixture when no caller inspects causes.

      Where a free coding model belongs


      Disclosure: This article was prepared as part of MonkeyCode's product outreach.

      A model can draft the extract. It must not invent a new taxonomy. MonkeyCode provides free model access and a free server option.

      Use either only after the characterization file is green. Feed the model the table and the test file. Ask for one extract, not a rewrite.

      Reject a patch that removes a row. Reject a patch that changes None into a raise. This is not an agent loop.

      One prompt. One diff. Same tests.

      Limitations


      The harness does not prove semantic equality. It pins types, keys, status, and log counts. It misses timing, retry storms, and byte identity.

      Log counts break if a library logs extra warnings. Pin the logger name events. Cap propagation on that logger.

      Do not pin the root logger. Root pins go red on unrelated imports. That noise hides a real taxonomy drift.

      The table is only as good as the fixtures. One unlisted caller path is an untested shape. Untested shapes are how "safe" extracts land in incident channels.

      Who should not use this


      Do not use this flow for greenfield APIs. Design one error shape there. Do not preserve None plus raises on purpose.

      Do not use this flow for security boundaries. Characterization will pin insecure behavior. Pinning is not hardening.

      Do not use this flow without tests you can run offline. A model server cannot replace the table. If pytest cannot collect locally, stop.

      Teams with a published OpenAPI error schema may skip dict-key rows. Use the schema as the table instead. Still pin process-local exception escapes.

      HTTP schemas often omit those local raises. Omitting them is how ValueError turns into a 500. Keep the escape column anyway.

      Checklist before merge


      1. Characterization file is the only new proof.
      2. Diff touches one handler extract or one except.
      3. Mutation test still fails against a unified-error fork.
      4. No fixture row changed shape.
      5. None callers still exist, or a version note ships.

      If a model patch violates any line, drop the patch. Rewrite pressure is not evidence. The table is.

      If the characterization file is already green, one extract prompt on the free server is enough. Skip that prompt when the table still has empty cells.
      Freeze the Error Contract Before One except Change

        Glyph boosted

        [?]phildini [He/Him] » 🌐
        @phildini@wandering.shop

        After a whirlwind tour of what is doing in health tech, I’m looking for my next role.

        If you need an empathetic engineering leader with deep experience in and broad experience in surprising disciplines, reach out!

          #refactoring boosted

          [?]Hack a Day (unofficial) » 🤖 🌐
          @hackaday@www.urbanmind.net

          Do not extract file helpers from a messy module yet. Snapshot every resolved absolute path before the first edit. Relative opens form a hidden contract across three roots.

          Most failed extracts start as a path-root mismatch. The helper looks cleaner after the extract lands. The files then land in a different directory tree.

          Three roots, one unpublished API


          A typical messy module mixes three path roots. None of them appear in the public function signature.

          os.getcwd() follows the process, not the source file. Pytest, systemd, and cron each change that value.

          Path(__file__).resolve() follows the module on disk. A later package move silently retargets every relative open.

          An env var such as DATA_DIR may override both. Empty, relative, and absolute values all behave differently.

          The public function still accepts only a basename. Callers believe the output path stays stable. That belief does not survive a chdir.

          Teaching example: three writes, three roots


          The listing below is a teaching example, not production code. It writes one report beside three different roots.

          # report_kit.py — messy on purpose
          from __future__ import annotations

          import json
          import os
          from pathlib import Path

          HERE = Path(__file__).resolve().parent

          def write_daily_report(name: str) -> dict[str, str]:
          data_dir = os.environ.get("DATA_DIR", "data")
          cwd_out = Path("out") / name
          here_out = HERE / "out" / name
          env_out = Path(data_dir) / name

          payload = {"name": name, "pid": os.getpid()}
          text = json.dumps(payload, sort_keys=True) + "\n"

          cwd_out.parent.mkdir(parents=True, exist_ok=True)
          here_out.parent.mkdir(parents=True, exist_ok=True)
          env_out.parent.mkdir(parents=True, exist_ok=True)

          cwd_out.write_text(text, encoding="utf-8")
          here_out.write_text(text, encoding="utf-8")
          env_out.write_text(text, encoding="utf-8")

          return {
          "cwd": str(cwd_out),
          "here": str(here_out),
          "env": str(env_out),
          }

          A naive extract wraps the three write_text calls. It often introduces Path.cwd() in one place. One root then silently absorbs the other two.

          Return values still look like relative strings. Tests that assert those strings stay green. The bytes move anyway.

          Artifact: a path ledger


          Build a ledger before any helper extract. Record caller, raw argument, and resolved absolute path. Hash the sorted ledger. Treat that hash as a characterization oracle.

          # path_ledger.py — teaching harness
          from __future__ import annotations

          import hashlib
          import json
          import os
          import traceback
          from pathlib import Path

          LEDGER: list[dict[str, str]] =

          []def _caller() -> str:
          frames = traceback.extract_stack()
          for frame in reversed(frames[:-1]):
          if "path_ledger.py" not in frame.filename:
          return f"{frame.filename}:{frame.lineno}:{frame.name}"
          return "unknown"

          def record(kind: str, raw: str, resolved: Path) -> None:
          LEDGER.append(
          {
          "kind": kind,
          "caller": _caller(),
          "raw": raw,
          "cwd": os.getcwd(),
          "resolved": str(resolved.resolve()),
          }
          )

          def ledger_hash() -> str:
          blob = json.dumps(LEDGER, sort_keys=True, indent=2)
          return hashlib.sha256(blob.encode("utf-8")).hexdigest()

          def dump(path: Path) -> str:
          path.write_text(
          json.dumps(LEDGER, indent=2, sort_keys=True) + "\n",
          encoding="utf-8",
          )
          return ledger_hash()

          Wrap writes at the test boundary only. Do not patch production code for this measurement. Run the same invocation the module already trusts.

          # test_path_ledger.py — characterization, not a unit test
          from __future__ import annotations

          from pathlib import Path
          from unittest.mock import patch

          import path_ledger
          import report_kit

          GOLDEN = Path(__file__).parent / "goldens" / "report_kit_paths.json"
          GOLDEN_HASH = Path(__file__).parent / "goldens" / "report_kit_paths.sha256"

          def _traced_write_text(self: Path, *args, **kwargs):
          path_ledger.record("Path.write_text", str(self), self)
          return Path.write_text(self, *args, **kwargs)

          def test_write_daily_report_path_ledger(tmp_path, monkeypatch):
          monkeypatch.chdir(tmp_path)
          monkeypatch.setenv("DATA_DIR", str(tmp_path / "env-data"))
          monkeypatch.setattr(report_kit, "HERE", tmp_path / "pkg")
          (tmp_path / "pkg").mkdir()

          with patch.object(Path, "write_text", _traced_write_text):
          report_kit.write_daily_report("daily.json")

          digest = path_ledger.dump(tmp_path / "ledger.json")
          if not GOLDEN.exists():
          GOLDEN.parent.mkdir(parents=True, exist_ok=True)
          GOLDEN.write_text(
          (tmp_path / "ledger.json").read_text(encoding="utf-8"),
          encoding="utf-8",
          )
          GOLDEN_HASH.write_text(digest + "\n", encoding="utf-8")
          raise AssertionError("golden created; rerun to pin")

          assert digest == GOLDEN_HASH.read_text(encoding="utf-8").strip()

          Label this pin as an oracle, not as coverage. The first run writes goldens on purpose. The second run fails on any resolved-path drift.

          Trace mkdir in the same harness when directories matter. A helper can reuse a folder the original code created. That reuse still retargets later writes.

          Decision table for one extract


          Use the table before any patch is accepted. Each row is a veto, not a preference.

          Signal in the ledger

          Safe extract?

          Required pin

          cwd-relative out/name

          Not yet

          chdir plus expected absolute

          __file__-relative out/name

          Not yet

          frozen HERE

          env-relative DATA_DIR/name

          Not yet

          empty, relative, absolute env

          mixed roots in one function

          No

          split by root, not call shape

          only basenames change

          Yes

          hash still matches


          A model often groups the three writes together. They share write_text, so the grouping looks obvious. The ledger groups them by root instead.

          Root grouping is the correct split. Call-shape grouping is the usual defect.

          Numbered workflow


          Follow these steps in order and skip none.

          1. Record one real invocation with cwd, env, and argv stored together.
          2. Trace every open, write_text, mkdir, and Path constructor you might move.
          3. Resolve each raw path against the recorded cwd, storing absolutes only.
          4. Hash the sorted ledger, then commit both the hash and JSON.
          5. Add three extra invocations: new cwd, unset DATA_DIR, absolute DATA_DIR.
          6. Refuse every extract until all four hashes stay stable across reruns.
          7. Extract one root only, and keep the other two writes inline.
          8. Diff the ledger JSON, not the source, before any merge.

          Relative goldens will lie after a machine change. Absolute goldens survive a different checkout path. That is the entire point of the pin.

          Commands for the first pin:

          mkdir -p goldens
          python -m pytest test_path_ledger.py -q
          # first run creates goldens and fails
          python -m pytest test_path_ledger.py -q
          # second run must pass before any extract

          Commands after a proposed extract:

          python -m pytest test_path_ledger.py -q
          git diff -- goldens/report_kit_paths.json
          # any resolved-path line change is a rejected patch

          A smoking-gun diff looks like this fragment:

          - "resolved": "/tmp/pytest-of-dev/test0/out/daily.json"
          + "resolved": "/home/ci/project/out/daily.json"

          The source diff can still look like a tidy helper. The ledger line is the reject signal.

          Smallest safe change


          The smallest change moves one root. It does not introduce a generic writer yet.

          def _write_cwd_report(name: str, payload: str) -> str:
          target = Path("out") / name
          target.parent.mkdir(parents=True, exist_ok=True)
          target.write_text(payload, encoding="utf-8")
          return str(target)

          Leave __file__ and DATA_DIR writes in the original function. A later extract can take the second root. Each extract must keep the ledger hash unchanged.

          Do not normalize paths inside the new helper. Normalization is a behavior change, not cleanup. Record it as a new ledger when you truly need it.

          Avoid .resolve() in the extracted helper. resolve() follows symlinks and can rewrite goldens. Prefer the same construction the messy module already used.

          Mixed open() and Path modules


          Some messy modules still call open() directly. Trace that path with a thin wrapper. Keep the same ledger schema for both styles.

          import builtins
          from pathlib import Path

          _real_open = builtins.open

          def traced_open(file, mode="r", *args, **kwargs):
          raw = str(file)
          path_ledger.record("open", raw, Path(file))
          return _real_open(file, mode, *args, **kwargs)

          Install the wrapper only inside the characterization test. Production code should keep its original open. The oracle lives in the test process.

          If both open and Path.write_text appear, keep both kinds. Dropping one kind hides a root. Hidden roots are how extracts ship broken CI writes.

          Where a free model fits


          A free coding model can draft the one-root helper. It cannot choose the root. The ledger already chose.

          Disclosure: This article was prepared as part of MonkeyCode's product outreach.

          MonkeyCode provides free model access and a free server option. Use the server to run the four pinned invocations. Feed the model the messy function, the ledger JSON, and the decision table. Reject any patch that alters a resolved field.

          The model is a diff generator in this workflow. The hash remains the reviewer for every patch. Do not skip that reviewer for a cleaner diff.

          Failure analysis


          Hash changes but the source looks equivalent. A Path constructor started calling .resolve() early. Absolute strings then diverge on symlinks.

          Hash stays stable on a laptop and fails in CI. The golden cwd was never isolated. Rerun the pin under tmp_path.

          Only two of three writes appear in the ledger. mkdir created a directory the extract later reuses. Trace mkdir as a first-class event.

          Env values look absolute in every golden row. The test set an absolute DATA_DIR only. Add the unset and relative cases before review.

          Returned relative strings still match after the extract. Callers never saw the absolute target. Assert the ledger, not the return map.

          Limitations


          This ledger does not prove functional correctness of the report. File contents can still rot under this pin. Pair it with a payload hash when bytes matter.

          It misses networked I/O by design. HTTP and object-store clients need a different oracle. Do not reuse this hash for those calls.

          It is weak against symlink farms in deploy trees. resolve() follows links; absolute() does not. Pick one rule and keep it fixed.

          Race conditions remain outside the ledger. Two processes can share one cwd. The ledger is per-process and will not serialize them.

          Windows drive letters and UNC paths need extra goldens. Do not copy a POSIX hash onto Windows runners. Split those hashes by platform.

          Who should not use this


          Do not use this workflow on a greenfield module. Write explicit path arguments first in new code. There is nothing useful to characterize there.

          Do not use it when output locations must change on purpose. Update the golden in the same commit as the move. Do not treat the hash as sacred then.

          Do not use it as a substitute for backup policy. Characterization does not recover overwritten files. Keep real backups for destructive jobs.

          Skip it for one-off notebooks and scratch CLIs. The process cwd is the product in those tools. A ledger mostly adds noise there.

          Checklist before merge


          1. Four invocations produced four hashes, and all four stayed green.
          2. One root was extracted, and two roots remained inline.
          3. The ledger JSON diff is empty after the helper lands.
          4. The helper introduced no new .resolve() calls on write paths.
          5. DATA_DIR cases include unset, relative, and absolute values.

          If any box is still open, keep the helper on the branch. Ship the path pin first. The extract can wait for a green hash.

          Run the ledger on a free server if you already have one. Keep the extract behind that green hash.
          Characterize Path Resolution Before You Move One open()

            [?]Leanpub » 🌐
            @leanpub@mastodon.social

            Mega Bundle 1 by Jason Turner is the featured bundle of ebooks 📚 on Leanpub!

            Link: leanpub.com/b/megabundle1

              Ron Jeffries boosted

              [?]Trey Hunner 🐍 » 🌐
              @treyhunner@mastodon.social

              “Note that passing generator expressions into iterable-accepting functions and classes makes something that looks a bit like a custom comprehension.”

              Read more 👉 pym.dev/custom-comprehensions/

                [?]Hey Gus » 🌐
                @elebertus@eigenmagic.net

                I swear I just saw something today or yesterday about pathlib vs os.path for parameters.

                I have forever done something like:

                ```
                from os.path import isfile
                def read_file(file_path: str) -> None:
                if not isfile(file_path):
                print(f"{file_path} is not a file")
                return None
                ...

                ```

                Which is fine, and returning `None` from there all depends on what you want to happen; should it raise an Exception etc..

                So instead of `file_path: str` and passing a `pathlib.Path` or similar would be calling a method on the object itself instead of just calling `os.path.isfile` (or similar).

                What am I missing here? Am I trying to be too creative about something trivial?

                  [?]Glyph » 🌐
                  @glyph@mastodon.social

                  If you are ever doing

                  try:
                  ...
                  except ...:
                  log.failure("...")

                  anywhere in your Twisted code, you should probably be doing

                  with mylog.failuresHandled("while doing operation"):
                  operation()

                  instead

                  docs.twisted.org/en/stable/api

                    [?]phildini [He/Him] » 🌐
                    @phildini@wandering.shop

                    Inspired by multiple years consuming blog posts from @hynek and @glyph, I realize I wish there was more guidance out in the world on when to use threads vs when to use multi-process workers vs when to use a queue-based task system like celery or rq.

                    In the spirit of the Zen of , it feels like there should be a “80% of the time do this” guide to these topics.

                      [?]Veronica Olsen » 🌐
                      @veronica@mastodon.online

                      RE: fosstodon.org/@novelwriter/117

                      I made some pretty significant changes under the hood for this release, which introduces real Qt threading, something that wasn't really used properly before. (Spell checking now runs off the main UI thread.)

                      The risk here is that the Python garbage collector isn't really designed for running on multiple threads. I now handle it the same way Calibre does.

                      I've spent many hours working on my own projects with this version, and it has been very stable on my system.

                        [?]Jesus Michał von Gentoo 🏔 (he) » 🌐
                        @mgorny@social.treehouse.systems

                        Do we already have a term for people whose ability to reason has seriously deteriorated after they started relying on ? If not, I propose slopbrain.

                        On a totally different topic, am I missing something here or is the maintainer plain wrong? github.com/tox-dev/toml-fmt/is

                          #agile boosted

                          [?]Alvin Ashcraft's Morning Dew » 🌐
                          @alvinashcraft.com@web.brid.gy

                          Dew Drop - August 31, 2026 (#4743)

                          Top Links
                          WinUI OSS Update: Phased Rollout Toward Open Collaboration (Beth Pan) - Rollout complete
                          TechBash 2026 - Communication Workshop Spotlight (plus don't miss out on Labor Day registration savings) (TechBash Team)
                          What were the biggest technical shifts in Visual Studio and …

                          Greg Wilson boosted

                          [?]Jon Udell » 🌐
                          @judell@social.coop

                          Problem: It was a pain in the ass to install Bram (a Tauri app) on a Windows machine that did not have Python installed. Why needed? The hooks that enforce the workflow were written in Python.

                          Solution: Port that apparatus to Rust, bake it into the cross-plaform binary. In the Before Time that would make no sense. Now it's a breeze.

                          Is Rust the language I'd choose for that job? No. Does that matter? No. I am not writing the code, only directing the agents who do it. For them, programming languages are fungible.

                            [?]Chris Siebenmann » 🌐
                            @cks@mastodon.social

                            GNU Emacs people who write Python using venvs, what's the state of the art for getting linters, LSP servers, and so on started with the right paths/etc set up for a particular project's venv? Is it (still) direnv + the envrc package, or something else (.dir-locals.el with a exec-path setting, maybe)?

                              #agile boosted

                              [?]Alvin Ashcraft's Morning Dew » 🌐
                              @alvinashcraft.com@web.brid.gy

                              Dew Drop - August 27, 2026 (#4741)

                              Top Links
                              Repeating the Same AI Prompts? The Agent Skills Handbook Helps You Build Reusable Skills (Suchitha Ramesh)
                              Copilot Code Reviews for Azure Repos (public preview) (Dan Hellem)
                              Visual Studio Code 1.136 (Insiders) (Visual Studio Code Team)
                              .NET Rocks! - Arguing about AI wit…

                              #agile boosted

                              [?]Alvin Ashcraft's Morning Dew » 🌐
                              @alvinashcraft.com@web.brid.gy

                              Dew Drop - August 26, 2026 (#4740)

                              Top Links
                              Explore new features available in C# 15 preview (Bill Wagner)
                              .NET Conf 2026 (Jon Galloway)
                              Unlocking the Power of AI for Every Developer in Visual Studio with Bring your Own Model (Tanmayee Kamath)
                              From dotnet run to Foundry Hosted Agent in 3 lines of C# (Bruno Capuano…

                              Glyph boosted

                              [?]Python Software Foundation » 🌐
                              @ThePSF@fosstodon.org

                              The 2026 Python Type System & Tooling Survey is live 🐍📝❓ No typing experience needed—your perspective as a dev matters most. Take a couple minutes to help improve Python typing for all!

                              surveymonkey.com/r/python_typi

                              This survey was developed with support from the Pyrefly team at Meta, the PyCharm team at JetBrains, the Python team at Microsoft, and the typing community on discourse.python.org.

                                #agile boosted

                                [?]Alvin Ashcraft's Morning Dew » 🌐
                                @alvinashcraft.com@web.brid.gy

                                Dew Drop - August 24, 2026 (#4739)

                                Top Links
                                Today I will… Modernize a .NET application (Matt Soucoup & Pablo Lopes)
                                The New MCP Roadmap (David Soria Parra & Den Delimarsky)
                                Microsoft Agent Framework for .NET v1.19.0 Release (Roger Barreto)
                                Build AI agents without leaving VS Code, join our 3-part Reactor Series (b…

                                #agile boosted

                                [?]Alvin Ashcraft's Morning Dew » 🌐
                                @alvinashcraft.com@web.brid.gy

                                Dew Drop - August 21, 2026 (#4738)

                                Top Links
                                WPF Hot Reload in Rider | JetBrains (Michael Hawker)
                                GitHub: The August 17 outage, and the work ahead (Vlad Fedorov)
                                terminal-code - VS Code Inside Your Terminal (Rob Pruzan) - Source on GitHub here
                                The Hanselminutes Podcast - Compile after Class Crossover Episode (Scot…

                                [?]Leanpub » 🌐
                                @leanpub@mastodon.social

                                Build Your Own Coding Agent by J. Owen is on sale on Leanpub! Its suggested price is $34.99; get it for $15.99 with this coupon: leanpub.com/build-your-own-cod

                                  #agile boosted

                                  [?]Alvin Ashcraft 🐿️ » 🌐
                                  @alvinashcraft@hachyderm.io

                                  [?]Leanpub » 🌐
                                  @leanpub@mastodon.social

                                  NEW! Leanpub Book LAUNCH 🚀 Python Concepts Questions & Code: The Total Pythoneering Learning System by Total Pythoneereing

                                  youtu.be/kzmz4dJeAVw

                                    [?]Leanpub » 🌐
                                    @leanpub@mastodon.social

                                    The Open Geospatial Python Series by Qiusheng Wu 📚 on Leanpub!

                                    Apprenez Python pour le géospatial, des bases jusqu’à la GeoAI avancée. Développez des workflows concrets pour les SIG, la gestion des données spatiales et l’analyse basée sur l’IA.

                                    Link: leanpub.com/b/geopython-fr

                                      [?]David Lord :python: » 🌐
                                      @davidism@mas.to

                                      Should we remove Flask's interactive debugger? (Being able to execute code at any frame in a traceback.) It's a huge amount of complexity and source of constant invalid security reports. I'm not sure it's been needed for a long time. github.com/pallets/werkzeug/is

                                        [?]Glyph » 🌐
                                        @glyph@mastodon.social

                                        UPDATE: we've got a volunteer for the proximate issue, but I'd love to have some more XMPP folks involved generally! Especially to have more than one!

                                        We could really use some help with Twisted's and implementation. Could you DM if these terms of are of interest to you and if you have any spare capacity to review a little bit of code? It would be much appreciated.

                                          [?]Leanpub » 🌐
                                          @leanpub@mastodon.social

                                          Conformal Prediction and CatBoost by Valery Manokhin 📚 on Leanpub!

                                          Link: leanpub.com/b/conformal_predic

                                            [?]Leanpub » 🌐
                                            @leanpub@mastodon.social

                                            Advanced Python Tips by Rahul Agarwal is free with a Leanpub Reader membership! Or you can buy it for $7.99! leanpub.com/advancedpythontips

                                              [?]Python Software Foundation » 🌐
                                              @ThePSF@fosstodon.org

                                              runs on ~zero AWS cost thanks to @fastlydevs caching 99% of traffic + AWS credits covering the rest. Huge thanks to both! But 2026 broke an 8-year streak: AWS spend is up 69% YoY as agents & CI runs surge.

                                              @Monorepo, PSF Director of Engineering, on what's changing: pyfound.blogspot.com/2026/08/h

                                                #agile boosted

                                                [?]Alvin Ashcraft's Morning Dew » 🌐
                                                @alvinashcraft.com@web.brid.gy

                                                Dew Drop - August 17, 2026 (#4734)

                                                Top Links
                                                Windows App Development CLI v0.6 – create new WinUI applications, sign packages with Azure, and more (Zachary Teutsch) - *Release notes available on *GitHub
                                                Uno Apps Inside of Uno Apps (Steve Bilogan)
                                                How to bring your software delivery workflow into GitHub with agent a…

                                                [?]Trey Hunner 🐍 » 🌐
                                                @treyhunner@mastodon.social

                                                Alex Martelli coined the term "goose typing" to describe this ability in Python to practice duck typing while also using isinstance and issubclass.

                                                Read more 👉 pym.dev/goose-typing/

                                                  Cassandrich boosted

                                                  [?]Jesus Michał von Gentoo 🏔 (he) » 🌐
                                                  @mgorny@social.treehouse.systems

                                                  So if you're wondering how great is, let's talk about . Mypy introduced its own Rust - package, ast-serialize. This package had a deep crate dependency that was broken on PowerPC. The issue was fixed a month ago but everything is still blocked on a deep chain of dependencies being updated and released.

                                                  github.com/mypyc/ast_serialize

                                                  EDIT: yes, I know, it's not Rust, it's Cargo. Because obviously Rust without Cargo makes so much sense for that one project using it.

                                                    #agile boosted

                                                    [?]Alvin Ashcraft's Morning Dew » 🌐
                                                    @alvinashcraft.com@web.brid.gy

                                                    Dew Drop - August 12, 2026 (#4731)

                                                    Top Links
                                                    .NET 11 Preview 7 is now available! (.NET Team)
                                                    Agentic Skills Demystified (Sam Basu)
                                                    MAI-Code-1-Flash Highlights Microsoft’s Lower-Cost Approach to Coding AI (Ali Farhat)
                                                    Today I will… manage Git Submodules without leaving the IDE (Harshada Hole)
                                                    Scott & Mark Learn To.…

                                                    #refactoring boosted

                                                    [?]Leanpub » 🌐
                                                    @leanpub@mastodon.social

                                                    A Short Guide to Naming by Tim Ottinger is free with a Leanpub Reader membership! Or you can buy it for $6.50! leanpub.com/naming_shortguide

                                                      Back to top - More...