eshangj/stackoverflow_q_and_a_sample huggingface dataset:
Question: using Python 3.11 and Mypy 1.7. I am trying to properly type hint a method that takes a class as parameter, with a default value, and returns an instance of that class. The class passed as parameter must be a subclass of a specific base class. How should I do that? I tried to use a type variable with upper bound like this: from typing import TypeVar class BaseClass: pass class ImplClass(BaseClass): pass T = TypeVar("T", bound=BaseClass) def method(return_type: type[T] = ImplClass) -> T: return return_type()  But mypy complains with this message: scratch_10.py: note: In function "method": scratch_10.py:9:35: error: Incompatible default for argument "return_type" (default has type "type[ImplClass]", argument has type "type[T]") [assignment] def method(return_type: type[T] = ImplClass) -> T: ^~~~~~~~~  But as far as I understand this error is wrong since the default ImplClass is a subclass of BaseClass which is the upper bound of T, so it respects the type constraints. Note that removing the upperbound does not help: T = TypeVar("T") #no upperbound this time def method(return_type: type[T] = ImplClass) -> T: return return_type()  (same error message) But removing the default value and explicitly calling method with ImplClass as parameter works without any complaints: def method(return_type: type[T]) -> T: # no default value this time return return_type() method(ImplClass)   Success, no issues found in 1 source file  So I don't understand why mypy complains about the default value but not about the actual parameter with the exact same value. Is that a false positive in mypy, or am I doing something wrong?

Answer: This is a known limitation of mypy. See the GitHub issues #8739 - mypy reporting error with default value for typevar and #3737 - Unable to specify a default value for a generic parameter for its discussion. You can make this work using typing.overload to separately annotate the case where the default value is used: from typing import TypeVar, overload class BaseClass: pass class ImplClass(BaseClass): pass T = TypeVar("T", bound=BaseClass) @overload def method() -> ImplClass: ... @overload def method(return_type: type[T]) -> T: ... def method(return_type=ImplClass): return return_type() reveal_type(method()) # ok: ImplClass reveal_type(method(BaseClass)) # ok: BaseClass reveal_type(method(ImplClass)) # ok: ImplClass # reveal_type(method(int)) # error  This passes type checking with mypy (Python 3.12, v1.7.1), and outputs main.py:23: note: Revealed type is "__main__.ImplClass" main.py:24: note: Revealed type is "__main__.BaseClass" main.py:25: note: Revealed type is "__main__.ImplClass" Success: no issues found in 1 source file  Try it yourself online.
Question: I have two multi-level column dataframes: data = { 'A': { 'X': {'Value1': 2, 'Value2': 1}, 'Y': {'Value1': 2, 'Value2': 3} }, 'B': { 'X': {'Value1': 10, 'Value2': 11}, 'Y': {'Value1': 10, 'Value2': 11} } } df = pd.DataFrame(data)  Which looks like this... Group A B Subgroup X Y X Y Metric Value1 Value2 Value1 Value2 Value1 Value2 Value1 Value2 2023-01-01 2 1 2 3 10 11 10 11 2023-01-02 2 1 2 3 10 11 10 11 2023-01-03 2 1 2 3 10 11 10 11 2023-01-04 2 1 2 3 10 11 10 11 2023-01-05 2 1 2 3 10 11 10 11  df2: data = { 'A': {'Value1': [3, 3, 1, 3, 3], 'Value2': [5, 2, 2, 2, 2]}, 'B': {'Value1': [3, 4, 7, 3, 3], 'Value2': [2, 2, 7, 2, 2]} } df_2 = pd.DataFrame(data, index=pd.to_datetime(['2023-01-01', '2023-01-02', '2023-01-03', '2023-01-04', '2023-01-05'])) # Convert to constructor df2 = df_2.unstack().unstack()  Which looks like this... Group A B Metric Value1 Value2 Value1 Value2 2023-01-01 3 5 3 2 2023-01-02 3 2 4 2 2023-01-03 1 2 7 7 2023-01-04 3 2 3 2 2023-01-05 3 2 3 2  and would like to add df2 to df1, but for each combination of Group and Metric, add across each Subgroup that match to look like this... Group A B Subgroup X Y X Y Metric Value1 Value2 Value1 Value2 Value1 Value2 Value1 Value2 2023-01-01 5 6 5 5 13 13 13 13 2023-01-02 5 3 6 5 14 15 14 13 2023-01-03 3 3 9 10 17 18 17 18 2023-01-04 5 3 5 5 13 14 13 13 2023-01-05 5 3 5 5 13 14 13 13  Any help would be appreciated. Some ideas like merging but I think i lose the middle subgroup level above but could have been doing it incorrectly.

