pydantic : duplicate validator function - python

I used the code below: It shows duplicated validator. Why cannot use both? How do I create an alias in the #validator if I cannot use Field?
from pydantic import BaseModel, validator, Field
import datetime
class MultiSourceInput(BaseModel):
abc : str = Field(..., alias= 'abc_1',description= "xxxxxxxxxxxx.")
xyz : int= Field(..., description= "xxxxxxxx ",ge=0, le=150)
#validator("abc")
def abc(value):
values = float(value)
if value <=141 and value>=0:
return value
else:
0
Here's the traceback:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 37, in MultiSourceInput
File "pydantic/class_validators.py", line 85, in pydantic.class_validators.validator.dec
File "pydantic/class_validators.py", line 144, in pydantic.class_validators._prepare_validator
pydantic.errors.ConfigError: duplicate validator function "__main__.MultiSourceInput.abc"; if this is intended, set `allow_reuse=True`

In my case, this occurred because the validation method was receiving self instead of cls, meaning:
#validator("my_field")
def parse_my_field(self, v):
...
Instead of:
#validator("my_field")
def parse_my_field(cls, v):
...

My issue was caused by errors (seemingly unrelated) earlier in the code. Some knock-on effects caused the duplicate validator function error. When I fixed the preceding errors this went away

Check if there is a validator created with abc method name. You might need to rename the method

Related

TypeError: issubclass() arg 1 must be a class, while I am quite sure arg 1 is a class

