Re: Property for dataclass field with default value

2020-06-18 Thread Peter Otten
Ivan Ivanyuk wrote:

> Hello All,
> 
> I have some trouble using @dataclass together with @property decorator
> or property() function.
> 
> From the documentation and PEP is seems that the intended behaviour of
> @dataclass is to be the same as normal __init__() that sets instance
> variables.
> 
> But it seems that when using @property decorator some parts work
> differently when relying on default values. I'm using Pyhton 3.8.3 for
> this.
> 
> Using the code:
> 
> from dataclasses import dataclass
> 
> @dataclass
> class Container:
> x: int = 30
> 
> @property
> def x(self) -> int:
> return self._x
> 
> @x.setter
> def x(self, z: int):
> if z > 1:
> self._x = z
> else:
> raise ValueError
> c= Container(x=10)
> print(c)
> c= Container()
> print(c)
> 
> output is:
> 
> Container(x=10)
> Traceback (most recent call last):
>   File
>   "/Users/ivanivanyuk/Documents/Shared/repos/bitbucket/evbox/g5plus-
automated-testing/dataclass_example.py",
> line 18, in 
> c= Container()
>   File "", line 3, in __init__
>   File
>   "/Users/ivanivanyuk/Documents/Shared/repos/bitbucket/evbox/g5plus-
automated-testing/dataclass_example.py",
> line 13, in x
> if z > 1:
> TypeError: '>' not supported between instances of 'property' and 'int'
> 
> Code with __init__() being inserted that should be roughly the same as
> generated by the @dataclass decorator:
> 
> @dataclass
> class Container:
> x: int = 30
> 
> def __init__(self, x:int = 30):
> self.x = x
> 
> @property
> def x(self) -> int:
> return self._x
> 
> @x.setter
> def x(self, z: int):
> if z > 1:
> self._x = z
> else:
> raise ValueError
> 
> c= Container(x=10)
> print(c)
> c= Container()
> print(c)
> 
> output is:
> Container(x=10)
> Container(x=30)
> 
> As far as I can see, this happens because actual __init__() generated
> by the @dataclass decorator looks like:
> 
> def __init__(self, x:int = ):
> self.x = x
> 
> I came up with a really convoluted way to work around it (just for
> fun, as this clearly defies the idea of dataclasses as a way to
> decrease boilerplate code):
> 
> from dataclasses import dataclass, field
> 
> def set_property():
> Container.x = property(Container.get_x, Container.set_x)
> return 30
> 
> @dataclass
> class Container:
> x: int = field(default_factory=set_property)
> 
> def get_x(self) -> int:
> return self._x
> 
> def set_x(self, z: int):
> if z > 1:
> self._x = z
> else:
> raise ValueError
> 
> c= Container(x=10)
> print(c)
> c= Container()
> print(c)
> 
> output is:
> Container(x=10)
> Container(x=30)
> 
> So, what I'm missing here? Is there some way to use field() or
> decorators to make property just work the same as in non-decorated
> class?

Your class definition is basically

class Container:
x = default_value
x = property_x

i. e. you use the same name twice. A possible workaround might be to define 
the property in a subclass. That way you get distinct namespaces for the 
default value and the property:

@dataclass
class ContainerBase:
x: int = 42

class Container(ContainerBase):
@property
def x(self):
return self._x

@x.setter
def x(self, value):
if value <= 1:
raise ValueError
self._x = value


-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Property for dataclass field with default value