Answer: I think the easiest might be to droplevel on df1, then add, finally recreate the DataFrame: pd.DataFrame(df1.droplevel('Subgroup', axis=1).add(df2).to_numpy(), index=df1.index, columns=df1.columns)  Alternatively, reindex df2 and convert to numpy: df1 += df2.reindex_like(df1.droplevel('Subgroup', axis=1)).to_numpy()  Output: Group A B Subgroup X Y X Y Metric Value1 Value2 Value1 Value2 Value1 Value2 Value1 Value2 2023-01-01 5 5 6 8 13 13 13 13 2023-01-02 5 5 3 5 14 14 13 13 2023-01-03 3 3 3 5 17 17 18 18 2023-01-04 5 5 3 5 13 13 13 13 2023-01-05 5 5 3 5 13 13 13 13
Question: At this code, an object of Foo() class is still alive after creating new one. I guess that reason is in the circular references on appending object's list property. So, how to let garbage collector free old object, withot manual calling gc.collect()? import gc class Foo(): def __init__(self): self.functions = [] print('CREATE', self) def some_func(self): for i in range(3): self.functions.append(self.print_func) print(self.functions) def print_func(self): print('I\'m a test') def __del__(self): print('DELETE', self) foo = Foo() foo.some_func() foo = Foo() # gc.collect() input = input()  input() at the end is just for keeping program running. Real project with this problem contains while loop, so keeping old unused objects may cause a memory leak. Now, output: CREATE <__main__.Foo object at 0x000002747001D850> [<bound method Foo.print_func of <__main__.Foo object at 0x000002747001D850>>, <bound method Foo.print_func of <__main__.Foo object at 0x000002747001D850>>, <bound method Foo.print_func of <__main__.Foo object at 0x000002747001D850>>] CREATE <__main__.Foo object at 0x000002746FD0BB90>  Output with calling gc.collect(): CREATE <__main__.Foo object at 0x0000021E45F0D8E0> [<bound method Foo.print_func of <__main__.Foo object at 0x0000021E45F0D8E0>>, <bound method Foo.print_func of <__main__.Foo object at 0x0000021E45F0D8E0>>, <bound method Foo.print_func of <__main__.Foo object at 0x0000021E45F0D8E0>>] CREATE <__main__.Foo object at 0x0000021E45CDBB90> DELETE <__main__.Foo object at 0x0000021E45F0D8E0>  It's a result, that I want to get, but without using gc

Answer: You can use weakref.WeakMethod to avoid creating strong references to the self.print_func method in the list attribute. Note that to call a weakly referenced method you would have to dereference it first by calling the weakref before calling the actual method: from weakref import WeakMethod class Foo(): def __init__(self): self.functions = [] print('CREATE', self) def some_func(self): for i in range(3): self.functions.append(WeakMethod(self.print_func)) print(self.functions) def print_func(self): print('I\'m a test') def __del__(self): print('DELETE', self) foo = Foo() foo.some_func() foo.functions[0]()() foo = Foo() input()  This outputs: CREATE <__main__.Foo object at 0x0000018F0B397150> [<weakref at 0x0000018F0B18E0A0; to 'Foo' at 0x0000018F0B397150>, <weakref at 0x0000018F0B18E1F0; to 'Foo' at 0x0000018F0B397150>, <weakref at 0x0000018F0B18E490; to 'Foo' at 0x0000018F0B397150>] I'm a test CREATE <__main__.Foo object at 0x0000018F0B397190> DELETE <__main__.Foo object at 0x0000018F0B397150>  Demo: https://replit.com/@blhsing1/LightheartedTurquoiseChord
Question: I always put on top of my Pytorch's notebooks a cell like this: device = ( "cuda" if torch.cuda.is_available() else "mps" if torch.backends.mps.is_available() else "cpu" ) torch.set_default_device(device)  In this convenient way, I can use the GPU, if the system has one, MPS on a Mac, or the cpu on a vanilla system. EDIT: Please note that, due to torch.set_default_device(device), any tensor is created, by default, on the device, e.g.:  Now, I'm trying to use a Pytorch generator: g = torch.Generator(device=device).manual_seed(1) and then: A = torch.randn((3, 2), generator=g) No problem whatsoever on my Macbook (where the device is MPS) or on systems with cpu only. But on my Cuda-enabled desktop, I get: RuntimeError: Expected a 'cpu' device type for generator but found 'cuda' Any solution? If I just abstain from specifying the device for the generator, it will use the cpu, but then the tensor A will be created on the CPU too...