Somewhere within my code I have the following line of code.
from inspect import isclass
if isclass(route.handler) and issubclass(route.handler, web.View):
Unfortunately this line of code gives the exception below in my production environment.
TypeError: issubclass() arg 1 must be a class
As far as I know, the Python (3.7.7) compiler will first check the first condition of the if statement and if this evaluates to false, it will not check the second condition. Therefore I must conclude that route.handler must be a class, and therefore the TypeError I am getting should not be occurring. Am I missing something here? Does someone know what might be causing this?
(Unfortunately I am not able to reproduce the error)
edit:
The error originates from the swagger-aiohttp package. Here's the entire traceback:
Traceback (most recent call last):
File "/var/www/app/main.py", line 249, in <module>
run_app(cfg)
File "/var/www/app/main.py", line 225, in run_app
setup_swagger(app, ui_version=SWAGGER_VERSION, swagger_url=SWAGGER_URL)
File "/home/webapp/.venv/lib/python3.7/site-packages/aiohttp_swagger/__init__.py", line 72, in setup_swagger
security_definitions=security_definitions
File "/home/webapp/.venv/lib/python3.7/site-packages/aiohttp_swagger/helpers/builders.py", line 163, in generate_doc_from_each_end_point
end_point_doc = _build_doc_from_func_doc(route)
File "/home/webapp/.venv/lib/python3.7/site-packages/aiohttp_swagger/helpers/builders.py", line 44, in _build_doc_from_func_doc
if isclass(route.handler) and issubclass(route.handler, web.View):
File "/home/webapp/.venv/lib/python3.7/abc.py", line 143, in __subclasscheck__
return _abc_subclasscheck(cls, subclass)
TypeError: issubclass() arg 1 must be a class
edit2:
The route.handler should be an aiohttp class-based view. For example this is how one would create one and build a swagger UI on top of that.
class PingHandler(web.View):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
async def get(request):
"""
---
description: This end-point allow to test that service is up.
tags:
- Health check
produces:
- text/plain
responses:
"200":
description: successful operation. Return "pong" text
"405":
description: invalid HTTP Method
"""
return web.Response(text="pong")
app = web.Application()
app.router.add_route('GET', "/ping", PingHandler)
setup_swagger(app, swagger_url="/api/v1/doc", ui_version=3)
In my current implementation I also have a decorator added to the Handler class.
edit3:
When debugging locally (where it's working fine), the route.handler seems to be a <class 'abc.ABCMeta'>.
I finally discovered the problem. The error is raised whenever a decorator from the wrapt library is used together with a abc.ABCMeta class. This is currently an open issue for the wrapt library. An example is shown below:
import abc
from inspect import isclass
import wrapt
class Base:
pass
class BaseWithMeta(metaclass=abc.ABCMeta):
pass
#wrapt.decorator
def pass_through(wrapped, instance, args, kwargs):
return wrapped(*args, **kwargs)
#pass_through
class B(BaseWithMeta):
pass
#pass_through
class C(Base):
pass
isclass(C)
>>>
True
issubclass(C, Base)
>>>
True
isclass(B)
>>>
True
issubclass(B, BaseWithMeta)
>>>
TypeError: issubclass() arg 1 must be a class

Why can I not read the 'typename' after creating a namedtuple object in Python

This query is further with reference to this query
So, I am trying to execute the following code :
from collections import *
tp = namedtuple('emp', 'eid enames mob')
print(tp)
print(emp)
I can execute print(tp) and the output generated is <class '__main__.emp'>.
But when I try to execute print(emp), It generates the following exception :
Traceback (most recent call last):
File "a.py", line 5, in <module>
print(emp)
NameError: name 'emp' is not defined
What is the reason. The class emp is created. But I can not figure out how to access it directly. Or can I not ?
So basically, I can create instance of tp as tp() but not instances of emp in the same way. Why?
Option 1: Just repeat the type name when assigning to the returned type
tp = emp = namedtuple('emp', 'eid enames mob')
Option 2: Use a declarative style instead of the functional APIs
from typing import NamedTuple
class emp(NamedTuple):
eid: str
enames: str
mob: str

How to get the literal representation of function argument?

I want to get a literal representation of function argument in exception message. Because x could be any object type, so there may be no str and repr defined for this type. Is there way to achieve that ? Thanks
e.g.
def f(x, y)
raise Exception("<x> is not valid")
As Johnrsharpe said in the commends a simple formatting should be fine for your use case.
For example if you have a class and a function.
class Myobj:
pass
def f(x, y):
raise Exception("{!r} is not valid".format(x))
f(Myobj, 1)
You should be able to get the output and a nice traceback
Traceback (most recent call last):
File "42920465.py", line 9, in <module>
f(Myobj, 1)
File "42920465.py", line 6, in f
raise Exception("{!r} is not valid".format(x))
Exception: <class '__main__.Myobj'> is not valid
You can see in the desciption the object that is being called is mentioned.

Splitting Lines in Python in a List?

I'm new-ish to Python and I'm having trouble achieving a result that I want. I'm opening a text file called urldata.txt which contains URLs that I need to break down by scheme, server, and path.
I have retrieved the data from the file:
urls = open("urldata.txt").read()
print(urls)
this returns:
http://www.google.com
https://twitter.com/search?q=%23ASUcis355
https://github.com/asu-cis-355/course-info
I want to break these URLs into 3 pieces each so that when I enter
urls.scheme()
urls.server()
urls.path()
It will return me the scheme of each URL when I enter
urls.scheme()
'http','https','https'
Then it will return the server when I enter
urls.server()
'google.com'
'twitter.com'
'github.com'
Finally, it will return the path when I enter
urls.path()
'/'
'/search?q=%23ASUcis355'
'/asu-cis-355/course-info'
I have defined a class to do this; however, I receive an error saying 'scheme() missing 1 required positional argument: 'self' Below is my class and the def parts to it that I have created.
class urls:
def __init__(self,url):
self.urls=urls
def scheme(self):
return urls.split("://")[0]
def server(self):
return urls.split("/")[2]
def path(self):
return urls.split(".com/")[1]
Any help at all is greatly appreciated!
This exists already. It's called urlparse:
from urllib.parse import urlparse
d = urlparse('https://twitter.com/search?q=%23ASUcis355')
print(d)
Output:
ParseResult(scheme='https', netloc='twitter.com', path='/search', params='', query='q=%23ASUcis355', fragment='')
If you attempt to call a class definition (what urls' is) without creating an instance of this class in Python3 then you get this error
>>> urls.scheme()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: scheme() missing 1 required positional argument: 'self'
>>>
But if you create an instance of urls and then use that instance this works as intended
>>> url_instance = urls("http://www.google.com")
>>> url_instance.scheme()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 5, in scheme
AttributeError: type object 'urls' has no attribute 'split'
Note that this fixes your current error but your code isn't correct as is. I'll leave you to figure out what's happening with this error.
The difference between a class definition (or type) and an instance of the class has some interesting nuance but generally speaking
class Thing:
pass
is a class definition and
thing_instance = Thing()
Is an instance of the class.

Python unittest assertraises error

I had this weird trouble running my unittest in Python:
I used assertRaises, and running the unittest raised the correct exception, but the test still failed. Ok I cannot really explain it, please see the traceback for yourself:
Error
Traceback (most recent call last):
File "/Users/chianti/PycharmProjects/Programming_Project/Part1and4/Part1and4Test.py", line 32, in test_non_alpha_name
self.assertRaises(RestNameContainNonAlphaError, RestaurantName(self.non_alpha_name))
File "/Users/chianti/PycharmProjects/Programming_Project/Part1and4/InputCheck.py", line 29, in __init__
raise RestNameContainNonAlphaError('There are non alphabetic characters that I can not recognize!')
RestNameContainNonAlphaError: There are non alphabetic characters that I can not recognize!
Error
Traceback (most recent call last):
File "/Users/chianti/PycharmProjects/Programming_Project/Part1and4/Part1and4Test.py", line 24, in test_non_string_name
self.assertRaises(InputNotStringError, RestaurantName, self.non_string_name)
File "/Users/chianti/anaconda/lib/python2.7/unittest/case.py", line 473, in assertRaises
callableObj(*args, **kwargs)
File "/Users/chianti/PycharmProjects/Programming_Project/Part1and4/InputCheck.py", line 33, in __init__
raise InputNotStringError('Not String! The input is supposed to be a string type!')
InputNotStringError: Not String! The input is supposed to be a string type!
Why ?????????? Any ideas are appreciated !!! THANK YOU
Here is my unittest:
class RestaurantNameTests(unittest.TestCase):
def setUp(self):
self.non_string_name = 123
self.valid_name = 'Italian rest '
self.non_alpha_name = 'valid ** n'
def tearDown(self):
self.non_string_name = None
self.valid_name = None
self.non_alpha_name = None
def test_non_string_name(self):
with self.assertRaises(InputNotStringError):
RestaurantName(self.non_string_name)
def test_valid_name(self):
self.assertEqual(RestaurantName(self.valid_name).__str__(), 'Italian rest')
def test_non_alpha_name(self):
self.assertRaises(RestNameContainNonAlphaError, RestaurantName(self.non_alpha_name))
If you need to see the definition of RestaurantName, here it is:
class RestaurantName():
def __init__(self, input_contents):
self.name = input_contents
if IsValidString(self.name):
self.no_space_name = self.name.replace(' ', '')
if str.isalpha(self.no_space_name):
pass
else:
raise RestNameContainNonAlphaError('There are non alphabetic characters that I can not recognize!')
else:
raise InputNotStringError('Not String! The input is supposed to be a string type!')
def __repr__(self):
return 'RestaurantName(%s)' % self.name.strip()
def __str__(self):
return self.name.strip()
Thanks again
The traceback doesn't match your description of the problem (nor your code FWIW). The error you get is in test_non_alpha_name() which you didn't post but from your error message looks like:
self.assertRaises(
RestNameContainNonAlphaError,
RestaurantName(self.non_alpha_name)
)
This is not the correct way to use assertRaises(). You must pass ExpectedExceptionClass, callable, *args, **kw to assertRaises, and args and kw will be passed to your callable. IOW you want:
self.assertRaises(
RestNameContainNonAlphaError,
RestaurantName,
self.non_alpha_name
)
The reason is simple: the way you currently call it, the exception is triggered before the call to assertRaises.
As a side note:
your tearDown method is useless
there's already a builtin exception for wrong types, it's named TypeError
there's also a builtin exception for wrong values which is named ValueError

Categories

Resources