2020-06-18 Thread Ivan Ivanyuk
On Thu, 18 Jun 2020 at 11:26, Peter Otten <[email protected]> wrote:
>
> Ivan Ivanyuk wrote:
>
> > Hello All,
> >
> > I have some trouble using @dataclass together with @property decorator
> > or property() function.
> >
> > From the documentation and PEP is seems that the intended behaviour of
> > @dataclass is to be the same as normal __init__() that sets instance
> > variables.
> >
> > But it seems that when using @property decorator some parts work
> > differently when relying on default values. I'm using Pyhton 3.8.3 for
> > this.
> >
> > Using the code:
> >
> > from dataclasses import dataclass
> >
> > @dataclass
> > class Container:
> > x: int = 30
> >
> > @property
> > def x(self) -> int:
> > return self._x
> >
> > @x.setter
> > def x(self, z: int):
> > if z > 1:
> > self._x = z
> > else:
> > raise ValueError
> > c= Container(x=10)
> > print(c)
> > c= Container()
> > print(c)
> >
> > output is:
> >
> > Container(x=10)
> > Traceback (most recent call last):
> >   File
> >   "/Users/ivanivanyuk/Documents/Shared/repos/bitbucket/evbox/g5plus-
> automated-testing/dataclass_example.py",
> > line 18, in 
> > c= Container()
> >   File "", line 3, in __init__
> >   File
> >   "/Users/ivanivanyuk/Documents/Shared/repos/bitbucket/evbox/g5plus-
> automated-testing/dataclass_example.py",
> > line 13, in x
> > if z > 1:
> > TypeError: '>' not supported between instances of 'property' and 'int'
> >
> > Code with __init__() being inserted that should be roughly the same as
> > generated by the @dataclass decorator:
> >
> > @dataclass
> > class Container:
> > x: int = 30
> >
> > def __init__(self, x:int = 30):
> > self.x = x
> >
> > @property
> > def x(self) -> int:
> > return self._x
> >
> > @x.setter
> > def x(self, z: int):
> > if z > 1:
> > self._x = z
> > else:
> > raise ValueError
> >
> > c= Container(x=10)
> > print(c)
> > c= Container()
> > print(c)
> >
> > output is:
> > Container(x=10)
> > Container(x=30)
> >
> > As far as I can see, this happens because actual __init__() generated
> > by the @dataclass decorator looks like:
> >
> > def __init__(self, x:int = ):
> > self.x = x
> >
> > I came up with a really convoluted way to work around it (just for
> > fun, as this clearly defies the idea of dataclasses as a way to
> > decrease boilerplate code):
> >
> > from dataclasses import dataclass, field
> >
> > def set_property():
> > Container.x = property(Container.get_x, Container.set_x)
> > return 30
> >
> > @dataclass
> > class Container:
> > x: int = field(default_factory=set_property)
> >
> > def get_x(self) -> int:
> > return self._x
> >
> > def set_x(self, z: int):
> > if z > 1:
> > self._x = z
> > else:
> > raise ValueError
> >
> > c= Container(x=10)
> > print(c)
> > c= Container()
> > print(c)
> >
> > output is:
> > Container(x=10)
> > Container(x=30)
> >
> > So, what I'm missing here? Is there some way to use field() or
> > decorators to make property just work the same as in non-decorated
> > class?
>
> Your class definition is basically
>
> class Container:
> x = default_value
> x = property_x
>
> i. e. you use the same name twice. A possible workaround might be to define
> the property in a subclass. That way you get distinct namespaces for the
> default value and the property:
>
> @dataclass
> class ContainerBase:
> x: int = 42
>
> class Container(ContainerBase):
> @property
> def x(self):
> return self._x
>
> @x.setter
> def x(self, value):
> if value <= 1:
> raise ValueError
> self._x = value
>
>
> --
> https://mail.python.org/mailman/listinfo/python-list

Didn't think about it in such a way! But now that it was pointed, I
see no obvious way to resolve this in dataclass decorator given the
way it's implemented now. And while adding another class looks easy it
somewhat detracts from the dataclasses' purpose of removing
boilerplate.

Does it seems like a good idea to ask for documenting that behaviour
in dataclasses documentation or it's not popular enough use case?

Regards,
Ivan
-- 
https://mail.python.org/mailman/listinfo/python-list


problem at the time of using editor

2020-06-18 Thread Sourav Kundu
when I am using the editor to write a long program and trying to run it the
python command line showing it syntax error
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: problem at the time of using editor

2020-06-18 Thread Mats Wichmann
On 6/18/20 4:20 AM, Sourav Kundu wrote:
> when I am using the editor to write a long program and trying to run it the
> python command line showing it syntax error
> 


That almost certainly means there is a syntax error in your code.

Please provide some details - like the actual error text.

Note: for certain syntax errors, the error began previously, and the
line where the error is reported is the first time you can be sure there
actually was an error.  Consider:

print("This is a problem"

x = 12


The closing paren on the function call print() was omitted.  This will
give this result:

x = 12
^
SyntaxError: invalid syntax



Clearly, "x = 12" does not contain a syntax error.  But paired parens
are allowed to span multiple lines, so Python keeps looking for the
closing one, and only when the syntax can't possibly be right any longer
does it give up and report an error.

A good Python-aware editor/IDE will do work to help show you where the
actual problem is.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: problem at the time of using editor

2020-06-18 Thread Terry Reedy

On 6/18/2020 6:20 AM, Sourav Kundu wrote:

when I am using the editor to write a long program and trying to run it the
python command line showing it syntax error


That happens to all of us, even for short programs.



--
Terry Jan Reedy

--
https://mail.python.org/mailman/listinfo/python-list


Re: problem at the time of using editor

2020-06-18 Thread Grant Edwards
On 2020-06-18, Sourav Kundu  wrote:

> when I am using the editor to write a long program and trying to run
> it the python command line showing it syntax error

Fix the syntax error using the editor, then run the program again.



-- 
https://mail.python.org/mailman/listinfo/python-list


Re: problem at the time of using editor

2020-06-18 Thread DL Neil via Python-list

On 18/06/20 10:20 PM, Sourav Kundu wrote:

when I am using the editor to write a long program and trying to run it the
python command line showing it syntax error


Of possible interest:-
Why SuperHELP for Python? | pssst
Search domain 
p-s.co.nz/wordpress/why-superhelp-for-python/p-s.co.nz/wordpress/why-superhelp-for-python/
SuperHELP reads a snippet of Python and provides advice, warnings, and 
basic information based on what it finds. For example, it might notice a 
function docstring is missing and show a template for adding one. Or 
identify the use of a named tuple and explain how to add docstrings to 
individual fields or the named tuple as a whole.



As mentioned, at this stage in your learning process, you may find it 
helpful to use a basic Python editor which has a built-in terminal console.

--
Regards =dn
--
https://mail.python.org/mailman/listinfo/python-list