Answer: When defining the tensor "A", it is defaulting to creating the tensor on the CPU. This results in an error, because the generator you are passing in is on the CUDA device. You can solve this by passing in the "device" parameter into torch.randn() as follows: device = ("cuda" if torch.cuda.is_available() else "mps" if torch.backends.mps.is_available() else "cpu") g = torch.Generator(device=device).manual_seed(1) A = torch.randn((3, 2), device=device, generator=g)  Edit: Just noticed that you specified set_default_device() in your starting block. While this works for tensors created with torch.Tensor or similar, it doesn't work for PyTorch factory functions that return a tensor (e.g. torch.randn()). Here's the documentation to support this: https://pytorch.org/docs/stable/generated/torch.set_default_device.html.
Question: I am confused by the type rules for numba dicts. Here is an MWE that works: import numpy as np import numba as nb @nb.njit def foo(a, b, c): d = {} d[(1,2,3)] = a return d a = np.array([1, 2]) b = np.array([3, 4]) t = foo(a, b, c)  But if I change the definition of foo as follows this fails:  @nb.njit def foo(a, b, c): d = {} d[(1,2,3)] = np.array(a) return d  TypingError: Failed in nopython mode pipeline (step: nopython frontend) No implementation of function Function(<built-in function array>) found for signature: >>> array(array(int64, 1d, C)) There are 2 candidate implementations: - Of which 2 did not match due to: Overload in function 'impl_np_array': File: numba/np/arrayobj.py: Line 5384. With argument(s): '(array(int64, 1d, C))': Rejected as the implementation raised a specific error: TypingError: Failed in nopython mode pipeline (step: nopython frontend) No implementation of function Function(<intrinsic np_array>) found for signature: >>> np_array(array(int64, 1d, C), none) There are 2 candidate implementations: - Of which 2 did not match due to: Intrinsic in function 'np_array': File: numba/np/arrayobj.py: Line 5358. With argument(s): '(array(int64, 1d, C), none)': Rejected as the implementation raised a specific error: TypingError: array(int64, 1d, C) not allowed in a homogeneous sequence raised from /home/raph/python/mypython3.10/lib/python3.10/site-packages/numba/core/typing/npydecl.py:482 During: resolving callee type: Function(<intrinsic np_array>) During: typing of call at /home/raph/python/mypython3.10/lib/python3.10/site-packages/numba/np/arrayobj.py (5395) File "../../python/mypython3.10/lib/python3.10/site-packages/numba/np/arrayobj.py", line 5395: def impl(object, dtype=None): return np_array(object, dtype) ^ raised from /home/raph/python/mypython3.10/lib/python3.10/site-packages/numba/core/typeinfer.py:1086 During: resolving callee type: Function(<built-in function array>) During: typing of call at <ipython-input-99-e05437a34ab9> (4) File "<ipython-input-99-e05437a34ab9>", line 4: def foo(a, b, c): <source elided> d = {} d[(1,2,3)] = np.array(a) ^  Why is this?

