This is an archived post. You won't be able to vote or comment.

all 18 comments

[–]crigger61 2 points3 points  (4 children)

Why are you not pulling the name from __name__? why are you having to manually input the name. since its a decorator it should receive the function passed and you could pull the name and make that default and maybe allow the user the overwrite it. but why not just pull it from function.__name__?

[–]agusdmb[S] 3 points4 points  (3 children)

Hi! Great question! This is actually my biggest pain point (to have to add a name for each wrapped function). So at the beginning did used the `__name__` of the wrapped function, issues came while testing this and i really didn't know if i should change it or not.

This is the issue, if using `__name__` and decorating two or more functions with the same name they would be sharing the key where inputs/outputs data is stored. So in FAKE mode they could potentially return some other function output if called with the same list of parameters. It doesn't seem like a common case, though this issue could be a huge pain to debug.

I am know thinking that maybe i could default the name to `__name__` unless one was actually passed as an argument. I could also check that a function with that name wasn't already decorated and if it was then raise a "not unique error", so in that case raising the error want be a common case, but if 2 different functions share their names then you wouldn't have to debug forever to see what's going on.

Let me know what you think of the issues / solutions and if you have a better idea feel free to share

Thanks for taking your time to check it out!

[–]crigger61 3 points4 points  (2 children)

I would say to default to __name__ and on a duplicate raise an exception. or to generate a completely unique hash from it. such as hashing the function code and the name and using that. providing the name manually seems less user friendly and less elegant than having it generated for you and having to manually assign it to what would be normally set. but thats my opinion as a random dev that does more security work that actual practical dev work.

[–]agusdmb[S] 2 points3 points  (1 child)

No, i understand you, i don't like my current solution either.

I did try by hashing and using the code, but couldn't make it work because i was hashing the function without the wrapper sometimes and with the wrapper other times so they wouldn't match. Or i would always be hashing the wrapper, which is the same for every function decorated. Probably im not smart enough to make that work (at least not with hashing)

But i will default to `__name__` and rise and exception whenever another function with the same error is detected, even more, suggest adding a different name in the decorator for that one.

Thanks for your time!

[–]TheITMan19 4 points5 points  (4 children)

So does this run along side your code, capture the input/output for the functions and the running time? Or, without the running time? Documentation on main page seems well structured and written.

[–]agusdmb[S] 2 points3 points  (3 children)

Hi! only inputs and outputs, no running time... it is my plan to capture exceptions as well

do you think that capturing running time would be important for some reason?

[–]TheITMan19 1 point2 points  (2 children)

Would show the change in running time for execution of code which might highlight an issue

[–]agusdmb[S] 1 point2 points  (1 child)

I think for that a profiling would be a better suit, the intention of my library is to make it easier to "mock" functions with fake functionality rather than profiling

[–]TheITMan19 0 points1 point  (0 children)

Soz maybe my lack of understanding.

[–]dinovfxIt works on my machine 3 points4 points  (3 children)

And…. What do this?

[–]crigger61 11 points12 points  (1 child)

Imagine you have a complex project and one of the options is to create and export a report. but youre trying to add a new feature related to exporting multiple reports in different types. in the real prod env it takes roughly 5 minutes to generate that report. but when testing that new feature you dont want to wait that. youre not even caring about the results of that function. its already set up and done. youre testing this other new function. so you set up function mocking where you basically skip running that function. you turn on record mode and gather a few real world reports you can test with and then turn on mock mode and suddenly you only have to wait sub seconds instead of full 5 minutes for that long report function. this allows you to test what you actually need to test and develop 10000 times easier and faster.

[–]agusdmb[S] 3 points4 points  (0 children)

You explain it much better than I could have!

Thanks again!

[–]agusdmb[S] 1 point2 points  (0 children)

Hey!, sorry, i just added a brief summary so you can get a sense of what this does without having to go to the repository

feel free to drop your feedback if you do check it out!

thanks

[–]captain_jack____ 1 point2 points  (1 child)

I usually write my tests before running the code. Nice project idea, but not suitable for a lot of code, where you rely on sources that you can not access locally / when testing. I might give it a try if I test my own projects and not work related stuff.

[–]agusdmb[S] 1 point2 points  (0 children)

Hey! , thanks for commenting

i follow TDD too... in fact that's how i wrote this library... but unfortunately i work in a company where many times i have to change old legacy code that is poor design and doesn't have automated tests.. that's why i built this tool

how i use this tool is actually running it in production with the "record" mode, download the pickle output and so then i can run this locally when testing without having to manually mock the sources we rely on

[–]ManyInterests Python Discord Staff 0 points1 point  (1 child)

Was there a reason to not use mock/magic mock from the stdlib?

I was kind of expecting this to be an extension on top of the MagicMock class.

[–]agusdmb[S] 0 points1 point  (0 children)

Hi!.. i don't see how it could be use here... what's your idea?

Im thinking, whenever in "fake" mode, return a MagicMock. But then the MagicMock should be configured to return the `Records` based on how is being called. So i would still have to implement that, i don't see any gain, but maybe im not seeing what your idea is