{"action":"opened","issue":{"url":"https://api.github.com/repos/lmfit/lmfit-py/issues/296","repository_url":"https://api.github.com/repos/lmfit/lmfit-py","labels_url":"https://api.github.com/repos/lmfit/lmfit-py/issues/296/labels{/name}","comments_url":"https://api.github.com/repos/lmfit/lmfit-py/issues/296/comments","events_url":"https://api.github.com/repos/lmfit/lmfit-py/issues/296/events","html_url":"https://github.com/lmfit/lmfit-py/issues/296","id":131356600,"number":296,"title":"Unexpected behavior of Parameters.copy() -- re-ordering or arguments in Parameters.__init__()","user":{"login":"tronsgaard","id":10196208,"avatar_url":"https://avatars.githubusercontent.com/u/10196208?v=3","gravatar_id":"","url":"https://api.github.com/users/tronsgaard","html_url":"https://github.com/tronsgaard","followers_url":"https://api.github.com/users/tronsgaard/followers","following_url":"https://api.github.com/users/tronsgaard/following{/other_user}","gists_url":"https://api.github.com/users/tronsgaard/gists{/gist_id}","starred_url":"https://api.github.com/users/tronsgaard/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tronsgaard/subscriptions","organizations_url":"https://api.github.com/users/tronsgaard/orgs","repos_url":"https://api.github.com/users/tronsgaard/repos","events_url":"https://api.github.com/users/tronsgaard/events{/privacy}","received_events_url":"https://api.github.com/users/tronsgaard/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":0,"created_at":"2016-02-04T14:04:25Z","updated_at":"2016-02-04T14:04:25Z","closed_at":null,"body":"I am relatively new to lmfit and Python in general, but I think I might have stumbled upon a small error in parameters.py:\r\n\r\nThese few lines of code triggers a mysterious AttributeError in lmfit-0.9.2, Python 3.4.3:\r\n```\r\nfrom lmfit import Parameters\r\np1 = Parameters()\r\np2 = p1.copy()\r\np2.add('foo')\r\n---------------------------------------------------------------------------\r\nTypeError                                 Traceback (most recent call last)\r\n/usr/local/lib/python3.4/dist-packages/lmfit/parameter.py in _getval(self)\r\n    546         try:\r\n--> 547             self.value = max(self.min, min(self._val, self.max))\r\n    548         except(TypeError, ValueError):\r\n\r\nTypeError: unorderable types: float() < NoneType()\r\n\r\nDuring handling of the above exception, another exception occurred:\r\n\r\nAttributeError                            Traceback (most recent call last)\r\n<ipython-input-5-b0051757b071> in <module>()\r\n----> 1 p2.add('foo')\r\n\r\n/usr/local/lib/python3.4/dist-packages/lmfit/parameter.py in add(self, name, value, vary, min, max, expr)\r\n    198         else:\r\n    199             self.__setitem__(name, Parameter(value=value, name=name, vary=vary,\r\n--> 200                                              min=min, max=max, expr=expr))\r\n    201 \r\n    202     def add_many(self, *parlist):\r\n\r\n/usr/local/lib/python3.4/dist-packages/lmfit/parameter.py in __setitem__(self, key, par)\r\n     83         par.name = key\r\n     84         par._expr_eval = self._asteval\r\n---> 85         self._asteval.symtable[key] = par.value\r\n     86 \r\n     87     def __add__(self, other):\r\n\r\n/usr/local/lib/python3.4/dist-packages/lmfit/parameter.py in value(self)\r\n    557     def value(self):\r\n    558         \"The numerical value of the Parameter, with bounds applied\"\r\n--> 559         return self._getval()\r\n    560 \r\n    561     @value.setter\r\n\r\n/usr/local/lib/python3.4/dist-packages/lmfit/parameter.py in _getval(self)\r\n    547             self.value = max(self.min, min(self._val, self.max))\r\n    548         except(TypeError, ValueError):\r\n--> 549             self.value = nan\r\n    550         return self._val\r\n    551 \r\n\r\n/usr/local/lib/python3.4/dist-packages/lmfit/parameter.py in value(self, val)\r\n    565         if not hasattr(self, '_expr_eval'):  self._expr_eval = None\r\n    566         if self._expr_eval is not None:\r\n--> 567             self._expr_eval.symtable[self.name] = val\r\n    568 \r\n    569     @property\r\n\r\nAttributeError: 'Parameters' object has no attribute 'symtable'\r\n```\r\n\r\nInterestingly, the old parameters object has ended up in p2._asteval:\r\n```\r\np2._asteval.add('foo')\r\nprint(p2._asteval)\r\n    Parameters([('foo', <Parameter 'foo', -inf, bounds=[-inf:inf]>)])\r\n```\r\nThe error seems to be caused by the definition of `Parameters.__init__()`:\r\n```\r\n    def __init__(self, asteval=None, *args, **kwds):\r\n        super(Parameters, self).__init__(self)\r\n        self._asteval = asteval\r\n\r\n        if asteval is None:\r\n            self._asteval = Interpreter()\r\n        self.update(*args, **kwds)\r\n```\r\nThe keyword argument `asteval=None` is being interpreted as a positional argument, so that when an existing Parameters object is passed to the constructor, it is seen as the `asteval` parameter. This is exactly what the .copy() method does:\r\n```\r\n[/usr/lib/python3.4/collections/__init__.py:211]\r\n\r\n    def copy(self):\r\n        'od.copy() -> a shallow copy of od'\r\n        return self.__class__(self)\r\n```\r\nUnaware of the possible unintended implications, I suggest to replace the method signature with the following in parameters.py:\r\n```\r\ndef __init__(self, *args, asteval=None, **kwds):\r\n```"}}