diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2022-01-09 11:49:02 -0500 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2022-01-24 15:14:01 -0500 |
| commit | ff1ab665cb1694b85085680d1a02c7c11fa2a6d4 (patch) | |
| tree | bb8414b44946d9cb96361d7dcd4a4541d8254672 /lib/sqlalchemy/cyextension | |
| parent | aba3ab247da4628e4e7baf993702e2efaccbc547 (diff) | |
| download | sqlalchemy-ff1ab665cb1694b85085680d1a02c7c11fa2a6d4.tar.gz | |
mypy: sqlalchemy.util
Starting to set up practices and conventions to
get the library typed.
Key goals for typing are:
1. whole library can pass mypy without any strict
turned on.
2. we can incrementally turn on some strict flags on a per-package/
module basis, as here we turn on more strictness for sqlalchemy.util, exc,
and log
3. mypy ORM plugin tests work fully without sqlalchemy2-stubs
installed
4. public facing methods all have return types, major parameter
signatures filled in also
5. Foundational elements like util etc. are typed enough so that
we can use them in fully typed internals higher up the stack.
Conventions set up here:
1. we can use lots of config in setup.cfg to limit where mypy
is throwing errors and how detailed it should be in different
packages / modules. We can use this to push up gerrits
that will pass tests fully without everything being typed.
2. a new tox target pep484 is added. this links to a new jenkins
pep484 job that works across all projects (alembic, dogpile, etc.)
We've worked around some mypy bugs that will likely
be around for awhile, and also set up some core practices
for how to deal with certain things such as public_factory
modules (mypy won't accept a module from a callable at all,
so need to use simple type checking conditionals).
References: #6810
Change-Id: I80be58029896a29fd9f491aa3215422a8b705e12
Diffstat (limited to 'lib/sqlalchemy/cyextension')
| -rw-r--r-- | lib/sqlalchemy/cyextension/collections.pyx | 60 | ||||
| -rw-r--r-- | lib/sqlalchemy/cyextension/immutabledict.pyx | 15 |
2 files changed, 52 insertions, 23 deletions
diff --git a/lib/sqlalchemy/cyextension/collections.pyx b/lib/sqlalchemy/cyextension/collections.pyx index e695d4c62..5a344da43 100644 --- a/lib/sqlalchemy/cyextension/collections.pyx +++ b/lib/sqlalchemy/cyextension/collections.pyx @@ -22,52 +22,53 @@ cdef list cunique_list(seq, hashfunc=None): def unique_list(seq, hashfunc=None): return cunique_list(seq, hashfunc) -cdef class OrderedSet(set): +cdef class OrderedSet: cdef list _list + cdef set _set def __init__(self, d=None): - set.__init__(self) if d is not None: self._list = cunique_list(d) - set.update(self, self._list) + self._set = set(self._list) else: self._list = [] + self._set = set() cdef OrderedSet _copy(self): cdef OrderedSet cp = OrderedSet.__new__(OrderedSet) cp._list = list(self._list) - set.update(cp, cp._list) + cp._set = set(cp._list) return cp cdef OrderedSet _from_list(self, list new_list): cdef OrderedSet new = OrderedSet.__new__(OrderedSet) new._list = new_list - set.update(new, new_list) + new._set = set(new_list) return new def add(self, element): if element not in self: self._list.append(element) - PySet_Add(self, element) + PySet_Add(self._set, element) def remove(self, element): # set.remove will raise if element is not in self - set.remove(self, element) + self._set.remove(element) self._list.remove(element) def insert(self, Py_ssize_t pos, element): if element not in self: self._list.insert(pos, element) - PySet_Add(self, element) + PySet_Add(self._set, element) def discard(self, element): if element in self: - set.remove(self, element) + self._set.remove(element) self._list.remove(element) def clear(self): - set.clear(self) + self._set.clear() self._list = [] def __getitem__(self, key): @@ -84,21 +85,34 @@ cdef class OrderedSet(set): __str__ = __repr__ - def update(self, iterable): - for e in iterable: - if e not in self: - self._list.append(e) - set.add(self, e) - return self + def update(self, *iterables): + for iterable in iterables: + for e in iterable: + if e not in self: + self._list.append(e) + self._set.add(e) def __ior__(self, iterable): - return self.update(iterable) + self.update(iterable) + return self def union(self, other): result = self._copy() result.update(other) return result + def __len__(self) -> int: + return len(self._set) + + def __eq__(self, other): + return self._set == other + + def __ne__(self, other): + return self._set != other + + def __contains__(self, element): + return element in self._set + def __or__(self, other): return self.union(other) @@ -138,27 +152,27 @@ cdef class OrderedSet(set): cdef set other_set = self._to_set(other) set.intersection_update(self, other_set) self._list = [a for a in self._list if a in other_set] - return self def __iand__(self, other): - return self.intersection_update(other) + self.intersection_update(other) + return self def symmetric_difference_update(self, other): set.symmetric_difference_update(self, other) self._list = [a for a in self._list if a in self] self._list += [a for a in other if a in self] - return self def __ixor__(self, other): - return self.symmetric_difference_update(other) + self.symmetric_difference_update(other) + return self def difference_update(self, other): set.difference_update(self, other) self._list = [a for a in self._list if a in self] - return self def __isub__(self, other): - return self.difference_update(other) + self.difference_update(other) + return self cdef object cy_id(object item): diff --git a/lib/sqlalchemy/cyextension/immutabledict.pyx b/lib/sqlalchemy/cyextension/immutabledict.pyx index 89bcf3ed6..d07c81bd4 100644 --- a/lib/sqlalchemy/cyextension/immutabledict.pyx +++ b/lib/sqlalchemy/cyextension/immutabledict.pyx @@ -12,10 +12,25 @@ class ImmutableContainer: __delitem__ = __setitem__ = __setattr__ = _immutable +class ImmutableDictBase(dict): + def _immutable(self, *a,**kw): + _immutable_fn(self) + + @classmethod + def __class_getitem__(cls, key): + return cls + + __delitem__ = __setitem__ = __setattr__ = _immutable + clear = pop = popitem = setdefault = update = _immutable + cdef class immutabledict(dict): def __repr__(self): return f"immutabledict({dict.__repr__(self)})" + @classmethod + def __class_getitem__(cls, key): + return cls + def union(self, *args, **kw): cdef dict to_merge = None cdef immutabledict result |
