| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Codecov Report✅ All modified and coverable lines are covered by tests. @@ Coverage Diff @@
## main #366 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 9 9
Lines 520 520
=========================================
Hits 520 520
|
Sorry, something went wrong.
Directions for deprecating functionsThis is step-by-step directions for deprecating an old method or class using the @deprecated decorator. We are doing this because lots of methods/functions using camel case (ie. myFunction()) which is not the standard. The standard is to use snake case (ie. my_function()). Additionally, we are refactoring diffpy.srfit to break out its modules into separate packages, meaning where a class is imported from will change (ie from diffpy.srfit.pdf import BasePDFGenerator will change to from diffpy.cmipdf import BasePDFGenerator. The new package created here is diffpy.cmipdf). This will break peoples scripts, therefore we want to deprecate these things. Here are instructions to do so!! Deprecating a function/methodFirst, you will have to locate method or function that needs to be deprecated. For this example, I will be using the setProfile() method from diffpy.srfit. This method is a part of the FitContribution class located under src/diffpy/srfit/fitbase/fitcontribution.py. 1) Write a private function for the deprecation messageTo make the deprecation methods consistent, its helpful to write a little function that prints the same message. We want the message to let the user know what is going to be broken in the future, what version it will be broken in, and what its new name will be. Because these changes are API-breaking, The removal will be made on a version bump of the first number (ie. going from version 3.2.0 to version 4.0.0 or something like that). This is what that function will look like for our current example: removal_version = "4.0.0"
def _dep_msg_fitcontrib(old_name, new_name, version=removal_version):
msg = (
f"'diffpy.srfit.fitbase.fitcontribution.FitContribution.{old_name}' "
f"is deprecated and will be removed in version {version}. Please use "
f"'diffpy.srfit.fitbase.fitcontribution.FitContribution.{new_name}' "
"instead."
)
return msg
Now i can reuse this throughout this file very easily! 2) import the deprecatorAs mentioned, I will be deprecating the setProfile() method and changing it to set_profile(). In Python 3.13, there is a built-in deprecation decorator. Since our packages support Python 3.12 still, we have to import a custom deprecator from diffpy.utils. Once we drop support for Python 3.12 (likely next year), we won't have to do this import. The API of the custom deprecator and the built-in one are identical so this will work for any python version. To import it, type from diffpy.utils._deprecator import deprecated 3) Change name of deprecated functionOnce imported, go to the method that needs to be deprecated, for me, this method looks like this currently, def setProfile(self, profile, xname=None, yname=None, dyname=None):
"""Assign the Profile for this FitContribution.
"""
# Enforce type of the profile argument
if not isinstance(profile, Profile):
emsg = "Argument must be an instance of the Profile class."
raise TypeError(emsg)
# Set the Profile and add its parameters to this organizer.
self.profile = profile
if xname is None:
xname = self.profile.xpar.name
if yname is None:
yname = self.profile.ypar.name
if dyname is None:
dyname = self.profile.dypar.name
self._xname = xname
self._yname = yname
self._dyname = dyname
xpar = ParameterProxy(xname, self.profile.xpar)
ypar = ParameterProxy(yname, self.profile.ypar)
dypar = ParameterProxy(dyname, self.profile.dypar)
self.addParameter(xpar, check=False)
self.addParameter(ypar, check=False)
self.addParameter(dypar, check=False)
# If we have ProfileGenerators, set their Profiles.
for gen in self._generators.values():
gen.setProfile(profile)
# If we have _eq, but not _reseq, set the residual
if self._eq is not None and self._reseq is None:
self.setResidualEquation("chiv")
return
To deprecate it, I will change this functions name from setProfile to set_profile. At the same time, I will add a new function directly above it with the old name that points to the new function name. This will look like, def setProfile(self, profile, xname=None, yname=None, dyname=None):
"""Deprecated.
Use set_profile instead.
"""
return self.set_profile(
profile, xname=xname, yname=yname, dyname=dyname
)
def set_profile(self, profile, xname=None, yname=None, dyname=None):
"""Assign the Profile for this FitContribution.
....
4) Use the @deprecated decorator to mark as deprecatedLastly, to finally do the deprecation, we will use the @deprecated decorator, this will throw the warning message when a user tries to use the deprecated function. To add it, add the following directly above the function with the old name. We will use our helper function right here, @deprecated(_dep_msg_fitcontrib("setProfile", "set_profile"))
def setProfile(self, profile, xname=None, yname=None, dyname=None):
"""Deprecated.
Use set_profile instead.
"""
return self.set_profile(
profile, xname=xname, yname=yname, dyname=dyname
)
5) global search to replace the old function name with the new oneLastly, to a case-sensitive global search of the old function name and replace all occurrences with the new name EXCEPT THE FUNCTION THAT WILL THROW THE DEPRECATION WARNING. Pre-commit should catch this redefinition though if you accidentally replace it. This is very important because if you don't do that, the user will see the deprecation warnings every time the function is called by the code, even if its not called by them. final outcomeNow, when the user tries to use the setProfile method in a script, it will print the following deprecation message, letting users know what will be removed in the future. $ python fitBulkNi.py /diffpy.cmi/docs/examples/pdf/ch03NiModelling/solutions/diffpy-cmi/fitBulkNi.py:151: DeprecationWarning: 'diffpy.srfit.fitbase.fitcontribution.FitContribution.setProfile' is deprecated and will be removed in version 4.0.0. Please use 'diffpy.srfit.fitbase.fitcontribution.FitContribution.set_profile' instead. |
Sorry, something went wrong.
|
@sbillinge I wrote instructions (see above) on how to deprecate things. I tested this and it works too. I think we can begin deprecating and assigning people to deprecation tasks. We can link them to here or put this information in a different/better spot. |
Sorry, something went wrong.
|
Let's move this to mission-control. I will create a new repo there called operation-deprecate-everything This could be a good job for new students at UCSB. Get them learning forking workflow and group standards..... |
Sorry, something went wrong.
|
@sbillinge Perfect, thats exactly what I was thinking. Let me know when its live. |
Sorry, something went wrong.
|
https://github.com/bg-mission-control/operation-deprecate-everything is live (but empty) |
Sorry, something went wrong.
|
@sbillinge I dont think i have permission for this repo. Im getting a 404 error. |
Sorry, something went wrong.
please could you try now? |
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
The other deprecator didnt match the API for python 3.13. This fixes that. I tested this in python 3.12 and 3.13 envs and it worked as expected (using debugging print statements).