Answer: This doesn't have anything with how numba handles dictionaries. This piece of code fails with the same error: @nb.njit def foo2(a, b, c): x = np.array(a) return x  When you look at the error message you see that numba doesn't know how to initialize np.array from other np.array: No implementation of function Function(<built-in function array>) found for signature: >>> array(array(int64, 1d, C))  If you change the code to: @nb.njit def foo2(a, b, c): x = np.array([*a]) return x  the compilation succeeds.
Question: This is kind of a hacky Python question. Consider the following Python code: def controlled_exec(code): x = 0 def increment_x(): nonlocal x x += 1 globals = {"__builtins__": {}} # remove every global (including all python builtins) locals = {"increment_x": increment_x} # expose only the increment function exec(code, globals, locals) return x  I expect this function to provide a controlled code API, which simply counts the number of increment_x() calls. I tried it and I get the correct behavior. # returns 2 controlled_exec("""\ increment_x() increment_x() """)  I assume this way of doing is not secure, but I wonder out of curiosity. Can I set x to an arbitrary value (say negative) by executing code via controlled_exec(...) ? How would I do that?

Answer: Yes, x can be set to an arbitrary value by code executed by controlled_exec. Consider the following demo: def controlled_exec(code): x = 0 def increment_x(): nonlocal x x += 1 print(f"{x=}") globals = {"__builtins__": {}} # remove every global (including all python builtins) locals = {"increment_x": increment_x} # expose only the increment function exec(code, globals, locals) return x controlled_exec("""\ increment_x() increment_x.__closure__[0].cell_contents = -100 increment_x() """)  This outputs x=1 x=-99  This is really no way to "secure" exec. No matter what you do, at the end of the day you're executing arbitrary Python code, which is just as free to access and modify the state of the Python interpreter as the code that you write. To highlight just how difficult it would be meaningfully secure exec, note that despite your attempt to hide builtins from the executed code, an attacker can still access any builtin via increment_x.__globals__['__builtins__']  This is just one of dozens of tricks that someone trying to exploit this function could use. The fact that we can modify the variable x is really a tame example. There's literally nothing stopping the code passed to controlled_exec from doing more disastrous things, like wiping your hard drive or downloading malware.
Question: This is my dataframe: import pandas as pd df = pd.DataFrame( { 'a': [100, 1123, 123, 100, 1, 0, 1], 'b': [1000, 11123, 1123, 0, 55, 0, 1], 'c': ['a', 'b', 'c', 'd', 'e', 'f', 'g'], } )  And this is the output that I want. I want to create column x:  a b c x 0 100 1000 a NaN 1 1123 11123 b NaN 2 123 1123 c NaN 3 100 0 d NaN 4 1 55 e e 5 0 0 f NaN 6 1 1 g NaN  By using a mask: mask = ( (df.a > df.b) )  First of all I need to find the first occurrence of this mask which in my example is row number 3. Then I want to move one row below it and use the value in column c to create column x. So in my example, the first occurrence of mask is row 3. One row after it is row 4. That is why e is selected for column x. Note that in row 4 which is one row after the mask, no condition is needed. For example for row 4, It is NOT necessary that df.a > df.b. This is what I have tried: df.loc[mask.cumsum().eq(1) & mask, 'x'] = df.c.shift(-1)  I provide some additional dfs for convenience to test whether the code works in other examples. For instance what if there are no cases that meet the conditions of mask. In that case I just want a column of NaN for x. df = pd.DataFrame({'a': [1000, 11230, 12300, 10000, 1000, 10000, 100000], 'b': [1000, 11123, 1123, 0, 55, 0, 1], 'c': ['a', 'b', 'c', 'd', 'e', 'f', 'g']}) df = pd.DataFrame({'a': [1, 1, 1, -1, -1, -1, -1], 'b': [1000, 11123, 1123, 0, 55, 0, 1], 'c': ['a', 'b', 'c', 'd', 'e', 'f', 'g']}) df = pd.DataFrame({'a': [-1, -1, -1, -1, -1, -1, 100000], 'b': [1000, 11123, 1123, 0, 55, 0, 1], 'c': ['a', 'b', 'c', 'd', 'e', 'f', 'g']}) 

