Update memory: Camie Tagger v2 upgrade results
This commit is contained in:
7
skills/py/.clawhub/origin.json
Normal file
7
skills/py/.clawhub/origin.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"version": 1,
|
||||
"registry": "https://clawhub.ai",
|
||||
"slug": "py",
|
||||
"installedVersion": "1.0.1",
|
||||
"installedAt": 1774833283796
|
||||
}
|
||||
35
skills/py/SKILL.md
Normal file
35
skills/py/SKILL.md
Normal file
@@ -0,0 +1,35 @@
|
||||
---
|
||||
name: Python
|
||||
slug: python
|
||||
version: 1.0.1
|
||||
description: Write reliable Python avoiding mutable defaults, import traps, and common runtime surprises.
|
||||
metadata: {"clawdbot":{"emoji":"🐍","requires":{"bins":["python3"]},"os":["linux","darwin","win32"]}}
|
||||
---
|
||||
|
||||
## Quick Reference
|
||||
|
||||
| Topic | File |
|
||||
|-------|------|
|
||||
| Dynamic typing, type hints, duck typing | `types.md` |
|
||||
| List/dict/set gotchas, comprehensions | `collections.md` |
|
||||
| Args/kwargs, closures, decorators, generators | `functions.md` |
|
||||
| Inheritance, descriptors, metaclasses | `classes.md` |
|
||||
| GIL, threading, asyncio, multiprocessing | `concurrency.md` |
|
||||
| Circular imports, packages, __init__.py | `imports.md` |
|
||||
| Pytest, mocking, fixtures | `testing.md` |
|
||||
|
||||
## Critical Rules
|
||||
|
||||
- `def f(items=[])` shares list across all calls — use `items=None` then `items = items or []`
|
||||
- `is` checks identity, `==` checks equality — `"a" * 100 is "a" * 100` may be False
|
||||
- Modifying list while iterating skips elements — iterate over copy: `for x in list(items):`
|
||||
- GIL prevents true parallel Python threads — use multiprocessing for CPU-bound
|
||||
- Bare `except:` catches `SystemExit` and `KeyboardInterrupt` — use `except Exception:`
|
||||
- `UnboundLocalError` when assigning to outer scope variable — use `nonlocal` or `global`
|
||||
- `open()` without context manager leaks handles — always use `with open():`
|
||||
- Circular imports fail silently or partially — import inside function to break cycle
|
||||
- `0.1 + 0.2 != 0.3` — floating point, use `decimal.Decimal` for money
|
||||
- Generator exhausted after one iteration — can't reuse, recreate or use `itertools.tee`
|
||||
- Class attributes with mutables shared across instances — define in `__init__` instead
|
||||
- `__init__` is not constructor — `__new__` creates instance, `__init__` initializes
|
||||
- Default encoding is platform-dependent — always specify `encoding='utf-8'`
|
||||
6
skills/py/_meta.json
Normal file
6
skills/py/_meta.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"ownerId": "kn73vp5rarc3b14rc7wjcw8f8580t5d1",
|
||||
"slug": "py",
|
||||
"version": "1.0.1",
|
||||
"publishedAt": 1771103241009
|
||||
}
|
||||
10
skills/py/classes.md
Normal file
10
skills/py/classes.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# Class Traps
|
||||
|
||||
- Class attribute shared — `class A: items = []` shared by all instances
|
||||
- `__init__` returns None — can't `return value`, use `__new__` for singletons
|
||||
- Mutable class default — same as function default trap, use `None` + init
|
||||
- `super()` in multiple inheritance — follows MRO, not just parent
|
||||
- `__slots__` breaks `__dict__` — can't add arbitrary attributes
|
||||
- `@property` setter needs getter — define getter first with `@property`
|
||||
- `__eq__` without `__hash__` — makes class unhashable, can't use in sets
|
||||
- Private `__name` mangling — `_ClassName__name`, not truly private
|
||||
10
skills/py/collections.md
Normal file
10
skills/py/collections.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# Collection Traps
|
||||
|
||||
- Modify list while iterating — skips elements, iterate over copy `list(x)`
|
||||
- Dict keys mutated — if key object changes hash, dict lookup fails silently
|
||||
- `dict.get()` returns None — can't distinguish missing key from None value
|
||||
- List slice creates copy — `a[:]` is new list, but shallow (nested objects shared)
|
||||
- `in` on list is O(n) — use `set` for membership testing
|
||||
- Empty list/dict is falsy — `if not my_list:` catches empty AND None
|
||||
- `+=` on tuple fails — tuples immutable, but `a = a + (x,)` works
|
||||
- `list * n` shares refs — `[[]] * 3` creates 3 refs to SAME inner list
|
||||
17
skills/py/concurrency.md
Normal file
17
skills/py/concurrency.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# Concurrency Traps
|
||||
|
||||
## GIL
|
||||
- Only one thread executes Python — CPU-bound = no speedup from threads
|
||||
- I/O releases GIL — threads help for I/O-bound (network, disk)
|
||||
- Use `multiprocessing` for CPU — separate processes, no GIL
|
||||
|
||||
## Threading
|
||||
- Race conditions — shared mutable state without locks corrupts data
|
||||
- Daemon threads killed abruptly — no cleanup on main thread exit
|
||||
- `threading.local()` for thread-local — but watch for leaks in pools
|
||||
|
||||
## Asyncio
|
||||
- `await` in sync function fails — must be in `async def`
|
||||
- Blocking call in async — `time.sleep()` blocks event loop, use `asyncio.sleep()`
|
||||
- Forgotten `await` — coroutine never runs, just returns coroutine object
|
||||
- `asyncio.run()` in running loop — fails, use `await` or `create_task`
|
||||
10
skills/py/functions.md
Normal file
10
skills/py/functions.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# Function Traps
|
||||
|
||||
- Mutable default arg — evaluated ONCE at definition, shared across calls
|
||||
- `*args` after keyword-only — `def f(*, name)` forces keyword
|
||||
- Late binding closures — `lambda: i` captures variable, not value
|
||||
- `return` in finally — overrides return/exception from try block
|
||||
- Generator exhausted — can only iterate once, `list(gen)` to reuse
|
||||
- `yield` makes function generator — returns iterator, not value
|
||||
- `@decorator` without parens — `@deco` vs `@deco()` are different
|
||||
- `global` vs `nonlocal` — `global` for module, `nonlocal` for enclosing
|
||||
9
skills/py/imports.md
Normal file
9
skills/py/imports.md
Normal file
@@ -0,0 +1,9 @@
|
||||
# Import Traps
|
||||
|
||||
- Circular import — partially initialized module, `ImportError` or `None` attrs
|
||||
- `from x import *` — pollutes namespace, shadows builtins
|
||||
- Relative import outside package — `from . import x` fails in script
|
||||
- `__init__.py` side effects — runs on ANY import from package
|
||||
- Import caching — `importlib.reload()` needed for changes, but breaks refs
|
||||
- Module runs on import — top-level code executes, use `if __name__ == "__main__"`
|
||||
- `sys.path` modification — affects ALL imports, prefer proper packaging
|
||||
9
skills/py/testing.md
Normal file
9
skills/py/testing.md
Normal file
@@ -0,0 +1,9 @@
|
||||
# Testing Traps
|
||||
|
||||
- `mock.patch` path — patch where imported, not where defined
|
||||
- Mock not reset — `mock.reset_mock()` between tests or use `autospec`
|
||||
- `assert` stripped in `-O` — never use `assert` for validation
|
||||
- Fixture scope confusion — `function` runs each test, `module` once
|
||||
- `pytest.raises` without match — catches wrong exception silently
|
||||
- Async test needs plugin — `pytest-asyncio` + `@pytest.mark.asyncio`
|
||||
- Mocking `datetime.now()` — mock `datetime` module, not method
|
||||
9
skills/py/types.md
Normal file
9
skills/py/types.md
Normal file
@@ -0,0 +1,9 @@
|
||||
# Type Traps
|
||||
|
||||
- Mutable default args — `def f(x=[])` shares list across calls, use `None`
|
||||
- `is` vs `==` — `is` checks identity, `==` checks value; `a is b` fails for equal objects
|
||||
- Integer caching — `256 is 256` is True, `257 is 257` may be False
|
||||
- Float comparison — `0.1 + 0.2 != 0.3`, use `math.isclose()`
|
||||
- `None` check — use `is None`, not `== None`
|
||||
- Type hints don't enforce — `def f(x: int)` accepts strings at runtime
|
||||
- `bool` subclass of `int` — `True + True == 2`, `False == 0`
|
||||
Reference in New Issue
Block a user