Repository: pydantic/pydantic

Issue:
npt.NDArray with `arbitrary_types_allowed=True` raises `pydantic.errors.PydanticSchemaGenerationError`
### Initial Checks

- [X] I confirm that I'm using Pydantic V2 installed directly from the `main` branch, or equivalent

### Description

I'm having the following `BaseModel` that was previously working with `v1`:

```python
CustomNDArrayType: TypeAlias = Union[npt.NDArray, List[npt.NDArray]]

class SomeModel(BaseModel):
    data: Optional[CustomNDArrayType]

    model_config = ConfigDict(
        arbitrary_types_allowed=True,
        extra="forbid",
        validate_assignment=True,
    )
```

but in `v2` raises the following:

```
pydantic.errors.PydanticSchemaGenerationError: Unable to generate pydantic-core schema for numpy.ndarray[typing.Any, numpy.dtype[+ScalarType]]. Set `arbitrary_types_allowed=True` in the model_config to ignore this error or implement `__get_pydantic_core_schema__` on your type to fully support it.

If you got this error by calling handler(<some type>) within `__get_pydantic_core_schema__` then you likely need to call `handler.generate_schema(<some type>)` since we do not call `__get_pydantic_core_schema__` on `<some type>` otherwise to avoid infinite recursion.
For further information visit https://errors.pydantic.dev/2.0.2/u/schema-for-unknown-type
```

Strange thing is, that setting `arbitrary_types_allowed=True` doesn't ignore the error at all. Any ideas how to deal with this?

### Example Code

```Python
CustomNDArrayType: TypeAlias = Union[npt.NDArray, List[npt.NDArray]]

class SomeModel(BaseModel):
    data: Optional[CustomNDArrayType]

    model_config = ConfigDict(
        arbitrary_types_allowed=True,
        extra="forbid",
        validate_assignment=True,
    )
```


### Python, Pydantic & OS Version

```Text
pydantic version: 2.0.2
        pydantic-core version: 2.1.2 release build profile
                 install path: /Users/panagiotisvardanis/miniforge3/envs/mac-tensorflow/lib/python3.8/site-packages/pydantic
               python version: 3.8.16 | packaged by conda-forge | (default, Feb  1 2023, 16:01:13)  [Clang 14.0.6 ]
                     platform: macOS-13.4.1-arm64-arm-64bit
     optional deps. installed: ['typing-extensions']
```


Selected Assignee: @adriangb


Discussion:
If the following is a self-contained version of your example (yours is missing imports and such):

```py
from typing import List, Optional, TypeAlias, Union

import numpy.typing as npt

from pydantic import BaseModel, ConfigDict

CustomNDArrayType: TypeAlias = Union[npt.NDArray, List[npt.NDArray]]

class SomeModel(BaseModel):
    data: Optional[CustomNDArrayType]

    model_config = ConfigDict(
        arbitrary_types_allowed=True,
    )
```

Then I don't get any error on `main` or `2.0.2`.
I've tested your provided example and didn't get any errors.

Are you sure about the installed version of Pydantic?
That is super weird. Are you on the right Python version (i.e. `3.8.16`)?
@adriangb I've the exact same imports as you with one exception:
```python
from typing_extensions import TypeAlias
```
Ok, I can confirm on `3.8.16` I get the error. 
What about 3.8.17?
> What about 3.8.17?

I get the same error
We check that the type annotation is a type: https://github.com/pydantic/pydantic/blob/8466f78da6b42d404fa721be6b3f57061b99cb30/pydantic/_internal/_generate_schema.py#L579C2-L579C2

And on < 3.9 that numpy type is not in fact a type: https://github.com/numpy/numpy/blob/1ed0bfd3a42bf0c8a0060684645ba97941778006/numpy/_typing/_generic_alias.py#L245.

I'll make a PR with a better error message, but I'd also suggest submitting a PR to numpy to try to make that pass `isinstance(..., type)`

Resolving patch:
diff --git a/pydantic/_internal/_generate_schema.py b/pydantic/_internal/_generate_schema.py
--- a/pydantic/_internal/_generate_schema.py
+++ b/pydantic/_internal/_generate_schema.py
@@ -16,6 +16,7 @@
 from operator import attrgetter
 from types import FunctionType, LambdaType, MethodType
 from typing import TYPE_CHECKING, Any, Callable, Dict, ForwardRef, Iterable, Iterator, Mapping, TypeVar, Union, cast
+from warnings import warn
 
 from pydantic_core import CoreSchema, PydanticUndefined, core_schema
 from typing_extensions import Annotated, Final, Literal, TypeAliasType, TypedDict, get_args, get_origin, is_typeddict
@@ -576,7 +577,16 @@ def _generate_schema(self, obj: Any) -> core_schema.CoreSchema:  # noqa: C901
             return self._arbitrary_type_schema(obj, origin)
 
     def _arbitrary_type_schema(self, obj: Any, type_: Any) -> CoreSchema:
-        if self.arbitrary_types and isinstance(type_, type):
+        if self.arbitrary_types:
+            if not isinstance(type_, type):
+                warn(
+                    f'{obj!r} is not a Python type (it may be an instance of an object),'
+                    ' Pydantic will allow any object with no validation since we cannot even'
+                    ' enforce that the input is an instance of the given type.'
+                    ' To get rid of this error wrap the type with `pydantic.SkipValidation`.',
+                    UserWarning,
+                )
+                return core_schema.any_schema()
             return core_schema.is_instance_schema(type_)
         else:
             raise PydanticSchemaGenerationError(


Test patch:
diff --git a/tests/test_main.py b/tests/test_main.py
--- a/tests/test_main.py
+++ b/tests/test_main.py
@@ -2679,3 +2679,19 @@ def __delattr__(self, item):
     assert test_calls == []
     del m.test
     assert test_calls == ['success']
+
+
+def test_arbitrary_types_not_a_type() -> None:
+    """https://github.com/pydantic/pydantic/issues/6477"""
+
+    class Foo:
+        pass
+
+    class Bar:
+        pass
+
+    with pytest.warns(UserWarning, match='is not a Python type'):
+        ta = TypeAdapter(Foo(), config=ConfigDict(arbitrary_types_allowed=True))
+
+    bar = Bar()
+    assert ta.validate_python(bar) is bar