Hello community, here is the log from the commit of package python-pyrsistent for openSUSE:Factory checked in at 2019-03-19 10:00:17 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-pyrsistent (Old) and /work/SRC/openSUSE:Factory/.python-pyrsistent.new.28833 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-pyrsistent" Tue Mar 19 10:00:17 2019 rev:3 rq:686035 version:0.14.11 Changes: -------- --- /work/SRC/openSUSE:Factory/python-pyrsistent/python-pyrsistent.changes 2018-08-12 20:55:52.429528308 +0200 +++ /work/SRC/openSUSE:Factory/.python-pyrsistent.new.28833/python-pyrsistent.changes 2019-03-19 10:00:28.179941891 +0100 @@ -1,0 +2,17 @@ +Mon Mar 18 10:49:20 UTC 2019 - Tomáš Chvátal <tchva...@suse.com> + +- Update to 0.14.11: + * Fix #152 Don't use __builtin_popcount, this hopefully fixes #147 Error in pvectorc.cp37-win_amd64.pyd file, as well. + Thanks @benrg for this! + * Fix #151 Fix compatibility for hypothesis 4. Thanks @felixonmars for this! + * Fix #148, only require pytest-runner if running tests. Thanks @ccorbacho for this! + * Fix #144, Compile pvectormodule.c on windows. Thanks @ganwell for this! + * Fix #142, Improve type stubs. Thanks @arxanas for this! + * Fix #102, add PEP 561 type annotation stubs for most pyrsistent types. Thanks @nattofriends for this! + * Fix #135, Type classes for Python 3 type annotations of pyrsistent types. Thanks @nattofriends for this! + * Fix #128, Allow PClass and PRecord to ignore input parameters to constructor that are not part of the spec + instead of blowing up with a type error. Thanks @agberk for this! + * Fix #137, deprecation warnings in Python 3.7. Thanks @thombashi for this! + * Fix #129, building via setuptools and setup.py. Thanks @galuszkak for this! + +------------------------------------------------------------------- Old: ---- pyrsistent-0.14.4.tar.gz New: ---- pyrsistent-0.14.11.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-pyrsistent.spec ++++++ --- /var/tmp/diff_new_pack.RaiuJ6/_old 2019-03-19 10:00:30.087941092 +0100 +++ /var/tmp/diff_new_pack.RaiuJ6/_new 2019-03-19 10:00:30.143941069 +0100 @@ -1,7 +1,7 @@ # # spec file for package python-pyrsistent # -# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -12,13 +12,13 @@ # license that conforms to the Open Source Definition (Version 1.9) # published by the Open Source Initiative. -# Please submit bugfixes or comments via http://bugs.opensuse.org/ +# Please submit bugfixes or comments via https://bugs.opensuse.org/ # %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-pyrsistent -Version: 0.14.4 +Version: 0.14.11 Release: 0 Summary: Persistent, Functional, Immutable data structures License: MIT @@ -57,9 +57,7 @@ %python_expand %fdupes %{buildroot}%{$python_sitearch} %check -%{python_expand export PYTHONPATH=%{buildroot}%{$python_sitearch} -py.test-%{$python_bin_suffix} -} +%pytest_arch %files %{python_files} %license LICENCE.mit ++++++ pyrsistent-0.14.4.tar.gz -> pyrsistent-0.14.11.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyrsistent-0.14.4/CHANGES.txt new/pyrsistent-0.14.11/CHANGES.txt --- old/pyrsistent-0.14.4/CHANGES.txt 2018-07-08 11:51:59.000000000 +0200 +++ new/pyrsistent-0.14.11/CHANGES.txt 2019-02-21 22:31:17.000000000 +0100 @@ -1,6 +1,32 @@ Revision history ---------------- -v0.14.4, 2018-07-08 +0.14.11, 2019-02-21 + * Fix #152 Don't use __builtin_popcount, this hopefully fixes #147 Error in pvectorc.cp37-win_amd64.pyd file, as well. + Thanks @benrg for this! + * Fix #151 Fix compatibility for hypothesis 4. Thanks @felixonmars for this! + +0.14.10, 2019-02-09 + * Fix #148, only require pytest-runner if running tests. Thanks @ccorbacho for this! + +0.14.9, 2019-01-06 + * Fix #144, Compile pvectormodule.c on windows. Thanks @ganwell for this! + +0.14.8, 2018-12-19 + * Fix #142, Improve type stubs. Thanks @arxanas for this! + +0.14.7, 2018-11-20 + * Fix #102, add PEP 561 type annotation stubs for most pyrsistent types. Thanks @nattofriends for this! + +0.14.6, 2018-11-17 + * Fix #135, Type classes for Python 3 type annotations of pyrsistent types. Thanks @nattofriends for this! + * Fix #128, Allow PClass and PRecord to ignore input parameters to constructor that are not part of the spec + instead of blowing up with a type error. Thanks @agberk for this! + +0.14.5, 2018-10-14 + * Fix #137, deprecation warnings in Python 3.7. Thanks @thombashi for this! + * Fix #129, building via setuptools and setup.py. Thanks @galuszkak for this! + +0.14.4, 2018-07-08 * Fix #133, minor Python 3.7 compatibility issue. Pyrsistent is now officially Python 3.7 compliant! v0.14.3, 2018-06-11 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyrsistent-0.14.4/LICENCE.mit new/pyrsistent-0.14.11/LICENCE.mit --- old/pyrsistent-0.14.4/LICENCE.mit 2018-07-07 15:53:48.000000000 +0200 +++ new/pyrsistent-0.14.11/LICENCE.mit 2019-01-06 22:04:57.000000000 +0100 @@ -1,4 +1,4 @@ -Copyright (c) 2018 Tobias Gustafsson +Copyright (c) 2019 Tobias Gustafsson Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyrsistent-0.14.4/PKG-INFO new/pyrsistent-0.14.11/PKG-INFO --- old/pyrsistent-0.14.4/PKG-INFO 2018-07-08 11:57:12.000000000 +0200 +++ new/pyrsistent-0.14.11/PKG-INFO 2019-02-21 22:31:40.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: pyrsistent -Version: 0.14.4 +Version: 0.14.11 Summary: Persistent/Functional/Immutable data structures Home-page: http://github.com/tobgu/pyrsistent/ Author: Tobias Gustafsson @@ -600,6 +600,13 @@ The pure python implementation is fully PyPy compatible. Running it under PyPy speeds operations up considerably if the structures are used heavily (if JITed), for some cases the performance is almost on par with the built in counterparts. + Type hints + ---------- + + PEP 561 style type hints for use with mypy and various editors are available for most types and functions in pyrsistent. + + Type classes for annotating your own code with pyrsistent types are also available under pyrsistent.typing. + Installation ------------ @@ -649,6 +656,24 @@ doozr https://github.com/doozr + Kamil Galuszka https://github.com/galuszkak + + Tsuyoshi Hombashi https://github.com/thombashi + + nattofriends https://github.com/nattofriends + + agberk https://github.com/agberk + + Waleed Khan https://github.com/arxanas + + Jean-Louis Fuchs https://github.com/ganwell + + Carlos Corbacho https://github.com/ccorbacho + + Felix Yan https://github.com/felixonmars + + benrg https://github.com/benrg + Contributing ------------ @@ -665,6 +690,15 @@ Run test for Python 2.7: ``tox -epy27`` + Release + ~~~~~~~ + * Update CHANGES.txt + * Update README with any new contributors and potential info needed. + * Update _pyrsistent_version.py + * python setup.py sdist upload + * Commit and tag with new version: git add -u . && git commit -m 'Prepare version vX.Y.Z' && git tag -a vX.Y.Z -m 'vX.Y.Z' + * Push commit and tags: git push && git push --tags + Project status -------------- Pyrsistent can be considered stable and mature (who knows, there may even be a 1.0 some day :-)). The project is diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyrsistent-0.14.4/README new/pyrsistent-0.14.11/README --- old/pyrsistent-0.14.4/README 2018-07-07 15:53:48.000000000 +0200 +++ new/pyrsistent-0.14.11/README 2019-02-21 22:31:17.000000000 +0100 @@ -592,6 +592,13 @@ The pure python implementation is fully PyPy compatible. Running it under PyPy speeds operations up considerably if the structures are used heavily (if JITed), for some cases the performance is almost on par with the built in counterparts. +Type hints +---------- + +PEP 561 style type hints for use with mypy and various editors are available for most types and functions in pyrsistent. + +Type classes for annotating your own code with pyrsistent types are also available under pyrsistent.typing. + Installation ------------ @@ -641,6 +648,24 @@ doozr https://github.com/doozr +Kamil Galuszka https://github.com/galuszkak + +Tsuyoshi Hombashi https://github.com/thombashi + +nattofriends https://github.com/nattofriends + +agberk https://github.com/agberk + +Waleed Khan https://github.com/arxanas + +Jean-Louis Fuchs https://github.com/ganwell + +Carlos Corbacho https://github.com/ccorbacho + +Felix Yan https://github.com/felixonmars + +benrg https://github.com/benrg + Contributing ------------ @@ -657,6 +682,15 @@ Run test for Python 2.7: ``tox -epy27`` +Release +~~~~~~~ +* Update CHANGES.txt +* Update README with any new contributors and potential info needed. +* Update _pyrsistent_version.py +* python setup.py sdist upload +* Commit and tag with new version: git add -u . && git commit -m 'Prepare version vX.Y.Z' && git tag -a vX.Y.Z -m 'vX.Y.Z' +* Push commit and tags: git push && git push --tags + Project status -------------- Pyrsistent can be considered stable and mature (who knows, there may even be a 1.0 some day :-)). The project is diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyrsistent-0.14.4/README.rst new/pyrsistent-0.14.11/README.rst --- old/pyrsistent-0.14.4/README.rst 2018-07-07 15:53:48.000000000 +0200 +++ new/pyrsistent-0.14.11/README.rst 2019-02-21 22:31:17.000000000 +0100 @@ -592,6 +592,13 @@ The pure python implementation is fully PyPy compatible. Running it under PyPy speeds operations up considerably if the structures are used heavily (if JITed), for some cases the performance is almost on par with the built in counterparts. +Type hints +---------- + +PEP 561 style type hints for use with mypy and various editors are available for most types and functions in pyrsistent. + +Type classes for annotating your own code with pyrsistent types are also available under pyrsistent.typing. + Installation ------------ @@ -641,6 +648,24 @@ doozr https://github.com/doozr +Kamil Galuszka https://github.com/galuszkak + +Tsuyoshi Hombashi https://github.com/thombashi + +nattofriends https://github.com/nattofriends + +agberk https://github.com/agberk + +Waleed Khan https://github.com/arxanas + +Jean-Louis Fuchs https://github.com/ganwell + +Carlos Corbacho https://github.com/ccorbacho + +Felix Yan https://github.com/felixonmars + +benrg https://github.com/benrg + Contributing ------------ @@ -657,6 +682,15 @@ Run test for Python 2.7: ``tox -epy27`` +Release +~~~~~~~ +* Update CHANGES.txt +* Update README with any new contributors and potential info needed. +* Update _pyrsistent_version.py +* python setup.py sdist upload +* Commit and tag with new version: git add -u . && git commit -m 'Prepare version vX.Y.Z' && git tag -a vX.Y.Z -m 'vX.Y.Z' +* Push commit and tags: git push && git push --tags + Project status -------------- Pyrsistent can be considered stable and mature (who knows, there may even be a 1.0 some day :-)). The project is diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyrsistent-0.14.4/_pyrsistent_version.py new/pyrsistent-0.14.11/_pyrsistent_version.py --- old/pyrsistent-0.14.4/_pyrsistent_version.py 2018-07-08 11:51:36.000000000 +0200 +++ new/pyrsistent-0.14.11/_pyrsistent_version.py 2019-02-21 22:31:17.000000000 +0100 @@ -1 +1 @@ -__version__ = '0.14.4' +__version__ = '0.14.11' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyrsistent-0.14.4/pvectorcmodule.c new/pyrsistent-0.14.11/pvectorcmodule.c --- old/pyrsistent-0.14.4/pvectorcmodule.c 2018-07-07 15:53:48.000000000 +0200 +++ new/pyrsistent-0.14.11/pvectorcmodule.c 2019-02-21 22:21:41.000000000 +0100 @@ -21,14 +21,13 @@ require to be exposed outside of this module. */ -#define BRANCH_FACTOR 32 +#define SHIFT 5 +#define BRANCH_FACTOR (1 << SHIFT) #define BIT_MASK (BRANCH_FACTOR - 1) static PyTypeObject PVectorType; static PyTypeObject PVectorEvolverType; -int SHIFT = 0; - typedef struct { void *items[BRANCH_FACTOR]; unsigned int refCount; @@ -1102,77 +1101,6 @@ return NULL; } -static PyMethodDef PyrsistentMethods[] = { - {"pvector", pyrsistent_pvec, METH_VARARGS, - "pvector([iterable])\n" - "Create a new persistent vector containing the elements in iterable.\n\n" - ">>> v1 = pvector([1, 2, 3])\n" - ">>> v1\n" - "pvector([1, 2, 3])"}, - {NULL, NULL, 0, NULL} -}; - - -#if PY_MAJOR_VERSION >= 3 - static struct PyModuleDef moduledef = { - PyModuleDef_HEAD_INIT, - "pvectorc", /* m_name */ - "Persistent vector", /* m_doc */ - -1, /* m_size */ - PyrsistentMethods, /* m_methods */ - NULL, /* m_reload */ - NULL, /* m_traverse */ - NULL, /* m_clear */ - NULL, /* m_free */ - }; -#endif - -PyObject* moduleinit(void) { - PyObject* m; - - // Only allow creation/initialization through factory method pvec - PVectorType.tp_init = NULL; - PVectorType.tp_new = NULL; - - if (PyType_Ready(&PVectorType) < 0) { - return NULL; - } - - -#if PY_MAJOR_VERSION >= 3 - m = PyModule_Create(&moduledef); -#else - m = Py_InitModule3("pvectorc", PyrsistentMethods, "Persistent vector"); -#endif - - if (m == NULL) { - return NULL; - } - - SHIFT = __builtin_popcount(BIT_MASK); - - if(EMPTY_VECTOR == NULL) { - EMPTY_VECTOR = emptyNewPvec(); - } - - nodeCache.size = 0; - - Py_INCREF(&PVectorType); - PyModule_AddObject(m, "PVector", (PyObject *)&PVectorType); - - return m; -} - -#if PY_MAJOR_VERSION >= 3 -PyMODINIT_FUNC PyInit_pvectorc(void) { - return moduleinit(); -} -#else -PyMODINIT_FUNC initpvectorc(void) { - moduleinit(); -} -#endif - /*********************** PVector Iterator **************************/ @@ -1196,7 +1124,7 @@ }; static PyTypeObject PVectorIterType = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) + PyVarObject_HEAD_INIT(NULL, 0) "pvector_iterator", /* tp_name */ sizeof(PVectorIter), /* tp_basicsize */ 0, /* tp_itemsize */ @@ -1307,7 +1235,7 @@ }; static PyTypeObject PVectorEvolverType = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) + PyVarObject_HEAD_INIT(NULL, 0) "pvector_evolver", /* tp_name */ sizeof(PVectorEvolver), /* tp_basicsize */ 0, /* tp_itemsize */ @@ -1633,3 +1561,80 @@ Py_VISIT(self->appendList); return 0; } + +static PyMethodDef PyrsistentMethods[] = { + {"pvector", pyrsistent_pvec, METH_VARARGS, + "pvector([iterable])\n" + "Create a new persistent vector containing the elements in iterable.\n\n" + ">>> v1 = pvector([1, 2, 3])\n" + ">>> v1\n" + "pvector([1, 2, 3])"}, + {NULL, NULL, 0, NULL} +}; + + +/********************* Python module initialization ************************/ + +#if PY_MAJOR_VERSION >= 3 + static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + "pvectorc", /* m_name */ + "Persistent vector", /* m_doc */ + -1, /* m_size */ + PyrsistentMethods, /* m_methods */ + NULL, /* m_reload */ + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL, /* m_free */ + }; +#endif + +PyObject* moduleinit(void) { + PyObject* m; + + // Only allow creation/initialization through factory method pvec + PVectorType.tp_init = NULL; + PVectorType.tp_new = NULL; + + if (PyType_Ready(&PVectorType) < 0) { + return NULL; + } + if (PyType_Ready(&PVectorIterType) < 0) { + return NULL; + } + if (PyType_Ready(&PVectorEvolverType) < 0) { + return NULL; + } + + +#if PY_MAJOR_VERSION >= 3 + m = PyModule_Create(&moduledef); +#else + m = Py_InitModule3("pvectorc", PyrsistentMethods, "Persistent vector"); +#endif + + if (m == NULL) { + return NULL; + } + + if(EMPTY_VECTOR == NULL) { + EMPTY_VECTOR = emptyNewPvec(); + } + + nodeCache.size = 0; + + Py_INCREF(&PVectorType); + PyModule_AddObject(m, "PVector", (PyObject *)&PVectorType); + + return m; +} + +#if PY_MAJOR_VERSION >= 3 +PyMODINIT_FUNC PyInit_pvectorc(void) { + return moduleinit(); +} +#else +PyMODINIT_FUNC initpvectorc(void) { + moduleinit(); +} +#endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyrsistent-0.14.4/pyrsistent/__init__.pyi new/pyrsistent-0.14.11/pyrsistent/__init__.pyi --- old/pyrsistent-0.14.4/pyrsistent/__init__.pyi 1970-01-01 01:00:00.000000000 +0100 +++ new/pyrsistent-0.14.11/pyrsistent/__init__.pyi 2018-12-19 22:07:14.000000000 +0100 @@ -0,0 +1,152 @@ +# flake8: noqa: E704 +# from https://gist.github.com/WuTheFWasThat/091a17d4b5cab597dfd5d4c2d96faf09 +# Stubs for pyrsistent (Python 3.6) + +from typing import Any +from typing import AnyStr +from typing import Callable +from typing import Iterable +from typing import List +from typing import Optional +from typing import Mapping +from typing import MutableMapping +from typing import Sequence +from typing import Set +from typing import Union +from typing import Tuple +from typing import Type +from typing import TypeVar +from typing import overload + +from pyrsistent.typing import PBag as PBag +from pyrsistent.typing import PDeque as PDeque +from pyrsistent.typing import PList as PList +from pyrsistent.typing import PMap as PMap +from pyrsistent.typing import PMapEvolver as PMapEvolver +from pyrsistent.typing import PSet as PSet +from pyrsistent.typing import PSetEvolver as PSetEvolver +from pyrsistent.typing import PVector as PVector +from pyrsistent.typing import PVectorEvolver as PVectorEvolver + +KT = TypeVar('KT') +VT = TypeVar('VT') + +def pmap(initial: Mapping[KT, VT] = {}, pre_size: int = 0) -> PMap[KT, VT]: ... +def m(**kwargs: Mapping[KT, VT]) -> PMap[KT, VT]: ... + +T = TypeVar('T') + +def pvector(iterable: Iterable[T]) -> PVector[T]: ... +def v(*iterable: Iterable[T]) -> PVector[T]: ... + +def pset(iterable: Iterable[T] = (), pre_size: int = 8) -> PSet[T]: ... +def s(*iterable: Iterable[T]) -> PSet[T]: ... + +# The actual return value (_PField) is irrelevant after a PRecord has been instantiated, +# see https://github.com/tobgu/pyrsistent/blob/master/pyrsistent/_precord.py#L10 +def field( + type: Union[Type[T], Sequence[Type[T]]] = (), + invariant: Callable[[Any], Tuple[bool, Optional[str]]] = lambda _: (True, None), + initial: Any = object(), + mandatory: bool = False, + factory: Callable[[Any], T] = lambda x: x, + serializer: Callable[[Any, T], Any] = lambda _, value: value, +) -> T: ... + +def pset_field( + item_type: Type[T], + optional: bool = False, + initial: Any = (), +) -> PSet[T]: ... + +def pmap_field( + key_type: Type[KT], + value_type: Type[VT], + optional: bool = False, + invariant: Callable[[Any], Tuple[bool, Optional[str]]] = lambda _: (True, None), +) -> PMap[KT, VT]: ... + +def pvector_field( + item_type: Type[T], + optional: bool = False, + initial: Any = (), +) -> PVector[T]: ... + +def pbag(elements: Iterable[T]) -> PBag[T]: ... +def b(*elements: Iterable[T]) -> PBag[T]: ... + +def plist(iterable: Iterable[T] = (), reverse: bool = False) -> PList[T]: ... +def l(*elements: Iterable[T]) -> PList[T]: ... + +def pdeque(iterable: Iterable[T], maxlen: Optional[int] = None) -> PDeque[T]: ... +def dq(*iterable: Iterable[T]) -> PDeque[T]: ... + +def optional(*typs: Iterable[type]) -> Iterable[type]: ... + +T_PRecord = TypeVar('T_PRecord', bound='PRecord') +class PRecord(PMap[AnyStr, Any]): + _precord_fields: dict + _precord_initial_values: dict + + def __init__(self, **kwargs: Any) -> None: ... + @classmethod + def create( + cls: Type[T_PRecord], + kwargs: Mapping, + _factory_fields: Optional[Iterable] = None, + ignore_extra: bool = False, + ) -> T_PRecord: ... + # This is OK because T_PRecord is a concrete type + def discard(self: T_PRecord, key: KT) -> T_PRecord: ... + def remove(self: T_PRecord, key: KT) -> T_PRecord: ... + def set(self: T_PRecord, key: KT, val: VT) -> T_PRecord: ... + + def serialize(format: Any = None) -> MutableMapping: ... + # From pyrsistent documentation: + # This set function differs slightly from that in the PMap + # class. First of all it accepts key-value pairs. Second it accepts multiple key-value + # pairs to perform one, atomic, update of multiple fields. + @overload + def set(self, key: KT, val: VT) -> Any: ... + @overload + def set(self, **kwargs: VT) -> Any: ... + +def immutable( + members: Union[str, Iterable[str]] = '', + name: str = 'Immutable', + verbose: bool = False, +) -> Tuple: ... # actually a namedtuple + +@overload +def freeze(o: Mapping[KT, VT]) -> PMap[KT, VT]: ... +@overload +def freeze(o: List[T]) -> PVector[T]: ... +@overload +def freeze(o: Tuple[T, ...]) -> Tuple[T, ...]: ... +@overload +def freeze(o: Set[T]) -> PSet[T]: ... + +@overload +def thaw(o: PMap[KT, VT]) -> Mapping[KT, VT]: ... +@overload +def thaw(o: PVector[T]) -> List[T]: ... +@overload +def thaw(o: Tuple[T, ...]) -> Tuple[T, ...]: ... +# collections.abc.MutableSet is kind of garbage: +# https://stackoverflow.com/questions/24977898/why-does-collections-mutableset-not-bestow-an-update-method +@overload +def thaw(o: PSet[T]) -> Set[T]: ... + +def mutant(fn: Callable) -> Callable: ... + +def inc(x: int) -> int: ... +@overload +def discard(evolver: PMapEvolver[KT, VT], key: KT) -> None: ... +@overload +def discard(evolver: PVectorEvolver[T], key: int) -> None: ... +@overload +def discard(evolver: PSetEvolver[T], key: T) -> None: ... +def rex(expr: str) -> Callable[[Any], bool]: ... +def ny(_: Any) -> bool: ... + +def get_in(keys: Iterable, coll: Mapping, default: Optional[Any] = None, no_default: bool = False) -> Any: ... diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyrsistent-0.14.4/pyrsistent/_checked_types.py new/pyrsistent-0.14.11/pyrsistent/_checked_types.py --- old/pyrsistent-0.14.4/pyrsistent/_checked_types.py 2018-07-07 15:53:48.000000000 +0200 +++ new/pyrsistent-0.14.11/pyrsistent/_checked_types.py 2018-10-14 12:06:35.000000000 +0200 @@ -1,4 +1,4 @@ -from collections import Iterable +from ._compat import Iterable import six from pyrsistent._compat import Enum, string_types diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyrsistent-0.14.4/pyrsistent/_compat.py new/pyrsistent-0.14.11/pyrsistent/_compat.py --- old/pyrsistent-0.14.4/pyrsistent/_compat.py 2018-07-07 15:53:48.000000000 +0200 +++ new/pyrsistent-0.14.11/pyrsistent/_compat.py 2018-10-14 12:06:35.000000000 +0200 @@ -7,3 +7,25 @@ except: class Enum(object): pass # no objects will be instances of this class + +# collections compat +try: + from collections.abc import ( + Container, + Hashable, + Iterable, + Mapping, + Sequence, + Set, + Sized, + ) +except ImportError: + from collections import ( + Container, + Hashable, + Iterable, + Mapping, + Sequence, + Set, + Sized, + ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyrsistent-0.14.4/pyrsistent/_field_common.py new/pyrsistent-0.14.11/pyrsistent/_field_common.py --- old/pyrsistent-0.14.4/pyrsistent/_field_common.py 2018-07-07 15:53:48.000000000 +0200 +++ new/pyrsistent-0.14.11/pyrsistent/_field_common.py 2018-10-14 12:06:35.000000000 +0200 @@ -1,4 +1,3 @@ -from collections import Iterable import six from pyrsistent._checked_types import ( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyrsistent-0.14.4/pyrsistent/_pbag.py new/pyrsistent-0.14.11/pyrsistent/_pbag.py --- old/pyrsistent-0.14.4/pyrsistent/_pbag.py 2018-07-07 15:53:48.000000000 +0200 +++ new/pyrsistent-0.14.11/pyrsistent/_pbag.py 2018-10-14 12:06:35.000000000 +0200 @@ -1,4 +1,4 @@ -from collections import Container, Iterable, Sized, Hashable +from ._compat import Container, Iterable, Sized, Hashable from functools import reduce from pyrsistent._pmap import pmap diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyrsistent-0.14.4/pyrsistent/_pclass.py new/pyrsistent-0.14.11/pyrsistent/_pclass.py --- old/pyrsistent-0.14.4/pyrsistent/_pclass.py 2018-07-07 15:53:48.000000000 +0200 +++ new/pyrsistent-0.14.11/pyrsistent/_pclass.py 2018-11-17 06:52:33.000000000 +0100 @@ -108,14 +108,20 @@ return self.__class__(_factory_fields=factory_fields, **kwargs) @classmethod - def create(cls, kwargs, _factory_fields=None): + def create(cls, kwargs, _factory_fields=None, ignore_extra=False): """ Factory method. Will create a new PClass of the current type and assign the values specified in kwargs. + + :param ignore_extra: A boolean which when set to True will ignore any keys which appear in kwargs that are not + in the set of fields on the PClass. """ if isinstance(kwargs, cls): return kwargs + if ignore_extra: + kwargs = {k: kwargs[k] for k in cls._pclass_fields if k in kwargs} + return cls(_factory_fields=_factory_fields, **kwargs) def serialize(self, format=None): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyrsistent-0.14.4/pyrsistent/_pdeque.py new/pyrsistent-0.14.11/pyrsistent/_pdeque.py --- old/pyrsistent-0.14.4/pyrsistent/_pdeque.py 2018-07-07 15:53:48.000000000 +0200 +++ new/pyrsistent-0.14.11/pyrsistent/_pdeque.py 2018-10-14 12:06:35.000000000 +0200 @@ -1,4 +1,4 @@ -from collections import Sequence, Hashable +from ._compat import Sequence, Hashable from itertools import islice, chain from numbers import Integral from pyrsistent._plist import plist diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyrsistent-0.14.4/pyrsistent/_plist.py new/pyrsistent-0.14.11/pyrsistent/_plist.py --- old/pyrsistent-0.14.4/pyrsistent/_plist.py 2018-07-07 15:53:48.000000000 +0200 +++ new/pyrsistent-0.14.11/pyrsistent/_plist.py 2018-10-14 12:06:35.000000000 +0200 @@ -1,4 +1,4 @@ -from collections import Sequence, Hashable +from ._compat import Sequence, Hashable from numbers import Integral from functools import reduce diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyrsistent-0.14.4/pyrsistent/_pmap.py new/pyrsistent-0.14.11/pyrsistent/_pmap.py --- old/pyrsistent-0.14.4/pyrsistent/_pmap.py 2018-07-07 15:53:48.000000000 +0200 +++ new/pyrsistent-0.14.11/pyrsistent/_pmap.py 2018-10-14 12:06:35.000000000 +0200 @@ -1,4 +1,4 @@ -from collections import Mapping, Hashable +from ._compat import Mapping, Hashable from itertools import chain import six from pyrsistent._pvector import pvector diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyrsistent-0.14.4/pyrsistent/_precord.py new/pyrsistent-0.14.11/pyrsistent/_precord.py --- old/pyrsistent-0.14.4/pyrsistent/_precord.py 2018-07-07 15:53:48.000000000 +0200 +++ new/pyrsistent-0.14.11/pyrsistent/_precord.py 2018-11-17 06:52:33.000000000 +0100 @@ -77,14 +77,20 @@ ', '.join('{0}={1}'.format(k, repr(v)) for k, v in self.items())) @classmethod - def create(cls, kwargs, _factory_fields=None): + def create(cls, kwargs, _factory_fields=None, ignore_extra=False): """ Factory method. Will create a new PRecord of the current type and assign the values specified in kwargs. + + :param ignore_extra: A boolean which when set to True will ignore any keys which appear in kwargs that are not + in the set of fields on the PRecord. """ if isinstance(kwargs, cls): return kwargs + if ignore_extra: + kwargs = {k: kwargs[k] for k in cls._precord_fields if k in kwargs} + return cls(_factory_fields=_factory_fields, **kwargs) def __reduce__(self): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyrsistent-0.14.4/pyrsistent/_pset.py new/pyrsistent-0.14.11/pyrsistent/_pset.py --- old/pyrsistent-0.14.4/pyrsistent/_pset.py 2018-07-07 15:53:48.000000000 +0200 +++ new/pyrsistent-0.14.11/pyrsistent/_pset.py 2018-10-14 12:06:35.000000000 +0200 @@ -1,4 +1,4 @@ -from collections import Set, Hashable +from ._compat import Set, Hashable import sys from pyrsistent._pmap import pmap diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyrsistent-0.14.4/pyrsistent/_pvector.py new/pyrsistent-0.14.11/pyrsistent/_pvector.py --- old/pyrsistent-0.14.4/pyrsistent/_pvector.py 2018-07-07 15:53:48.000000000 +0200 +++ new/pyrsistent-0.14.11/pyrsistent/_pvector.py 2018-10-14 12:06:35.000000000 +0200 @@ -1,5 +1,5 @@ from abc import abstractmethod, ABCMeta -from collections import Sequence, Hashable +from ._compat import Sequence, Hashable from numbers import Integral import operator import six diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyrsistent-0.14.4/pyrsistent/typing.py new/pyrsistent-0.14.11/pyrsistent/typing.py --- old/pyrsistent-0.14.4/pyrsistent/typing.py 1970-01-01 01:00:00.000000000 +0100 +++ new/pyrsistent-0.14.11/pyrsistent/typing.py 2018-11-17 06:52:33.000000000 +0100 @@ -0,0 +1,57 @@ +"""Helpers for use with type annotation. + +Use the empty classes in this module when annotating the types of Pyrsistent +objects, instead of using the actual collection class. + +For example, + + from pyrsistent import pvector + from pyrsistent.typing import PVector + + myvector: PVector[str] = pvector(['a', 'b', 'c']) + +""" + +try: + from typing import Container + from typing import Hashable + from typing import Generic + from typing import Iterable + from typing import Mapping + from typing import Sequence + from typing import Sized + from typing import TypeVar + + __all__ = ['CheckedPSet', 'CheckedPVector', 'PBag', 'PDeque', 'PList', 'PMap', 'PSet', 'PVector'] + + T = TypeVar('T') + KT = TypeVar('KT') + VT = TypeVar('VT') + + # PSet.add and PSet.discard have different type signatures than that of Set. + class CheckedPSet(Generic[T], Hashable): + pass + + class CheckedPVector(Sequence[T], Hashable): + pass + + class PBag(Container[T], Iterable[T], Sized, Hashable): + pass + + class PDeque(Sequence[T], Hashable): + pass + + class PList(Sequence[T], Hashable): + pass + + class PMap(Mapping[KT, VT], Hashable): + pass + + # PSet.add and PSet.discard have different type signatures than that of Set. + class PSet(Generic[T], Hashable): + pass + + class PVector(Sequence[T], Hashable): + pass +except ImportError: + pass diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyrsistent-0.14.4/pyrsistent/typing.pyi new/pyrsistent-0.14.11/pyrsistent/typing.pyi --- old/pyrsistent-0.14.4/pyrsistent/typing.pyi 1970-01-01 01:00:00.000000000 +0100 +++ new/pyrsistent-0.14.11/pyrsistent/typing.pyi 2018-11-20 22:52:04.000000000 +0100 @@ -0,0 +1,188 @@ +# flake8: noqa: E704 +# from https://gist.github.com/WuTheFWasThat/091a17d4b5cab597dfd5d4c2d96faf09 +# Stubs for pyrsistent (Python 3.6) +# +from typing import Any +from typing import Callable +from typing import Generic +from typing import Hashable +from typing import Iterator +from typing import Iterable +from typing import Mapping +from typing import MutableMapping +from typing import Optional +from typing import Sequence +from typing import AbstractSet +from typing import Sized +from typing import Tuple +from typing import TypeVar +from typing import Union +from typing import overload + +T = TypeVar('T') +KT = TypeVar('KT') +VT = TypeVar('VT') + +class PMap(Mapping[KT, VT], Hashable): + def __add__(self, other: PMap[KT, VT]) -> PMap[KT, VT]: ... + def __getitem__(self, key: KT) -> VT: ... + def __hash__(self) -> int: ... + def __iter__(self) -> Iterator[KT]: ... + def __len__(self) -> int: ... + def copy(self) -> PMap[KT, VT]: ... + def discard(self, key: KT) -> PMap[KT, VT]: ... + def evolver(self) -> 'PMapEvolver[KT, VT]': ... + def iteritems(self) -> Iterable[Tuple[KT, VT]]: ... + def iterkeys(self) -> Iterable[KT]: ... + def itervalues(self) -> Iterable[VT]: ... + def remove(self, key: KT) -> PMap[KT, VT]: ... + def set(self, key: KT, val: VT) -> PMap[KT, VT]: ... + def transform(self, *transformations: Any) -> PMap[KT, VT]: ... + def update(self, *args: Mapping): ... + def update_with(self, update_fn: Callable[[VT, VT], VT], *args: Mapping) -> Any: ... + + +class PMapEvolver(MutableMapping[KT, VT]): + def __delitem__(self, key: KT) -> None: ... + def __getitem__(self, key: KT) -> VT: ... + def __iter__(self) -> Iterator[KT]: ... + def __len__(self) -> int: ... + def __setitem__(self, key: KT, val: VT) -> None: ... + def is_dirty(self) -> bool: ... + def persistent(self) -> PMap[KT, VT]: ... + def remove(self, key: KT) -> PMapEvolver[KT, VT]: ... + def set(self, key: KT, val: VT) -> PMapEvolver[KT, VT]: ... + + +class PVector(Sequence[T], Hashable): + def __add__(self, other: PVector[T]) -> PVector[T]: ... + @overload + def __getitem__(self, index: int) -> T: ... + @overload + def __getitem__(self, index: slice) -> PVector[T]: ... + def __hash__(self) -> int: ... + def __len__(self) -> int: ... + def __mul__(self, other: PVector[T]) -> PVector[T]: ... + def append(self, val: T) -> PVector[T]: ... + def delete(self, index: int, stop: Optional[int]) -> PVector[T]: ... + def evolver(self) -> 'PVectorEvolver[T]': ... + def extend(self, obj: Iterable[T]) -> PVector[T]: ... + def mset(self, *args: Iterable[Union[T, int]]) -> PVector[T]: ... + def remove(self, value: T) -> PVector[T]: ... + # Not compatible with MutableSequence + def set(self, i: int, val: T) -> PVector[T]: ... + def transform(self, *transformations: Any) -> PVector[T]: ... + + +class PVectorEvolver(Sequence[T], Sized): + def __delitem__(self, i: Union[int, slice]) -> None: ... + @overload + def __getitem__(self, index: int) -> T: ... + # Not actually supported + @overload + def __getitem__(self, index: slice) -> PVectorEvolver[T]: ... + def __len__(self) -> int: ... + def __setitem__(self, index: int, val: T) -> None: ... + def append(self, val: T) -> PVectorEvolver[T]: ... + def delete(self, value: T) -> PVectorEvolver[T]: ... + def extend(self, obj: Iterable[T]) -> PVectorEvolver[T]: ... + def is_dirty(self) -> bool: ... + def persistent(self) -> PVector[T]: ... + def set(self, i: int, val: T) -> PVectorEvolver[T]: ... + + +class PSet(AbstractSet[T], Hashable): + def __contains__(self, element: object) -> bool: ... + def __hash__(self) -> int: ... + def __iter__(self) -> Iterator[KT]: ... + def __len__(self) -> int: ... + def add(self, element: T) -> PSet[T]: ... + def copy(self) -> PSet[T]: ... + def difference(self, iterable: Iterable) -> PSet[T]: ... + def discard(self, element: T) -> PSet[T]: ... + def evolver(self) -> 'PSetEvolver[T]': ... + def intersection(self, iterable: Iterable) -> PSet[T]: ... + def issubset(self, iterable: Iterable) -> bool: ... + def issuperset(self, iterable: Iterable) -> bool: ... + def remove(self, element: T) -> PSet[T]: ... + def symmetric_difference(self, iterable: Iterable[T]) -> PSet[T]: ... + def union(self, iterable: Iterable[T]) -> PSet[T]: ... + def update(self, iterable: Iterable[T]) -> PSet[T]: ... + + +class PSetEvolver(Generic[T], Sized): + def __len__(self) -> int: ... + def add(self, element: T) -> PSetEvolver[T]: ... + def is_dirty(self) -> bool: ... + def persistent(self) -> PSet[T]: ... + def remove(self, element: T) -> PSetEvolver[T]: ... + + +class PBag(Generic[T], Sized, Hashable): + def __add__(self, other: PBag[T]) -> PBag[T]: ... + def __and__(self, other: PBag[T]) -> PBag[T]: ... + def __contains__(self, elem: object) -> bool: ... + def __hash__(self) -> int: ... + def __iter__(self) -> Iterator[T]: ... + def __len__(self) -> int: ... + def __or__(self, other: PBag[T]) -> PBag[T]: ... + def __sub__(self, other: PBag[T]) -> PBag[T]: ... + def add(self, elem: T) -> PBag[T]: ... + def count(self, elem: T) -> int: ... + def remove(self, elem: T) -> PBag[T]: ... + def update(self, iterable: Iterable[T]) -> PBag[T]: ... + + +class PDeque(Sequence[T], Hashable): + @overload + def __getitem__(self, index: int) -> T: ... + @overload + def __getitem__(self, index: slice) -> PDeque[T]: ... + def __hash__(self) -> int: ... + def __len__(self) -> int: ... + def __lt__(self, other: PDeque[T]) -> bool: ... + def append(self, elem: T) -> PDeque[T]: ... + def appendleft(self, elem: T) -> PDeque[T]: ... + def extend(self, iterable: Iterable[T]) -> PDeque[T]: ... + def extendleft(self, iterable: Iterable[T]) -> PDeque[T]: ... + @property + def left(self) -> T: ... + # The real return type is Integral according to what pyrsistent + # checks at runtime but mypy doesn't deal in numeric.*: + # https://github.com/python/mypy/issues/2636 + @property + def maxlen(self) -> int: ... + def pop(self, count: int = 1) -> PDeque[T]: ... + def popleft(self, count: int = 1) -> PDeque[T]: ... + def remove(self, elem: T) -> PDeque[T]: ... + def reverse(self) -> PDeque[T]: ... + @property + def right(self) -> T: ... + def rotate(self, steps: int) -> PDeque[T]: ... + + +class PList(Sequence[T], Hashable): + @overload + def __getitem__(self, index: int) -> T: ... + @overload + def __getitem__(self, index: slice) -> PList[T]: ... + def __hash__(self) -> int: ... + def __len__(self) -> int: ... + def __lt__(self, other: PDeque[T]) -> bool: ... + def cons(self, elem: T) -> PList[T]: ... + def mcons(self, iterable: Iterable[T]) -> PList[T]: ... + def remove(self, elem: T) -> PList[T]: ... + def reverse(self) -> PList[T]: ... + def split(self, index: int) -> Tuple[PList[T], PList[T]]: ... + + +class CheckedPMap(PMap[KT, VT]): + pass + + +class CheckedPVector(PVector[T]): + pass + + +class CheckedPSet(PSet[T]): + pass diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyrsistent-0.14.4/pyrsistent.egg-info/PKG-INFO new/pyrsistent-0.14.11/pyrsistent.egg-info/PKG-INFO --- old/pyrsistent-0.14.4/pyrsistent.egg-info/PKG-INFO 2018-07-08 11:57:12.000000000 +0200 +++ new/pyrsistent-0.14.11/pyrsistent.egg-info/PKG-INFO 2019-02-21 22:31:40.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: pyrsistent -Version: 0.14.4 +Version: 0.14.11 Summary: Persistent/Functional/Immutable data structures Home-page: http://github.com/tobgu/pyrsistent/ Author: Tobias Gustafsson @@ -600,6 +600,13 @@ The pure python implementation is fully PyPy compatible. Running it under PyPy speeds operations up considerably if the structures are used heavily (if JITed), for some cases the performance is almost on par with the built in counterparts. + Type hints + ---------- + + PEP 561 style type hints for use with mypy and various editors are available for most types and functions in pyrsistent. + + Type classes for annotating your own code with pyrsistent types are also available under pyrsistent.typing. + Installation ------------ @@ -649,6 +656,24 @@ doozr https://github.com/doozr + Kamil Galuszka https://github.com/galuszkak + + Tsuyoshi Hombashi https://github.com/thombashi + + nattofriends https://github.com/nattofriends + + agberk https://github.com/agberk + + Waleed Khan https://github.com/arxanas + + Jean-Louis Fuchs https://github.com/ganwell + + Carlos Corbacho https://github.com/ccorbacho + + Felix Yan https://github.com/felixonmars + + benrg https://github.com/benrg + Contributing ------------ @@ -665,6 +690,15 @@ Run test for Python 2.7: ``tox -epy27`` + Release + ~~~~~~~ + * Update CHANGES.txt + * Update README with any new contributors and potential info needed. + * Update _pyrsistent_version.py + * python setup.py sdist upload + * Commit and tag with new version: git add -u . && git commit -m 'Prepare version vX.Y.Z' && git tag -a vX.Y.Z -m 'vX.Y.Z' + * Push commit and tags: git push && git push --tags + Project status -------------- Pyrsistent can be considered stable and mature (who knows, there may even be a 1.0 some day :-)). The project is diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyrsistent-0.14.4/pyrsistent.egg-info/SOURCES.txt new/pyrsistent-0.14.11/pyrsistent.egg-info/SOURCES.txt --- old/pyrsistent-0.14.4/pyrsistent.egg-info/SOURCES.txt 2018-07-08 11:57:12.000000000 +0200 +++ new/pyrsistent-0.14.11/pyrsistent.egg-info/SOURCES.txt 2019-02-21 22:31:40.000000000 +0100 @@ -5,8 +5,10 @@ README.rst _pyrsistent_version.py pvectorcmodule.c +setup.cfg setup.py pyrsistent/__init__.py +pyrsistent/__init__.pyi pyrsistent/_checked_types.py pyrsistent/_compat.py pyrsistent/_field_common.py @@ -22,6 +24,9 @@ pyrsistent/_pvector.py pyrsistent/_toolz.py pyrsistent/_transformations.py +pyrsistent/py.typed +pyrsistent/typing.py +pyrsistent/typing.pyi pyrsistent.egg-info/PKG-INFO pyrsistent.egg-info/SOURCES.txt pyrsistent.egg-info/dependency_links.txt diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyrsistent-0.14.4/setup.cfg new/pyrsistent-0.14.11/setup.cfg --- old/pyrsistent-0.14.4/setup.cfg 2018-07-08 11:57:12.000000000 +0200 +++ new/pyrsistent-0.14.11/setup.cfg 2019-02-21 22:31:40.000000000 +0100 @@ -1,3 +1,6 @@ +[aliases] +test = pytest + [egg_info] tag_build = tag_date = 0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyrsistent-0.14.4/setup.py new/pyrsistent-0.14.11/setup.py --- old/pyrsistent-0.14.4/setup.py 2018-07-08 10:28:47.000000000 +0200 +++ new/pyrsistent-0.14.11/setup.py 2019-02-21 22:21:41.000000000 +0100 @@ -18,16 +18,17 @@ if platform.python_implementation() == 'CPython': extensions = [Extension('pvectorc', sources=['pvectorcmodule.c'])] +needs_pytest = {'pytest', 'test', 'ptr'}.intersection(sys.argv) +pytest_runner = ['pytest-runner'] if needs_pytest else [] + class custom_build_ext(build_ext): """Allow C extension building to fail.""" warning_message = """ ******************************************************************************** -WARNING: Could not build the %s. - +WARNING: Could not build the %s. Pyrsistent will still work but performance may be degraded. - %s ******************************************************************************** """ @@ -79,9 +80,12 @@ 'Programming Language :: Python :: Implementation :: PyPy', ], test_suite='tests', + tests_require=['pytest','hypothesis<5'], scripts=[], + setup_requires=pytest_runner, ext_modules=extensions, - cmdclass={"build_ext": custom_build_ext}, + cmdclass={'build_ext': custom_build_ext}, install_requires=['six'], - packages=['pyrsistent'] + packages=['pyrsistent'], + package_data={'pyrsistent': ['py.typed', '__init__.pyi', 'typing.pyi']}, ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyrsistent-0.14.4/tests/class_test.py new/pyrsistent-0.14.11/tests/class_test.py --- old/pyrsistent-0.14.4/tests/class_test.py 2018-07-07 15:53:48.000000000 +0200 +++ new/pyrsistent-0.14.11/tests/class_test.py 2018-11-17 06:52:33.000000000 +0100 @@ -1,4 +1,4 @@ -from collections import Hashable +from pyrsistent._compat import Hashable import math import pickle import pytest @@ -26,6 +26,19 @@ x = field(type=int) +def test_create_ignore_extra(): + p = Point.create({'x': 5, 'y': 10, 'z': 15, 'a': 0}, ignore_extra=True) + assert p.x == 5 + assert p.y == 10 + assert p.z == 15 + assert isinstance(p, Point) + + +def test_create_ignore_extra_false(): + with pytest.raises(AttributeError): + _ = Point.create({'x': 5, 'y': 10, 'z': 15, 'a': 0}) + + def test_evolve_pclass_instance(): p = Point(x=1, y=2) p2 = p.set(x=p.x+2) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyrsistent-0.14.4/tests/hypothesis_vector_test.py new/pyrsistent-0.14.11/tests/hypothesis_vector_test.py --- old/pyrsistent-0.14.4/tests/hypothesis_vector_test.py 2018-07-07 15:53:48.000000000 +0200 +++ new/pyrsistent-0.14.11/tests/hypothesis_vector_test.py 2019-02-21 22:21:41.000000000 +0100 @@ -4,7 +4,7 @@ import gc -from collections import Iterable +from pyrsistent._compat import Iterable from functools import wraps from pyrsistent import PClass, field @@ -45,7 +45,7 @@ # Pairs of a list and corresponding pvector: -PVectorAndLists = st.lists(st.builds(TestObject), average_size=5).map( +PVectorAndLists = st.lists(st.builds(TestObject)).map( lambda l: (l, pvector(l))) @@ -123,70 +123,70 @@ l3.extend(l2) return l3, pv.extend(pv2) - @rule(target=sequences, former=sequences, choice=st.choices()) + @rule(target=sequences, former=sequences, data=st.data()) @verify_inputs_unmodified - def remove(self, former, choice): + def remove(self, former, data): """ Remove an item from the sequences. """ l, pv = former assume(l) l2 = l[:] - i = choice(range(len(l))) + i = data.draw(st.sampled_from(range(len(l)))) del l2[i] return l2, pv.delete(i) - @rule(target=sequences, former=sequences, choice=st.choices()) + @rule(target=sequences, former=sequences, data=st.data()) @verify_inputs_unmodified - def set(self, former, choice): + def set(self, former, data): """ Overwrite an item in the sequence. """ l, pv = former assume(l) l2 = l[:] - i = choice(range(len(l))) + i = data.draw(st.sampled_from(range(len(l)))) obj = TestObject() l2[i] = obj return l2, pv.set(i, obj) - @rule(target=sequences, former=sequences, choice=st.choices()) + @rule(target=sequences, former=sequences, data=st.data()) @verify_inputs_unmodified - def transform_set(self, former, choice): + def transform_set(self, former, data): """ Transform the sequence by setting value. """ l, pv = former assume(l) l2 = l[:] - i = choice(range(len(l))) + i = data.draw(st.sampled_from(range(len(l)))) obj = TestObject() l2[i] = obj return l2, pv.transform([i], obj) - @rule(target=sequences, former=sequences, choice=st.choices()) + @rule(target=sequences, former=sequences, data=st.data()) @verify_inputs_unmodified - def transform_discard(self, former, choice): + def transform_discard(self, former, data): """ Transform the sequence by discarding a value. """ l, pv = former assume(l) l2 = l[:] - i = choice(range(len(l))) + i = data.draw(st.sampled_from(range(len(l)))) del l2[i] return l2, pv.transform([i], discard) - @rule(target=sequences, former=sequences, choice=st.choices()) + @rule(target=sequences, former=sequences, data=st.data()) @verify_inputs_unmodified - def subset(self, former, choice): + def subset(self, former, data): """ A subset of the previous sequence. """ l, pv = former assume(l) - i = choice(range(len(l))) - j = choice(range(len(l))) + i = data.draw(st.sampled_from(range(len(l)))) + j = data.draw(st.sampled_from(range(len(l)))) return l[i:j], pv[i:j] @rule(pair=sequences) @@ -250,34 +250,34 @@ start.current_evolver.extend(end.current_list) start.current_list.extend(end.current_list) - @rule(item=sequences, choice=st.choices()) - def delete(self, item, choice): + @rule(item=sequences, data=st.data()) + def delete(self, item, data): """ Remove an item from the sequences. """ assume(item.current_list) - i = choice(range(len(item.current_list))) + i = data.draw(st.sampled_from(range(len(item.current_list)))) del item.current_list[i] del item.current_evolver[i] - @rule(item=sequences, choice=st.choices()) - def setitem(self, item, choice): + @rule(item=sequences, data=st.data()) + def setitem(self, item, data): """ Overwrite an item in the sequence using ``__setitem__``. """ assume(item.current_list) - i = choice(range(len(item.current_list))) + i = data.draw(st.sampled_from(range(len(item.current_list)))) obj = TestObject() item.current_list[i] = obj item.current_evolver[i] = obj - @rule(item=sequences, choice=st.choices()) - def set(self, item, choice): + @rule(item=sequences, data=st.data()) + def set(self, item, data): """ Overwrite an item in the sequence using ``set``. """ assume(item.current_list) - i = choice(range(len(item.current_list))) + i = data.draw(st.sampled_from(range(len(item.current_list)))) obj = TestObject() item.current_list[i] = obj item.current_evolver.set(i, obj) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyrsistent-0.14.4/tests/map_test.py new/pyrsistent-0.14.11/tests/map_test.py --- old/pyrsistent-0.14.4/tests/map_test.py 2018-07-07 15:53:48.000000000 +0200 +++ new/pyrsistent-0.14.11/tests/map_test.py 2018-10-14 12:06:35.000000000 +0200 @@ -1,4 +1,5 @@ -from collections import Mapping, Hashable +from pyrsistent._compat import Mapping, Hashable +import six from operator import add import pytest from pyrsistent import pmap, m, PVector diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyrsistent-0.14.4/tests/record_test.py new/pyrsistent-0.14.11/tests/record_test.py --- old/pyrsistent-0.14.4/tests/record_test.py 2018-07-07 15:53:48.000000000 +0200 +++ new/pyrsistent-0.14.11/tests/record_test.py 2018-11-17 06:52:33.000000000 +0100 @@ -37,6 +37,18 @@ assert isinstance(r, ARecord) +def test_create_ignore_extra(): + r = ARecord.create({'x': 1, 'y': 'foo', 'z': None}, ignore_extra=True) + assert r.x == 1 + assert r.y == 'foo' + assert isinstance(r, ARecord) + + +def test_create_ignore_extra_false(): + with pytest.raises(AttributeError): + _ = ARecord.create({'x': 1, 'y': 'foo', 'z': None}) + + def test_correct_assignment(): r = ARecord(x=1, y='foo') r2 = r.set('x', 2.0) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyrsistent-0.14.4/tests/vector_test.py new/pyrsistent-0.14.11/tests/vector_test.py --- old/pyrsistent-0.14.4/tests/vector_test.py 2018-07-07 15:53:48.000000000 +0200 +++ new/pyrsistent-0.14.11/tests/vector_test.py 2018-10-14 12:06:35.000000000 +0200 @@ -321,7 +321,7 @@ def test_is_sequence(pvector): - from collections import Sequence + from pyrsistent._compat import Sequence assert isinstance(pvector(), Sequence) @@ -350,7 +350,7 @@ def test_is_hashable(pvector): - from collections import Hashable + from pyrsistent._compat import Hashable v = pvector([1, 2, 3]) v2 = pvector([1, 2, 3])