Answer: You can generate a mask that indicates one location past where the first value of a is greater than b: mask = (df.a > df.b).shift(fill_value=False) mask = mask & ~mask.cumsum().shift().astype(bool)  You can then use that mask to set the value of x equal to c: df.loc[mask, 'x'] = df['c']  Output for each of your dfs:  a b c x 0 100 1000 a NaN 1 1123 11123 b NaN 2 123 1123 c NaN 3 100 0 d NaN 4 1 55 e e 5 0 0 f NaN 6 1 1 g NaN a b c x 0 1000 1000 a NaN 1 11230 11123 b NaN 2 12300 1123 c c 3 10000 0 d NaN 4 1000 55 e NaN 5 10000 0 f NaN 6 100000 1 g NaN a b c x 0 1 1000 a NaN 1 1 11123 b NaN 2 1 1123 c NaN 3 -1 0 d NaN 4 -1 55 e NaN 5 -1 0 f NaN 6 -1 1 g NaN a b c x 0 -1 1000 a NaN 1 -1 11123 b NaN 2 -1 1123 c NaN 3 -1 0 d NaN 4 -1 55 e NaN 5 -1 0 f NaN 6 100000 1 g NaN  More generically, you can use cummax and shift by N to select the next N values: N = 3 mask = (df.a > df.b).shift(fill_value=False).cummax() mask = mask & ~mask.cumsum().shift(N, fill_value=0).astype(bool)
Question: When a FastAPI endpoint expects a Pydantic model and one is passed with a string it works as expected unless that string contains unicode characters. First I create an example application for FastAPI with an example model. serv.py from pydantic import BaseModel class exClass(BaseModel): id: int = Field(example=1) text: str = Field(example="Text example") app = FastAPI(debug=True) @app.post("/example") async def receive_pyd(ex: exClass): print(ex) return True if __name__ == "__main__": import uvicorn uvicorn.run(app, host="127.0.0.1", port=8000)  The client that shows the error in question client.py from pydantic import BaseModel, Field import requests class exClass(BaseModel): id: int = Field(example=1) text: str = Field(example="Text example") ex1 = exClass(id=1, text="working example") ex2 = exClass(id=2, text="this’ will fail") ex3 = exClass(id=3, text="🤗 <- also non-working") r = requests.post(f"http://127.0.0.1:8000/example", data=ex1.model_dump_json()) print(r.text) r = requests.post(f"http://127.0.0.1:8000/example", data=ex2.model_dump_json()) print(r.text) r = requests.post(f"http://127.0.0.1:8000/example", data=ex3.model_dump_json()) print(r.text)  Output: true Invalid HTTP request received. Invalid HTTP request received.  When text contains unicode characters the result is a 422 Unprocessable Entity. I have tried ex.dict(), model_dump(), and using json instead of data in the requests call. Enabling debugging in FastAPI/starlette bubbles up that the Invalid HTTP request is a JSON decode error.

Answer: This is not a problem of Pydantic and FastAPI. You should encode you request data like it's shown below: r = requests.post( f"http://127.0.0.1:8000/example", data=ex1.model_dump_json().encode('utf-8') ) print(r.text) r = requests.post( f"http://127.0.0.1:8000/example", data=ex2.model_dump_json().encode('utf-8') ) print(r.text) r = requests.post( f"http://127.0.0.1:8000/example", data=ex3.model_dump_json().encode('utf-8') ) print(r.text)
Question: I have been recently finding a popup that tells me some operation level options override the global server options: As per image:  I do not understand whether this is a bug in my application or anything but normal. I would not like to show the user that message. EDIT: This is my main.py file: from fastapi import FastAPI,Depends from ml.model_recommendation import predict_intention from ml.training_ml import create_ml import crud,models,schemas from db import SessionLocal,engine from sqlalchemy.orm import Session from typing import Optional from enum import Enum import numpy as np app = FastAPI(title="ML prediction",description="API to serve data used for prediction of intended remediation date (IRD)") class Tags(Enum): ITEMS = "Retrieve ITSO and Software Versions" DELETE = "Delete Data" INSERT = "Get IRD predictions" DOWNLOAD = "Download Data" @app.on_event("startup") def on_startup(): models.Base.metadata.create_all(bind=engine) # Dependency def get_db(): db = SessionLocal() try: yield db finally: db.close() @app.get( "/service_owners/", response_model=list[schemas.Evergreen], tags=[Tags.ITEMS] ) def read_owners(service_owner: str ,software_product_version_name: Optional[str] = None,db: Session = Depends(get_db),skip: int = 0, limit: int = 100): owners = crud.get_service_owners(db,service_owner=service_owner,software_product_version_name=software_product_version_name,skip=skip,limit=limit) return owners  This is my crud.py function: import models from sqlalchemy.orm import Session from sqlalchemy import select from typing import Optional def get_service_owners(db: Session, service_owner: str,software_product_version_name: Optional[str] = None,skip: int = 0, limit: int = 100): if software_product_version_name: stmt = (select(models.Evergreen.service_owner,models.Evergreen.software_product_version_name) .where(models.Evergreen.service_owner.ilike(f'%{service_owner}%')) .where(models.Evergreen.software_product_version_name.ilike(f'%{software_product_version_name}%')) ).distinct().offset(skip).limit(limit) return db.execute(stmt).all() stmt = select(models.Evergreen.service_owner,models.Evergreen.software_product_version_name).where(models.Evergreen.service_owner.ilike(f'%{service_owner}%')).distinct().offset(skip).limit(limit) return db.execute(stmt).all()  And this my schema.py for validation: from typing import Optional from pydantic import BaseModel from typing_extensions import TypedDict class Evergreen(BaseModel): service_owner: Optional[str] software_product_version_name: Optional[str] class Config: from_attributes = True class Items(TypedDict): service_owner: str software_product_version_name: str class Pred(TypedDict): service_owner: str software_product_version_name: str future_expectation: int 

Answer: This option seem to appear for OAS 3.1 documents. This must be a bug in swagger-ui. Although servers are not overridden on operation level, swagger-ui defaults to '/' and always displays the override.
Question: In ctransformers library, I can only load around a dozen supported models. How can I run local inference on CPU (not just on GPU) from any open-source LLM quantized in the GGUF format (e.g. Llama 3, Mistral, Zephyr, i.e. ones unsupported in ctransformers)?

Answer: llama-cpp-python is my personal choice, because it is easy to use and it is usually one of the first to support quantized versions of new models. To install it for CPU, just run pip install llama-cpp-python. Compiling for GPU is a little more involved, so I'll refrain from posting those instructions here since you asked specifically about CPU inference. I also recommend installing huggingface_hub (pip install huggingface_hub) to easily download models. Once you have both llama-cpp-python and huggingface_hub installed, you can download and use a model (e.g. mixtral-8x7b-instruct-v0.1-gguf) like so: ## Imports from huggingface_hub import hf_hub_download from llama_cpp import Llama ## Download the GGUF model model_name = "TheBloke/Mixtral-8x7B-Instruct-v0.1-GGUF" model_file = "mixtral-8x7b-instruct-v0.1.Q4_K_M.gguf" # this is the specific model file we'll use in this example. It's a 4-bit quant, but other levels of quantization are available in the model repo if preferred model_path = hf_hub_download(model_name, filename=model_file) ## Instantiate model from downloaded file llm = Llama( model_path=model_path, n_ctx=16000, # Context length to use n_threads=32, # Number of CPU threads to use n_gpu_layers=0 # Number of model layers to offload to GPU ) ## Generation kwargs generation_kwargs = { "max_tokens":20000, "stop":["
"], "echo":False, # Echo the prompt in the output "top_k":1 # This is essentially greedy decoding, since the model will always return the highest-probability token. Set this value > 1 for sampling decoding } ## Run inference prompt = "The meaning of life is " res = llm(prompt, **generation_kwargs) # Res is a dictionary ## Unpack and the generated text from the LLM response dictionary and print it print(res["choices"][0]["text"]) # res is short for result  Keep in mind that mixtral is a fairly large model for most laptops and requires ~25+ GB RAM, so if you need a smaller model, try using one like llama-13b-chat-gguf (model_name="TheBloke/Llama-2-13B-chat-GGUF"; model_file="llama-2-13b-chat.Q4_K_M.gguf") or mistral-7b-openorca-gguf (model_name="TheBloke/Mistral-7B-OpenOrca-GGUF"; model_file="mistral-7b-openorca.Q4_K_M.gguf").